Android 4.4 Graphic系统详解(3) VSYNC的处理

http://blog.csdn.net/lee_3do/article/details/39288329

回顾

我们在上面一节中讲到了SurfaceFlinger创建过程中和VSync有关的一些处理,总结起来如下图:此处输入图片的描述图中红色部分涉及到了VSync信号的在系统内的传输过程,我们在这一章详细的展开说明。

向Eventhread注册一个事件的监听者——createEventConnection

在SurfaceFlinger的init函数中,我们调用了mEventQueue.setEventThread(mSFEventThread)函数,我们在前面一章中已经提到过,这个函数将SurfaceFlinger的MessageQueue真正和我们刚才创建的EventThread建立起了连接。我们来看下这段代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  
  2. {  
  3.     mEventThread = eventThread;  
  4.     mEvents = eventThread->createEventConnection();  
  5.     mEventTube = mEvents->getDataChannel();  
  6.     mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,  
  7.             MessageQueue::cb_eventReceiver, this);  
  8. }  


createEventConnection是将EventThread和MessageQueue建立连接的函数:

   
   
  1. sp<EventThread::Connection> EventThread::createEventConnection() const {  
  2.     return new Connection(const_cast<EventThread*>(this));  
  3. }  
  4. EventThread::Connection::Connection(  
  5.         const sp<EventThread>& eventThread)  
  6.     : count(-1), mEventThread(eventThread), mChannel(new BitTube())  
  7. {  
  8. }  
  9. void EventThread::Connection::onFirstRef() {  
  10.     mEventThread->registerDisplayEventConnection(this);  
  11. }  
  12. status_t EventThread::registerDisplayEventConnection(  
  13.         const sp<EventThread::Connection>& connection) {  
  14.     mDisplayEventConnections.add(connection);  
  15.     mCondition.broadcast();  
  16. }  

我们看这个函数虽然传递了很多次,但是其实逻辑依然很简单易懂。其实无非是这个函数会导致一个Connection类的创建,而这个connection类会被保存在EventThread下的一个容器内。

通过createEventConnection这样一个简单的方法,我们其实就注册了一个事件的监听者,得到了发送VSYNC事件通知的BitTube,然后监控这个BitTube中的套接字,并且指定了收到通知后的回调函数,MessageQueue::cb_eventReceiver。这样一旦VSync信号传来,函数cb_eventReceiver将被调用。

等待事件

继续回到上一章的图中:
此处输入图片的描述
刚才我们分析了创建一个连接,SurfaceFlinger的MessageQueue注册了一个监听者到EventThread中的mDisplayEventConnections容器中,等待event事件到来时被通知。下面我们继续分析一下我们前面一章没有展开说明的另外一个函数:
EventThread中等待事件时的函数waitForEvent。

   
   
  1. // This will return when (1) a vsync event has been received, and (2) there was  
  2. // at least one connection interested in receiving it when we started waiting.  
  3. Vector< sp<EventThread::Connection> > EventThread::waitForEvent(  
  4.         DisplayEventReceiver::Event* event)  
  5. {  
  6.         // Here we figure out if we need to enable or disable vsyncs  
  7.         if (timestamp && !waitForVSync) {  
  8.             // we received a VSYNC but we have no clients  
  9.             // don't report it, and disable VSYNC events  
  10.             disableVSyncLocked();  
  11.         } else if (!timestamp && waitForVSync) {  
  12.             // we have at least one client, so we want vsync enabled  
  13.             // (TODO: this function is called right after we finish  
  14.             // notifying clients of a vsync, so this call will be made  
  15.             // at the vsync rate, e.g. 60fps.  If we can accurately  
  16.             // track the current state we could avoid making this call  
  17.             // so often.)  
  18.             enableVSyncLocked();  
  19.         }  
  20.   
  21.         // note: !timestamp implies signalConnections.isEmpty(), because we  
  22.         // don't populate signalConnections if there's no vsync pending  
  23.         if (!timestamp && !eventPending) {  
  24.             // wait for something to happen  
  25.             if (waitForVSync) {  
  26.                 // This is where we spend most of our time, waiting  
  27.                 // for vsync events and new client registrations.  
  28.                 //  
  29.                 // If the screen is off, we can't use h/w vsync, so we  
  30.                 // use a 16ms timeout instead.  It doesn't need to be  
  31.                 // precise, we just need to keep feeding our clients.  
  32.                 //  
  33.                 // We don't want to stall if there's a driver bug, so we  
  34.                 // use a (long) timeout when waiting for h/w vsync, and  
  35.                 // generate fake events when necessary.  
  36.                 bool softwareSync = mUseSoftwareVSync;  
  37.                 nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);  
  38.                 if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {  
  39.                     if (!softwareSync) {  
  40.                         ALOGW("Timed out waiting for hw vsync; faking it");  
  41.                     }  
  42.                     // FIXME: how do we decide which display id the fake  
  43.                     // vsync came from ?  
  44.                     mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  45.                     mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;  
  46.                     mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);  
  47.                     mVSyncEvent[0].vsync.count++;  
  48.                 }  
  49.             } else {  
  50.                 // Nobody is interested in vsync, so we just want to sleep.  
  51.                 // h/w vsync should be disabled, so this will wait until we  
  52.                 // get a new connection, or an existing connection becomes  
  53.                 // interested in receiving vsync again.  
  54.                 mCondition.wait(mLock);  
  55.             }  
  56.         }  
  57.     } while (signalConnections.isEmpty());  
  58.   
  59.     // here we're guaranteed to have a timestamp and some connections to signal  
  60.     // (The connections might have dropped out of mDisplayEventConnections  
  61.     // while we were asleep, but we'll still have strong references to them.)  
  62.     return signalConnections;  
  63. }  

