天天看點

android graphic(4)—surfaceflinger和Vsync

http://blog.csdn.net/lewif/article/details/50573397

目錄(?)[+]

  • android44中的實作
  • 整體流程
  • HWComposer對象的建立
  • EventControlThread閘刀的建立
  • DispSync和DispSyncThread
  • DispSyncSource和EventThread
  • 完整走一遍

Android 4.1一個很大的更新是Project Butter,黃油計劃,為了解決使用者互動體驗差的問題(Jelly Bean iscrazy fast)。 

主要包括兩部分:Vsync和Triple Buffering。(以下surfaceflinger簡寫為SF) 

Vsync,垂直同步,HWC利用硬體或者軟體産生的持續Vsync信号去觸發SF和UI去做繪圖相關的工作,讓繪圖工作充分利用每個Vsync信号間隔的時間; 

Triple Buffering,雖然有Vsync,細想肯定還是無法避免Jank,三緩沖會将Jank幾率降到最小,當然如果出現第一次Jack肯定避免不了。

android4.4中的實作

 DispSync maintainsa model of the periodic hardware-based vsync events of a

 display and usesthat model to execute period callbacks at specific phase

 offsets from thehardware vsync events.  The model isconstructed by

 feedingconsecutive hardware event timestamps to the DispSync object via

 the addResyncSamplemethod.

在4.4中,新加了個DispSync,從上面的解釋,DispSync根據特定螢幕硬體的vsync信号建立一個模型,利用這個模型去做定期的回調工作,回調的時間比vsync信号的到來稍晚一點,有個偏移量。為何要有個偏移量呢?因為這個模型會驅動多個事件,例如SF去合成圖形,如果多個事件一起工作就會出現搶占cpu。是以對每個事件的偏移量設定為不同的,就能減緩這種問題的存在。 

目前隻是看代碼的實作流程,還沒對參數在真實機器上調試過,效果待觀察。

整體流程

android graphic(4)—surfaceflinger和Vsync

上面圖形是Vsync信号從産生到驅動SF去工作的一個過程,其中綠色部分是HWC中的Vsync信号軟體模拟程序,其他都是SF中的: 

其中包含4個線程,EventControlThread,就像是Vsync信号産生的閘刀,當然閘刀肯定需要人去打開和關閉,這個人就是SF; 

VsyncThread,下面的代碼隻介紹軟體模拟的Vsync信号,這個線程主要工作就是循環定期産生信号,然後調用SF中的函數,這就相當于觸發了; 

DispSyncThread,是Vsync信号的模型,VsyncThread首先觸發DispSyncThread,然後DispSyncThread再去驅動其他事件,它就是Vsync在SF中的代表; 

EventThread,具體的事件線程,由DispSyncThread去驅動。 

主要步驟可以分為8步,下面的展開也基本是基于這個步驟。

HWComposer對象的建立

在SF的init()中,

    mHwc = new HWComposer(this,

            *static_cast<HWComposer::EventHandler*>(this));

由于SF也繼承了HWComposer::EventHandler,是以上面的構造函數的輸入都是SF對象。

class SurfaceFlinger : publicBnSurfaceComposer,

                      private IBinder::DeathRecipient,

                      private HWComposer::EventHandler{

                      }

在構造函數中,對mFlinger和mEventHandler指派,這裡不涉及Vsync的硬體實作和Gralloc,其實硬體實作最終調用的SF中的函數和軟體是一樣的。隻關注最後一行軟體實作,建立了一個VSyncThread對象,VSyncThread繼承了Thread,是個線程。

HWComposer::HWComposer(

        constsp<SurfaceFlinger>& flinger,

       EventHandler& handler)

    :mFlinger(flinger),

      mFbDev(0), mHwc(0), mNumDisplays(1),

      mCBContext(new cb_context),

     mEventHandler(handler),

     mDebugForceFakeVSync(false)

{

    //Vsync軟體實作

    if(needVSyncThread) {

        // we don't have VSYNC support, we needto fake it

       mVSyncThread = new VSyncThread(*this);

    }

}

構造函數中,設定了mRefreshPeriod,從HWC_DISPLAY_PRIMARY,從主螢幕擷取。

HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)

    : mHwc(hwc), mEnabled(false),

      mNextFakeVSync(0),

      mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY))

{

}

注意,由于sp<VSyncThread>mVSyncThread;,是個sp指針,第一次引用的時候回去調用onFirstRef() ,一貫的伎倆,啟動了這個線程。

void HWComposer::VSyncThread::onFirstRef() {

    run("VSyncThread", PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);

}

那麼我們需要看下線程函數的實作,

boolHWComposer::VSyncThread::threadLoop() {

    { // scope for lock

       Mutex::Autolock _l(mLock);

        //①

        //初始為false,阻塞

        while (!mEnabled) {

            mCondition.wait(mLock);

        }

    }

    const nsecs_t period= mRefreshPeriod;

    const nsecs_t now =systemTime(CLOCK_MONOTONIC);

    nsecs_tnext_vsync = mNextFakeVSync;

    nsecs_t sleep =next_vsync - now;

    if (sleep < 0) {

        // we missed, find where the next vsyncshould be

        sleep =(period - ((now - next_vsync) % period));

        next_vsync= now + sleep;

    }

    mNextFakeVSync= next_vsync + period;

    struct timespec spec;

    spec.tv_sec  = next_vsync / 1000000000;

    spec.tv_nsec = next_vsync % 1000000000;

    int err;

    do {

        err =clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);

    } while (err<0 &&errno == EINTR);

    if (err == 0) {

    //②

    //去驅動SF

        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);

    }

    returntrue;

}

上面的代碼,我們需要注意兩個地方: 

1. mEnabled預設為false,mCondition在這裡阻塞,直到有人調用了signal(),同時mEnabled為true。 

2. 如果阻塞解開,則會定期休眠,然後去驅動SF,這就相當于産生了持續的Vsync信号。

到目前為止,HWC中建立了一個線程VSyncThread,阻塞中,下面我們看下打開Vsync開關的閘刀是如何建立的,以及何處去開閘刀。

EventControlThread閘刀的建立

在SF的init()中,有下面的代碼,

    mEventControlThread= newEventControlThread(this);

   mEventControlThread->run("EventControl",PRIORITY_URGENT_DISPLAY);

建立了一個EventControlThread對象,同時啟動這個線程,構造函數很簡單,mVsyncEnabled預設為false,閘刀預設是關閉的。

EventControlThread::EventControlThread(constsp<SurfaceFlinger>& flinger):

       mFlinger(flinger),

       mVsyncEnabled(false) {

}

下面看下線程函數,

bool EventControlThread::threadLoop() {

    Mutex::Autolock lock(mMutex);

    boolvsyncEnabled = mVsyncEnabled;

    mFlinger->eventControl(HWC_DISPLAY_PRIMARY,SurfaceFlinger::EVENT_VSYNC,

           mVsyncEnabled);

    while (true) {

     //①

     //mCond阻塞,

        status_terr = mCond.wait(mMutex);

        if (err != NO_ERROR) {

            ALOGE("error waiting for new events: %s(%d)",

                strerror(-err), err);

            returnfalse;

        }

    //②

    //vsyncEnabled 開始和mVsyncEnabled都為false,如果有其他地方改變了mVsyncEnabled

    //會去調用SF的eventControl函數

        if (vsyncEnabled != mVsyncEnabled){

           mFlinger->eventControl(HWC_DISPLAY_PRIMARY,

                   SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);

           vsyncEnabled = mVsyncEnabled;

        }

    }

    returnfalse;

}

