Android SurfaceFlinger服務(七) ----- 圖像的合成

android應用中申請的Surface在SurfaceFlinger服務中都有對應有圖層Layer與之對應。將這些圖層合併且輸出到顯示外設是SurfaceFlinger的工作重點。本文來分析下合成的過程。合成工作在接收到VSync消息(MessageQueue::REFRESH)後開始。

void SurfaceFlinger::onMessageReceived(int32_t what) {
    ATRACE_CALL();
    switch (what) {
        
        ......
        
        case MessageQueue::REFRESH: {  
            handleMessageRefresh();        
            break;
        }
    }  
}
  • 調用消息處理函數handleMessageRefresh來進行顯示刷新工作,圖像合成與輸出的核心就在這個處理函數裏
void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

    ......
    
        preComposition();
        rebuildLayerStacks();
        setUpHWComposer();
        doDebugFlashRegions();
        doComposition();
        postComposition();
    
    ......


    previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}
  • preComposition、rebuildLayerStacks、setUpHWComposer圖層合成準備工作
  • setUpHWComposer會去設置圖層屬性compositionType(HWC_OVERLAY、HWC_FRAMEBUFFER等),這個屬性將決定該圖層在合成採用什麼方式(硬件合成或軟件合成)
  • doComposition圖層合成的主要工作,合成後的圖像也在這裏進行輸出顯示,重點關注
  • postComposition主要做一些收尾工作,不是關注的重點
void SurfaceFlinger::doComposition() {
    ATRACE_CALL();
    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        const sp<DisplayDevice>& hw(mDisplays[dpy]);
        if (hw->isDisplayOn()) {           
            // transform the dirty region into this screen's coordinate space
            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));

            // repaint the framebuffer (if needed)
            doDisplayComposition(hw, dirtyRegion);

            hw->dirtyRegion.clear();       
            hw->flip(hw->swapRegion);      
            hw->swapRegion.clear();    
        }
        // inform the h/w that we're done compositing
        hw->compositionComplete(); 
    }  
    postFramebuffer();
}
  • doDisplayComposition函數對第個DisplayDevice的圖層進行合成,在沒有硬件合成模塊的情況下,還進行輸出顯示
  • postFramebuffer在有硬件合成模塊時,提交圖層到HWComposer
void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
        const Region& inDirtyRegion)
{
    ......
    
    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
        if (!doComposeSurfaces(hw, dirtyRegion)) return;
    } else {
        RenderEngine& engine(getRenderEngine());
        mat4 colorMatrix = mColorMatrix;
        if (mDaltonize) {
            colorMatrix = colorMatrix * mDaltonizer();
        }
        mat4 oldMatrix = engine.setupColorTransform(colorMatrix);
        doComposeSurfaces(hw, dirtyRegion);
        engine.setupColorTransform(oldMatrix);
    }

    // update the swap region and clear the dirty region
    hw->swapRegion.orSelf(dirtyRegion);

    // swap buffers (presentation)
    hw->swapBuffers(getHwComposer());
}
  • 調用doComposeSurfaces函數進行圖層的合成,圖像合成的真正執行者
  • 調用hw->swapBuffers將軟件合成的結果提交到圖像緩衝區,待消費者去處理(後文分析)
bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
    

    ......
    

    /*
     * and then, render the layers targeted at the framebuffer
     */

    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
    const size_t count = layers.size();
    const Transform& tr = hw->getTransform();
    if (cur != end) {
        // we're using h/w composer
        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
            const sp<Layer>& layer(layers[i]);
            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                switch (cur->getCompositionType()) {
                    case HWC_CURSOR_OVERLAY:
                    case HWC_OVERLAY: {
                        const Layer::State& state(layer->getDrawingState());
                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                                && i
                                && layer->isOpaque(state) && (state.alpha == 0xFF)
                                && hasGlesComposition) {
                            // never clear the very first layer since we're
                            // guaranteed the FB is already cleared
                            layer->clearWithOpenGL(hw, clip);
                        }
                        break;
                    }
                    case HWC_FRAMEBUFFER: {
                        layer->draw(hw, clip);
                        break;
                    }
                    case HWC_FRAMEBUFFER_TARGET: {
                        // this should not happen as the iterator shouldn't
                        // let us get there.
                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
                        break;
                    }
                }
            }
            layer->setAcquireFence(hw, *cur);
        }
    } else {
        // we're not using h/w composer
        for (size_t i=0 ; i<count ; ++i) {
            const sp<Layer>& layer(layers[i]);
            const Region clip(dirty.intersect(
                    tr.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                layer->draw(hw, clip);
            }
        }
    }

    // disable scissor at the end of the frame
    engine.disableScissor();
    return true;
}
  • 當圖層的compositionType值爲HWC_CURSOR_OVERLAY或HWC_OVERLAY,採用硬件合成。既將圖層提交給HWComposer去處理
  • 當圖層的compositionType值爲HWC_FRAMEBUFFER,採用軟件gl合成。既調用Layer的draw方法繪製

至此,圖層合成流程大體走完,圖像輸出的過程將在下文分析。

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章