waitForEvent是一个相当长的函数,我们上文只截取了函数的后半部分,在被删掉的前半部分中,函数主要在处理和EventThread建立起连接的客户端,也就是我们上面提到的通过createEventConnection来于EventThread建立起连接的客户端。
前半部分代码通过计算对两个变量的赋值产生了影响,timestamp非零代表有一个VSync信号需要处理,waitForVSync为true则代表有客户端在等待VSync信号。我们下面来仔细分析下后半部分的代码:

   
   
  1. // Here we figure out if we need to enable or disable vsyncs  
  2. if (timestamp && !waitForVSync) {  
  3.     // we received a VSYNC but we have no clients  
  4.     // don't report it, and disable VSYNC events  
  5.     disableVSyncLocked();  
  6. else if (!timestamp && waitForVSync) {  
  7.     // we have at least one client, so we want vsync enabled  
  8.     // (TODO: this function is called right after we finish  
  9.     // notifying clients of a vsync, so this call will be made  
  10.     // at the vsync rate, e.g. 60fps.  If we can accurately  
  11.     // track the current state we could avoid making this call  
  12.     // so often.)  
  13.     enableVSyncLocked();  
  14. }  

上面这段代码的含义其实注释里面写的很清楚,根据是否需要来决定禁用和开启VSync信号。两个分支的条件也都有注释,第一个分支的含义是收到了VSync但是却没有客户端感兴趣,这个时候我们会选择禁用VSync,另一条分支则是没有收到VSync信号但是有客户端对信号感兴趣,那么这个时候我们会开启VSync。

在上一章中我们已经提到了,真正向硬件发送开关VSync信号的命令的是EventControlThread,那么这里的disableVSyncLocked和enableVSyncLocked的原理是否和EventControlThread一致呢?我们来仔细分析一下这个函数:

   
   
  1. void EventThread::enableVSyncLocked() {  
  2.     if (!mUseSoftwareVSync) {//这个条件会筛掉灭屏的情况  
  3.         // never enable h/w VSYNC when screen is off  
  4.         if (!mVsyncEnabled) {  
  5.             mVsyncEnabled = true;  
  6.             mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));  
  7.             mVSyncSource->setVSyncEnabled(true);  
  8.             mPowerHAL.vsyncHint(true);  
  9.         }  
  10.     }  
  11.     mDebugVsyncEnabled = true;  
  12. }  