其中, 

1. 在mCond阻塞,可以看到外面是個死循環,while(true),是以如果有其他地方對這個mCond調用了signal,執行完下面的代碼又會阻塞 

2. 解除阻塞後,如果vsyncEnabled !=mVsyncEnabled,也就是開關狀态不同,由開到關和由關到開,都回去調用mFlinger->eventControl,調用完成後把這次的開關狀态儲存,vsyncEnabled =mVsyncEnabled;,與下次做比較。 

從上面我們能明顯認識到EventControlThread線程,其實就起到了個閘刀的作用,等待着别人去開、關。 

下面研究下開關函數,

voidSurfaceFlinger::eventControl(int disp, intevent, int enabled) {

    ATRACE_CALL();

   getHwComposer().eventControl(disp, event, enabled);

}

前面在SF的init()中已經建立了一個HWC,這裡就是mHwc,

voidHWComposer::eventControl(int disp, intevent, int enabled) {

    ....

    //隻看最後一句,mVSyncThread就是HWC中的軟體模拟Vsync線程

    if (err ==NO_ERROR && mVSyncThread != NULL) {

       mVSyncThread->setEnabled(enabled);

    }

}

将軟體模拟線程VSyncThread的mCondition釋放,這時候VSyncThread就會定期産生“信号”,去驅動SF了。

void HWComposer::VSyncThread::setEnabled(bool enabled) {

    Mutex::Autolock _l(mLock);

    //mEnabled和enabled不同,即從開到關和從關到開

    if (mEnabled != enabled) {

        mEnabled = enabled;

        //釋放mCondition

        mCondition.signal();

    }

}

那麼EventControlThread這個閘刀到底在哪被SF打開的呢? 

在SF的init()中調用了initializeDisplays();

voidSurfaceFlinger::initializeDisplays() {

    classMessageScreenInitialized : public MessageBase {

       SurfaceFlinger* flinger;

    public:

        MessageScreenInitialized(SurfaceFlinger*flinger) : flinger(flinger) { }

        virtualbool handler() {

           flinger->onInitializeDisplays();

            returntrue;

        }

    };

   sp<MessageBase> msg = new MessageScreenInitialized(this);

   postMessageAsync(msg);  // we may be called from main thread,use async message

}

發送異步消息,前面一節已經分析過處理流程了,即會執行handler(),flinger->onInitializeDisplays();,

void SurfaceFlinger::onInitializeDisplays() {

    //主要看這個

   onScreenAcquired(getDefaultDisplayDevice());

}

void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {

    if (type< DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {

        // built-in display, tell the HWC

       getHwComposer().acquire(type);

    //主螢幕,Primary,回去調用

        if (type== DisplayDevice::DISPLAY_PRIMARY) {

            // FIXME: eventthread only knows aboutthe main display right now

           mEventThread->onScreenAcquired();

           resyncToHardwareVsync(true);

        }

    }

   mVisibleRegionsDirty =true;

   repaintEverything();

}

接着調用resyncToHardwareVsync(true),從字面意思就是能看出,是去和HardwareVsync去同步,參數為true。

void SurfaceFlinger::resyncToHardwareVsync(boolmakeAvailable) {

    Mutex::Autolock_l(mHWVsyncLock);

    if (makeAvailable){

       mHWVsyncAvailable =true;

    } elseif (!mHWVsyncAvailable) {

        ALOGE("resyncToHardwareVsync called whenHW vsync unavailable");

        return;

    }

    const nsecs_tperiod =

           getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);

   mPrimaryDispSync.reset();

    mPrimaryDispSync.setPeriod(period);

    if (!mPrimaryHWVsyncEnabled) {

       mPrimaryDispSync.beginResync();

        //eventControl(HWC_DISPLAY_PRIMARY,SurfaceFlinger::EVENT_VSYNC, true);

        //打開閘刀,

       mEventControlThread->setVsyncEnabled(true);

       mPrimaryHWVsyncEnabled =true;

    }

}

很明顯,代碼中調用了mEventControlThread->setVsyncEnabled(true);,

voidEventControlThread::setVsyncEnabled(bool enabled) {

    Mutex::Autolocklock(mMutex);

    mVsyncEnabled =enabled;

    //釋放mCond

    mCond.signal();

}

可以看到,在這裡釋放了前面的mCond,讓EventControlThread去調用mFlinger->eventControl()函數,進而去HWC中打開Vsync開關。 

上面分析的這些對應了最開始圖的步驟①。

DispSync和DispSyncThread

下面開始分析,android 4.4中對hardware Vsync模型的建立,在SF類中有一個field為DispSyncmPrimaryDispSync;,是以在SF類建立的時候,會去在棧上生成這個對象,首先看下構造函數,

