Android下SF合成流程重学习之Refresh流程

Android下SF合成流程重学习之Refresh流程

引言

在前面初步分析完成了Android下SF合成流程重学习之Invalidate流程,我们接下来继续下面的分析。当有事务的更新或者有Buffer的更新便会触发后面刷新的流程,即Refresh流程!


一. onMessageRefresh

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
void SurfaceFlinger::onMessageRefresh() {
    ATRACE_CALL();

    mRefreshPending = false;
    //这里的主要逻辑是搜集需要送显的layer的情况,封装成compositionengine::CompositionRefreshArgs参数传递
    //给CompositionEngine做进一步操作
    compositionengine::CompositionRefreshArgs refreshArgs;
    const auto& displays = ON_MAIN_THREAD(mDisplays);
     // display 的数量,把当前displaydevice 记录下来
    refreshArgs.outputs.reserve(displays.size());
    for (const auto& [_, display] : displays) {
        refreshArgs.outputs.push_back(display->getCompositionDisplay());
    }
    // 把当前layer记录下来
    mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
        if (auto layerFE = layer->getCompositionEngineLayerFE())
            refreshArgs.layers.push_back(layerFE);
    });
    // 把当前有queueframe的layer记录下来, 有Buffer的layer
    refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
    for (sp<Layer> layer : mLayersWithQueuedFrames) {
        if (auto layerFE = layer->getCompositionEngineLayerFE())
            refreshArgs.layersWithQueuedFrames.push_back(layerFE);
    }
 
    ...
    // 主要逻辑在present里面
    mCompositionEngine->present(refreshArgs);
   }

前面主要搜集需要送显的layer的情况,封装成compositionengine::CompositionRefreshArgs参数传递给CompositionEngine做进一步操作。并且最最主要合成及调用Hal composer送显的逻辑都在在present里面了。


二. CompositionEngine::present

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp

void CompositionEngine::present(CompositionRefreshArgs& args) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);
    // 根据是否还有layer没有消费掉,判断再调起一次刷新
    preComposition(args);

    {
        // latchedLayers is used to track the set of front-end layer state that
        // has been latched across all outputs for the prepare step, and is not
        // needed for anything else.
        LayerFESet latchedLayers;

        for (const auto& output : args.outputs) {
            // 计算各个区域大小以及创建hwc layer
            output->prepare(args, latchedLayers);
        }
    }
    // 更新layerCompositionState
    updateLayerStateFromFE(args);

    for (const auto& output : args.outputs) {
        // 逻辑在output.cpp的present里面
        output->present(args);
    }
}

2.1 preComposition

cpp 复制代码
void CompositionEngine::preComposition(CompositionRefreshArgs& args) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);

    bool needsAnotherUpdate = false;

    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
    //调用了layer->onPreComposition做composition前的准备。进去看没做啥实际操作
    for (auto& layer : args.layers) {
        if (layer->onPreComposition(mRefreshStartTime)) {
            needsAnotherUpdate = true;
        }
    }

    mNeedsAnotherUpdate = needsAnotherUpdate;
}

其主要逻辑就是调用了layer->onPreComposition做composition前的准备。进去看没做啥实际操作。

2.2 Output::prepare

prepare主要的作用是收集可见的Layers并计算各个区域大小以及创建hwc layer!

cpp 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
                     LayerFESet& geomSnapshots) {
    
    ...
    rebuildLayerStacks(refreshArgs, geomSnapshots);
}

void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
                                LayerFESet& layerFESet) {
    ...
    // Process the layers to determine visibility and coverage
    compositionengine::Output::CoverageState coverage{layerFESet};
    collectVisibleLayers(refreshArgs, coverage);
    ...
}

void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs,
                                  compositionengine::Output::CoverageState& coverage) {
    ...
    for (auto layer : reversed(refreshArgs.layers)) {
        // Incrementally process the coverage for each layer
        ensureOutputLayerIfVisible(layer, coverage);

        // TODO(b/121291683): Stop early if the output is completely covered and
        // no more layers could even be visible underneath the ones on top.
    }
    ...
}

其主要逻辑在ensureOutputLayerIfVisible里面。

2.3 ensureOutputLayerIfVisible

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
                                        compositionengine::Output::CoverageState& coverage) {

    ....
    // 创建OutputLayer
    auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
    ...
 }

各个layer区域的计算结果可以通过adb shell dumpsys SurfaceFlinger看到,通过区域的计算把区域为空的layer过滤掉.

ensureOutputLayer将创建Output layer,这些layer最后是要显示到屏幕上的