上面函数主要调用了VSyncSource的setVSyncEnabled函数:

   
   
  1. virtual void setVSyncEnabled(bool enable) {  
  2.     // Do NOT lock the mutex here so as to avoid any mutex ordering issues  
  3.     // with locking it in the onDispSyncEvent callback.  
  4.     if (enable) {  
  5.         status_t err = mDispSync->addEventListener(mPhaseOffset,  
  6.                 static_cast<DispSync::Callback*>(this));  
  7.         if (err != NO_ERROR) {  
  8.             ALOGE("error registering vsync callback: %s (%d)",  
  9.                     strerror(-err), err);  
  10.         }  
  11.         ATRACE_INT("VsyncOn", 1);  
  12.     } else {  
  13.         status_t err = mDispSync->removeEventListener(  
  14.                 static_cast<DispSync::Callback*>(this));  
  15.         if (err != NO_ERROR) {  
  16.             ALOGE("error unregistering vsync callback: %s (%d)",  
  17.                     strerror(-err), err);  
  18.         }  
  19.         ATRACE_INT("VsyncOn", 0);  
  20.     }  
  21. }  
  22.   
  23. status_t DispSync::addEventListener(nsecs_t phase,  
  24.     const sp<Callback>& callback) {  
  25.     return mThread->addEventListener(phase, callback);  
  26. }  

看到这里我们发现,其实所谓的disableVSyncLocked和enableVSyncLocked禁用开启VSync信号并非真的让硬件停止发送信号,只是向DispSync(里面的DispSyncThread,DispSyncThread在DispSync被创建时启动)删除和添加事件的监听者,通过添加监听者,新的监听者就可以收到来自硬件的VSync消息,而一旦删除,EventThread不再能收到消息,显然对于EventThread来说,也就禁用了VSync消息。

分析完EventThread的disableVSyncLocked和enableVSyncLocked函数,我们回到waitForEvent函数继续分析。剩下的逻辑很简单了:

   
   
  1. // wait for something to happen  
  2.             if (waitForVSync) {  
  3.                 // This is where we spend most of our time, waiting  
  4.                 // for vsync events and new client registrations.  
  5.                 //  
  6.                 // If the screen is off, we can't use h/w vsync, so we  
  7.                 // use a 16ms timeout instead.  It doesn't need to be  
  8.                 // precise, we just need to keep feeding our clients.  
  9.                 //  
  10.                 // We don't want to stall if there's a driver bug, so we  
  11.                 // use a (long) timeout when waiting for h/w vsync, and  
  12.                 // generate fake events when necessary.  
  13.                 bool softwareSync = mUseSoftwareVSync;  
  14.                 nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);  
  15.                 if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {  
  16.                     if (!softwareSync) {  
  17.                         ALOGW("Timed out waiting for hw vsync; faking it");  
  18.                     }  
  19.                     // FIXME: how do we decide which display id the fake  
  20.                     // vsync came from ?  
  21.                     mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  22.                     mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;  
  23.                     mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);  
  24.                     mVSyncEvent[0].vsync.count++;  
  25.                 }  
  26.             } else {  
  27.                 // Nobody is interested in vsync, so we just want to sleep.  
  28.                 // h/w vsync should be disabled, so this will wait until we  
  29.                 // get a new connection, or an existing connection becomes  
  30.                 // interested in receiving vsync again.  
  31.                 mCondition.wait(mLock);  
  32.             }  

代码不长,逻辑也很简单,这里通过mCondition.waitRelative和mCondition.wait开始等待事件的发生了。
终于分析完这里,我们已经注册好了监听者,起好了线程,开始等待VSync的到来了。我们终于可以回到最最开始的问题里面,当VSync信号发出来时,系统到底是怎么处理的?

VSync信号的处理

我们在前面一章也提到了无论是软件方式还是硬件方式,SurfaceFlinger收到VSync信号后,处理函数都是onVSyncReceived函数:

   
   
  1. void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {  
  2.     bool needsHwVsync = false;  
  3.     {  
  4.         if (type == 0 && mPrimaryHWVsyncEnabled) {  
  5.             needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);  
  6.         }  
  7.     }  
  8.     if (needsHwVsync) {  
  9.         enableHardwareVsync();  
  10.     } else {  
  11.         disableHardwareVsync(false);  
  12.     }  
  13. }  

前文中我们也说过这段代码中最重要的一个函数调用—-addResyncSample,下面本文也将从这个函数开始继续VSync的研究。

真正开始处理VSync消息——addResyncSample

   
   
  1. bool DispSync::addResyncSample(nsecs_t timestamp) {  
  2.     size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;  
  3.     mResyncSamples[idx] = timestamp;  
  4.   
  5.     if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {  
  6.         mNumResyncSamples++;  
  7.     } else {  
  8.         mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;  
  9.     }  
  10.   
  11.     updateModelLocked();  
  12.   
  13.     if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {  
  14.         resetErrorLocked();  
  15.     }  
  16.     if (runningWithoutSyncFramework) {  
  17.         // If we don't have the sync framework we will never have  
  18.         // addPresentFence called.  This means we have no way to know whether  
  19.         // or not we're synchronized with the HW vsyncs, so we just request  
  20.         // that the HW vsync events be turned on whenever we need to generate  
  21.         // SW vsync events.  
  22.         return mThread->hasAnyEventListeners();  
  23.     }  
  24.   
  25.     return mPeriod == 0 || mError > errorThreshold;  
  26. }  

