以下是Android 14中SurfaceFlinger::composite
函数的逐行解析,详细说明其逻辑和关键代码的作用:
void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId)
FTL_FAKE_GUARD(kMainThreadContext) {
ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId.value);
FTL_FAKE_GUARD
:标记当前代码段在kMainThreadContext
线程上下文中运行(调试用)。ATRACE_FORMAT
:记录函数名和vsyncId
到性能跟踪系统(如Perfetto)。compositionengine::CompositionRefreshArgs refreshArgs;
const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
refreshArgs.outputs.reserve(displays.size());
std::vector<DisplayId> displayIds;
refreshArgs
。mDisplays
:获取当前所有显示设备(受mStateLock
保护)。outputs.reserve
:预分配内存,避免动态扩容。displayIds
:记录所有显示设备的ID。for (const auto& [_, display] : displays) {
bool dropFrame = false;
if (display->isVirtual()) {
Fps refreshRate = display->getAdjustedRefreshRate();
using fps_approx_ops::operator>;
dropFrame = (refreshRate > 0_Hz) && !mScheduler->isVsyncInPhase(frameTime, refreshRate);
}
if (!dropFrame) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
display->tracePowerMode();
displayIds.push_back(display->getId());
}
mPowerAdvisor->setDisplays(displayIds);
tracePowerMode
:记录显示设备的电源状态(用于调试或电源管理)。mPowerAdvisor->setDisplays
:通知电源管理模块当前活动的显示设备。const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test(
compositionengine::Feature::kSnapshotLayerMetadata);
if (updateTaskMetadata && (mVisibleRegionsDirty || mLayerMetadataSnapshotNeeded)) {
updateLayerMetadataSnapshot();
mLayerMetadataSnapshotNeeded = false;
}
kSnapshotLayerMetadata
:合成引擎的特性标志,表示需要元数据快照。mVisibleRegionsDirty
:可见区域是否变化(脏标记)。if (DOES_CONTAIN_BORDER) {
refreshArgs.borderInfoList.clear();
mDrawingState.traverse([&refreshArgs](Layer* layer) {
if (layer->isBorderEnabled()) {
compositionengine::BorderRenderInfo info;
info.width = layer->getBorderWidth();
info.color = layer->getBorderColor();
layer->traverse(LayerVector::StateSet::Drawing, [&info](Layer* ilayer) {
info.layerIds.push_back(ilayer->getSequence());
});
refreshArgs.borderInfoList.emplace_back(std::move(info));
}
});
}
refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache);
refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
for (auto layer : mLayersWithQueuedFrames) {
if (auto layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layersWithQueuedFrames.push_back(layerFE);
}
mLayersWithQueuedFrames
:当前有未处理帧的图层列表。refreshArgs.outputColorSetting = useColorManagement
? mDisplayColorSetting
: compositionengine::OutputColorSetting::kUnmanaged;
refreshArgs.colorSpaceAgnosticDataspace = mColorSpaceAgnosticDataspace;
refreshArgs.forceOutputColorMode = mForceColorMode;
useColorManagement
:是否启用颜色管理(如HDR)。refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) || mVisibleRegionsDirty;
refreshArgs.internalDisplayRotationFlags = getActiveDisplayRotationFlags();
mVisibleRegionsDirty
:可见区域是否变化。mGeometryDirty
:几何信息是否变化(原子变量,交换后重置)。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);
}
mDebugDisableHWC
:禁用硬件合成(HWC),强制使用GPU。mDebugFlashDelay
:脏区域闪烁延迟(用于可视化调试)。const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
if (!getHwComposer().getComposer()->isSupported(
Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
wouldPresentEarly(frameTime, vsyncPeriod)) {
const auto prevVsyncTime = mExpectedPresentTime - vsyncPeriod;
const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
}
hwcMinWorkDuration
:硬件合成器(HWC)需要的最小工作时间。refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
refreshArgs.expectedPresentTime = mExpectedPresentTime.ns();
refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;
const auto presentTime = systemTime();
std::vector<std::pair<Layer*, LayerFE*>> layers =
moveSnapshotsToCompositionArgs(refreshArgs, /*cursorOnly=*/false, vsyncId.value);
mCompositionEngine->present(refreshArgs);
moveSnapshotsFromCompositionArgs(refreshArgs, layers);
moveSnapshotsToCompositionArgs
:传递图层快照到合成参数。present
:触发合成引擎的present
方法。for (auto [layer, layerFE] : layers) {
CompositionResult compositionResult{layerFE->stealCompositionResult()};
layer->onPreComposition(compositionResult.refreshStartTime);
for (auto& [releaseFence, layerStack] : compositionResult.releaseFences) {
Layer* clonedFrom = layer->getClonedFrom().get();
auto owningLayer = clonedFrom ? clonedFrom : layer;
owningLayer->onLayerDisplayed(std::move(releaseFence), layerStack);
}
if (compositionResult.lastClientCompositionFence) {
layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
}
}
releaseFences
:通知图层可以释放缓冲区。setWasClientComposed
:标记图层是否由GPU合成。mTimeStats->recordFrameDuration(frameTime.ns(), systemTime());
if (mPowerHintSessionEnabled) {
const auto& previousPresentFence = mPreviousPresentFences[0].fenceTime;
mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(previousPresentFence->getSignalTime()),
TimePoint::now());
mPowerAdvisor->reportActualWorkDuration();
}
if (mScheduler->onPostComposition(presentTime)) {
scheduleComposite(FrameHint::kNone);
}
postComposition(presentTime);
const bool hadGpuComposited = mCompositionCoverage.test(CompositionCoverage::Gpu);
mCompositionCoverage.clear();
postComposition
:处理合成后的清理(如释放旧的帧缓冲区)。mCompositionCoverage
:记录合成方式(GPU/HWC)。TimeStats::ClientCompositionRecord clientCompositionRecord;
for (const auto& [_, display] : displays) {
const auto& state = display->getCompositionDisplay()->getState();
// ...统计GPU/HWC使用情况
}
mTimeStats->pushCompositionStrategyState(clientCompositionRecord);
mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
mLayersWithQueuedFrames.clear();
if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
addToLayerTracing(mVisibleRegionsDirty, frameTime.ns(), vsyncId.value);
}
mVisibleRegionsDirty = false;
if (mCompositionEngine->needsAnotherUpdate()) {
scheduleCommit(FrameHint::kNone);
}
if (mPowerHintSessionEnabled) {
mPowerAdvisor->setCompositeEnd(TimePoint::now());
}
SurfaceFlinger::composite
是Android图形合成的核心函数,负责:
CompositionEngine
进行实际合成。Output::prepare是Android合成引擎中处理每一帧准备阶段的核心函数,其主要作用是为后续的图层合成准备必要的状态和数据。具体流程如下:
updatingOutputGeometryThisFrame=false
),则跳过。ensureOutputLayerIfVisible
,确保可见的图层创建对应的OutputLayer
。coveredRegion
)和脏区(dirtyRegion
)。setReleasedLayers
):标记不再使用的图层。finalizePendingOutputLayers
)。undefinedRegion
。dirtyRegion
中。getOutputLayersOrderedByZ
)。OutputLayer
调用uncacheBuffers
,传入需要释放的缓冲区ID列表(bufferIdsToUncache
)。dirtyRegion
,仅合成发生变化的区域,提升性能。uncacheBuffers
释放无效缓冲区,避免内存占用过高。void Output::prepare(...) {
rebuildLayerStacks(...); // 重建图层堆栈,更新覆盖区域和脏区
uncacheBuffers(...); // 释放不再使用的缓冲区
}
Output::prepare
的作用是为帧合成做准备,核心任务包括:
从代码注释来看,rebuildLayerStacks
的注释提到“Process the layers to determine visibility and coverage”,即处理图层以确定可见性和覆盖范围。因此,初步推测这个函数的主要功能是确定哪些图层在当前输出中是可见的,并计算它们的覆盖区域,从而为后续的合成步骤提供必要的信息。
接下来,我需要逐行分析代码逻辑:
检查输出是否启用(outputState.isEnabled
)。
检查是否需要更新输出几何结构(refreshArgs.updatingOutputGeometryThisFrame
)。
如果任一条件不满足,直接返回,跳过后续处理。这表明只有在需要更新几何结构时才会执行重建图层堆栈的操作。
创建一个CoverageState
对象,用于跟踪图层的可见性、覆盖区域等信息。
根据refreshArgs.hasTrustedPresentationListener
决定是否排除覆盖层(如状态栏)的影响。
调用collectVisibleLayers
函数,逆序遍历图层(从Z轴最高的图层开始),处理每个图层的可见性。
对于每个图层,调用ensureOutputLayerIfVisible
函数,确保可见的图层创建对应的OutputLayer
,并更新覆盖区域和脏区。
初始未定义区域为整个显示区域。
通过减去被不透明图层覆盖的区域(coverage.aboveOpaqueLayers
),得到最终的未定义区域。
在分析过程中,需要确认以下关键点:
逆序遍历图层的原因:逆序遍历(从最上层到底层)可以确保上层图层的覆盖区域正确计算,避免下层图层被错误地认为可见。
覆盖区域和脏区的计算:通过累加各图层的可见区域和覆盖区域,确定哪些区域需要重新合成。
未定义区域的作用:未定义区域表示未被任何不透明图层覆盖的部分,可能需要填充默认颜色或进行透明合成。
此外,需要注意代码中的一些细节:
coverage.aboveCoveredLayers
和coverage.aboveOpaqueLayers
分别记录累积的覆盖区域和不透明区域。
dirtyRegion
用于标记需要重新绘制的区域,优化合成性能。
在理解过程中,可能会遇到一些疑问,例如:
collectVisibleLayers
的具体实现:需要查看collectVisibleLayers
函数,了解如何处理每个图层的可见性和覆盖区域。
ensureOutputLayerIfVisible
的作用:该函数可能负责创建或更新OutputLayer
,确保图层在输出中的正确表示。
finalizePendingOutputLayers
的功能:可能用于确认所有待处理的输出层已准备就绪。
通过逐步分析代码逻辑和验证每个步骤的作用,可以全面理解rebuildLayerStacks
的功能及其在合成流程中的重要性。
Output::rebuildLayerStacks
是 Android 合成引擎中负责 重建图层堆栈并计算可见性与覆盖区域 的核心函数。其作用是为当前输出(如屏幕)确定哪些图层可见、如何被覆盖,并更新相关合成状态(如脏区、未定义区域)。以下是其代码逻辑的详细解析:
outputState.isEnabled
)。refreshArgs.updatingOutputGeometryThisFrame
)。CoverageState
对象,包含以下关键字段:
aboveCoveredLayers
:累积的覆盖区域(包括透明和半透明图层)。aboveOpaqueLayers
:累积的不透明区域(完全遮挡下层)。dirtyRegion
:需重新合成的脏区。latchedLayers
:已处理的图层快照(避免重复处理同一图层)。aboveCoveredLayersExcludingOverlays
(可选):排除覆盖层(如状态栏)的覆盖区域。ensureOutputLayerIfVisible
:对每个图层执行以下操作:
includesLayer
判断图层是否属于当前输出(如多屏场景)。layerFEState->isVisible
为假),跳过。geomLayerTransform
)和边界(geomLayerBounds
),计算其在屏幕上的可见区域(visibleRegion
)。shadowRadius > 0
),扩展可见区域并计算阴影区域(shadowRegion
)。isOpaque = false
),根据 transparentRegionHint
裁剪透明区域。coveredRegion
:当前图层被上层覆盖的区域。aboveCoveredLayers
累积所有图层的覆盖区域。aboveOpaqueLayers
累积所有不透明图层的覆盖区域。contentDirty
),标记整个可见区域为脏区。newExposed - oldExposed
)。OutputLayer
:
OutputLayer
,并保存其可见性、覆盖区域等信息。undefinedRegion
初始为整个显示区域(outputState.displaySpace.getBoundsAsRect()
)。undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
undefinedRegion
表示未被任何不透明图层覆盖的区域,可能需要填充默认背景或进行透明合成。coverage.dirtyRegion
)合并到全局脏区(outputState.dirtyRegion
)。outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
outputState.undefinedRegion = undefinedRegion;
dirtyRegion
标记需要重新合成的区域,优化性能。OutputLayer
,减少内存分配开销。orSelf
操作高效合并区域,减少全屏重绘。通过 rebuildLayerStacks
,Android 合成引擎能够高效管理图层的可见性、覆盖关系和资源状态,为后续的合成操作(如 GPU/硬件合成)奠定基础。
接下来,我需要仔细阅读collectVisibleLayers
的代码。函数参数是refreshArgs
和coverage
,其中coverage
是一个CoverageState
对象。函数内部有一个逆序循环遍历refreshArgs.layers
,也就是从最上层的图层开始处理。对于每个图层,调用了ensureOutputLayerIfVisible
,然后调用setReleasedLayers
和finalizePendingOutputLayers
。
首先,ensureOutputLayerIfVisible
这个函数名看起来是确保如果图层可见的话,就创建一个对应的OutputLayer
。这里可能涉及到判断图层的可见性,比如检查图层是否属于当前输出、是否被隐藏、是否有透明区域等。然后,setReleasedLayers
可能用于标记不再需要的图层,以便后续释放资源。finalizePendingOutputLayers
可能是确认所有的OutputLayer
已经处理完毕。
在ensureOutputLayerIfVisible
内部,首先检查图层是否已经被快照处理过,如果没有,则加入latchedLayers
集合。接着判断图层是否属于当前输出,如果不是则返回。然后获取图层的前端状态layerFEState
,如果图层不可见则返回。接下来计算opaqueRegion
、visibleRegion
、coveredRegion
等区域,并更新覆盖状态。
在计算可见区域时,考虑了图层的变换、阴影、透明度等因素。例如,如果有阴影的话,需要扩展可见区域。然后处理透明区域,如果图层不是不透明的,需要根据transparentRegionHint
进行调整。接着计算被上层覆盖的区域,并更新累积的覆盖区域aboveCoveredLayers
和aboveOpaqueLayers
。
脏区的计算也很重要,如果图层内容有变化(contentDirty
),则整个可见区域都是脏区;否则根据新旧覆盖区域的差异计算需要重新绘制的区域。最后,如果图层可见,就创建或复用OutputLayer
,并保存相关区域信息。
不过,我在理解具体的区域计算和覆盖关系时还是有些困惑,比如coveredRegion
和aboveCoveredLayers
是如何具体更新的,以及如何判断一个区域是否被覆盖。可能需要进一步查看相关的Region操作函数,比如intersect
、subtractSelf
等,来理解这些区域是如何组合的。
另外,setReleasedLayers
在collectVisibleLayers
中被调用,但具体的实现在哪里呢?在代码中,setReleasedLayers
的基类实现是空的,可能子类会有具体实现,但当前代码中可能只是标记需要释放的图层。
总结来说,collectVisibleLayers
的主要作用是遍历所有图层,计算它们的可见区域、覆盖关系,并更新脏区,以便后续的合成操作。同时,管理OutputLayer
的创建和释放,确保只有可见的图层被处理。
Output::collectVisibleLayers
是 Android 合成引擎中用于 逐层筛选可见图层并计算覆盖关系 的核心函数。其作用是通过逆序遍历所有图层(从最上层开始),确定每个图层的可见性、覆盖区域和脏区,并生成或复用对应的 OutputLayer
。以下是其代码逻辑的详细解析:
refreshArgs
:包含当前帧的合成参数(如图层列表、是否需要更新几何结构等)。coverage
:CoverageState
对象,用于累积图层的覆盖状态(如脏区、不透明区域等)。for (auto layer : reversed(refreshArgs.layers)) {
ensureOutputLayerIfVisible(layer, coverage);
}
latchedLayers
集合中不存在),则将其加入集合,避免重复处理。includesLayer(layerFE)
判断图层是否属于当前输出(如多屏场景)。layerFEState->isVisible
为 false
),跳过后续处理。geomLayerTransform
)和边界(geomLayerBounds
),计算其在屏幕上的 visibleRect
。shadowRadius > 0
),扩展可见区域并计算 shadowRegion
。isOpaque = false
),根据 transparentRegionHint
裁剪透明区域。coveredRegion
:当前图层被上层覆盖的区域(通过 coverage.aboveCoveredLayers.intersect(visibleRegion)
计算)。coverage.aboveCoveredLayers
累积所有图层的覆盖区域(包括透明和半透明)。coverage.aboveOpaqueLayers
累积所有不透明图层的覆盖区域。contentDirty
),标记整个可见区域为脏区。newExposed - oldExposed
)。OutputLayer
,保存其可见区域、覆盖区域等信息。setReleasedLayers(refreshArgs);
mReleasedLayers
,后续释放资源。finalizePendingOutputLayers();
OutputLayer
已处理完毕,更新输出状态。dirtyRegion
标记需要重新合成的区域,优化性能。OutputLayer
,减少内存分配开销。// 逆序遍历图层
for (auto layer : reversed(refreshArgs.layers)) {
ensureOutputLayerIfVisible(layer, coverage);
}
// 计算脏区示例
if (layerFEState->contentDirty) {
dirty = visibleRegion; // 整个可见区域为脏区
} else {
// 计算新旧暴露区域的差异
dirty = (visibleRegion & oldCoveredRegion) | (newExposed - oldExposed);
}
coverage.dirtyRegion.orSelf(dirty); // 合并到全局脏区
Region
类的高效集合操作(intersect
、subtractSelf
等),减少计算复杂度。通过 collectVisibleLayers
,Android 合成引擎能够高效管理图层的可见性和覆盖关系,为后续的 GPU/硬件合成提供精确的输入数据。
Output::present()
是 Android SurfaceFlinger 中负责 将图层合成为最终帧并提交到显示设备 的核心函数。其执行流程可分解为以下关键步骤:
Output::present()
通过 状态更新 → 策略规划 → 异步/同步执行 → 提交显示 的流程,平衡性能与正确性。其核心优化点包括:
该函数直接影响了 Android 系统的显示性能、功耗及视觉效果,是图形栈的关键路径。
Planner::plan()
是 Android SurfaceFlinger 中 图层合成策略规划 的核心函数,其作用是通过 追踪图层状态变化、优化合成策略 来减少 GPU 负载并提升合成效率。以下是其代码逻辑的详细解析:
std::unordered_set<LayerId> removedLayers;
std::transform(mPreviousLayers.begin(), ..., [](const auto& layer) { return layer.first; });
removedLayers
,假设所有上一帧的图层都可能被移除。std::transform
将上一帧的图层 ID(mPreviousLayers
)存入 removedLayers
,后续再根据当前帧的图层状态剔除仍存在的图层,最终剩余的即为真正被移除的图层。for (auto layer : layers) {
LayerId id = layer->getLayerFE().getSequence();
// 处理已有图层或新增图层
}
LayerState& state = layerEntry->second;
ftl::Flags<LayerStateField> differences = state.update(layer);
differences
:标记变化的字段(如 Buffer
、Geometry
、Alpha
等)。framesSinceBufferUpdate
,用于判断图层是否可缓存。LayerState state(layer);
mPreviousLayers.emplace(id, std::move(state));
LayerState
并存入 mPreviousLayers
。currentLayerIds.emplace_back(id);
removedLayers.erase(id); // 剔除未移除的图层
removedLayers
以反映实际被移除的图层。mCurrentLayers.clear();
std::transform(currentLayerIds.cbegin(), ..., [this](LayerId id) { return &mPreviousLayers.at(id); });
mCurrentLayers
,并重置 overrideInfo
(可能用于调试或覆盖合成参数)。const NonBufferHash hash = getNonBufferHash(mCurrentLayers);
mFlattenedHash = mFlattener.flattenLayers(...);
const bool layersWereFlattened = (hash != mFlattenedHash);
NonBufferHash
:基于图层的 非缓冲属性(位置、透明度、变换矩阵等)生成的哈希值,用于判断图层状态是否变化。flattenLayers
:合并多个静态或低变化图层为一个(如 UI 背景),减少绘制调用次数。layersWereFlattened
:标记是否发生了扁平化操作,影响后续预测策略。if (mPredictorEnabled) {
mPredictedPlan = mPredictor.getPredictedPlan(...);
}
layersWereFlattened
),传递空列表(扁平化后无法预测单个图层);否则传递当前图层列表。for (LayerId removedLayer : removedLayers) {
mPreviousLayers.erase(removedLayer);
}
mPreviousLayers
中删除已被移除的图层,避免内存泄漏和无效状态累积。状态跟踪:
合成优化:
资源管理:
mPreviousLayers
缓存,避免重复创建/销毁图层状态对象。framesSinceBufferUpdate
识别静态图层,复用缓存结果。Output::present()
的关系Planner::plan()
在 Output::present()
的 planComposition()
阶段被调用,为合成提供优化策略。mPredictedPlan
可能影响 prepareFrameAsync()
或 prepareFrame()
的执行逻辑。此函数是 Android 图形栈中 平衡性能与正确性 的关键环节,直接影响界面流畅度与功耗。
首先,函数名writeCompositionState
暗示它可能与将合成状态写入硬件相关,比如HWC(Hardware Composer)。之前的讨论中,Planner::plan
负责规划合成策略,而Output::present
中的writeCompositionState
可能是在执行具体的状态写入操作。
接下来,代码开始处检查getState().isEnabled
,如果未启用则直接返回。这说明该函数只在Output启用时执行操作。然后,设置earliestPresentTime
和expectedPresentTime
,这些可能与帧的呈现时间有关,用于同步。
然后,变量peekThroughLayer
和previousOverride
被初始化,可能用于处理某些特殊图层,比如覆盖层或穿透层。includeGeometry
根据refreshArgs.updatingGeometryThisFrame
决定是否包含几何信息,这可能在几何变化时才需要更新。
循环遍历getOutputLayersOrderedByZ()
返回的图层,按Z轴顺序处理每个图层。这里有一个条件判断,如果当前图层是peekThroughLayer
,则跳过,因为可能已经被提前处理过。注释提到“peekThroughLayer was already drawn ahead of its z order”,说明可能存在某种图层覆盖的情况,需要调整绘制顺序。
接下来,检查是否有overrideInfo.buffer
,即是否存在覆盖缓冲区。如果存在,且与之前的覆盖缓冲区相同,则跳过当前图层,避免重复处理。如果是新的覆盖缓冲区,处理peekThroughLayer
,这可能是一个需要提前绘制的底层图层。这里会调用writeStateToHWC
方法,将图层状态写入HWC,并更新哈希值outputLayerHash
。同时,previousOverride
被更新,以便后续图层比较。
对于每个图层,调用writeStateToHWC
,传递参数如是否包含几何信息、是否跳过、Z轴顺序等。如果未跳过,则计算哈希值,用于后续可能的状态验证或缓存。
最后,将outputLayerHash
存入editState().outputLayerHash
,可能用于后续的验证或优化步骤。
总结,writeCompositionState
的作用是将当前帧的图层状态(包括位置、缓冲区、合成方式等)写入HWC,处理特殊的覆盖层情况,并生成哈希值以跟踪状态变化。这有助于HWC高效执行硬件合成,减少不必要的GPU操作,提升性能。
在解析过程中,需要注意几个关键点:
peekThroughLayer
的处理逻辑,可能涉及图层覆盖或穿透,比如半透明效果需要先绘制底层图层。
overrideInfo
的作用,可能用于调试或特定合成策略的覆盖。
哈希值的生成,可能用于检测图层状态变化,优化后续帧的处理。
按Z轴顺序处理图层,确保正确的合成顺序。
可能存在的疑问包括:overrideInfo
的具体应用场景,peekThroughLayer
如何被设置,以及哈希值在后续流程中的具体用途。这些可能需要参考其他部分的代码或文档来深入理解,但根据现有代码,可以推断其主要目的是状态提交和优化处理。
Output::writeCompositionState()
是 Android SurfaceFlinger 中 将图层合成状态提交到硬件合成器(HWC) 的核心函数,其作用是通过 按 Z 轴顺序遍历图层、处理特殊覆盖逻辑、生成状态哈希值,确保 HWC 能以最优方式合成帧。以下是其代码逻辑的详细解析:
if (!getState().isEnabled) return;
editState().earliestPresentTime = refreshArgs.earliestPresentTime;
editState().expectedPresentTime = refreshArgs.expectedPresentTime;
Output
(如屏幕)启用时执行。compositionengine::OutputLayer* peekThroughLayer = nullptr;
sp<GraphicBuffer> previousOverride = nullptr;
bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
uint32_t z = 0;
bool overrideZ = false;
uint64_t outputLayerHash = 0;
for (auto* layer : getOutputLayersOrderedByZ()) { ... }
peekThroughLayer
:标记需要提前绘制的穿透层(如半透明图层下方的背景层)。previousOverride
:缓存上一个覆盖缓冲区,避免重复提交相同内容。includeGeometry
:若当前帧有几何变化(如旋转、缩放),需向 HWC 提交几何信息。z
:当前图层的 Z 轴顺序计数器。overrideZ
:标记是否因穿透层调整了绘制顺序。outputLayerHash
:图层状态哈希值,用于检测合成状态变化。if (layer == peekThroughLayer) {
peekThroughLayer = nullptr;
continue;
}
const auto& overrideInfo = layer->getState().overrideInfo;
if (overrideInfo.buffer != nullptr) {
if (previousOverride && overrideInfo.buffer->getBuffer() == previousOverride) {
skipLayer = true; // 跳过重复缓冲区
} else {
// 处理新覆盖缓冲区
if (overrideInfo.peekThroughLayer) {
peekThroughLayer = overrideInfo.peekThroughLayer;
// 提前绘制穿透层
peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ, true);
// 更新哈希值
outputLayerHash ^= hashCombine(...);
}
previousOverride = overrideInfo.buffer->getBuffer();
}
}
peekThroughLayer
),再绘制状态栏自身。constexpr bool isPeekingThrough = false;
layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
if (!skipLayer) {
outputLayerHash ^= hashCombine(...);
}
writeStateToHWC
:
includeGeometry
:仅当几何变化时提交,避免冗余传输。skipLayer
:若为覆盖缓冲区的重复内容,跳过提交。z
:递增 Z 轴顺序,确保合成顺序正确。overrideZ
:若因穿透层调整了顺序,需标记此状态。editState().outputLayerHash = outputLayerHash;
状态提交到 HWC:
穿透层处理:
状态哈希跟踪:
outputLayerHash
快速检测图层状态变化,避免无效的 HWC 重配置。此函数是 Android 图形栈中 连接合成策略与硬件执行 的关键环节,直接影响显示效果与能效。