SurfaceFlinger之Refresh

本內容基于自己對于代碼的理解以及網上大牛的博客參考寫的,作為回顧時的參考之用。

SurfaceFlinger在經過事務處理以及Page Flip之后,所有的數據都準備好,最后一步就是把內容刷新到屏幕上。

1. handleMessageRefresh

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

#ifdef ENABLE_FENCE_TRACKING
    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
#else
    nsecs_t refreshStartTime = 0; 
#endif
    static nsecs_t previousExpectedPresent = 0; 
    nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);
    static bool previousFrameMissed = false;
    bool frameMissed = (expectedPresent == previousExpectedPresent);
    if (frameMissed != previousFrameMissed) {
        ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
    }    
    previousFrameMissed = frameMissed;

    if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {
        // Latch buffers, but don't send anything to HWC, then signal another
        // wakeup for the next vsync
        preComposition();
        repaintEverything();
    } else {
        preComposition();
        rebuildLayerStacks();
        //setUpHWComposer先會遍歷各個設備DisplayDevice,然后根據可見layer數量,調用createWorkList創建hwc_layer_list_t列表,
        //然后在每個設備上遍歷可見layer,將layer的mActiveBuffer設置到HWComposer中去,最后調用了HWComposer的prepare函數。
        setUpHWComposer();
        doDebugFlashRegions();
        //合成所有層的圖像, 經過這一步后,就顯示新的內容了。
        doComposition();
        postComposition(refreshStartTime);
    }    

    previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}

setUpHWComposer 參考Android6.0 圖像合成過程詳解(一) setUpHWComposer函數

doComposition請Android6.0 圖像合成過程詳解(二) doComposition函數

2. preComposition

void SurfaceFlinger::preComposition()
{
    mPowerHintThread->requestPowerHint(); //電源管理相關

    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()) { //調用Layer的 onPreComposition
            needExtraInvalidate = true;
        }
    }
    if (needExtraInvalidate) {
        signalLayerUpdate(); //如果需要invalidate的話,觸發下一個VSYNC
    }
}
  • Layer.cpp
bool Layer::onPreComposition() {
    mRefreshPending = false;
    //自動刷新或還有QUEUED的Frame, 以及設置了side band
    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; 
}

3. rebuildLayerStacks

void SurfaceFlinger::rebuildLayerStacks() {
    // rebuild the visible layer list per screen
    if (CC_UNLIKELY(mVisibleRegionsDirty)) { //重建屏幕的Layer Stack
        ATRACE_CALL();
        mVisibleRegionsDirty = false;
        invalidateHwcGeometry();

        const LayerVector& layers(mDrawingState.layersSortedByZ);
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            Region opaqueRegion;
            Region dirtyRegion;
            Vector< sp<Layer> > layersSortedByZ;
            const sp<DisplayDevice>& hw(mDisplays[dpy]);
            const Transform& tr(hw->getTransform());
            const Rect bounds(hw->getBounds());
            if (hw->isDisplayOn()) {
                //對該DISPLAY的所有Layer計算可視化區域
                SurfaceFlinger::computeVisibleRegions(layers,
                        hw->getLayerStack(), dirtyRegion, opaqueRegion);

                const size_t count = layers.size();
                for (size_t i=0 ; i<count ; i++) {
                    const sp<Layer>& layer(layers[i]);
                    const Layer::State& s(layer->getDrawingState());
                    if (s.layerStack == hw->getLayerStack()) {
                        Region drawRegion(tr.transform(
                                layer->visibleNonTransparentRegion));
                        drawRegion.andSelf(bounds);
                        if (!drawRegion.isEmpty()) {
                            layersSortedByZ.add(layer);
                        }
                    }
                }
            }
            //設置 on-screen上的變量, layers,  dirty區域
            hw->setVisibleLayersSortedByZ(layersSortedByZ);
            hw->undefinedRegion.set(bounds); //整個屏幕size
            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); //這個沒有內容的區域,一般就是黑色區域了
            hw->dirtyRegion.orSelf(dirtyRegion); //dirty 區域
        }
    }
}

4. computeVisibleRegions