粗略浏览下这个函数,发现前半部分其实在做一些简单的计数统计,重点实现显然是updateModelLocked函数:

   
   
  1. void DispSync::updateModelLocked() {  
  2.     if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {  
  3.         nsecs_t durationSum = 0;  
  4.         for (size_t i = 1; i < mNumResyncSamples; i++) {  
  5.             size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;  
  6.             size_t prev = (idx + MAX_RESYNC_SAMPLES - 1) % MAX_RESYNC_SAMPLES;  
  7.             durationSum += mResyncSamples[idx] - mResyncSamples[prev];  
  8.         }  
  9.   
  10.         mPeriod = durationSum / (mNumResyncSamples - 1);  
  11.   
  12.         double sampleAvgX = 0;  
  13.         double sampleAvgY = 0;  
  14.         double scale = 2.0 * M_PI / double(mPeriod);  
  15.         for (size_t i = 0; i < mNumResyncSamples; i++) {  
  16.             size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;  
  17.             nsecs_t sample = mResyncSamples[idx];  
  18.             double samplePhase = double(sample % mPeriod) * scale;  
  19.             sampleAvgX += cos(samplePhase);  
  20.             sampleAvgY += sin(samplePhase);  
  21.         }  
  22.   
  23.         sampleAvgX /= double(mNumResyncSamples);  
  24.         sampleAvgY /= double(mNumResyncSamples);  
  25.   
  26.         mPhase = nsecs_t(atan2(sampleAvgY, sampleAvgX) / scale);  
  27.   
  28.         if (mPhase < 0) {  
  29.             mPhase += mPeriod;  
  30.         }  
  31.   
  32.         if (traceDetailedInfo) {  
  33.             ATRACE_INT64("DispSync:Period", mPeriod);  
  34.             ATRACE_INT64("DispSync:Phase", mPhase);  
  35.         }  
  36.   
  37.         mThread->updateModel(mPeriod, mPhase);  
  38.     }  
  39. }  

不得不说,前面大段的数学计算让人有些困惑,我们暂且跳过,先分析下主线流程,也就是mThread->updateModel(mPeriod, mPhase)这个调用:

DispSyncThread.updateModel的用途

   
   
  1. void updateModel(nsecs_t period, nsecs_t phase) {  
  2.     Mutex::Autolock lock(mMutex);  
  3.     mPeriod = period;  
  4.     mPhase = phase;  
  5.     mCond.signal();  
  6. }  

updateModel是DispSyncThread类的函数,这个函数本身代码很短,其实它的主要作用是mCond.signal发送一个信号给等待中的线程。那么究竟是谁在等待这个条件呢?
其实等待这个条件的正是DispSyncThread的循环函数:

  
   
   
  1. virtual bool threadLoop() {  
  2.       status_t err;  
  3.       nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  
  4.       nsecs_t nextEventTime = 0;  
  5.       while (true) {  
  6.           Vector<CallbackInvocation> callbackInvocations;  
  7.           nsecs_t targetTime = 0;  
  8.           { // Scope for lock  
  9.               Mutex::Autolock lock(mMutex);  
  10.               if (mStop) {  
  11.                   return false;  
  12.               }  
  13.               if (mPeriod == 0) {  
  14.                   err = mCond.wait(mMutex);  
  15.                   if (err != NO_ERROR) {  
  16.                       ALOGE("error waiting for new events: %s (%d)",  
  17.                               strerror(-err), err);  
  18.                       return false;  
  19.                   }  
  20.                   continue;  
  21.               }  
  22.               nextEventTime = computeNextEventTimeLocked(now);  
  23.               targetTime = nextEventTime;  
  24.               bool isWakeup = false;  
  25.               if (now < targetTime) {  
  26.                   err = mCond.waitRelative(mMutex, targetTime - now);  
  27.                   if (err == TIMED_OUT) {  
  28.                       isWakeup = true;  
  29.                   } else if (err != NO_ERROR) {  
  30.                       ALOGE("error waiting for next event: %s (%d)",  
  31.                               strerror(-err), err);  
  32.                       return false;  
  33.                   }  
  34.               }  
  35.               now = systemTime(SYSTEM_TIME_MONOTONIC);  
  36.               if (isWakeup) {  
  37.                   mWakeupLatency = ((mWakeupLatency * 63) +  
  38.                           (now - targetTime)) / 64;  
  39.                   if (mWakeupLatency > 500000) {  
  40.                       // Don't correct by more than 500 us  
  41.                       mWakeupLatency = 500000;  
  42.                   }  
  43.                   if (traceDetailedInfo) {  
  44.                       ATRACE_INT64("DispSync:WakeupLat", now - nextEventTime);  
  45.                       ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);  
  46.                   }  
  47.               }  
  48.               callbackInvocations = gatherCallbackInvocationsLocked(now);  
  49.           }  
  50.           if (callbackInvocations.size() > 0) {  
  51.               fireCallbackInvocations(callbackInvocations);  
  52.           }  
  53.       }  
  54.       return false;  
  55.   }  

