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

时间:2022-05-17 03:55:33


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

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

surfaceflinger中类的关系

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

int Looper::pollInner(int timeoutMillis) {


    struct epoll_event eventItems[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_t epollEvents = eventItems[i].events;
        if (fd == mWakeReadPipeFd) {
            if (epollEvents & EPOLLIN) {
                awoken();
            } else {
                ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
            }
        } else {
            //mRequests键值对前面就注册好了,这里通过fd取到mRequests中fd的index
            ssize_t requestIndex = 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("Ignoring unexpected 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;
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
            ALOGD("%p ~ pollOnce - invoking fd event callback %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 the response structure promptly because we
            // will not clear the response vector itself until the next poll.
            response.request.callback.clear();
            result = POLL_CALLBACK;
        }
    }
    return result;
}

SimpleLooperCallback的handleEvent()函数,其实执行的是mCallback(),即cb_eventReceiver()。

int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
    return mCallback(fd, events, data);
}

HWC驱动DispSync

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

mHwc.mEventHandler.onVSyncReceived(0, next_vsync);

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

void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
    bool needsHwVsync = false;

    { // Scope for the lock
        Mutex::Autolock _l(mHWVsyncLock);
        if (type == 0 && mPrimaryHWVsyncEnabled) {
            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
        }
    }
}

进而调用DispSync的updateModelLocked()函数,

bool DispSync::addResyncSample(nsecs_t timestamp) {
    updateModelLocked();
}

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

void DispSync::updateModelLocked() {
    if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
        //驱动DispSyncThread线程不停工作了
        mThread->updateModel(mPeriod, mPhase);
    }
}