1. 程式人生 > >surfaceflinger 合成過程解析

surfaceflinger 合成過程解析

[TOC]來生成目錄:

整體流程

我們知道,當VSync訊號到來時,SurfaceFlinger最主要是通過處理INVALIDATE和REFRESH訊息來做合併渲染和輸出的工作的。這裡的核心思想是能少處理一點是一點,所以在渲染前有很多髒區域的計算工作,這樣後面只要處理那些區域的更新就可以了。
這樣是有現實意義的,一方面由於圖層間的遮蓋,有些不可見圖層不需要渲染。另一方面,因為我們的應用程式中前後幀一般只有一小部分變化,要是每幀都全變估計人都要看吐了。這裡主要是呼叫了這幾個函式:
handleMessageTransaction

()主要處理之前對螢幕和應用程式視窗的改動。因這些改動很有可能會改變圖層的可見區域,進而影響髒區域的計算。
handleMessageInvalidate()主要呼叫handlePageFlip()函式。這裡Page Flip是指從BufferQueue中取下一個圖形緩衝區內容,就好像是“翻頁”一樣。該函式主要是從各Layer對應的BufferQueue中拿圖形緩衝區資料,並根據內容更新髒區域。
handleMessageRefresh()就是合併和渲染輸出了。

handleMessageInvalidate

如上所說,這個主要是把所有可見的layer的buffer拿出來。
handleMessageInvalidate只調用了handlePageFlip

bool SurfaceFlinger::handlePageFlip()
{
    Region dirtyRegion;

    bool visibleRegions = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);//拿出所有的layer
    bool frameQueued = false;

    Vector<Layer*> layersWithQueuedFrames;
    for (size_t i = 0, count = layers.size(); i<count ; i++) {
        const
sp<Layer>& layer(layers[i]); if (layer->hasQueuedFrame()) {//看Layer的mQueuedFrames > 0? frameQueued = true; if (layer->shouldPresentNow(mPrimaryDispSync)) { layersWithQueuedFrames.push_back(layer.get()); } } } //如果layersWithQueuedFrames.size()>0,說明有更新 for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { Layer* layer = layersWithQueuedFrames[i]; const Region dirty(layer->latchBuffer(visibleRegions));//呼叫latchBuffer,該函式會拿出BufferQueue的新buffer const Layer::State& s(layer->getDrawingState()); invalidateLayerStack(s.layerStack, dirty); } mVisibleRegionsDirty |= visibleRegions; if (frameQueued && layersWithQueuedFrames.empty()) { signalLayerUpdate();//如果沒有任何layer更新,那就呼叫signalLayerUpdate->requestNextVsync,等待下一個vsync } return !layersWithQueuedFrames.empty();//有新幀,就返回true }

handleMessageRefresh

前一步,已經把各個layer的buffer更新了,接著就是要合成並輸出了,這個函式就幹這個事情。
且看其定義。

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition();
}

1. preComposition

void SurfaceFlinger::preComposition()
{
    bool needExtraInvalidate = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
        if (layers[i]->onPreComposition()) {//判斷mQueuedFrames > 0
            needExtraInvalidate = true;
        }
    }
    if (needExtraInvalidate) {
        signalLayerUpdate();//一旦有某一個layer有更新,就呼叫signalLayerUpdate->requestNextVsync
    }
}

signalLayerUpdate主要呼叫
mEvents->requestNextVsync();

2. rebuildLayerStacks

根據函式名字就可以知道,他主要是對所有的layer過濾一遍,拿出可見的layer,等待下一步處理。
函式比較簡單,這裡不詳說。

3. setUpHWComposer

void SurfaceFlinger::setUpHWComposer() {
    //省略。。。
    HWComposer& hwc(getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
        // build the h/w work list
        if (CC_UNLIKELY(mHwWorkListDirty)) {
            mHwWorkListDirty = false;
            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {//其實大部分情況,只有一個DisplayDevice
                sp<const DisplayDevice> hw(mDisplays[dpy]);
                const int32_t id = hw->getHwcDisplayId();//DisplayDevice的id
                if (id >= 0) {
                    const Vector< sp<Layer> >& currentLayers(
                        hw->getVisibleLayersSortedByZ());//rebuildLayerStacks時,把可見的layer存在DisplayDevice了
                    const size_t count = currentLayers.size();//可見的layer
                    if (hwc.createWorkList(id, count) == NO_ERROR) {//HWC的createWorkList很重要。
                        HWComposer::LayerListIterator cur = hwc.begin(id);
                        const HWComposer::LayerListIterator end = hwc.end(id);
                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                            const sp<Layer>& layer(currentLayers[i]);
                            layer->setGeometry(hw, *cur);
                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
                                cur->setSkip(true);
                            }
                        }
                    }
                }
            }
        }
}

4. doDebugFlashRegions

5. doComposition

6. postComposition