SurfaceFlinger的composite方法,用于将多个窗口的图像进行合成,主要负责对相关要进行上帧的layer进行,识别排序好,然后合成,有hwc合成的会构建对应OutputLayer传递hwc,GPU合成则直接合成,再传递到hwc中,它主要完成以下几个步骤:
-
从队列中获取所有待合成的缓冲区。
-
将这些缓冲区按照一定的顺序进行合成,生成最终的图像。
-
将合成后的图像提交给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); //设置缓存数据空间

1万+

被折叠的 条评论
为什么被折叠?



