android display之VSync和线程处理关系

来源:互联网 发布:网络管理与通信软件 编辑:程序博客网 时间:2024/06/06 05:14

目录:

0.mtk平台相关surfaceflinger线程有那些?

1 mtk采用的是:硬件VSYNC线程

2.Mtk通过surfaceflinger注册了3eventthread

     2.1DispSyncThread如何区分和执行vssyncsrcsfVsyncSrcvs

      2.2 vssyncsrc和sfVsyncSrc的事件接受者什么创建

     2.3EventControl线程

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

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.1DispSyncThread如何区分和执行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::CallbackonVSyncEvent是纯虚函数: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() {

    returnmEventThread->createEventConnection();

}

 

 

2.3EventControl线程

EventControlThread::threadLoop(

---->

      mFlinger->eventControl(HWC_DISPLAY_PRIMARY,

                   SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);

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

 

---- mHwc->eventControl() hal

0 0