DispSync::DispSync() {

    //①

    //建立DispSyncThread線程,并運作

    mThread =newDispSyncThread();

    mThread->run("DispSync",PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

    //線程自己運作去了,SF主線程繼續

   ....

}

在DispSync的構造函數中,建立DispSyncThread線程,并運作,DispSyncThread的構造函數将mStop設定為false,mPeriod設定為0,

   DispSyncThread():

            mStop(false),

           mPeriod(0),

            mPhase(0),

           mWakeupLatency(0) {

    }

線程函數,

   virtualbool threadLoop() {

        status_terr;

        nsecs_t now= systemTime(SYSTEM_TIME_MONOTONIC);

        nsecs_tnextEventTime = 0;

        while (true) {

           Vector<CallbackInvocation> callbackInvocations;

            nsecs_ttargetTime = 0;

            { // Scope for lock

               Mutex::Autolock lock(mMutex);

                if (mStop) {

                   returnfalse;

                }

                //①

        //mCond阻塞,當signal,同時mPeriod 不為0時,繼續往下執行,

                if (mPeriod == 0) {

                   err = mCond.wait(mMutex);

                   if (err !=NO_ERROR) {

                       ALOGE("errorwaiting for new events: %s (%d)",

                                strerror(-err), err);

                       returnfalse;

                   }

                   continue;

                }

               nextEventTime = computeNextEventTimeLocked(now);

               targetTime = nextEventTime;

                bool isWakeup = false;

                if (now <targetTime) {

                   err = mCond.waitRelative(mMutex, targetTime - now);

                   if (err ==TIMED_OUT) {

                       isWakeup = true;

                    } elseif (err !=NO_ERROR) {

                       ALOGE("errorwaiting for next event: %s (%d)",

                                strerror(-err),err);

                       returnfalse;

                   }

                }

                now = systemTime(SYSTEM_TIME_MONOTONIC);

                if (isWakeup) {

                   mWakeupLatency = ((mWakeupLatency * 63) +

                            (now - targetTime))/ 64;

                   if (mWakeupLatency> 500000) {

                        // Don't correct by more than 500 us

                       mWakeupLatency = 500000;

                   }

                   if(traceDetailedInfo) {

                       ATRACE_INT64("DispSync:WakeupLat", now -nextEventTime);

                        ATRACE_INT64("DispSync:AvgWakeupLat",mWakeupLatency);

                   }

                }

        //②

        //很重要,這是模型線程去驅動SF做事的關鍵

               callbackInvocations = gatherCallbackInvocationsLocked(now);

            }

            if(callbackInvocations.size() > 0) {

               fireCallbackInvocations(callbackInvocations);

            }

        }

        returnfalse;

    }

主要2點: 

1. 模型線程DispSyncThread阻塞在mCond,等待别人給mPeriod 指派和signal; 

2. gatherCallbackInvocationsLocked()和fireCallbackInvocations()函數是模型線程DispSyncThread驅動SF去做事的關鍵,這裡先不介紹,對應開始圖形中的④。 

3. 

建立的DispSyncThread線程,目前被阻塞,先不管,我們先看模型DispSync和要驅動的事件(DispSyncSource,EventThread等)是如何聯系起來的。 

到這裡我們先打住,思考個問題: 

如果自己寫代碼,在同一程序中,我們如何實作這種多個事件之間驅動?我認為多線程就是最好的方式,然後再加上同步機制和回調。而android Vsync的實作我認為也是用了這種實作方式,模型DispSync和DispSyncThread線程相結合,而驅動事件由DispSyncSource和EventThread線程相結合。

DispSyncSource和EventThread

在SF的init函數中,有如下代碼,涉及到了DispSync,DispSyncSource,EventThread和mEventQueue的糾纏關系。我們可以看到在驅動事件DispSyncSource的構造中,我們輸入了模型DispSync,這樣就為回調創造了機會,下面看具體如何實作的。

    //把模型mPrimaryDispSync(DispSync)儲存在DispSyncSource中

   sp<VSyncSource> sfVsyncSrc = newDispSyncSource(&mPrimaryDispSync,

           sfVsyncPhaseOffsetNs, false);

    mSFEventThread= newEventThread(sfVsyncSrc);

   mEventQueue.setEventThread(mSFEventThread);

先看下DispSyncSource對象的建立,其實這個對象從名字上看就是模型所驅動的事件,構造函數中主要設定了模型mDispSync(dispSync),以及觸發時間的偏移量mPhaseOffset(phaseOffset)。

    DispSyncSource(DispSync*dispSync, nsecs_t phaseOffset, bool traceVsync) :

            mValue(0),

           mPhaseOffset(phaseOffset),

           mTraceVsync(traceVsync),

           mDispSync(dispSync) {}

繼續mSFEventThread =new EventThread(sfVsyncSrc);,

EventThread::EventThread(constsp<VSyncSource>& src)

    :mVSyncSource(src),

     mUseSoftwareVSync(false),

     mVsyncEnabled(false),

     mDebugVsyncEnabled(false) {

 //DisplayEventReceiver::EventmVSyncEvent[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];

    //i<2

    for (int32_t i=0;i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {

       mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

       mVSyncEvent[i].header.id = 0;

       mVSyncEvent[i].header.timestamp = 0;

       mVSyncEvent[i].vsync.count =  0;

    }

}

在EventThread的構造中,輸入了與之對應的DispSyncSource,同時把mUseSoftwareVSync和mVsyncEnabled, mDebugVsyncEnabled都設定為false,同時初始化了一個DisplayEventReceiver類型的數組,從名字上看這是display event,也就是Vsync信号,接收到的Vsync信号相關的一個數組。把type設定為DISPLAY_EVENT_VSYNC。

注意,又是小伎倆,把EventThread線程啟動起來,

//在onFirstRef中啟動線程,相當于mEventThread.run();,把這個線程啟動起來

void EventThread::onFirstRef() {

    run("EventThread",PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

}

那麼我們需要看下線程函數,

boolEventThread::threadLoop() {

   DisplayEventReceiver::Event event;

    Vector< sp<EventThread::Connection>> signalConnections;

    //①

    //等待事件

   signalConnections = waitForEvent(&event);

    // ②

    // 把事件分發給listener

    // dispatch events to listeners...

    const size_t count =signalConnections.size();

    for (size_t i=0 ; i<count ;i++) {

        constsp<Connection>& conn(signalConnections[i]);

        // now see if we still need to reportthis event

        // ③

        // 調用postEvent

        status_terr = conn->postEvent(event);

        if (err == -EAGAIN|| err == -EWOULDBLOCK) {

            // The destination doesn't accept eventsanymore, it's probably

            // full. For now, we just drop theevents on the floor.

            // FIXME: Note that some events cannotbe dropped and would have

            // to be re-sent later.

            // Right-now we don't have the abilityto do this.

            ALOGW("EventThread: dropping event (%08x)for connection %p",

                   event.header.type,conn.get());

        } elseif (err < 0) {

            // handle any other error on the pipe as fatal. the only

            // reasonable thing to do is to clean-upthis connection.

            // The most common error we'll get hereis -EPIPE.

           removeDisplayEventConnection(signalConnections[i]);

        }

    }

    returntrue;

}

上面重點主要有: 

1. 等待事件到來 

2. 把事件分發給listener 

3. 調用conn->postEvent(event) 

2和3後面再看,先看1,難道EventThread線程上來直接也休眠了?

Vector< sp<EventThread::Connection> >EventThread::waitForEvent(

       DisplayEventReceiver::Event* event)

{

    Mutex::Autolock_l(mLock);

    Vector<sp<EventThread::Connection> > signalConnections;

    do {

        booleventPending = false;

        boolwaitForVSync = false;

        size_tvsyncCount = 0;

        nsecs_ttimestamp = 0;

        //上面初始化EventThread時候,都是0

        for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; i++) {

           timestamp = mVSyncEvent[i].header.timestamp;

            if (timestamp) {

                // we have a vsync event to dispatch

               *event = mVSyncEvent[i];

               mVSyncEvent[i].header.timestamp = 0;

               vsyncCount = mVSyncEvent[i].vsync.count;

                break;

            }

        }

        if (!timestamp) {

            // no vsync event, see if there are someother event

           eventPending = !mPendingEvents.isEmpty();

            //初始為假

            if (eventPending){

                // we have some other event to dispatch

               *event = mPendingEvents[0];

               mPendingEvents.removeAt(0);

            }

        }

    // SortedVector< wp<Connection>> mDisplayEventConnections;

    // 初始也是空的

        // find out connections waiting forevents

        size_t count =mDisplayEventConnections.size();

        for (size_t i=0 ; i<count ; i++) {

           sp<Connection> connection(mDisplayEventConnections[i].promote());

            if (connection !=NULL) {

               bool added = false;

                if(connection->count >= 0) {

                   // we need vsyncevents because at least

                   // oneconnection is waiting for it

                   waitForVSync = true;

                   if (timestamp) {

                       // we consumethe event only if it's time

                       // (ie: wereceived a vsync event)

                       if (connection->count == 0) {

                            // fired this time around

                            connection->count = -1;

                           signalConnections.add(connection);

                            added = true;

                       } elseif(connection->count == 1 ||

                                (vsyncCount %connection->count) == 0) {

                            // continuous event, and time to reportit

                           signalConnections.add(connection);

                            added = true;

                       }

                   }

                }

                if (eventPending&& !timestamp && !added) {

                   // we don't havea vsync event to process

                   //(timestamp==0), but we have some pending

                   // messages.

                   signalConnections.add(connection);

                }

            } else {

                // we couldn't promote this reference,the connection has

                // died, so clean-up!

               mDisplayEventConnections.removeAt(i);

               --i; --count;

            }

        }

        // Here we figure out if we need toenable or disable vsyncs

        if (timestamp&& !waitForVSync) {

            // we received a VSYNC but we have noclients

            // don't report it, and disable VSYNCevents

           disableVSyncLocked();

        } elseif (!timestamp&& waitForVSync) {

            // we have at least one client, so wewant vsync enabled

            // (TODO: this function is called rightafter we finish

            // notifying clients of a vsync, so thiscall will be made

            // at the vsync rate, e.g. 60fps.  If we can accurately

            // track the current state we couldavoid making this call

            // so often.)

           enableVSyncLocked();

        }

        // note: !timestamp impliessignalConnections.isEmpty(), because we

        // don't populate signalConnections ifthere's no vsync pending

        if (!timestamp&& !eventPending) {

            // wait for something to happen

            if (waitForVSync){

                // This is where we spend most of ourtime, waiting

                // for vsync events and new clientregistrations.

                //

                // If the screen is off, we can't useh/w vsync, so we

                // use a 16ms timeout instead.  It doesn't need to be

                // precise, we just need to keep feedingour clients.

                //

                // We don't want to stall if there's adriver bug, so we

                // use a (long) timeout when waiting forh/w vsync, and

                // generate fake events when necessary.

               bool softwareSync = mUseSoftwareVSync;

               nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);

                if(mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {

                   if (!softwareSync){

                       ALOGW("Timed outwaiting for hw vsync; faking it");

                   }

                    // FIXME: how do we decide which display idthe fake

                   // vsync camefrom ?

                   mVSyncEvent[0].header.type =DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

                   mVSyncEvent[0].header.id =DisplayDevice::DISPLAY_PRIMARY;

                   mVSyncEvent[0].header.timestamp= systemTime(SYSTEM_TIME_MONOTONIC);

                   mVSyncEvent[0].vsync.count++;

                }

            } else {

                // Nobody is interested in vsync, so wejust want to sleep.

                // h/w vsync should be disabled, so thiswill wait until we

                // get a new connection, or an existingconnection becomes

                // interested in receiving vsync again.

                // ①

                // 是以EventThread初始的時候會在這阻塞

               mCondition.wait(mLock);

            }

        }

     //②

    } while(signalConnections.isEmpty());

//因為mCondition有可能異常傳回,是以要看下這個while,就知道何時mCondition被正常的signal

//如果signalConnections不為空了,這時候就會從while中退出來

//也就是上面的mDisplayEventConnections有東西了

    // here we're guaranteed to have atimestamp and some connections to signal

    // (The connections might have droppedout of mDisplayEventConnections

    // while we were asleep, but we'll stillhave strong references to them.)

    returnsignalConnections;

}

上面的代碼主要關注2點: 

1. 初始的時候,mCondition會阻塞 

2. 因為mCondition有可能異常傳回,是以要看下外圍的while循環,就知道何時mCondition會被signal。即使mCondition異常傳回,也會再去判斷signalConnections是否為空。空的話繼續阻塞,如果signalConnections不為空了,這時候就會從while中退出來,也就是上面的mDisplayEventConnections有東西了。是以mDisplayEventConnections需要留意何時指派啦。

至此,建立了一個mSFEventThread =new EventThread(sfVsyncSrc);,也阻塞着了。。 

下面繼續看mEventQueue.setEventThread(mSFEventThread);,會不會柳暗花明又一村呢? 

這裡EventThread和SF主線程的MessageQueue又糾纏到了一起。

void MessageQueue::setEventThread(const sp<EventThread>& eventThread)

{

    mEventThread = eventThread;

    //①

    mEvents = eventThread->createEventConnection();

    //②

    mEventTube = mEvents->getDataChannel();

    //③

    mLooper->addFd(mEventTube->getFd(), 0,ALOOPER_EVENT_INPUT,

           MessageQueue::cb_eventReceiver, this);

}

上面代碼主要看三點: 

首先, eventThread->createEventConnection(),建立了一個Connection對象,

sp<EventThread::Connection>EventThread::createEventConnection() const {

    returnnew Connection(const_cast<EventThread*>(this));

}

建立的 Connection 對象如下圖所示,  

android graphic(4)—surfaceflinger和Vsync

Connection中儲存了了一個EventThread對象,和一個生成的BitTube對象mChannel,下面看下Connection的構造函數,

EventThread::Connection::Connection(

        constsp<EventThread>& eventThread)

    : count(-1), mEventThread(eventThread), mChannel(newBitTube())

{

}

調用了BitTube的無參構造函數,

BitTube::BitTube()

    : mSendFd(-1), mReceiveFd(-1)

{

    init(DEFAULT_SOCKET_BUFFER_SIZE,DEFAULT_SOCKET_BUFFER_SIZE);

}

//就是建立一個域套接字對,一個讀,一個寫,mSendFd和mReceiveFd ,

void BitTube::init(size_trcvbuf, size_t sndbuf) {

    int sockets[2];

    if(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {

        size_t size= DEFAULT_SOCKET_BUFFER_SIZE;

       setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));

        setsockopt(sockets[1], SOL_SOCKET,SO_SNDBUF, &sndbuf, sizeof(sndbuf));

        // sine we don't use the "returnchannel", we keep it small...

       setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));

       setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));

       fcntl(sockets[0], F_SETFL, O_NONBLOCK);

       fcntl(sockets[1], F_SETFL, O_NONBLOCK);

        mReceiveFd= sockets[0];

        mSendFd =sockets[1];

    } else {

        mReceiveFd= -errno;

        ALOGE("BitTube: pipe creation failed(%s)", strerror(-mReceiveFd));

    }

}

