Android UI架构(九)--探秘刷新动力Vsync(5)之Layer合成composer.md

本文详细探讨了Android系统中SurfaceFlinger在接收到Vsync信号后的处理过程,包括handleMessageRefresh方法的执行、Layer的遍历、可视区域的计算以及合成阶段的关键步骤。通过对handleMessageRefresh、rebuildLayerStacks、calculateWorkingSet和doComposition等方法的分析,揭示了Android UI的刷新动力机制。
摘要由CSDN通过智能技术生成

参考资料

  1. Android Synchronization Fences – An Introduction
  2. Android 4.0.3 显示系统深入理解
  3. Clang 10 documentation ATTRIBUTES IN CLANG
  4. 「Android」SurfaceFlinger分析
  5. 显示系统:第005课_Vsync机制:第007节_rebuildLayerStacks源码分析
  6. Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析
  7. Android Region代码分析

Andorid Q

接着上文,当我们接收到来自App RenderThread线程渲染后的Surface之后,会在SurfaceFlinger收到下一次Vsync时做合成。
前面我们也稍微分析了一下,直接看handleMessageRefresh方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LAd0wxbT-1592309583800)(picture/5_1_sf_onVsync.png)]

从上面trace上也可以看出收到Vsync后,sf首先调用handleMessageInvalidate检查时候需要进行合成。
如果需要就会调用方法handleMessageRefresh去做合成,最后将合成后的图像送入屏幕显示。

这里重点分析handleMessageRefresh.

一. handleMessageRefresh

1.1 SurfaceFlinger:handleMessageRefresh

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

    mRefreshPending = false;

    const bool repaintEverything = mRepaintEverything.exchange(false);
    // 1.2 合成前再过一遍Layer是否被更新了
    // 如果有则触发signalLayerUpdate(),通过EventThread安排一次invalidate sf vsync。
    preComposition();

    // 1.3 重建layer堆栈, 提取可见的Laye并计算可见区域
    // 并将数据更新给对应的Display
    rebuildLayerStacks();

    // 1.4 hwcomposer的设定,将Layer数据更新给HWC
    calculateWorkingSet();

    // 遍历所有Display,依次合成处理
    for (const auto& [token, display] : mDisplays) {
        // 1.5 其实beginFrame和prepareFrame最终都是调用到FrameBufferSurface中,没有做特别的事情
        beginFrame(display);
        prepareFrame(display);
        doDebugFlashRegions(display, repaintEverything);
        // 1.6 正式的合成处理,简单来说就是申请GraphicBuffer,向其中填充帧数据
        // 最终给到硬件帧缓冲区
        doComposition(display, repaintEverything); 
    }

    logLayerStats();

    // 通知composer,即HWC
    postFrame();

    // 回调每个layer的onPostComposition
    postComposition();

    mHadClientComposition = false;
    mHadDeviceComposition = false;
    for (const auto& [token, displayDevice] : mDisplays) {
        auto display = displayDevice->getCompositionDisplay();
        const auto displayId = display->getId();
        mHadClientComposition =
                mHadClientComposition || getHwComposer().hasClientComposition(displayId);
        mHadDeviceComposition =
                mHadDeviceComposition || getHwComposer().hasDeviceComposition(displayId);
    }

    // 根据状况决定是否更新Vsync Offset
    mVsyncModulator.onRefreshed(mHadClientComposition);

    // 清空mLayersWithQueuedFrames,下一次vsync来到时,会在handlePageFlip中重新添加
    mLayersWithQueuedFrames.clear();
}

1.2 SurfaceFlinger:perComposition

void SurfaceFlinger::preComposition()
{
    ATRACE_CALL();
    ALOGV("preComposition");
    // 记录刷新时间
    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

    bool needExtraInvalidate = false;
    // 1.2.1 遍历所有layer, 处理处于Drawing状态的layer
    // 这里使用了lambda函数
    mDrawingState.traverseInZOrder([&](Layer* layer) {
        // 1.2.3 判断Layer是否需要更新
        if (layer->onPreComposition(mRefreshStartTime)) {
            // 如果有layer有frame更新,则标记该值为true,表示需要下一个vsync
            // 做合成
            needExtraInvalidate = true;
        }
    });

    if (needExtraInvalidate) {
        signalLayerUpdate();
    }
}

void SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const {
    // 这里的mDrawingState里面的stateSet为StateSet::Drawing
    layersSortedByZ.traverseInZOrder(stateSet, visitor);
}

// SurfaceFlinger.h
State mDrawingState{LayerVector::StateSet::Drawing};

layersSortedByZ中存储的layer都是SurfaceFlinger.addClientLayer过程中添加的。

1.2.1 LayerVector:traverseInZOrder

void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
    for (size_t i = 0; i < size(); i++) {
        const auto& layer = (*this)[i];
        // 遍历所有layer,拿到合适State的Layer做处理
        // 这里是拿所有Drawing状态的Layer
        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
                                                      : layer->getDrawingState();
        // zOrderRelativeOf中的layer是上层调用setRelativeLayer后添加的
        // 如果为非null,则表示此Surface的Z顺序相对于此进行解释
        // 默认是null的。
        if (state.zOrderRelativeOf != nullptr) {
            continue;
        }
        // 处理Layer
        layer->traverseInZOrder(stateSet, visitor);
    }
}

1.2.2 Layer:traverseInZOrder

void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {

    bool skipRelativeZUsers = false;
    // 1.2.2.1 按顺序将当前Layer所有z轴相关的layer和子layer添加至列表
    const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);

    // 也就是说首先遍历Z轴相关的Layer
    size_t i = 0;
    for (; i < list.size(); i++) {
        const auto& relative = list[i];
        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
            continue;
        }

        // 注意Layer的添加都是按照Z轴顺序插入排序的
        // 这里的意思就是首先要遍历并对所有z轴小于0的Layer调用onPreComposition方法
        // 所以需要理解z轴小于0的意义,什么时候z轴值才会小于0?
        // 因为P/Q上Layer组合的数据结构是:树形结构+Z轴排序。现在Z轴的大小一般为 [-2, 2]
        // Z轴小的在下面会被覆盖。现在可以理解了,这里为什么碰到z大于0就要退出循环了
        if (relative->getZ() >= 0) {
            break;
        }
        relative->traverseInZOrder(stateSet, visitor);
    }

    // 对本Layer做onPreComposition
    visitor(this);

    // 最后对所有Z轴不小于0的Layer做onPreComposition
    for (; i < list.size(); i++) {
        const auto& relative = list[i];

        if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
            continue;
        }
        relative->traverseInZOrder(stateSet, visitor);
    }
}

visitor这个就是lambda表达式:

    mDrawingState.traverseInZOrder([&](Layer* layer) {

        // 1.2.3 调用onPreComposition
        if (layer->onPreComposition(mRefreshStartTime)) {
            needExtraInvalidate = true;
        }
    });

总的来说就是按顺序依次调用layer的onPreComposition方法,标记其mRefreshPending为false。

1.2.2.1 Layer:makeTraversalList
// __attribute__((no_sanitize("unsigned-integer-overflow")))的意思
// 是不进行无符号int溢出检测
__attribute__((no_sanitize("unsigned-integer-o
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值