Android13 SurfaceFlinger composite(合成)流程分析

SurfaceFlinger的composite方法,用于将多个窗口的图像进行合成,主要负责对相关要进行上帧的layer进行,识别排序好,然后合成,有hwc合成的会构建对应OutputLayer传递hwc,GPU合成则直接合成,再传递到hwc中,它主要完成以下几个步骤:

  1. 从队列中获取所有待合成的缓冲区。

  2. 将这些缓冲区按照一定的顺序进行合成,生成最终的图像。

  3. 将合成后的图像提交给HWC进行显示。

SurfaceFlinger的composite方法代码如下:

//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
        FTL_FAKE_GUARD(kMainThreadContext) {
    ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId);


    if (mPowerHintSessionData.sessionEnabled) {
        mPowerHintSessionData.compositeStart = systemTime();
    }


    compositionengine::CompositionRefreshArgs refreshArgs;
    const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
    refreshArgs.outputs.reserve(displays.size());
    for (const auto& [_, display] : displays) {
        refreshArgs.outputs.push_back(display->getCompositionDisplay());
    }
    mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
        if (auto layerFE = layer->getCompositionEngineLayerFE())
            refreshArgs.layers.push_back(layerFE);
    });
    refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
    for (auto layer : mLayersWithQueuedFrames) {
        if (auto layerFE = layer->getCompositionEngineLayerFE())
            refreshArgs.layersWithQueuedFrames.push_back(layerFE);
    }


    refreshArgs.outputColorSetting = useColorManagement
            ? mDisplayColorSetting
            : compositionengine::OutputColorSetting::kUnmanaged;
    refreshArgs.colorSpaceAgnosticDataspace = mColorSpaceAgnosticDataspace;
    refreshArgs.forceOutputColorMode = mForceColorMode;


    refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
    refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) || mVisibleRegionsDirty;
    refreshArgs.blursAreExpensive = mBlursAreExpensive;
    refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();


    if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
        refreshArgs.colorTransformMatrix = mDrawingState.colorMatrix;
        mDrawingState.colorMatrixChanged = false;
    }


    refreshArgs.devOptForceClientComposition = mDebugDisableHWC;


    if (mDebugFlashDelay != 0) {
        refreshArgs.devOptForceClientComposition = true;
        refreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::milliseconds(mDebugFlashDelay);
    }


    const auto expectedPresentTime = mExpectedPresentTime.load();
    const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(expectedPresentTime);
    const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
    refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
    refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime;
    refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
    refreshArgs.expectedPresentTime = expectedPresentTime;


    // Store the present time just before calling to the composition engine so we could notify
    // the scheduler.
    const auto presentTime = systemTime();


    mCompositionEngine->present(refreshArgs);


    if (mPowerHintSessionData.sessionEnabled) {
        mPowerHintSessionData.presentEnd = systemTime();
    }


    mTimeStats->recordFrameDuration(frameTime, systemTime());


    if (mScheduler->onPostComposition(presentTime)) {
        scheduleComposite(FrameHint::kNone);
    }


    postFrame();
    postComposition();


    const bool prevFrameHadClientComposition = mHadClientComposition;


    mHadClientComposition = mHadDeviceComposition = mReusedClientComposition = false;
    TimeStats::ClientCompositionRecord clientCompositionRecord;
    for (const auto& [_, display] : displays) {
        const auto& state = display->getCompositionDisplay()->getState();
        mHadClientComposition |= state.usesClientComposition && !state.reusedClientComposition;
        mHadDeviceComposition |= state.usesDeviceComposition;
        mReusedClientComposition |= state.reusedClientComposition;
        clientCompositionRecord.predicted |=
                (state.strategyPrediction != CompositionStrategyPredictionState::DISABLED);
        clientCompositionRecord.predictionSucceeded |=
                (state.strategyPrediction == CompositionStrategyPredictionState::SUCCESS);
    }


    clientCompositionRecord.hadClientComposition = mHadClientComposition;
    clientCompositionRecord.reused = mReusedClientComposition;
    clientCompositionRecord.changed = prevFrameHadClientComposition != mHadClientComposition;
    mTimeStats->pushCompositionStrategyState(clientCompositionRecord);


    // TODO: b/160583065 Enable skip validation when SF caches all client composition layers
    const bool usedGpuComposition = mHadClientComposition || mReusedClientComposition;
    modulateVsync(&VsyncModulator::onDisplayRefresh, usedGpuComposition);


    mLayersWithQueuedFrames.clear();
    if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
        // This will block and should only be used for debugging.
        mLayerTracing.notify(mVisibleRegionsDirty, frameTime);
    }


    mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
    mVisibleRegionsDirty = false;


    if (mCompositionEngine->needsAnotherUpdate()) {
        scheduleCommit(FrameHint::kNone);
    }


    // calculate total render time for performance hinting if adpf cpu hint is enabled,
    if (mPowerHintSessionData.sessionEnabled) {
        const nsecs_t flingerDuration =
                (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart);
        mPowerAdvisor->sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd);
    }
}

调用CompositionEngine的present,开始真正的Layer合成:

//frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
void CompositionEngine::present(CompositionRefreshArgs& args) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);


    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) {
            output->prepare(args, latchedLayers);
        }
    }


    updateLayerStateFromFE(args);


    for (const auto& output : args.outputs) {
        output->present(args);
    }
}