cpp 复制代码
文件: frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h

OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
                                       const sp<LayerFE>& layerFE) {

            // 判断当前的outputlayer 集合里面有没有当前的layer,如果没有则新创建一个
            auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
                    ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
                    : BaseOutput::createOutputLayer(layerFE);
            auto result = outputLayer.get();
            mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
            return result;
        }


文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp

std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
        const sp<compositionengine::LayerFE>& layerFE) const {
    auto result = impl::createOutputLayer(*this, layerFE);

    if (result && mId) {
        auto& hwc = getCompositionEngine().getHwComposer();
        auto displayId = *mId;
        // 创建hwclayer
        auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
                                                     [&hwc, displayId](HWC2::Layer* layer) {
                                                         hwc.destroyLayer(displayId, layer);
                                                     });
        ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
                 getName().c_str());
        // 更新state.hwc
        result->setHwcLayer(std::move(hwcLayer));
    }
    return result;
}

可以看到prepare主要的作用是遍历layer计算各个区域大小,过滤掉空区域的layer以及创建hwc layer。

2.4 updateLayerStateFromFE

它的核心逻辑是跟新更新OutputlayerState的参数,即layer的状态信息

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/Layer.cpp

void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
    using StateSubset = compositionengine::LayerFE::StateSubset;

    switch (subset) {
        case StateSubset::BasicGeometry:
            prepareBasicGeometryCompositionState();
            break;

        case StateSubset::GeometryAndContent:
            prepareBasicGeometryCompositionState();
            prepareGeometryCompositionState();
            preparePerFrameCompositionState();
            break;

        case StateSubset::Content:
            preparePerFrameCompositionState();
            break;

        case StateSubset::Cursor:
            prepareCursorCompositionState();
            break;
    }
}C++
文件:frameworks/native/services/surfaceflinger/Layer.cpp

void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
    using StateSubset = compositionengine::LayerFE::StateSubset;

    switch (subset) {
        case StateSubset::BasicGeometry:
            prepareBasicGeometryCompositionState();
            break;

        case StateSubset::GeometryAndContent:
            prepareBasicGeometryCompositionState();
            prepareGeometryCompositionState();
            preparePerFrameCompositionState();
            break;

        case StateSubset::Content:
            preparePerFrameCompositionState();
            break;

        case StateSubset::Cursor:
            prepareCursorCompositionState();
            break;
    }
}

这部分也可以通过adb shell dumpsys SurfaceFlinger看出来有哪些属性。


三. Output::present

如果说前面的都是洒洒水,开胃菜。那么从这里开始就是大餐了。

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);
     //设置 Display的dataspace, colormode
    updateColorProfile(refreshArgs);
    // 设置outputlayer的dispFrame和sourceCrop等以及将outputlayer属性设给hwc
    updateAndWriteCompositionState(refreshArgs);
    // 设置display的颜色矩阵,对全屏有效
    setColorTransform(refreshArgs);
    // FrameBuffer里面没做啥操作
    beginFrame();
     // 选择合成策略,判断是device还是GPU合成,如果是device合成,直接present,如果要走GPU合成则需要validate
    prepareFrame();
    // 一般不走
    devOptRepaintFlash(refreshArgs);
    // GPU合成主要逻辑在此,device合成没做啥
    finishFrame(refreshArgs);
    // device合成设置release fence,GPU合成需要present给hwc
    postFramebuffer();
}

先关注device合成,涉及GPU部分单独分析(简单带过)!

3.1 updateAndWriteCompositionState

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::updateAndWriteCompositionState(
        const compositionengine::CompositionRefreshArgs& refreshArgs) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);

    if (!getState().isEnabled) {
        return;
    }

    mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
    // 如果是有背景模糊的layer则强制使用GPU合成
    bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;

    for (auto* layer : getOutputLayersOrderedByZ()) {
        // 遍历outputlayer,计算DisplayFrame, SourceCrop 等参数
        layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
                                      refreshArgs.devOptForceClientComposition ||
                                              forceClientComposition,
                                      refreshArgs.internalDisplayRotationFlags);

        if (mLayerRequestingBackgroundBlur == layer) {
            forceClientComposition = false;
        }

        // 将layer属性设给hwc
        layer->writeStateToHWC(refreshArgs.updatingGeometryThisFrame);
    }

这部分参数也可以通过adb shell dumpsys SurfaceFlinger看到:

3.2 setColorTransform

C++ 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp

void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
    Output::setColorTransform(args);

    if (!mId || CC_LIKELY(!args.colorTransformMatrix)) {
        return;
    }

    auto& hwc = getCompositionEngine().getHwComposer();
    // 将上层设的colorTransformMatrix 设给hwc,这个效果作用于全屏,比如护眼模式下,改变的就是这个colorTransformMatrix
    status_t result = hwc.setColorTransform(*mId, *args.colorTransformMatrix);
    ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
             mId ? to_string(*mId).c_str() : "", result);
}

setColorTransform 设置颜色矩阵给屏幕,作用于屏幕显示,所有的layer都受影响,护眼效果就是改变的这个值。

3.3 beginFrame

最终调用到FramebufferSurface,并没有执行具体的逻辑:

cpp 复制代码
//frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
    return NO_ERROR;
}

3.4 prepareFrame

它的核心逻辑是选择合成策略,判断是device还是GPU合成,如果是device合成,直接present,如果要走GPU合成则需要validate。让我们通过代码具体分析:

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::prepareFrame() {

    ...
    const auto& outputState = getState();
    if (!outputState.isEnabled) {
        return;
    }
    // 选择合成类型,如果是device合成,则跳过validate,直接present送显
    chooseCompositionStrategy();
    // 把合成类型送到frameBufferSurface,没啥逻辑
    mRenderSurface->prepareFrame(outputState.usesClientComposition,
                                 outputState.usesDeviceComposition);
}

void Output::chooseCompositionStrategy() {
    // The base output implementation can only do client composition
    // 默认使用GPU合成,针对没有hwc的设备
    auto& outputState = editState();
    outputState.usesClientComposition = true;
    outputState.usesDeviceComposition = false;
    outputState.reusedClientComposition = false;
}

文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp

void Display::chooseCompositionStrategy() {

    ...
    // Default to the base settings -- client composition only.
    Output::chooseCompositionStrategy();

    ...

    // Get any composition changes requested by the HWC device, and apply them.
    std::optional<android::HWComposer::DeviceRequestedChanges> changes;
    auto& hwc = getCompositionEngine().getHwComposer();
    // 从HWC device获得合成类型的改变,这个根据hwc能力来选择device还是GPU合成
    if (status_t result = hwc.getDeviceCompositionChanges(*mId, anyLayersRequireClientComposition(),
                                                          &changes);
        result != NO_ERROR) {
        ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
              strerror(-result));
        return;
    }
    //如果有变化则设置给对应的layer
    if (changes) {
        applyChangedTypesToLayers(changes->changedTypes);
        applyDisplayRequests(changes->displayRequests);
        applyLayerRequestsToLayers(changes->layerRequests);
        applyClientTargetRequests(changes->clientTargetProperty);
    }

    // Determine what type of composition we are doing from the final state
    // 决定最后的合成类型
    auto& state = editState();
    state.usesClientComposition = anyLayersRequireClientComposition();
    state.usesDeviceComposition = !allLayersRequireClientComposition();
}

文件:frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

status_t HWComposer::getDeviceCompositionChanges(
        DisplayId displayId, bool frameUsesClientComposition,
        std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {


    ...
    if (!frameUsesClientComposition) {
        sp<Fence> outPresentFence;
        uint32_t state = UINT32_MAX;
         // 如果所有的layer都能走device合成,则在hwc里面直接present,若有不支持device合成的情况,则走GPU合成,会走validate逻辑
        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
        if (!hasChangesError(error)) {
            RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
        }
        if (state == 1) { //Present Succeeded.
            // present成功,数据直接提交给了hwc
            std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
            error = hwcDisplay->getReleaseFences(&releaseFences);
            displayData.releaseFences = std::move(releaseFences);
            displayData.lastPresentFence = outPresentFence;
            displayData.validateWasSkipped = true;
            displayData.presentError = error;
            return NO_ERROR;
        }
 // Present failed but Validate ran.
    } else {
        // 这个分支走不到
        error = hwcDisplay->validate(&numTypes, &numRequests);
    }
   // 接收hwc过来的change,对于device合成不走,GPU合成走的逻辑,这个后续GPU合成专门分析
   ...

prepareFrame 的作用是根据hwc的能力选择合成方式,如果是device合成则直接走hwc present上屏,如果是GPU合成后面则走hwc validate,然后根据hwc过来的变化改变layer的合成方式。用另外一种方式表达就是首先将合成策略给HWC看是否接受,然后如果有变化就将变化应用于layer

3. 5 Output::finishFrame

cpp 复制代码
文件: frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);

    if (!getState().isEnabled) {
        return;
    }

    // Repaint the framebuffer (if needed), getting the optional fence for when
    // the composition completes.
    // 主要针对GPU合成的逻辑
    auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
    // device合成直接return
    if (!optReadyFence) {
        return;
    }

    // swap buffers (presentation)
    mRenderSurface->queueBuffer(std::move(*optReadyFence));
}