繼續回到MessageQueue::setEventThread中,mEvents =eventThread->createEventConnection();,又是sp指派,得小心onFirstRef(),這裡的處理非常關鍵。

void EventThread::Connection::onFirstRef() {

    // NOTE: mEventThread doesn't hold astrong reference on us

    mEventThread->registerDisplayEventConnection(this);

}

前面提到,EventThread一直阻塞在waitForEvent中,正是這個mCondition,這裡也對mDisplayEventConnections添加了東西,不為空了。

status_t EventThread::registerDisplayEventConnection(

        const sp<EventThread::Connection>& connection) {

    Mutex::Autolock _l(mLock);

    //把connection添加到mDisplayEventConnections

   mDisplayEventConnections.add(connection);

    //mCondition解除

    mCondition.broadcast();

    return NO_ERROR;

}

為了友善,這裡再把waitForEvent()函數列出來,

Vector< sp<EventThread::Connection> >EventThread::waitForEvent(

       DisplayEventReceiver::Event* event)

{

    Mutex::Autolock_l(mLock);

    Vector<sp<EventThread::Connection> > signalConnections;

    do {

        booleventPending = false;

        boolwaitForVSync = false;

        size_tvsyncCount = 0;

        nsecs_t timestamp = 0;

        for (int32_t i=0 ;i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {

           timestamp = mVSyncEvent[i].header.timestamp;

            if (timestamp) {

                // we have a vsync event to dispatch

                *event = mVSyncEvent[i];

               mVSyncEvent[i].header.timestamp = 0;

               vsyncCount = mVSyncEvent[i].vsync.count;

                break;

            }

        }

        //②

    //這裡timestamp 還是0

        if (!timestamp) {

            // no vsync event, see if there are some other event

           eventPending = !mPendingEvents.isEmpty();

            if (eventPending){

                // we have some other event to dispatch

               *event = mPendingEvents[0];

                mPendingEvents.removeAt(0);

            }

        }

    //③

    //有東西了,就是儲存的Connection

        // find out connections waiting forevents

        size_t count =mDisplayEventConnections.size();

        for (size_t i=0 ; i<count ; i++) {

           sp<Connection> connection(mDisplayEventConnections[i].promote());

            if (connection !=NULL) {

               bool added = false;

                if(connection->count >= 0) {

                   // we need vsyncevents because at least

                   // oneconnection is waiting for it

                    waitForVSync = true;

                   if (timestamp) {

                       // we consumethe event only if it's time

                       // (ie: wereceived a vsync event)

                       if(connection->count == 0) {

                            // fired this time around

                            connection->count = -1;

                           signalConnections.add(connection);

                            added = true;

                       } elseif(connection->count == 1 ||

                                (vsyncCount %connection->count) == 0) {

                            // continuous event, and time to reportit

                           signalConnections.add(connection);

                            added = true;

                        }

                   }

                }

                if (eventPending&& !timestamp && !added) {

                   // we don't havea vsync event to process

                   //(timestamp==0), but we have some pending

                    // messages.

                   signalConnections.add(connection);

                }

            } else {

                // we couldn't promote this reference,the connection has

                // died, so clean-up!

               mDisplayEventConnections.removeAt(i);

               --i; --count;

            }

        }

        // Here we figure out if we need toenable or disable vsyncs

        if (timestamp&& !waitForVSync) {

            // we received a VSYNC but we have noclients

            // don't report it, and disable VSYNC events

           disableVSyncLocked();

        } elseif (!timestamp&& waitForVSync) {

            // we have at least one client, so wewant vsync enabled

            // (TODO: this function is called rightafter we finish

            // notifying clients of a vsync, so thiscall will be made

            // at the vsync rate, e.g. 60fps.  If we can accurately

            // track the current state we couldavoid making this call

            // so often.)

            //④

            //這次執行到這裡了

           enableVSyncLocked();

        }

        // note: !timestamp impliessignalConnections.isEmpty(), because we

        // don't populate signalConnections ifthere's no vsync pending

        if (!timestamp&& !eventPending) {

            // wait for something to happen

            if (waitForVSync){

                // This is where we spend most of ourtime, waiting

                // for vsync events and new clientregistrations.

                //

                // If the screen is off, we can't useh/w vsync, so we

                // use a 16ms timeout instead.  It doesn't need to be

                // precise, we just need to keep feedingour clients.

                //

                // We don't want to stall if there's adriver bug, so we

                // use a (long) timeout when waiting forh/w vsync, and

                // generate fake events when necessary.

               bool softwareSync = mUseSoftwareVSync;

               nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);

                if(mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {

                   if (!softwareSync){

                       ALOGW("Timed outwaiting for hw vsync; faking it");

                   }

                    // FIXME: how do we decide which display id the fake

                   // vsync camefrom ?

                   mVSyncEvent[0].header.type =DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

                   mVSyncEvent[0].header.id =DisplayDevice::DISPLAY_PRIMARY;

                   mVSyncEvent[0].header.timestamp= systemTime(SYSTEM_TIME_MONOTONIC);

                   mVSyncEvent[0].vsync.count++;

                }

            } else {

                // Nobody is interested in vsync, so wejust want to sleep.

                // h/w vsync should be disabled, so thiswill wait until we

                // get a new connection, or an existingconnection becomes

                // interested in receiving vsync again.

                // ①

                // mCondition這次解開了

               mCondition.wait(mLock);

            }

        }

    } while(signalConnections.isEmpty());

    // here we're guaranteed to have atimestamp and some connections to signal

    // (The connections might have droppedout of mDisplayEventConnections

    // while we were asleep, but we'll stillhave strong references to them.)

    returnsignalConnections;

}

上面代碼,主要看4點: 

1. 建立Connection後,mCondition傳回了; 

2. 這裡timestamp 還是0 

3. mDisplayEventConnections非空了,将waitForVSync = true; 

4. 是以會執行到enableVSyncLocked();。

繼續看,enableVSyncLocked(),

voidEventThread::enableVSyncLocked() {

    //初始為false

    if(!mUseSoftwareVSync) {

        // never enable h/w VSYNC when screen isoff

        //初始為false

        if(!mVsyncEnabled) {

        //①

            mVsyncEnabled = true;

           mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));

            //②

           mVSyncSource->setVSyncEnabled(true);

           mPowerHAL.vsyncHint(true);

        }

    }

   mDebugVsyncEnabled = true;

}

主要看兩點: 

1. 将mVsyncEnabled 設為true,調用mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));,this為EventThread,既是調用DispSyncSource的setCallback,把mCallback設定為EventThread,

    virtualvoid setCallback(constsp<VSyncSource::Callback>& callback) {

       Mutex::Autolock lock(mMutex);

        mCallback =callback;

    }

2.調用mVSyncSource->setVSyncEnabled(true);,既是調用DispSyncSource的setVSyncEnabled, 

,這裡的this為DispSyncSource

  virtualvoidsetVSyncEnabled(bool enable) {

        // Do NOT lock the mutex here so as toavoid any mutex ordering issues

        // with locking it in theonDispSyncEvent callback.

        if (enable) {

            //在硬體modelmDispSync中添加addEventListener,一個參數為偏移量,一個為DispSyncSource

           status_t err = mDispSync->addEventListener(mPhaseOffset,

                   static_cast<DispSync::Callback*>(this));

            if (err !=NO_ERROR) {

               ALOGE("errorregistering vsync callback: %s (%d)",

                       strerror(-err), err);

            }

            ATRACE_INT("VsyncOn", 1);

        } else {

           status_t err = mDispSync->removeEventListener(

                   static_cast<DispSync::Callback*>(this));

            if (err !=NO_ERROR) {

               ALOGE("errorunregistering vsync callback: %s (%d)",

                       strerror(-err), err);

            }

           ATRACE_INT("VsyncOn", 0);

        }

    }

從上面的代碼可以看出,這裡是将驅動事件DispSyncSource和硬體模型mDispSync建立起關系,繼續,

status_t DispSync::addEventListener(nsecs_t phase,

        const sp<Callback>& callback) {

    Mutex::Autolock lock(mMutex);

    return mThread->addEventListener(phase,callback);

}

    status_taddEventListener(nsecs_t phase, const sp<DispSync::Callback>& callback) {

       Mutex::Autolock lock(mMutex);

        for (size_t i = 0; i <mEventListeners.size(); i++) {

            if(mEventListeners[i].mCallback == callback) {

                return BAD_VALUE;

            }

        }

       EventListener listener;

       listener.mPhase = phase;

       listener.mCallback = callback;

        // We want to allow the firstmost futureevent to fire without

        // allowing any past events tofire.  Because

        // computeListenerNextEventTimeLockedfilters out events within a half

        // a period of the last event time, weneed to initialize the last

        // event time to a half a period in thepast.

       listener.mLastEventTime = systemTime(SYSTEM_TIME_MONOTONIC) - mPeriod / 2;

    //把listener放到mEventListeners中,

       mEventListeners.push(listener);

    //釋放mCond

       mCond.signal();

        return NO_ERROR;

    }

這裡可以看出,驅動事件DispSyncSource是硬體模型DispSync的“listener”,監聽者,把兩者聯系了起來。并把DispSyncThread線程中的阻塞mCond解除,但是,前面我們分析過,還要mPeriod 非0,

         if (mPeriod == 0) {

                   err = mCond.wait(mMutex);

                   if (err !=NO_ERROR) {

                       ALOGE("errorwaiting for new events: %s (%d)",

                                strerror(-err),err);

                        return false;

                   }

                   continue;

                }

那麼哪裡給mPeriod 指派呢?在SF的init中initializeDisplays()會調用resyncToHardwareVsync()函數,又調用

mPrimaryDispSync.setPeriod(period);

mPeriod 指派後,已經不為0,

void DispSync::setPeriod(nsecs_t period){

    Mutex::Autolock lock(mMutex);

    mPeriod = period;

    mPhase =0;

    //調用線程的更新模型函數

    mThread->updateModel(mPeriod,mPhase);

}

Cond解除阻塞,

    voidupdateModel(nsecs_t period, nsecs_t phase) {

       Mutex::Autolock lock(mMutex);

        mPeriod =period;

        mPhase =phase;

        //mCond阻塞解除

       mCond.signal();

    }

至此,DispSync中設定了監聽者DispSyncSource,mPeriod 也不為0,硬體模型線程不再阻塞,不阻塞了幹什麼先不分析,繼續回到前面的MessageQueue::setEventThread()函數,經過調用mEvents =eventThread->createEventConnection();完成了, 

1. MessageQueue中儲存了一個Connection,mEvents ; 

2. EventThread中儲存了這個Connection,mDisplayEventConnections.add(connection); 

3. mVSyncSource->setCallback 把mCallback = callback 設定為EventThread 

4. 在mDispSync中注冊listener,放到DispSyncthread的mEventListeners中,這個listener的callback就是mVSyncSource,

        listener.mPhase = phase;

        listener.mCallback = callback;

接着繼續MessageQueue::setEventThread()函數,調用,

 mEventTube = mEvents->getDataChannel();

binder傳資料,bp側

    virtual sp<BitTube>getDataChannel() const

    {

        Parceldata, reply;

        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());

       remote()->transact(GET_DATA_CHANNEL, data, &reply);

        //傳回的是一個包含接收描述符的parcel,在這裡調用帶參的BitTube構造函數,是以mEventTube隻負責讀

        return new BitTube(reply);

    }

bn側

       caseGET_DATA_CHANNEL: {

            CHECK_INTERFACE(IDisplayEventConnection, data, reply);

            sp<BitTube>channel(getDataChannel());

           channel->writeToParcel(reply);

            return NO_ERROR;

        } break;

這樣 mEventTube 中隻包含了讀 fd ,而 mEvents 這個 connection 中的 mChannel 隻剩下寫 fd ,兩個依然是一對讀寫,,但是分開了,如下圖所示  

android graphic(4)—surfaceflinger和Vsync

繼續調用,這裡就是把mEventTube這個讀tube注冊到SF主線程的Looper中去,回調函數為MessageQueue::cb_eventReceiver,

    mLooper->addFd(mEventTube->getFd(), 0,ALOOPER_EVENT_INPUT,

            MessageQueue::cb_eventReceiver, this);

int Looper::addFd(int fd, int ident, int events,ALooper_callbackFunc callback, void* data) {

    return addFd(fd,ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);

}

int Looper::addFd(int fd, int ident, int events, constsp<LooperCallback>& callback, void* data) {

#ifDEBUG_CALLBACKS

    ALOGD("%p ~ addFd - fd=%d, ident=%d,events=0x%x, callback=%p, data=%p", this, fd, ident,

            events,callback.get(), data);

#endif

    if (!callback.get()) {

        if (!mAllowNonCallbacks) {

            ALOGE("Invalid attempt to set NULLcallback but not allowed for this looper.");

            return -1;

        }

        if (ident < 0) {

            ALOGE("Invalid attempt to set NULLcallback with ident < 0.");

            return -1;

        }

    } else {

        ident =ALOOPER_POLL_CALLBACK;

    }

    int epollEvents = 0;

    if (events &ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN;

    if (events &ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT;

    { // acquire lock

        AutoMutex_l(mLock);

    //封裝一個request,callback其實就是MessageQueue::cb_eventReceiver

        Requestrequest;

        request.fd= fd;

       request.ident = ident;

       request.callback = callback;

       request.data = data;

        struct epoll_eventeventItem;

       memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data fieldunion

       eventItem.events = epollEvents;

       eventItem.data.fd = fd;

        ssize_trequestIndex = mRequests.indexOfKey(fd);

        if (requestIndex< 0) {

        //epoll監聽讀bittube

            int epollResult =epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);

            if (epollResult< 0) {

               ALOGE("Erroradding epoll events for fd %d, errno=%d", fd, errno);

                return -1;

            }

            //把fd和request的鍵值對放到全局的mRequests中,

           mRequests.add(fd, request);

        } else {

            int epollResult =epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);

            if (epollResult < 0) {

               ALOGE("Errormodifying epoll events for fd %d, errno=%d", fd, errno);

                return -1;

            }

           mRequests.replaceValueAt(requestIndex, request);

        }

    } // release lock

    return1;

}

完整走一遍

分析了這麼多,從頭來一遍, 

1.首先HWC發送Vsync信号,

mHwc.mEventHandler.onVSyncReceived(0, next_vsync);

2.SF處理onVSyncReceived 

那麼來一次信号,就會調用一次硬體模型mPrimaryDispSync的addResyncSample(timestamp)函數,輸入為時間戳,

voidSurfaceFlinger::onVSyncReceived(int type, nsecs_ttimestamp) {

    boolneedsHwVsync = false;

    { // Scope for the lock

       Mutex::Autolock _l(mHWVsyncLock);

        //啟動,mPrimaryHWVsyncEnabled前面已經指派為true了

        if (type == 0 && mPrimaryHWVsyncEnabled) {

           needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);

        }

    }

    if (needsHwVsync){

       enableHardwareVsync();

    } else {

       disableHardwareVsync(false);

    }

}

boolDispSync::addResyncSample(nsecs_t timestamp) {

    Mutex::Autolocklock(mMutex);

    size_t idx =(mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;

   mResyncSamples[idx] = timestamp;

    if(mNumResyncSamples < MAX_RESYNC_SAMPLES) {

       mNumResyncSamples++;

    } else {

       mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;

    }

   updateModelLocked();

    if(mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {

       resetErrorLocked();

    }

    if(runningWithoutSyncFramework) {

        // If we don't have the sync frameworkwe will never have

        // addPresentFence called.  This means we have no way to know whether

        // or not we're synchronized with the HWvsyncs, so we just request

        // that the HW vsync events be turned onwhenever we need to generate

        // SW vsync events.

        returnmThread->hasAnyEventListeners();

    }

    return mPeriod == 0 || mError >errorThreshold;

}

mNumResyncSamples大于3次以後都會調用 mThread->updateModel(mPeriod, mPhase);,那意思就是前三個周期不通知SF工作。

oid DispSync::updateModelLocked() {

    //mNumResyncSamples 大于3次以後

    if(mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {

        nsecs_tdurationSum = 0;

        for (size_t i = 1; i <mNumResyncSamples; i++) {

            size_tidx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;

            size_t prev = (idx + MAX_RESYNC_SAMPLES - 1) %MAX_RESYNC_SAMPLES;

           durationSum += mResyncSamples[idx] - mResyncSamples[prev];

        }

        mPeriod =durationSum / (mNumResyncSamples - 1);

        double sampleAvgX = 0;

        double sampleAvgY = 0;

        double scale = 2.0 * M_PI / double(mPeriod);

        for (size_t i = 0; i <mNumResyncSamples; i++) {

            size_tidx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;

            nsecs_tsample = mResyncSamples[idx];

            double samplePhase = double(sample %mPeriod) * scale;

           sampleAvgX += cos(samplePhase);

           sampleAvgY += sin(samplePhase);

        }

        sampleAvgX/= double(mNumResyncSamples);

        sampleAvgY/= double(mNumResyncSamples);

        mPhase =nsecs_t(atan2(sampleAvgY,sampleAvgX) / scale);

        if (mPhase < 0) {

            mPhase+= mPeriod;

        }

        if(traceDetailedInfo) {

           ATRACE_INT64("DispSync:Period", mPeriod);

           ATRACE_INT64("DispSync:Phase", mPhase);

        }

       mThread->updateModel(mPeriod, mPhase);

    }

}

    voidupdateModel(nsecs_t period, nsecs_t phase) {

       Mutex::Autolock lock(mMutex);

        mPeriod =period;

        mPhase =phase;

       mCond.signal();

    }

mPeriod 不為0,也有signal,DispSyncThread線程不阻塞了,執行gatherCallbackInvocationsLocked(now)和fireCallbackInvocations(callbackInvocations)

 virtualbool threadLoop() {

        status_terr;

        nsecs_t now= systemTime(SYSTEM_TIME_MONOTONIC);

        nsecs_tnextEventTime = 0;

        while (true) {

           Vector<CallbackInvocation> callbackInvocations;

            nsecs_ttargetTime = 0;

            { // Scope for lock

               Mutex::Autolock lock(mMutex);

                if (mStop) {

                    returnfalse;

                }

                if (mPeriod == 0) {

                   err = mCond.wait(mMutex);

                   if (err !=NO_ERROR) {

                       ALOGE("errorwaiting for new events: %s (%d)",

                               strerror(-err), err);

                       returnfalse;

                   }

                   continue;

                }

               nextEventTime = computeNextEventTimeLocked(now);

               targetTime = nextEventTime;

                bool isWakeup = false;

                if (now <targetTime) {

                   err = mCond.waitRelative(mMutex, targetTime - now);

                   if (err ==TIMED_OUT) {

                       isWakeup = true;

                   } elseif (err !=NO_ERROR) {

                       ALOGE("errorwaiting for next event: %s (%d)",

                                strerror(-err),err);

                       returnfalse;

                   }

                }

                now= systemTime(SYSTEM_TIME_MONOTONIC);

                if (isWakeup) {

                   mWakeupLatency = ((mWakeupLatency * 63) +

                            (now - targetTime))/ 64;

                   if (mWakeupLatency> 500000) {

                       // Don't correct by more than 500 us

                       mWakeupLatency = 500000;

                   }

                   if(traceDetailedInfo) {

                       ATRACE_INT64("DispSync:WakeupLat", now -nextEventTime);

                       ATRACE_INT64("DispSync:AvgWakeupLat",mWakeupLatency);

                   }

                }

               callbackInvocations = gatherCallbackInvocationsLocked(now);

            }

            if(callbackInvocations.size() > 0) {

                fireCallbackInvocations(callbackInvocations);

            }

        }

        returnfalse;

    }

這裡的mEventListeners[i].mCallback都是驅動的事件DispSyncSource,

   Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_tnow) {

       Vector<CallbackInvocation> callbackInvocations;

        nsecs_t ref = now -mPeriod;

        for (size_t i = 0; i <mEventListeners.size(); i++) {

            nsecs_tt = computeListenerNextEventTimeLocked(mEventListeners[i],

                   ref);

            if (t < now) {

               CallbackInvocation ci;

               ci.mCallback = mEventListeners[i].mCallback;

               ci.mEventTime = t;

               callbackInvocations.push(ci);

               mEventListeners.editItemAt(i).mLastEventTime = t;

            }

        }

        returncallbackInvocations;

    }

這裡的callbacks[i].mCallback,就是驅動的事件DispSyncSource,

   voidfireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {

        for (size_t i = 0; i <callbacks.size(); i++) {

            callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);

        }

    }

    virtual voidonDispSyncEvent(nsecs_t when) {

        sp<VSyncSource::Callback> callback;

        {

            Mutex::Autolock lock(mMutex);

           callback = mCallback;

            if (mTraceVsync) {

               mValue = (mValue +1) %2;

               ATRACE_INT("VSYNC", mValue);

            }

        }

    //這裡的callback為EventThread

        if (callback !=NULL) {

           callback->onVSyncEvent(when);

        }

    }

繼續調用,這裡已經從驅動事件,轉化到驅動事件的線程EventThread中,填充EventThread的mVSyncEvent,

void EventThread::onVSyncEvent(nsecs_t timestamp) {

    Mutex::Autolock_l(mLock);

    mVSyncEvent[0].header.type =DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

    mVSyncEvent[0].header.id = 0;

    mVSyncEvent[0].header.timestamp = timestamp;

    mVSyncEvent[0].vsync.count++;

    mCondition.broadcast();

}

EventThread的waitForEvent(),傳回signalConnections,就是開始建立的Connection,這個Connection裡面有個BitTube的寫fd,另外的讀fd在MessageQueue中,

Vector< sp<EventThread::Connection> >EventThread::waitForEvent(

       DisplayEventReceiver::Event* event)

{

    Mutex::Autolock_l(mLock);

    Vector<sp<EventThread::Connection> > signalConnections;

    do {

        booleventPending = false;

        bool waitForVSync= false;

        size_tvsyncCount = 0;

        nsecs_ttimestamp = 0;

        for (int32_t i=0 ;i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {

           timestamp = mVSyncEvent[i].header.timestamp;

            if (timestamp) {

                // we have a vsync event to dispatch

               *event = mVSyncEvent[i];

               mVSyncEvent[i].header.timestamp = 0;

               vsyncCount = mVSyncEvent[i].vsync.count;

                break;

            }

        }

        if (!timestamp) {

            // no vsync event, see if there are someother event

           eventPending = !mPendingEvents.isEmpty();

            if (eventPending){

                // we have some other event to dispatch

               *event = mPendingEvents[0];

               mPendingEvents.removeAt(0);

            }

        }

        // find out connections waiting forevents

        size_t count =mDisplayEventConnections.size();

        for (size_t i=0 ; i<count ; i++) {

           sp<Connection> connection(mDisplayEventConnections[i].promote());

            if (connection !=NULL) {

               bool added = false;

                if(connection->count >= 0) {

                   // we need vsyncevents because at least

                   // oneconnection is waiting for it

                   waitForVSync = true;

                   if (timestamp) {

                       // we consumethe event only if it's time

                       // (ie: wereceived a vsync event)

                       if (connection->count == 0) {

                            // fired this time around

                            connection->count = -1;

                           signalConnections.add(connection);

                            added = true;

                        } elseif(connection->count == 1 ||

                                (vsyncCount %connection->count) == 0) {

                            // continuous event, and time to reportit

                           signalConnections.add(connection);

                            added = true;

                       }

                   }

                }

                if (eventPending&& !timestamp && !added) {

                   // we don't havea vsync event to process

                   // (timestamp==0),but we have some pending

                   // messages.

                   signalConnections.add(connection);

                }

            } else {

                // we couldn't promote this reference,the connection has

                // died, so clean-up!

               mDisplayEventConnections.removeAt(i);

               --i; --count;

            }

        }

        // Here we figure out if we need toenable or disable vsyncs

        if (timestamp&& !waitForVSync) {

            // we received a VSYNC but we have noclients

            // don't report it, and disable VSYNCevents

           disableVSyncLocked();

        } elseif (!timestamp&& waitForVSync) {

            // we have at least one client, so wewant vsync enabled

            // (TODO: this function is called rightafter we finish

            // notifying clients of a vsync, so thiscall will be made

            // at the vsync rate, e.g. 60fps.  If we can accurately

            // track the current state we couldavoid making this call

            // so often.)

           enableVSyncLocked();

        }

        // note: !timestamp impliessignalConnections.isEmpty(), because we

        // don't populate signalConnections ifthere's no vsync pending

        if (!timestamp&& !eventPending) {

            // wait for something to happen

            if (waitForVSync){

                // This is where we spend most of ourtime, waiting

                // for vsync events and new clientregistrations.

                //

                // If the screen is off, we can't use h/wvsync, so we

                // use a 16ms timeout instead.  It doesn't need to be

                // precise, we just need to keep feedingour clients.

                //

                // We don't want to stall if there's adriver bug, so we

                // use a (long) timeout when waiting forh/w vsync, and

                // generate fake events when necessary.

               bool softwareSync = mUseSoftwareVSync;

               nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);

                if(mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {

                   if (!softwareSync){

                       ALOGW("Timed outwaiting for hw vsync; faking it");

                    }

                   // FIXME: how dowe decide which display id the fake

                   // vsync camefrom ?

                   mVSyncEvent[0].header.type =DisplayEventReceiver::DISPLAY_EVENT_VSYNC;

                   mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;

                   mVSyncEvent[0].header.timestamp= systemTime(SYSTEM_TIME_MONOTONIC);

                   mVSyncEvent[0].vsync.count++;

                }

            } else {

                // Nobody is interested in vsync, so wejust want to sleep.

                // h/w vsync should be disabled, so thiswill wait until we

                // get a new connection, or an existingconnection becomes

                // interested in receiving vsync again.

                mCondition.wait(mLock);

            }

        }

    } while(signalConnections.isEmpty());

    // here we're guaranteed to have atimestamp and some connections to signal

    // (The connections might have droppedout of mDisplayEventConnections

    // while we were asleep, but we'll stillhave strong references to them.)

    returnsignalConnections;

}

waitForEvent傳回,調用conn->postEvent(event),

boolEventThread::threadLoop() {

   DisplayEventReceiver::Event event;

    Vector<sp<EventThread::Connection> > signalConnections;

   signalConnections = waitForEvent(&event);

    // dispatch events to listeners...

    const size_t count =signalConnections.size();

    for (size_t i=0 ; i<count ;i++) {

        constsp<Connection>& conn(signalConnections[i]);

        // now see if we still need to report this event

        status_terr = conn->postEvent(event);

        if (err == -EAGAIN|| err == -EWOULDBLOCK) {

            // The destination doesn't accept eventsanymore, it's probably

            // full. For now, we just drop theevents on the floor.

            // FIXME: Note that some events cannotbe dropped and would have

            // to be re-sent later.

            // Right-now we don't have the abilityto do this.

            ALOGW("EventThread: dropping event (%08x)for connection %p",

                   event.header.type,conn.get());

        } elseif (err < 0) {

            // handle any other error on the pipe asfatal. the only

            // reasonable thing to do is to clean-upthis connection.

            // The most common error we'll get here is-EPIPE.

           removeDisplayEventConnection(signalConnections[i]);

        }

    }

    returntrue;

}

也就是通過Connection的寫fd将event發送給MessageQueue,

status_t EventThread::Connection::postEvent(

        constDisplayEventReceiver::Event& event) {

    ssize_t size =DisplayEventReceiver::sendEvents(mChannel, &event, 1);

    returnsize < 0 ? status_t(size) :status_t(NO_ERROR);

}

這時候MessageQueue的looper epoll傳回,最終會去調用response.request.callback->handleEvent,

intLooper::pollInner(int timeoutMillis){

    // Release lock.

    mLock.unlock();

    // Invoke all response callbacks.

    for (size_t i = 0; i <mResponses.size(); i++) {

       Response& response = mResponses.editItemAt(i);

        if (response.request.ident== ALOOPER_POLL_CALLBACK) {

            int fd =response.request.fd;

            int events =response.events;

            void* data =response.request.data;

#ifDEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS

            ALOGD("%p ~ pollOnce - invoking fd eventcallback %p: fd=%d, events=0x%x, data=%p",

                   this,response.request.callback.get(), fd, events, data);

#endif

            int callbackResult= response.request.callback->handleEvent(fd, events, data);

            if (callbackResult== 0) {

               removeFd(fd);

            }

            // Clear the callback reference in theresponse structure promptly because we

            // will not clear the response vectoritself until the next poll.

           response.request.callback.clear();

            result= ALOOPER_POLL_CALLBACK;

        }

    }

    return result;

}

最終調用的是mCallback(fd,events, data);

intSimpleLooperCallback::handleEvent(int fd, int events, void* data) {

    return mCallback(fd,events, data);

}

而這個mCallback,既是MessageQueue::cb_eventReceiver,

intMessageQueue::cb_eventReceiver(int fd, int events, void* data) {

    MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);

    returnqueue->eventReceiver(fd,events);

}

這裡會從MessageQueue的讀BitTube中讀出event,然後調用mHandler->dispatchInvalidate();

intMessageQueue::eventReceiver(int fd, int events) {

    ssize_t n;

   DisplayEventReceiver::Event buffer[8];

    while ((n =DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {

        for (int i=0 ; i<n ; i++){

            if(buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {

#ifINVALIDATE_ON_VSYNC

               mHandler->dispatchInvalidate();

#else

               mHandler->dispatchRefresh();

#endif

                break;

            }

        }

    }

    return1;

}

void MessageQueue::Handler::dispatchInvalidate() {

    if((android_atomic_or(eventMaskInvalidate, &mEventMask) &eventMaskInvalidate) ==0) {

        mQueue.mLooper->sendMessage(this,Message(MessageQueue::INVALIDATE));

    }

}

void MessageQueue::Handler::handleMessage(constMessage& message) {

    switch (message.what) {

        caseINVALIDATE:

           android_atomic_and(~eventMaskInvalidate, &mEventMask);

            mQueue.mFlinger->onMessageReceived(message.what);

            break;

        caseREFRESH:

           android_atomic_and(~eventMaskRefresh, &mEventMask);

            mQueue.mFlinger->onMessageReceived(message.what);

            break;

        caseTRANSACTION:

           android_atomic_and(~eventMaskTransaction, &mEventMask);

            mQueue.mFlinger->onMessageReceived(message.what);

            break;

    }

}

進而去調用SF的onMessageReceived函數,最終每次Vsync信号來了,SF都會去執行handleMessageTransaction()等函數。

voidSurfaceFlinger::onMessageReceived(int32_t what) {

    ATRACE_CALL();

    switch (what) {

    caseMessageQueue::TRANSACTION:

       handleMessageTransaction();

        break;

    caseMessageQueue::INVALIDATE:

       handleMessageTransaction();

       handleMessageInvalidate();

       signalRefresh();

        break;

    caseMessageQueue::REFRESH:

       handleMessageRefresh();

        break;

    }

}