07.显示系统:第005课_Vsync机制:第004节_surface使用vsync过程代码分析

前面的小节中,我们讲解了Vsync机制机制的框架,无论SurfaceFlinger还是APP应用程序,对Vsync的使用,都是按需进行的:

在这里插入图片描述比如应用程序把新界面发送给SurfaceFlinger之后,SurfaceFlinger就需要得到一个Vsync信号,他就会把这个需求发送给EventThread,EventThread再转发给DispSyncThread,DispSyncThread收到硬件Vsync信号,或者软件Vsync信号之后,发会休眠一段时间,把信号虚拟化成Vsync-APP与Vsync-SF,然后发送给对应的EventThread,EventThread在发送给SurfaceFlinger,然后SurfaceFlinge在进行图片合成。
该小节我们对surface使用vsync的过程进行分析。

surface使用vsync可以分为以下几个步骤:

1.APP发送数据给SurfaceFlinger。
2.SurfaceFlinger发送请求给EventThread(sf)。
3.EventThread在发送请求给DispSyncThread
4.软件或者硬件的Vsync会唤醒DispSyncThread。
5.DispSyncThread发送信号给EventThread,EventThread发送信号给SurfaceFlinger,然后SurfaceFlinger在对图片进行处理(如:合成等等)

下面是是一个详细的代码调用过程:
在这里插入图片描述
在左上角标号1的处开始阅读

为了大家快速的了解,下面是一个草图。我们将围绕这这个草图进行讲解。
在这里插入图片描述

首先是应用程序APP发送数据给SurfaceFlinger,SurfaceFlinger跟EventThread存在一个connection的连接,SurfaceFlinger会向EventThread提出请求,这个请求会转发给DispSyncThread,DispSyncThread会被软件(一个线程VsyncThread)或者硬件产生的Vsync信号唤醒,

1.APP发送数据给SurfaceFlinger与SurfaceFlinger发送请求给EventThread(sf)

我们首先来看看APP发送数据给SurfaceFlinger的过程,其详细过程,我们在之前的章节中。已经进行了讲解,故此,这里只做简单的分析。

打开SurfaceFlinger.cpp文件,找到signalLayerUpdate函数:

/*当检测到有数据需要更新的时候,就会调用该函数*/
void SurfaceFlinger::signalLayerUpdate() {
    mEventQueue.invalidate();
    	/*请求得到下一个vsync信号,其中mEvents为Connection*/
    	mEvents->requestNextVsync();

可以看到其上mEvents为Connection类型,requestNextVsync函数在EventThread.cpp中实现:

void EventThread::requestNextVsync(
    /*如果count<0*/
    if (connection->count < 0) {
        connection->count = 0;
        /*发送一个广播,其目的是为了唤醒某一个线程*/
        mCondition.broadcast();
    }

注意requestNextVsync是EventThread中的线程,但是在SurfaceFlinger进程中使用,也就是说,SurfaceFlinger利用EventThread中提供的函数唤醒EventThread线程。
下面我们开始讲解第三个步骤。

EventThread再发送请求给DispSyncThread

之前我们提到,SurfaceFlinger把信号请求发送给EventThread,EventThread在把这个请求发送给DispSyncThread。

在EventThread.cpp中存在函数ThreadLoop:

bool EventThread::threadLoop() {
	/*1.发出Vsync信号请求,然后等待Vsync信号,其内部会判断所有Connection的count
	如果count大于0,这代表需要得到Vsync信号*/
	signalConnections = waitForEvent(&event);
		/*得到一个connection*/
		sp<Connection> connection(mDisplayEventConnections[i].promote());
		/*如果connection->count >= 0,则代表需要下一个vsync信号*/
		waitForVSync = true;
		enableVSyncLocked();
			/*给DispSyncThread设置回调函数Callback*/
			mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
			mVSyncSource->setVSyncEnabled(true);
		/*等待vsync信号*/
		mCondition.wait(mLock);	
	/*发送信号给SurfaceFlinger*/
	status_t err = conn->postEvent(event);

从上面我们可以看到,当connection->count >= 0时,代表需要Vsync信号,其会为DispSyncThread线程设置一个回调函数Callback,当DispSyncThread接收到信号之后,就会调用该回调函数。

4.软件或者硬件的Vsync会唤醒DispSyncThread

从上面我们知道EventThread发送给请求给DispSyncThread之后进入休眠状态,DispSyncThread一般也处于休眠状态,其会被一个Vsync信号唤醒,我们暂时不理会硬件的sync信号,我们来看看软件的sync信号如何产生。

打开frameworks\native\services\surfaceflinger\DisplayHardware目录下的SoftVsyncObserver.cpp文件:

bool SoftVsyncObserver::threadLoop()
	spec.tv_sec  = next_vsync / 1000000000;
    spec.tv_nsec = next_vsync % 1000000000;
    err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
    /*发出Vsync信号*/
    mDisplayDevice.onVsync(next_vsync);
    	mHwc.vsync(DEVICE_VIRTUAL, timestamp);

软件产生的方式比较简单,就是循环延时发出信号,然后会唤醒DispSyncThread线程,DispSyncThread发送信号给EventThread,EventThread调用

void SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {

函数唤醒SurfaceFlinger线程。在DispSync.cpp中:

virtual bool threadLoop() {
	/**计算最近的EventThread的时间Listeer*/
    targetTime = computeNextEventTimeLocked(now);
    	nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i],
    /*现在的时间少于目标时间,则等待*/
    if (now < targetTime) {
    	/*修改等待时间到*/
         err = mCond.waitRelative(mMutex, targetTime - now);
    /*收集回调函数*/
    callbackInvocations = gatherCallbackInvocationsLocked(now);
    /*调用回调函数*/
    fireCallbackInvocations(callbackInvocations);

其上的回调函数,即前面EventThread线程中设置的回调函数。其中的Listeer来源:
EventThread线程发现connection->count >= 0时,向DispSyncThread注册Callback。Callback最终会导致EventThread中的onVSyncEvent被调用:

void EventThread::onVSyncEvent(nsecs_t timestamp) {
	/*发出一个广播*/
	mCondition.broadcast();

实际就是通过广播唤醒EventThread(ThreadLoop)线程。

SurfaceFlinger接收到Vsync信号之后会调用MessageQueue.cpp中:

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
    queue->eventReceiver(fd, events);
    	 mHandler->dispatchInvalidate();
    	 	/*发送一个消息*/
			mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));

发送消息之后:

void MessageQueue::Handler::handleMessage(const Message& message) {
	mQueue.mFlinger->onMessageReceived(message.what);

handleMessage会进行处理。其中onMessageReceived在SurfaceFlinger.cpp中实现:

void SurfaceFlinger::onMessageReceived(int32_t what) {
	signalLayerUpdate();
	refreshNeeded |= handleMessageInvalidate();
	handleMessageRefresh();

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/89047328