android graphic(5)—surfaceflinger和Vsync (简化)

来源:互联网 发布:无涯子 知乎 编辑:程序博客网 时间:2024/05/25 23:59

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

  • surfaceflinger中类的关系
  • HWC驱动DispSync

上一节分析了Vsync的多个类之间的关系,感觉非常不清晰,特地画了一张图,感觉清晰了很多。(黄色的方框是类名,绿色方框为field,联系用虚线箭头表示,如果不同线条之间有重叠,用了不同的颜色)

surfaceflinger中类的关系

下面照着这张图,梳理下Android 4.4 SFVsync相关类之间的联系,surfaceflinger简写为SF 
1. Vsync
的硬件模型类,DispSync,其对应的thread保存在mThread中,thread是一个DispSyncThread类型; 
2. DispSyncThread
mEventListeners是个EventListener类型的Vector 
3. EventListener
类中的mCallback其实保存的是DispSyncSource对象,这样就将硬件模型和驱动的事件DispSyncSource类联系起来了,在上面图中我们看到了两个mCallback,一个指向了DispSyncSource,一个指向了EventThread,容易搞混,正是由于这两个mCallbackDispSyncThread类,DispSyncSourceEventThread联系了起来; 
4. DispSyncSource
类中的mCallback指向的其实是其对应的EventThread类,而EventThread类中的mDisplayEventConnections是个 wp 类型的SortedVector,但是所指向的Connection中的BitTube mChannel只有写fd,这样我们往这个写fd写东西,哪里会收到呢? 
5.
当然是SF主线程中的MessageQueue,其中保存了另外一个BitTube mEventTube,里面保存了读fd,当Vsync信号到来时,EventThread会去往写fd中写东西,而这时候SF主线程中MessageQueuelooperepoll会被唤醒; 
6.
looper中保存了一个KeyedVector<int, Request>mRequests键值对,其中以fd做键,Request做值,其中fd指向了读fd,而data指向了MessageQueuecallback指向了一个SimpleLooperCallback类,SimpleLooperCallback类中的mCallback则指向了最终的事件处理函数cb_eventReceiver() 
下面看下LooperpollInner函数,

int Looper::pollInner(int timeoutMillis){

 

 

    struct epoll_eventeventItems[EPOLL_MAX_EVENTS];

    int eventCount =epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);

    //epoll_wait返回,

 

 

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

        int fd =eventItems[i].data.fd;

        uint32_tepollEvents = eventItems[i].events;

        if (fd ==mWakeReadPipeFd) {

            if (epollEvents& EPOLLIN) {

               awoken();

            } else {

               ALOGW("Ignoringunexpected epoll events 0x%x on wake read pipe.", epollEvents);

            }

        } else {

            //mRequests键值对前面就注册好了,这里通过fd取到mRequestsfdindex

            ssize_trequestIndex = mRequests.indexOfKey(fd);

            if (requestIndex>=0) {

                int events =0;

                if (epollEvents& EPOLLIN) events |= EVENT_INPUT;

                if (epollEvents& EPOLLOUT) events |= EVENT_OUTPUT;

                if (epollEvents& EPOLLERR) events |= EVENT_ERROR;

                if (epollEvents& EPOLLHUP) events |= EVENT_HANGUP;

                //取出mRequests相关的值,放到mResponses

               pushResponse(events, mRequests.valueAt(requestIndex));

            } else {

               ALOGW("Ignoringunexpected epoll events 0x%x on fd %d that is "

                        "no longer registered.", epollEvents,fd);

            }

        }

    }

 

 

    // Release lock.

    mLock.unlock();

     //前面的mResponses已经填充好了,这里取出来处理具体事件

    // Invoke all response callbacks.

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

       Response& response = mResponses.editItemAt(i);

        if(response.request.ident == 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

            //这里的callbackcallback指向了一个SimpleLooperCallback类,SimpleLooperCallback类中的mCallback则指向了最终的事件处理函数cb_eventReceiver()

            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 = POLL_CALLBACK;

        }

    }

    return result;

}

SimpleLooperCallbackhandleEvent()函数,其实执行的是mCallback(),即cb_eventReceiver()

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

    return mCallback(fd,events, data);

}

HWC驱动DispSync

最开始的图形描述的都是SFVsync相关类的关系,那么HWC如何驱动DispSync 
HWC
中每个Vsync信号到来时,都会调用SFonVSyncReceived函数,

mHwc.mEventHandler.onVSyncReceived(0, next_vsync);

进而去调用mPrimaryDispSyncaddResyncSamplemPrimaryDispSync就是DispSync,根据函数名,添加时间片,就相当于不停的产生时间,就把DispSync驱动起来了,

voidSurfaceFlinger::onVSyncReceived(inttype, nsecs_ttimestamp) {

    boolneedsHwVsync = false;

 

    { // Scope for the lock

       Mutex::Autolock _l(mHWVsyncLock);

        if (type ==0 && mPrimaryHWVsyncEnabled) {

           needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);

        }

    }

}

进而调用DispSyncupdateModelLocked()函数,

boolDispSync::addResyncSample(nsecs_t timestamp) {

   updateModelLocked();

}

这里就会去驱动DispSyncThread线程工作了,后续的在图上都能看到。

void DispSync::updateModelLocked() {

    if(mNumResyncSamples>= MIN_RESYNC_SAMPLES_FOR_UPDATE){

        //驱动DispSyncThread线程不停工作了

        mThread->updateModel(mPeriod,mPhase);

    }

}

0 0
原创粉丝点击