大量的时间相关的计算和状态的转变我们不再深入研究,我们来看下这个线程被通知唤醒之后做的两个主要的函数的处理,gatherCallbackInvocationsLocked和fireCallbackInvocations。

gatherCallbackInvocationsLocked的代码其实很简单:

   
   
  1. Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) {  
  2.     Vector<CallbackInvocation> callbackInvocations;  
  3.     nsecs_t ref = now - mPeriod;  
  4.     for (size_t i = 0; i < mEventListeners.size(); i++) {  
  5.         nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i],  
  6.                 ref);  
  7.         if (t < now) {  
  8.             CallbackInvocation ci;  
  9.             ci.mCallback = mEventListeners[i].mCallback;  
  10.             ci.mEventTime = t;  
  11.             callbackInvocations.push(ci);  
  12.             mEventListeners.editItemAt(i).mLastEventTime = t;  
  13.         }  
  14.     }  
  15.     return callbackInvocations;  
  16. }  

其实就是从mEventListeners取出之前注册的事件监听者,放入callbackInvocations中,等待后面的调用。至于监听者从何处而来?我们在前面已经给出了分析,在waitforevent时通过enableVSyncLocked注册的。

继续看下fireCallbackInvocations函数:

   
   
  1. void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {  
  2.     for (size_t i = 0; i < callbacks.size(); i++) {  
  3.         callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);  
  4.     }  
  5. }`  

我们目前只分析主线的走向,接下来调用了DispSyncSource的onDispSyncEvent在:

   
   
  1.     virtual void onDispSyncEvent(nsecs_t when) {  
  2.         sp<VSyncSource::Callback> callback;  
  3.         {  
  4.             callback = mCallback;  
  5.         }  
  6.         if (callback != NULL) {  
  7.             callback->onVSyncEvent(when);  
  8.         }  
  9.     }  
  10. void EventThread::onVSyncEvent(nsecs_t timestamp) {  
  11.     Mutex::Autolock _l(mLock);  
  12.     mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;  
  13.     mVSyncEvent[0].header.id = 0;  
  14.     mVSyncEvent[0].header.timestamp = timestamp;  
  15.     mVSyncEvent[0].vsync.count++;  
  16.     mCondition.broadcast();  
  17. }  

我们看到这里mCondition.broadcas发出了命令,那么EventThread中waitforEvent的等待就会被唤醒。而一旦唤醒,我们就回到了EventThread的loop中,我们来看下代码:

   
   
  1. bool EventThread::threadLoop() {  
  2.     DisplayEventReceiver::Event event;  
  3.     Vector< sp<EventThread::Connection> > signalConnections;  
  4.     signalConnections = waitForEvent(&event);  
  5.   
  6.     // dispatch events to listeners...  
  7.     const size_t count = signalConnections.size();  
  8.     for (size_t i=0 ; i<count ; i++) {  
  9.         const sp<Connection>& conn(signalConnections[i]);  
  10.         // now see if we still need to report this event  
  11.         status_t err = conn->postEvent(event);  
  12.         if (err == -EAGAIN || err == -EWOULDBLOCK) {  
  13.             // The destination doesn't accept events anymore, it's probably  
  14.             // full. For now, we just drop the events on the floor.  
  15.             // FIXME: Note that some events cannot be dropped and would have  
  16.             // to be re-sent later.  
  17.             // Right-now we don't have the ability to do this.  
  18.             ALOGW("EventThread: dropping event (%08x) for connection %p",  
  19.                     event.header.type, conn.get());  
  20.         } else if (err < 0) {  
  21.             // handle any other error on the pipe as fatal. the only  
  22.             // reasonable thing to do is to clean-up this connection.  
  23.             // The most common error we'll get here is -EPIPE.  
  24.             removeDisplayEventConnection(signalConnections[i]);  
  25.         }  
  26.     }  
  27.     return true;  
  28. }  

这里主要就是通过conn->postEvent来分发事件:

   
   
  1. status_t EventThread::Connection::postEvent(  
  2.         const DisplayEventReceiver::Event& event) {  
  3.     ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);  
  4.     return size < 0 ? status_t(size) : status_t(NO_ERROR);  
  5. }  
  6. ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel,  
  7.         Event const* events, size_t count)  
  8. {  
  9.     return BitTube::sendObjects(dataChannel, events, count);  
  10. }  

其实看到这里的BitTube我们就明白了,在本文开始时候我们提到:

通过createEventConnection这样一个简单的方法,我们其实就注册了一个事件的监听者,得到了发送VSYNC事件通知的BitTube,然后监控这个BitTube中的套接字,并且指定了收到通知后的回调函数,MessageQueue::cb_eventReceiver。这样一旦VSync信号传来,函数cb_eventReceiver将被调用。

所以我们这里可以来看看MessageQueue::cb_eventReceiver函数了:

   
   
  1. int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {  
  2.     MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);  
  3.     return queue->eventReceiver(fd, events);  
  4. }  
  5.   
  6. int MessageQueue::eventReceiver(int fd, int events) {  
  7.     ssize_t n;  
  8.     DisplayEventReceiver::Event buffer[8];  
  9.     while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {  
  10.         for (int i=0 ; i<n ; i++) {  
  11.             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {  
  12.                 mHandler->dispatchInvalidate();  
  13.                 break;  
  14.             }  
  15.         }  
  16.     }  
  17.     return 1;  
  18. }  

我们看到收到消息之后MessageQueue对消息进行了分发,我们目前走的是dispatchInvalidate。

   
   
  1. void MessageQueue::Handler::dispatchInvalidate() {  
  2.     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {  
  3.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));  
  4.     }  
  5. }  
  6.   
  7. void MessageQueue::Handler::handleMessage(const Message& message) {  
  8.     switch (message.what) {  
  9.         case INVALIDATE:  
  10.             android_atomic_and(~eventMaskInvalidate, &mEventMask);  
  11.             mQueue.mFlinger->onMessageReceived(message.what);  
  12.             break;  
  13.         case REFRESH:  
  14.             android_atomic_and(~eventMaskRefresh, &mEventMask);  
  15.             mQueue.mFlinger->onMessageReceived(message.what);  
  16.             break;  
  17.         case TRANSACTION:  
  18.             android_atomic_and(~eventMaskTransaction, &mEventMask);  
  19.             mQueue.mFlinger->onMessageReceived(message.what);  
  20.             break;  
  21.     }  
  22. }  
  23.   
  24. void SurfaceFlinger::onMessageReceived(int32_t what) {  
  25.     ATRACE_CALL();  
  26.     switch (what) {  
  27.     case MessageQueue::TRANSACTION:  
  28.         handleMessageTransaction();  
  29.         break;  
  30.     case MessageQueue::INVALIDATE:  
  31.         handleMessageTransaction();  
  32.         handleMessageInvalidate();  
  33.         signalRefresh();  
  34.         break;  
  35.     case MessageQueue::REFRESH:  
  36.         handleMessageRefresh();  
  37.         break;  
  38.     }  
  39. }  

到了这里,就进入了SurfaceFlinger的处理流程,我们看到对于INVALIDATE的消息,实际上系统在处理过程中实际还是会发送一个Refresh消息。
这后面的处理过程,我会在博客后面的文章中详细讲解。

总结

我们用了两小节的篇幅来讲解了VSync在android系统中的作用,生成以及传递。详细说明了从VSync软硬件的生成,一直到事件如何做为一个INVALIDATE消息传递给了Surfaceflinger处理。我们再来回顾一下整体的流程图:
此处输入图片的描述


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值