composeSurface的主要核心逻辑是针对GPU合成,对于device合成,则直接return了。

3.6 Output::postFramebuffer

这块的核心逻辑主要是对于device合成设置release fence,GPU合成需要present给hwc。我们通过代码来看下:

cpp 复制代码
文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp

void Output::postFramebuffer() {
   ...
    // device合成获取release fence
    auto frame = presentAndGetFrameFences();
   
    mRenderSurface->onPresentDisplayCompleted();

    for (auto* layer : getOutputLayersOrderedByZ()) {
        sp<Fence> releaseFence = Fence::NO_FENCE;

        if (auto hwcLayer = layer->getHwcLayer()) {
            if (auto f = frame.layerFences.find(hwcLayer); f != frame.layerFences.end()) {
                releaseFence = f->second;
            }
        }
        if (outputState.usesClientComposition) {
            releaseFence =
                    Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
        }
       // 将releasefence放到mslot里面,这个是dequeueBuffer等的fence
        layer->getLayerFE().onLayerDisplayed(releaseFence);
    }
...
}

文件:frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
    ATRACE_CALL();
    
    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
    
    auto& displayData = mDisplayData[displayId];
    auto& hwcDisplay = displayData.hwcDisplay;
     // device合成直接return
    if (displayData.validateWasSkipped) {
        // explicitly flush all pending commands
        auto error = static_cast<hal::Error>(mComposer->executeCommands()); 
        RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
        RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
        return NO_ERROR;
    }
    //GPU 合成走present
    auto error = hwcDisplay->present(&displayData.lastPresentFence);
    RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);

    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
    error = hwcDisplay->getReleaseFences(&releaseFences);
    RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);

    displayData.releaseFences = std::move(releaseFences);

    return NO_ERROR;
}

3.6 postComposition

cpp 复制代码
文件: frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::postComposition()
{
    ATRACE_CALL();
    ALOGV("postComposition");

    nsecs_t dequeueReadyTime = systemTime();
     // release Bufferqueuelayer
    for (auto& layer : mLayersWithQueuedFrames) {
        layer->releasePendingBuffer(dequeueReadyTime);
    }
    ...
     // mPreviousPresentFences[0]是这一帧的present fence,mPreviousPresentFences[1]是上一帧的present fence
    mPreviousPresentFences[1] = mPreviousPresentFences[0];
    mPreviousPresentFences[0] =
            display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
    ...
     // 这个有关vsync,是校验presentfence释放的时间戳
     if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON &&
        presentFenceTime->isValid()) {
        mScheduler->addPresentFence(presentFenceTime);
    }
   ....
}

postComposition的作用就是释放上一帧显示的Buffer,然后重新设置当前帧的present fence,以及根据presentfence时间戳判断是否重新打开HW Vsync和软件Vsync进行校准。至此,SurfaceFlinger刷新的主体函数分析完了,可以看出来,如果是走device合成,SurfaceFlinger是直接把layer信息提交给hwc,由hwc去合成.


写在最后

好了今天的博客Android下SF合成流程重学习之Refresh流程就到这里了。总之,青山不改绿水长流先到这里了。如果本博客对你有所帮助,麻烦关注或者点个赞,如果觉得很烂也可以踩一脚!谢谢各位了!!

相关推荐
_小马快跑_6 分钟前
ConstraintLayout之layout_constraintDimensionRatio属性详解
android
百锦再1 小时前
Android Studio开发 SharedPreferences 详解
android·ide·android studio
青春给了狗1 小时前
Android 14 修改侧滑手势动画效果
android
CYRUS STUDIO2 小时前
Android APP 热修复原理
android·app·frida·hotfix·热修复
火柴就是我2 小时前
首次使用Android Studio时,http proxy,gradle问题解决
android
limingade3 小时前
手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段
android·智能手机·电脑·蓝牙电话·电脑打电话
浩浩测试一下3 小时前
计算机网络中的DHCP是什么呀? 详情解答
android·网络·计算机网络·安全·web安全·网络安全·安全架构
青春给了狗5 小时前
Android 14 系统统一修改app启动时图标大小和圆角
android
pengyu5 小时前
【Flutter 状态管理 - 柒】 | InheritedWidget:藏在组件树里的"魔法"✨
android·flutter·dart
居然是阿宋7 小时前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin