Android N之SurfaceFlinger流程解析(4)

来源:互联网 发布:网络喷人 侮辱罪 编辑:程序博客网 时间:2024/06/07 18:44

SurfaceFlinger中的Vsync信号相关的处理,也就是启动EventThread的分析:

如下代码:

    // start the EventThread    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,            vsyncPhaseOffsetNs, true, "app");    mEventThread = new EventThread(vsyncSrc, *this);    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,            sfVsyncPhaseOffsetNs, true, "sf");    mSFEventThread = new EventThread(sfVsyncSrc, *this);    mEventQueue.setEventThread(mSFEventThread);

Android中的Vsync信号分两种,分别是硬件生成的信号和软件生成的信号。
硬件的信号是由hwcomposer产生的,代码放置在HAL层中,如果厂商提供的HAL层可以产生Vsync信号,则使用硬件产生的信号,不然的话则使用软件生成的信号。
通过上面的代码可以看到,在SurfaceFlinger的成员函数init中,会创建两个DispSyncSource,一个是给app的,一个是给SurfaceFlinger的,然后会相应的new了EventThread线程。
如何传递信号的呢?
一个app如果需要信号的话,则会向EventThread注册一个connection,然后该EventThread会向所有的connection发送VSYNC信号,那么对于SF自己来说的话就更容易了,只要通过setEventThread向SF来注册connection就行了。

void MessageQueue::setEventThread(const sp<EventThread>& eventThread){    mEventThread = eventThread;    mEvents = eventThread->createEventConnection();    mEventTube = mEvents->getDataChannel();    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,            MessageQueue::cb_eventReceiver, this);}

那么SurfaceFlinger接收处理Vsync的过程大致为:HWComposer HAL通过callback函数,把VSYNC信号传给DispSyncThread,DispSyncThread传给EventThread。

接下来分析Vsync信号传递途径:
1.信号如何从hwc到SF
HWComposer HAL层获得硬件中断,然后通过callback函数,回调到SurfaceFlinger的onVsyncReceived。 SurfaceFlinger调用DispSync的updateModel函数,唤醒DispSyncThread。然后DispSyncThread通过fireCallbackInvocations函数,告诉DispSyncSource有Vsync信号来了。
网上有篇博客讲的很好:http://blog.csdn.net/newchenxf/article/details/49131167
这里写图片描述

2.信号如何从SF到app
应用在起来的时候会new一个RenderThread,在new RenderThread的时候会调用成员函数initializeDisplayEventReceiver,在initializeDisplayEventReceiver中会new DisplayEventReceiver,很明显知道DisplayEventReceiver是为了接收Vsync信号的,DisplayEventReceiver构造函数,就首先会调用surfaceflinger去注册一个connection,connection又会创建BitTube。客户端便可以通过getDataChannel()获得这个BitTube。

DisplayEventReceiver::DisplayEventReceiver() {    sp<ISurfaceComposer> sf(ComposerService::getComposerService());    if (sf != NULL) {        mEventConnection = sf->createDisplayEventConnection();        if (mEventConnection != NULL) {            mDataChannel = mEventConnection->getDataChannel();        }    }}

surfaceflinger进程的EventThread把VSYNC不断的往BitTube写,而app进程将会创建DisplayEventReceiver,该app进程又可以不断的读BitTube。这样,Vsync就可以传输了。

此外在init中还会new一个EventControlThread,然后让其运行起来。用于开始/关闭 HWComposer HAL的VSYNC。

    mEventControlThread = new EventControlThread(this);    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

下面来看一下EventControlThread类的构造函数:

EventControlThread::EventControlThread(const sp<SurfaceFlinger>& flinger):        mFlinger(flinger),        mVsyncEnabled(false) {}

在来看EventControlThread的成员函数threadLoop,代码如下:

bool EventControlThread::threadLoop() {    Mutex::Autolock lock(mMutex);    bool vsyncEnabled = mVsyncEnabled;#ifdef USE_HWC2    mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);#else    mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,            mVsyncEnabled);#endif    while (true) {        status_t err = mCond.wait(mMutex);        if (err != NO_ERROR) {            ALOGE("error waiting for new events: %s (%d)",                strerror(-err), err);            return false;        }        if (vsyncEnabled != mVsyncEnabled) {#ifdef USE_HWC2            mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);#else            mFlinger->eventControl(HWC_DISPLAY_PRIMARY,                    SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);#endif            vsyncEnabled = mVsyncEnabled;        }    }    return false;}

后面会抽时间好好分析一波这里面的细节部分,先写个轮廓。

0 0
原创粉丝点击