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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容