計算該Display上的可視區域
void SurfaceFlinger::computeVisibleRegions(
        const LayerVector& currentLayers, uint32_t layerStack,
        Region& outDirtyRegion, Region& outOpaqueRegion)
{
    ATRACE_CALL();

    //
    Region aboveOpaqueLayers;
    //
    Region aboveCoveredLayers;
    Region dirty;

    outDirtyRegion.clear();

    size_t i = currentLayers.size();
    while (i--) { //按照Z軸從大到小,也就是從頂至下計算
        const sp<Layer>& layer = currentLayers[i];

        // start with the whole surface at its current location
        const Layer::State& s(layer->getDrawingState());

        // only consider the layers on the given layer stack
        //只考慮一個DISPLAY device上所有的Layer
        if (s.layerStack != layerStack)
            continue;

        /*
         * opaqueRegion: area of a surface that is fully opaque.
         */
        Region opaqueRegion; //具體一層Layer的完全不透明區域

        /*
         * visibleRegion: area of a surface that is visible on screen
         * and not fully transparent. This is essentially the layer's
         * footprint minus the opaque regions above it.
         * Areas covered by a translucent surface are considered visible.
         */
        Region visibleRegion;  //具體一層Layer的可見區域

        /*
         * coveredRegion: area of a surface that is covered by all
         * visible regions above it (which includes the translucent areas).
         */
        Region coveredRegion;//具體一層Layer的被覆蓋的區域

        /*
         * transparentRegion: area of a surface that is hinted to be completely
         * transparent. This is only used to tell when the layer has no visible
         * non-transparent regions and can be removed from the layer list. It
         * does not affect the visibleRegion of this layer or any layers
         * beneath it. The hint may not be correct if apps don't respect the
         * SurfaceView restrictions (which, sadly, some don't).
         */
        Region transparentRegion; //具體一層的透明區域


        // handle hidden surfaces by setting the visible region to empty
        if (CC_LIKELY(layer->isVisible())) {
            //是否是半透明狀態
            const bool translucent = !layer->isOpaque(s);
            //計算Layer的可視區域
            Rect bounds(s.active.transform.transform(layer->computeBounds()));
            // 具體一層Layer的初始化可視區域
            visibleRegion.set(bounds);
            if (!visibleRegion.isEmpty()) {//如果該Layer層可視區域不為空
                // Remove the transparent area from the visible region
                if (translucent) { //如果是半透明的區域, 計算透明區域大小
                    const Transform tr(s.active.transform);
                    if (tr.preserveRects()) { //如果矩陣是一些常規矩陣,比如平移、縮放、旋轉這些
                        // transform the transparent region
                        //獲得透明的區域
                        transparentRegion = tr.transform(s.activeTransparentRegion);
                    } else {
                        //矩陣變換太復雜,不用優化了. 囧 ...
                        // transformation too complex, can't do the
                        // transparent region optimization.
                        transparentRegion.clear();
                    }
                }

                // compute the opaque region
                const int32_t layerOrientation = s.active.transform.getOrientation();
                if (s.alpha==255 && !translucent &&
                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
                    // the opaque region is the layer's footprint
                    opaqueRegion = visibleRegion; //完全不透明的區域
                }
            }
        }

        // Clip the covered region to the visible region
        // 當前區域被前面的Layer覆蓋的區域 
        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);

        // Update aboveCoveredLayers for next (lower) layer
        //之前的Layer和自己所占的總的區域,相對于下一個Layer,就是已經覆蓋的總區域
        aboveCoveredLayers.orSelf(visibleRegion);

        // subtract the opaque region covered by the layers above us
        //除了之前的Layer覆蓋的區域外,我這層Layer還剩多少可視區域
        visibleRegion.subtractSelf(aboveOpaqueLayers);

        // compute this layer's dirty region
        if (layer->contentDirty) { //這個值在 Layer的doTransaction中可能為True, 當新舊的sequence不一致時
            // we need to invalidate the whole region
            dirty = visibleRegion;  // invalidate整個區域
            // as well, as the old visible region
            dirty.orSelf(layer->visibleRegion); //整個Dirty的區域要加上上一個可視區域,這個在之前有講,自己想一下為什么
            layer->contentDirty = false;
        } else {
            /* compute the exposed region:
             *   the exposed region consists of two components:
             *   1) what's VISIBLE now and was COVERED before
             *   2) what's EXPOSED now less what was EXPOSED before
             *
             * note that (1) is conservative, we start with the whole
             * visible region but only keep what used to be covered by
             * something -- which mean it may have been exposed.
             *
             * (2) handles areas that were not covered by anything but got
             * exposed because of a resize.
             */
            const Region newExposed = visibleRegion - coveredRegion;
            const Region oldVisibleRegion = layer->visibleRegion;
            const Region oldCoveredRegion = layer->coveredRegion;
            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
            //只計算局部dirty區域
            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
        }
        //Layer的區域減掉上層Layer的覆蓋的區域
        dirty.subtractSelf(aboveOpaqueLayers);

        // accumulate to the screen dirty region
        //outDirtyRegion是整個屏幕的臟區域,這個肯定是累加的
        outDirtyRegion.orSelf(dirty);

        // Update aboveOpaqueLayers for next (lower) layer
        aboveOpaqueLayers.orSelf(opaqueRegion);

        // Store the visible region in screen space
        // 保存到這些區域到 Layer中,以便下一次合成使用
        layer->setVisibleRegion(visibleRegion);
        layer->setCoveredRegion(coveredRegion);
        layer->setVisibleNonTransparentRegion(
                visibleRegion.subtract(transparentRegion));
    }
    //完全不透明的區域
    outOpaqueRegion = aboveOpaqueLayers;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容