上面方面主要处理如下:

1、调用CompositionEngine的preComposition方法,进行layer预合成。

2、调用Output的prepare方法,进行预合成。

3、调用Output的present方法,进行Layer合成。

下面分别进行分析:

CompositionEngine preComposition

调用CompositionEngine的preComposition方法,进行合成前预处理:

//frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
void CompositionEngine::preComposition(CompositionRefreshArgs& args) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);


    bool needsAnotherUpdate = false;


    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);


    //遍历所有layer,进行layer预合成
    for (auto& layer : args.layers) {
        if (layer->onPreComposition(mRefreshStartTime)) {
            needsAnotherUpdate = true;
        }
    }


    mNeedsAnotherUpdate = needsAnotherUpdate;
}

BufferLayer onPreComposition

调用Layer的onPreComposition方法,BufferLayer继承于Layer:

//frameworks/native/services/surfaceflinger/BufferLayer.cpp
bool BufferLayer::onPreComposition(nsecs_t) {
    return hasReadyFrame();
}

调用BufferLayer的hasReadyFrame方法:

//frameworks/native/services/surfaceflinger/BufferLayer.cpp
bool BufferLayer::hasReadyFrame() const {
    return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh();
}

Output prepare

调用Output的prepare方法,进行预合成:

/frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
                     LayerFESet& geomSnapshots) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);


    rebuildLayerStacks(refreshArgs, geomSnapshots); //Output实际上就是display, 通过调用每个Display的rebuildLayerStacks ,建立display 的 LayerStacks.
}

Output rebuildLayerStacks

调用Output的rebuildLayerStacks方法:

//frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
                                LayerFESet& layerFESet) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);


    auto& outputState = editState();


    // Do nothing if this output is not enabled or there is no need to perform this update
    if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
        return;
    }


    // Process the layers to determine visibility and coverage
    compositionengine::Output::CoverageState coverage{layerFESet};
    collectVisibleLayers(refreshArgs, coverage);


    // Compute the resulting coverage for this output, and store it for later
    const ui::Transform& tr = outputState.transform;
    Region undefinedRegion{outputState.displaySpace.getBoundsAsRect()};
    undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));


    outputState.undefinedRegion = undefinedRegion;
    outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
}

Output present

调用Output的present方法,进行Layer合成。

//frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);


    updateColorProfile(refreshArgs); //更新颜色配置文件
    updateCompositionState(refreshArgs); //更新合成状态
    planComposition(); //计划合成
    writeCompositionState(refreshArgs); //写入合成状态
    setColorTransform(refreshArgs); //设置颜色矩阵
    beginFrame(); //开始帧


    GpuCompositionResult result;
    const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
    if (predictCompositionStrategy) {
        result = prepareFrameAsync(refreshArgs); //准备帧数据以进行显示(Async方式)
    } else {
        prepareFrame(); //准备帧数据以进行显示
    }


    devOptRepaintFlash(refreshArgs); //处理显示输出设备的可选重绘闪烁
    finishFrame(refreshArgs, std::move(result)); //完成帧
    postFramebuffer(); //将帧缓冲区(framebuffer)的内容发送到显示设备进行显示
    renderCachedSets(refreshArgs); //进行渲染缓存设置
}

上面方法主要处理如下:

1、调用Output的updateColorProfile方法,更新颜色配置。

2、调用Output的updateCompositionState方法,更新合成状态。

3、调用Output的planComposition方法,计划合成。

4、调用Output的writeCompositionState方法,写入合成状态。

5、调用Output的setColorTransform方法,设置颜色矩阵。

6、调用Output的beginFrame方法,开始帧。

7、调用Output的prepareFrameAsync方法,准备帧数据以进行显示(Async方式)。

8、调用Output的prepareFrame方法,准备帧数据以进行显示。

9、调用Output的devOptRepaintFlash方法,处理显示输出设备的可选重绘闪烁。

10、调用Output的finishFrame方法,完成帧。

11、调用Output的postFramebuffer方法,将帧缓冲区(framebuffer)的内容发送到显示设备进行显示。

12、调用Output的renderCachedSets方法,进行渲染缓存设置。

下面分别进行分析:

Output updateColorProfile

调用Output的updateColorProfile方法,更新颜色配置:

//frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
void Output::updateColorProfile(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    setColorProfile(pickColorProfile(refreshArgs));
}

调用Output的setColorProfile方法:

//frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
void Output::setColorProfile(const ColorProfile& colorProfile) {
    ui::Dataspace targetDataspace =
            getDisplayColorProfile()->getTargetDataspace(colorProfile.mode, colorProfile.dataspace,
                                                         colorProfile.colorSpaceAgnosticDataspace);


    auto& outputState = editState();
    if (outputState.colorMode == colorProfile.mode &&
        outputState.dataspace == colorProfile.dataspace &&
        outputState.renderIntent == colorProfile.renderIntent &&
        outputState.targetDataspace == targetDataspace) {
        return;
    }


    outputState.colorMode = colorProfile.mode;
    outputState.dataspace = colorProfile.dataspace;
    outputState.renderIntent = colorProfile.renderIntent;
    outputState.targetDataspace = targetDataspace;


    mRenderSurface->setBufferDataspace(colorProfile.dataspace); //设置缓存数据空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值