android display之VSync和線程處理關係

目錄:

0.mtk平臺相關surfaceflinger線程有那些?

1 mtk採用的是:硬件VSYNC 線程

2.Mtk 通過surfaceflinger註冊了3eventthread

     2.1 DispSyncThread如何區分和執行vssyncsrcsfVsyncSrcvs

      2.2 vssyncsrc和sfVsyncSrc的事件接受者什麼創建

     2.3 EventControl線程

//////////////////////////////////////////////////////////////////////////////////////

0.mtk平臺相關surfaceflinger線程有:


 

1 mtk採用的是:硬件VSYNC 線程:


 

 

2.Mtk 通過surfaceflinger註冊了3eventthread




 

每個event線程都註冊:

voidEventThread::Connection::onFirstRef() {

    // NOTE: mEventThread doesn't hold a strongreference on us

    mEventThread->registerDisplayEventConnection(this);

}

 

線程

VS信號源

功能

eventthread

vssyncsrc硬件VS

用於控制App UI的同步,產生sfVsyncSrc的週期:sfVsyncPhaseOffsetNs在setVSyncEnabled()的時候mDispSync->addEventListener()來設置週期

Eventthread

sfVsyncSrc

surfaceflinger的渲染同步,產生vssyncsrc的週期是:vsyncPhaseOffsetNs在setVSyncEnabled()的時候mDispSync->addEventListener()來設置週期

EventControl

用來向VSync硬件發命令,只是使能和關閉硬件vs信號

DispSync線程

vssyncsrc硬件VS

統一處理硬件產生的vs信號,以及計算幀時間

理論上來說:vssyncsrcsfVsyncSrc都是虛擬的vs。兩者都是通過DispSync線程來計算髮出vs的時間。

 

2.1 DispSyncThread如何區分和執行vssyncsrcsfVsyncSrcVsyncSrc

答案:

1)首先VSyncSource對象的創建如下

 // start the EventThread

    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,返回一個DispSyncSource對象給vsyncSrc

            vsyncPhaseOffsetNs, true);

    mEventThread = new EventThread(vsyncSrc);

    sp<VSyncSource>sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,----返回一個DispSyncSource對象給sfVsyncSrc

            sfVsyncPhaseOffsetNs, false);

    mSFEventThread = newEventThread(sfVsyncSrc);

    mEventQueue.setEventThread(mSFEventThread);

-------也就是每個EventThread都是有管理自己的對象vsyncSrc或者sfVsyncSrc;

 ---------EventThread::threadLoop-------

{

……...

-waitForEvent()

…...

}

//增加監聽者以及設置接收到vsync的時候callbakc

waitForEvent(){

…..

// Here we figure outif we need to enable or disable vsyncs

        if (timestamp && !waitForVSync){

            // we received a VSYNC but we haveno clients

            // don't report it, and disableVSYNC events

            disableVSyncLocked();

        } else if (!timestamp &&waitForVSync) {

            // we have at least one client, sowe want vsync enabled

            // (TODO: this function is calledright after we finish

            // notifying clients of a vsync, sothis call 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();

        }

………

}

void EventThread::enableVSyncLocked() {

    if (!mUseSoftwareVSync) {

        // never enable h/w VSYNC when screenis off

        if (!mVsyncEnabled) {

            mVsyncEnabled = true;

/*設置回調VSyncSource::Callback onVSyncEvent是純虛函數:EventThread繼承自VSyncSource::Callback。實現了onVSyncEvent()回調函數。

//classEventThread : public Thread, private VSyncSource::Callback

最終:mCallback = callback;

virtual voidsetCallback(const sp<VSyncSource::Callback>& callback) {

        Mutex::Autolock lock(mMutex);

        mCallback = callback;

    }

 

*/

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

            mVSyncSource->setVSyncEnabled(true);-----這側監聽者到mEventListeners

            mPowerHAL.vsyncHint(true);

        }

    }

    mDebugVsyncEnabled = true;

}

 

2)其次硬件常常一個VS--->通知到SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp)//timestamp就是用來計算這次vs的週期:mPeriod ;而mPeriod 就是DispSync線程的執行週期。

 virtual bool threadLoop() {

        status_t err;

        nsecs_t now =systemTime(SYSTEM_TIME_MONOTONIC);

        nsecs_t nextEventTime = 0;

 

        while (true) {

            Vector<CallbackInvocation>callbackInvocations;

………...

                if (mPeriod == 0) {

                    err = mCond.wait(mMutex);//週期超時  ,則wait,直到下一次HW VS產生

                    if (err != NO_ERROR) {

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

                                strerror(-err),err);

                        return false;

                    }

                    continue;

                }

 

               。。。。。。。。。

                if (isWakeup) {

                    mWakeupLatency =((mWakeupLatency * 63) +

                            (now - targetTime))/ 64;

                    if (mWakeupLatency >500000) {

                        // Don't correct bymore than 500 us

                        mWakeupLatency =500000;

                    }

                    if (traceDetailedInfo) {

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

                       ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);

                    }

                }

//gatherCallbackInvocationsLocked() 計算出虛擬VSync信號 要多久產生。

                callbackInvocations= gatherCallbackInvocationsLocked(now);

            }

 

            if (callbackInvocations.size() >0) {

                fireCallbackInvocations(callbackInvocations);

//調起監聽者的回調函數DispSyncSource::onDispSyncEvent()-----》callback->onVSyncEvent(when);

            }

        }

 

        return false;

    }

voidfireCallbackInvocations(const Vector<CallbackInvocation>& callbacks){

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

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

        }

    }

 

 

 

DispSyncThread就像樂隊鼓手一樣控制着大家的節奏。它在主循環中會先通過已經向DispSync註冊的listener計算下一個要產生的虛擬VSync信號還要多久,等待相應時間後就會調用相應listenercallback函數。這樣,對於那些註冊了listener的監聽者來說,就好像被真實的VSync信號控制着一樣。”

 

小結:相對DispSyncThread而言,vssyncsrc線程和sfVsyncSrc線程vsync監聽者。

             vssyncsrcsfVsyncSrc收到vsync之後,應用程序和surfaceflinger(兩線程循環 獲取Event)是vsync事件的接收者。

所以vsynv的路徑就是:DispSyncThread--->vssyncsrc和sfVsyncSrc---->vsync事件的接收者:應用程序和surfaceflinger.

 

2.2 vssyncsrc線程和sfVsyncSrc線程的vsync事件接受者什麼創建?

1sfVsyncSrcvsync事件接收者創建:通過mSFEventThread對象

    mSFEventThread= new EventThread(sfVsyncSrc);

    mEventQueue.setEventThread(mSFEventThread);

 

voidMessageQueue::setEventThread(constsp<EventThread>& eventThread)

{

    mEventThread = eventThread;

    mEvents =eventThread->createEventConnection();

    mEventTube = mEvents->getDataChannel();

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

            MessageQueue::cb_eventReceiver,this);

}

 

2vssyncsrcvsync事件接收者創建:

應用層通過DisplayEventReceiver.java

--->android_view_DisplayEventReceiver.cpp

--->DisplayEventReceiver.cpp

---->EventThread.cpp

一直到mEventThread對象:

sp<IDisplayEventConnection>SurfaceFlinger::createDisplayEventConnection() {

    return mEventThread->createEventConnection();

}

 

 

2.3 EventControl線程

EventControlThread::threadLoop(

---->

       mFlinger->eventControl(HWC_DISPLAY_PRIMARY,

                   SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);

----->getHwComposer().eventControl(disp, event, enabled);----->HWComposer::eventControl()

 

---- mHwc->eventControl() hal

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章