赞
踩
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方法,进行合成前预处理:
- //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;
- }
调用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方法,进行预合成:
- /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方法:
- //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方法,进行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方法,更新颜色配置:
- //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); //设置缓存数据空间
-
-
- ALOGV("Set active color mode: %s (%d), active render intent: %s (%d)",
- decodeColorMode(colorProfile.mode).c_str(), colorProfile.mode,
- decodeRenderIntent(colorProfile.renderIntent).c_str(), colorProfile.renderIntent);
-
-
- dirtyEntireOutput(); //重置脏区
- }
上面方法主要处理如下:
1、调用mRenderSurface(RenderSurface)的setBufferDataspace方法,设置缓存数据空间。
2、调用Output的dirtyEntireOutput方法,重置脏区。
下面分别进行分析:
调用mRenderSurface(RenderSurface)的setBufferDataspace方法,设置缓存数据空间:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/RenderSurface.cpp
- void RenderSurface::setBufferDataspace(ui::Dataspace dataspace) {
- native_window_set_buffers_data_space(mNativeWindow.get(),
- static_cast<android_dataspace>(dataspace));
- }
调用Output的updateCompositionState方法,更新合成状态:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- if (!getState().isEnabled) {
- return;
- }
-
-
- mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
- bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
-
-
- for (auto* layer : getOutputLayersOrderedByZ()) {
- layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
- refreshArgs.devOptForceClientComposition ||
- forceClientComposition,
- refreshArgs.internalDisplayRotationFlags);
-
-
- if (mLayerRequestingBackgroundBlur == layer) {
- forceClientComposition = false;
- }
- }
- }
调用OutputLayer的updateCompositionState方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/OutputLayer.cpp
- void OutputLayer::updateCompositionState(
- bool includeGeometry, bool forceClientComposition,
- ui::Transform::RotationFlags internalDisplayRotationFlags) {
- const auto* layerFEState = getLayerFE().getCompositionState();
- if (!layerFEState) {
- return;
- }
-
-
- const auto& outputState = getOutput().getState();
- const auto& profile = *getOutput().getDisplayColorProfile();
- auto& state = editState();
-
-
- if (includeGeometry) {
- // Clear the forceClientComposition flag before it is set for any
- // reason. Note that since it can be set by some checks below when
- // updating the geometry state, we only clear it when updating the
- // geometry since those conditions for forcing client composition won't
- // go away otherwise.
- state.forceClientComposition = false;
-
-
- state.displayFrame = calculateOutputDisplayFrame();
- state.sourceCrop = calculateOutputSourceCrop(internalDisplayRotationFlags);
- state.bufferTransform = static_cast<Hwc2::Transform>(
- calculateOutputRelativeBufferTransform(internalDisplayRotationFlags));
-
-
- if ((layerFEState->isSecure && !outputState.isSecure) ||
- (state.bufferTransform & ui::Transform::ROT_INVALID)) {
- state.forceClientComposition = true;
- }
- }
-
-
- // Determine the output dependent dataspace for this layer. If it is
- // colorspace agnostic, it just uses the dataspace chosen for the output to
- // avoid the need for color conversion.
- state.dataspace = layerFEState->isColorspaceAgnostic &&
- outputState.targetDataspace != ui::Dataspace::UNKNOWN
- ? outputState.targetDataspace
- : layerFEState->dataspace;
-
-
- // Override the dataspace transfer from 170M to sRGB if the device configuration requests this.
- // We do this here instead of in buffer info so that dumpsys can still report layers that are
- // using the 170M transfer. Also we only do this if the colorspace is not agnostic for the
- // layer, in case the color profile uses a 170M transfer function.
- if (outputState.treat170mAsSrgb && !layerFEState->isColorspaceAgnostic &&
- (state.dataspace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_SMPTE_170M) {
- state.dataspace = static_cast<ui::Dataspace>(
- (state.dataspace & HAL_DATASPACE_STANDARD_MASK) |
- (state.dataspace & HAL_DATASPACE_RANGE_MASK) | HAL_DATASPACE_TRANSFER_SRGB);
- }
-
-
- // For hdr content, treat the white point as the display brightness - HDR content should not be
- // boosted or dimmed.
- // If the layer explicitly requests to disable dimming, then don't dim either.
- if (isHdrDataspace(state.dataspace) ||
- getOutput().getState().displayBrightnessNits == getOutput().getState().sdrWhitePointNits ||
- getOutput().getState().displayBrightnessNits == 0.f || !layerFEState->dimmingEnabled) {
- state.dimmingRatio = 1.f;
- state.whitePointNits = getOutput().getState().displayBrightnessNits;
- } else {
- state.dimmingRatio = std::clamp(getOutput().getState().sdrWhitePointNits /
- getOutput().getState().displayBrightnessNits,
- 0.f, 1.f);
- state.whitePointNits = getOutput().getState().sdrWhitePointNits;
- }
-
-
- // These are evaluated every frame as they can potentially change at any
- // time.
- if (layerFEState->forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
- forceClientComposition) {
- state.forceClientComposition = true;
- }
- }
调用Output的planComposition方法,计划合成:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::planComposition() {
- if (!mPlanner || !getState().isEnabled) {
- return;
- }
-
-
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- mPlanner->plan(getOutputLayersOrderedByZ());
- }
调用Planner的plan方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Planner.cpp
- void Planner::plan(
- compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers) {
- ATRACE_CALL();
- std::unordered_set<LayerId> removedLayers;
- removedLayers.reserve(mPreviousLayers.size());
-
-
- std::transform(mPreviousLayers.begin(), mPreviousLayers.end(),
- std::inserter(removedLayers, removedLayers.begin()),
- [](const auto& layer) { return layer.first; });
-
-
- std::vector<LayerId> currentLayerIds;
- for (auto layer : layers) {
- LayerId id = layer->getLayerFE().getSequence();
- if (const auto layerEntry = mPreviousLayers.find(id); layerEntry != mPreviousLayers.end()) {
- // Track changes from previous info
- LayerState& state = layerEntry->second;
- ftl::Flags<LayerStateField> differences = state.update(layer);
- if (differences.get() == 0) {
- state.incrementFramesSinceBufferUpdate();
- } else {
- ALOGV("Layer %s changed: %s", state.getName().c_str(),
- differences.string().c_str());
-
-
- if (differences.test(LayerStateField::Buffer)) {
- state.resetFramesSinceBufferUpdate();
- } else {
- state.incrementFramesSinceBufferUpdate();
- }
- }
- } else {
- LayerState state(layer);
- ALOGV("Added layer %s", state.getName().c_str());
- mPreviousLayers.emplace(std::make_pair(id, std::move(state)));
- }
-
-
- currentLayerIds.emplace_back(id);
-
-
- if (const auto found = removedLayers.find(id); found != removedLayers.end()) {
- removedLayers.erase(found);
- }
- }
-
-
- mCurrentLayers.clear();
- mCurrentLayers.reserve(currentLayerIds.size());
- std::transform(currentLayerIds.cbegin(), currentLayerIds.cend(),
- std::back_inserter(mCurrentLayers), [this](LayerId id) {
- LayerState* state = &mPreviousLayers.at(id);
- state->getOutputLayer()->editState().overrideInfo = {};
- return state;
- });
-
-
- const NonBufferHash hash = getNonBufferHash(mCurrentLayers);
- mFlattenedHash =
- mFlattener.flattenLayers(mCurrentLayers, hash, std::chrono::steady_clock::now());
- const bool layersWereFlattened = hash != mFlattenedHash;
-
-
- ALOGV("[%s] Initial hash %zx flattened hash %zx", __func__, hash, mFlattenedHash);
-
-
- if (mPredictorEnabled) {
- mPredictedPlan =
- mPredictor.getPredictedPlan(layersWereFlattened ? std::vector<const LayerState*>()
- : mCurrentLayers,
- mFlattenedHash);
- if (mPredictedPlan) {
- ALOGV("[%s] Predicting plan %s", __func__, to_string(mPredictedPlan->plan).c_str());
- } else {
- ALOGV("[%s] No prediction found\n", __func__);
- }
- }
-
-
- // Clean up the set of previous layers now that the view of the LayerStates in the flattener are
- // up-to-date.
- for (LayerId removedLayer : removedLayers) {
- if (const auto layerEntry = mPreviousLayers.find(removedLayer);
- layerEntry != mPreviousLayers.end()) {
- const auto& [id, state] = *layerEntry;
- ALOGV("Removed layer %s", state.getName().c_str());
- mPreviousLayers.erase(removedLayer);
- }
- }
- }
调用Output的writeCompositionState方法,写入合成状态:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- if (!getState().isEnabled) {
- return;
- }
-
-
- editState().earliestPresentTime = refreshArgs.earliestPresentTime;
- editState().previousPresentFence = refreshArgs.previousPresentFence;
- editState().expectedPresentTime = refreshArgs.expectedPresentTime;
-
-
- 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()) {
- if (layer == peekThroughLayer) {
- // No longer needed, although it should not show up again, so
- // resetting it is not truly needed either.
- peekThroughLayer = nullptr;
-
-
- // peekThroughLayer was already drawn ahead of its z order.
- continue;
- }
- bool skipLayer = false;
- const auto& overrideInfo = layer->getState().overrideInfo;
- if (overrideInfo.buffer != nullptr) {
- if (previousOverride && overrideInfo.buffer->getBuffer() == previousOverride) {
- ALOGV("Skipping redundant buffer");
- skipLayer = true;
- } else {
- // First layer with the override buffer.
- if (overrideInfo.peekThroughLayer) {
- peekThroughLayer = overrideInfo.peekThroughLayer;
-
-
- // Draw peekThroughLayer first.
- overrideZ = true;
- includeGeometry = true;
- constexpr bool isPeekingThrough = true;
- peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ,
- isPeekingThrough);
- outputLayerHash ^= android::hashCombine(
- reinterpret_cast<uint64_t>(&peekThroughLayer->getLayerFE()),
- z, includeGeometry, overrideZ, isPeekingThrough,
- peekThroughLayer->requiresClientComposition());
- }
-
-
- previousOverride = overrideInfo.buffer->getBuffer();
- }
- }
-
-
- constexpr bool isPeekingThrough = false;
- layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
- if (!skipLayer) {
- outputLayerHash ^= android::hashCombine(
- reinterpret_cast<uint64_t>(&layer->getLayerFE()),
- z, includeGeometry, overrideZ, isPeekingThrough,
- layer->requiresClientComposition());
- }
- }
- editState().outputLayerHash = outputLayerHash;
- }
调用Output的setColorTransform方法,设置颜色矩阵:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
- auto& colorTransformMatrix = editState().colorTransformMatrix;
- if (!args.colorTransformMatrix || colorTransformMatrix == args.colorTransformMatrix) {
- return;
- }
-
-
- colorTransformMatrix = *args.colorTransformMatrix;
-
-
- dirtyEntireOutput();
- }
调用Output的beginFrame方法,开始帧:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::beginFrame() {
- auto& outputState = editState();
- const bool dirty = !getDirtyRegion().isEmpty();
- const bool empty = getOutputLayerCount() == 0;
- const bool wasEmpty = !outputState.lastCompositionHadVisibleLayers;
-
-
- // If nothing has changed (!dirty), don't recompose.
- // If something changed, but we don't currently have any visible layers,
- // and didn't when we last did a composition, then skip it this time.
- // The second rule does two things:
- // - When all layers are removed from a display, we'll emit one black
- // frame, then nothing more until we get new layers.
- // - When a display is created with a private layer stack, we won't
- // emit any black frames until a layer is added to the layer stack.
- const bool mustRecompose = dirty && !(empty && wasEmpty);
-
-
- const char flagPrefix[] = {'-', '+'};
- static_cast<void>(flagPrefix);
- ALOGV_IF("%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__,
- mustRecompose ? "doing" : "skipping", getName().c_str(), flagPrefix[dirty],
- flagPrefix[empty], flagPrefix[wasEmpty]);
-
-
- mRenderSurface->beginFrame(mustRecompose);
-
-
- if (mustRecompose) {
- outputState.lastCompositionHadVisibleLayers = !empty;
- }
- }
调用mRenderSurface(RenderSurface)的beginFrame方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/RenderSurface.cpp
- const sp<DisplaySurface> mDisplaySurface;
- status_t RenderSurface::beginFrame(bool mustRecompose) {
- return mDisplaySurface->beginFrame(mustRecompose);
- }
调用mDisplaySurface(DisplaySurface)的beginFrame方法,FramebufferSurface继承DisplaySurface,调用FramebufferSurface的beginFrame方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
- status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
- return NO_ERROR;
- }
调用mDisplaySurface(DisplaySurface)的beginFrame方法,VirtualDisplaySurface继承DisplaySurface,调用VirtualDisplaySurface的beginFrame方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
- status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
- return NO_ERROR;
- }
-
-
- mMustRecompose = mustRecompose;
-
-
- VDS_LOGW_IF(mDebugState != DebugState::Idle, "Unexpected %s in %s state", __func__,
- ftl::enum_string(mDebugState).c_str());
- mDebugState = DebugState::Begun;
-
-
- return refreshOutputBuffer();
- }
调用VirtualDisplaySurface的refreshOutputBuffer方法,刷新输出缓冲区:
- //frameworks/native/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
- HWComposer& mHwc;
- status_t VirtualDisplaySurface::refreshOutputBuffer() {
- LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
-
-
- if (mOutputProducerSlot >= 0) {
- mSource[SOURCE_SINK]->cancelBuffer(
- mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot),
- mOutputFence);
- }
-
-
- int sslot;
- status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage,
- &sslot, &mOutputFence);
- if (result < 0)
- return result;
- mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
-
-
- // On GPU-only frames, we don't have the right output buffer acquire fence
- // until after GPU calls queueBuffer(). So here we just set the buffer
- // (for use in HWC prepare) but not the fence; we'll call this again with
- // the proper fence once we have it.
- const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
- LOG_FATAL_IF(!halDisplayId);
- result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
- mProducerBuffers[mOutputProducerSlot]);
-
-
- return result;
- }
调用mHwc(HWComposer)的setOutputBuffer方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
- std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
- std::unique_ptr<HWC2::Display> hwcDisplay;
- status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
- const sp<GraphicBuffer>& buffer) {
- RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- const auto& displayData = mDisplayData[displayId];
-
-
- auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
- RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
- return NO_ERROR;
- }
调用HWC2::Display的setOutputBuffer方法,之后就是HWC的处理了。
调用Output的prepareFrameAsync方法,准备帧数据以进行显示(Async方式):
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- GpuCompositionResult Output::prepareFrameAsync(const CompositionRefreshArgs& refreshArgs) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
- auto& state = editState();
- const auto& previousChanges = state.previousDeviceRequestedChanges;
- std::optional<android::HWComposer::DeviceRequestedChanges> changes;
- resetCompositionStrategy();
- auto hwcResult = chooseCompositionStrategyAsync(&changes);
- if (state.previousDeviceRequestedSuccess) {
- applyCompositionStrategy(previousChanges);
- }
- finishPrepareFrame();
-
-
- base::unique_fd bufferFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- updateProtectedContentState();
- const bool dequeueSucceeded = dequeueRenderBuffer(&bufferFence, &buffer);
- GpuCompositionResult compositionResult;
- if (dequeueSucceeded) {
- std::optional<base::unique_fd> optFd =
- composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
- if (optFd) {
- compositionResult.fence = std::move(*optFd);
- }
- }
-
-
- auto chooseCompositionSuccess = hwcResult.get();
- const bool predictionSucceeded = dequeueSucceeded && changes == previousChanges;
- state.strategyPrediction = predictionSucceeded ? CompositionStrategyPredictionState::SUCCESS
- : CompositionStrategyPredictionState::FAIL;
- if (!predictionSucceeded) {
- ATRACE_NAME("CompositionStrategyPredictionMiss");
- resetCompositionStrategy();
- if (chooseCompositionSuccess) {
- applyCompositionStrategy(changes);
- }
- finishPrepareFrame();
- // Track the dequeued buffer to reuse so we don't need to dequeue another one.
- compositionResult.buffer = buffer;
- } else {
- ATRACE_NAME("CompositionStrategyPredictionHit");
- }
- state.previousDeviceRequestedChanges = std::move(changes);
- state.previousDeviceRequestedSuccess = chooseCompositionSuccess;
- return compositionResult;
- }
调用Output的prepareFrame方法,准备帧数据以进行显示:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::prepareFrame() {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- auto& outputState = editState();
- if (!outputState.isEnabled) {
- return;
- }
-
-
- std::optional<android::HWComposer::DeviceRequestedChanges> changes;
- bool success = chooseCompositionStrategy(&changes); //向HWC询问合成策略
- resetCompositionStrategy();
- outputState.strategyPrediction = CompositionStrategyPredictionState::DISABLED;
- outputState.previousDeviceRequestedChanges = changes;
- outputState.previousDeviceRequestedSuccess = success;
- if (success) {
- applyCompositionStrategy(changes);
- }
- finishPrepareFrame();
- }
调用Output的chooseCompositionStrategy方法,向HWC询问合成策略:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- std::unique_ptr<HwcAsyncWorker> mHwComposerAsyncWorker;
- std::future<bool> Output::chooseCompositionStrategyAsync(
- std::optional<android::HWComposer::DeviceRequestedChanges>* changes) {
- return mHwComposerAsyncWorker->send(
- [&, changes]() { return chooseCompositionStrategy(changes); });
- }
调用mHwComposerAsyncWorker(HwcAsyncWorker)的send方法,获取合成策略:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/HwcAsyncWorker.cpp
- std::future<bool> HwcAsyncWorker::send(std::function<bool()> task) {
- std::unique_lock<std::mutex> lock(mMutex);
- android::base::ScopedLockAssertion assumeLock(mMutex);
- mTask = std::packaged_task<bool()>([task = std::move(task)]() { return task(); });
- mTaskRequested = true;
- mCv.notify_one();
- return mTask.get_future();
- }
返回chooseCompositionStrategy:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Display.cpp
- bool Display::chooseCompositionStrategy(
- std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- if (mIsDisconnected) {
- return false;
- }
-
-
- // If we don't have a HWC display, then we are done.
- const auto halDisplayId = HalDisplayId::tryCast(mId);
- if (!halDisplayId) {
- return false;
- }
-
-
- // Get any composition changes requested by the HWC device, and apply them.
- std::optional<android::HWComposer::DeviceRequestedChanges> changes;
- auto& hwc = getCompositionEngine().getHwComposer();
- if (status_t result =
- hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
- getState().earliestPresentTime,
- getState().previousPresentFence,
- getState().expectedPresentTime, outChanges);
- result != NO_ERROR) {
- ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
- strerror(-result));
- return false;
- }
-
-
- return true;
- }
调用hwc(HWComposer)的getDeviceCompositionChanges方法,向HWC获取合成策略:
- //frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
- status_t HWComposer::getDeviceCompositionChanges(
- HalDisplayId displayId, bool frameUsesClientComposition,
- std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence, nsecs_t expectedPresentTime,
- std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
- ATRACE_CALL();
-
-
- RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
-
-
- auto& displayData = mDisplayData[displayId];
- auto& hwcDisplay = displayData.hwcDisplay;
- if (!hwcDisplay->isConnected()) {
- return NO_ERROR;
- }
-
-
- uint32_t numTypes = 0;
- uint32_t numRequests = 0;
-
-
- hal::Error error = hal::Error::NONE;
-
-
- // First try to skip validate altogether. We can do that when
- // 1. The previous frame has not been presented yet or already passed the
- // earliest time to present. Otherwise, we may present a frame too early.
- // 2. There is no client composition. Otherwise, we first need to render the
- // client target buffer.
- const bool canSkipValidate = [&] {
- // We must call validate if we have client composition
- if (frameUsesClientComposition) {
- return false;
- }
-
-
- // If composer supports getting the expected present time, we can skip
- // as composer will make sure to prevent early presentation
- if (mComposer->isSupported(Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
- return true;
- }
-
-
- // composer doesn't support getting the expected present time. We can only
- // skip validate if we know that we are not going to present early.
- return std::chrono::steady_clock::now() >= earliestPresentTime ||
- previousPresentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING;
- }();
-
-
- displayData.validateWasSkipped = false;
- if (canSkipValidate) {
- sp<Fence> outPresentFence;
- uint32_t state = UINT32_MAX;
- error = hwcDisplay->presentOrValidate(expectedPresentTime, &numTypes, &numRequests,
- &outPresentFence, &state);
- if (!hasChangesError(error)) {
- RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
- }
- if (state == 1) { //Present Succeeded.
- 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(expectedPresentTime, &numTypes, &numRequests);
- }
- ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
- if (!hasChangesError(error)) {
- RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
- }
-
-
- android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
- changedTypes.reserve(numTypes);
- error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
- RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
-
-
- auto displayRequests = static_cast<hal::DisplayRequest>(0);
- android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
- layerRequests.reserve(numRequests);
- error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
- RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
-
-
- DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
- error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
-
-
- outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
- std::move(layerRequests),
- std::move(clientTargetProperty)});
- error = hwcDisplay->acceptChanges();
- RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
-
-
- return NO_ERROR;
- }
调用Output的devOptRepaintFlash方法,处理显示输出设备的可选重绘闪烁:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& refreshArgs) {
- if (CC_LIKELY(!refreshArgs.devOptFlashDirtyRegionsDelay)) {
- return;
- }
-
-
- if (getState().isEnabled) {
- if (const auto dirtyRegion = getDirtyRegion(); !dirtyRegion.isEmpty()) {
- base::unique_fd bufferFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- updateProtectedContentState();
- dequeueRenderBuffer(&bufferFence, &buffer);
- static_cast<void>(composeSurfaces(dirtyRegion, refreshArgs, buffer, bufferFence));
- mRenderSurface->queueBuffer(base::unique_fd());
- }
- }
-
-
- postFramebuffer();
-
-
- std::this_thread::sleep_for(*refreshArgs.devOptFlashDirtyRegionsDelay);
-
-
- prepareFrame();
- }
调用mRenderSurface(RenderSurface)的queueBuffer方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/RenderSurface.cpp
- void RenderSurface::queueBuffer(base::unique_fd readyFence) {
- auto& state = mDisplay.getState();
-
-
- if (state.usesClientComposition || state.flipClientTarget) {
- // hasFlipClientTargetRequest could return true even if we haven't
- // dequeued a buffer before. Try dequeueing one if we don't have a
- // buffer ready.
- if (mTexture == nullptr) {
- ALOGI("Attempting to queue a client composited buffer without one "
- "previously dequeued for display [%s]. Attempting to dequeue "
- "a scratch buffer now",
- mDisplay.getName().c_str());
- // We shouldn't deadlock here, since mTexture == nullptr only
- // after a successful call to queueBuffer, or if dequeueBuffer has
- // never been called.
- base::unique_fd unused;
- dequeueBuffer(&unused);
- }
-
-
- if (mTexture == nullptr) {
- ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
- } else {
- status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(),
- mTexture->getBuffer()->getNativeBuffer(),
- dup(readyFence));
- if (result != NO_ERROR) {
- ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
- result);
- // We risk blocking on dequeueBuffer if the primary display failed
- // to queue up its buffer, so crash here.
- if (!mDisplay.isVirtual()) {
- LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
- } else {
- mNativeWindow->cancelBuffer(mNativeWindow.get(),
- mTexture->getBuffer()->getNativeBuffer(),
- dup(readyFence));
- }
- }
-
-
- mTexture = nullptr;
- }
- }
-
-
- status_t result = mDisplaySurface->advanceFrame();
- if (result != NO_ERROR) {
- ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplay.getName().c_str(), result);
- }
- }
调用mDisplaySurface(DisplaySurface)的advanceFrame方法,FramebufferSurface继承与DisplaySurface,调用FramebufferSurface的advanceFrame方法,FramebufferSurface的advanceFrame方法用于更新帧并将其显示在屏幕上
- //frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
- status_t FramebufferSurface::advanceFrame() {
- uint32_t slot = 0;
- sp<GraphicBuffer> buf;
- sp<Fence> acquireFence(Fence::NO_FENCE);
- Dataspace dataspace = Dataspace::UNKNOWN;
- status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
- mDataSpace = dataspace;
- if (result != NO_ERROR) {
- ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
- strerror(-result), result);
- }
- return result;
- }
调用FramebufferSurface的nextBuffer方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
- status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
- sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
- Dataspace& outDataspace) {
- Mutex::Autolock lock(mMutex);
-
-
- BufferItem item;
- status_t err = acquireBufferLocked(&item, 0);
- if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
- mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer);
- return NO_ERROR;
- } else if (err != NO_ERROR) {
- ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
- return err;
- }
-
-
- // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
- // then we may have acquired the slot we already own. If we had released
- // our current buffer before we call acquireBuffer then that release call
- // would have returned STALE_BUFFER_SLOT, and we would have called
- // freeBufferLocked on that slot. Because the buffer slot has already
- // been overwritten with the new buffer all we have to do is skip the
- // releaseBuffer call and we should be in the same state we'd be in if we
- // had released the old buffer first.
- if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
- item.mSlot != mCurrentBufferSlot) {
- mHasPendingRelease = true;
- mPreviousBufferSlot = mCurrentBufferSlot;
- mPreviousBuffer = mCurrentBuffer;
- }
- mCurrentBufferSlot = item.mSlot;
- mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
- mCurrentFence = item.mFence;
-
-
- outFence = item.mFence;
- mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer);
- outDataspace = static_cast<Dataspace>(item.mDataSpace);
- status_t result = mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace);
- if (result != NO_ERROR) {
- ALOGE("error posting framebuffer: %d", result);
- return result;
- }
-
-
- return NO_ERROR;
- }
调用mHwc(HWComposer)的setClientTarget方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
- std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
- std::unique_ptr<HWC2::Display> hwcDisplay;
- status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
- const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
- ui::Dataspace dataspace) {
- RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
-
-
- ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
- auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
- auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
- RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
- return NO_ERROR;
- }
调用HWC2::Display的setClientTarget方法,之后就是HWC的处理了。
调用Output的finishFrame方法,完成帧:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
- const auto& outputState = getState();
- if (!outputState.isEnabled) {
- return;
- }
-
-
- std::optional<base::unique_fd> optReadyFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- base::unique_fd bufferFence;
- if (outputState.strategyPrediction == CompositionStrategyPredictionState::SUCCESS) {
- optReadyFence = std::move(result.fence);
- } else {
- if (result.bufferAvailable()) {
- buffer = std::move(result.buffer);
- bufferFence = std::move(result.fence);
- } else {
- updateProtectedContentState();
- if (!dequeueRenderBuffer(&bufferFence, &buffer)) {
- return;
- }
- }
- // Repaint the framebuffer (if needed), getting the optional fence for when
- // the composition completes.
- optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
- }
- if (!optReadyFence) {
- return;
- }
-
-
- // swap buffers (presentation)
- mRenderSurface->queueBuffer(std::move(*optReadyFence));
- }
调用Output的postFramebuffer方法,将帧缓冲区(framebuffer)的内容发送到显示设备进行显示:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::postFramebuffer() {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
-
- if (!getState().isEnabled) {
- return;
- }
-
-
- auto& outputState = editState();
- outputState.dirtyRegion.clear();
- mRenderSurface->flip();
-
-
- auto frame = presentAndGetFrameFences();
-
-
- mRenderSurface->onPresentDisplayCompleted();
-
-
- for (auto* layer : getOutputLayersOrderedByZ()) {
- // The layer buffer from the previous frame (if any) is released
- // by HWC only when the release fence from this frame (if any) is
- // signaled. Always get the release fence from HWC first.
- 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 the layer was client composited in the previous frame, we
- // need to merge with the previous client target acquire fence.
- // Since we do not track that, always merge with the current
- // client target acquire fence when it is available, even though
- // this is suboptimal.
- // TODO(b/121291683): Track previous frame client target acquire fence.
- if (outputState.usesClientComposition) {
- releaseFence =
- Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
- }
- layer->getLayerFE().onLayerDisplayed(
- ftl::yield<FenceResult>(std::move(releaseFence)).share());
- }
-
-
- // We've got a list of layers needing fences, that are disjoint with
- // OutputLayersOrderedByZ. The best we can do is to
- // supply them with the present fence.
- for (auto& weakLayer : mReleasedLayers) {
- if (const auto layer = weakLayer.promote()) {
- layer->onLayerDisplayed(ftl::yield<FenceResult>(frame.presentFence).share());
- }
- }
-
-
- // Clear out the released layers now that we're done with them.
- mReleasedLayers.clear();
- }
上面方法主要处理如下:
1、调用Output的presentAndGetFrameFences方法,通过presentAndGetReleaseFences显示获取releaseFences。
2、调用BufferQueueLayer的onLayerDisplayed方法。
下面分别进行分析。
调用Output的presentAndGetFrameFences方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- compositionengine::Output::FrameFences Output::presentAndGetFrameFences() {
- compositionengine::Output::FrameFences result;
- if (getState().usesClientComposition) {
- result.clientTargetAcquireFence = mRenderSurface->getClientTargetAcquireFence();
- }
- return result;
- }
调用mRenderSurface(RenderSurface)的getClientTargetAcquireFence方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/RenderSurface.cpp
- const sp<DisplaySurface> mDisplaySurface;
- const sp<Fence>& RenderSurface::getClientTargetAcquireFence() const {
- return mDisplaySurface->getClientTargetAcquireFence();
- }
调用mDisplaySurface(DisplaySurface)的prepareFrame方法,FramebufferSurface 继承于DisplaySurface,因此调用FramebufferSurface的getClientTargetAcquireFence方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
- const sp<Fence>& FramebufferSurface::getClientTargetAcquireFence() const {
- return mCurrentFence;
- }
调用Layer的onLayerDisplayed方法,BufferQueueLayer继承于BuffeLayer,BuffeLayer由继承于Layer,因此调用BufferQueueLayer的onLayerDisplayed方法:
Android13 BufferQueueLayer onLayerDisplayed流程分析-CSDN博客
调用Output的renderCachedSets方法,进行渲染缓存设置:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::renderCachedSets(const CompositionRefreshArgs& refreshArgs) {
- if (mPlanner) {
- mPlanner->renderCachedSets(getState(), refreshArgs.scheduledFrameTime);
- }
- }
调用Output的dirtyEntireOutput方法,重置脏区:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- OutputCompositionState outputState ;
- Region dirtyRegion;
- using OutputCompositionState = compositionengine::impl::OutputCompositionState;
- void Output::dirtyEntireOutput() {
- auto& outputState = editState();
- outputState.dirtyRegion.set(outputState.displaySpace.getBoundsAsRect());
- }
调用outputState(OutputCompositionState )内成员变量dirtyRegion(Region)的set方法,设置脏区:
- //frameworks/native/libs/ui/Region.cpp
- FatVector<Rect> mStorage;
- void Region::set(const Rect& r)
- {
- mStorage.clear();
- mStorage.push_back(r);
- }
调用Output的finishPrepareFrame方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
- void Output::finishPrepareFrame() {
- const auto& state = getState();
- if (mPlanner) {
- mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
- }
- mRenderSurface->prepareFrame(state.usesClientComposition, state.usesDeviceComposition);
- }
调用mPlanner(Planner)的reportFinalPlan方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Planner.cpp
- void Planner::reportFinalPlan(
- compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers) {
- ATRACE_CALL();
- if (!mPredictorEnabled) {
- return;
- }
-
-
- Plan finalPlan;
- const GraphicBuffer* currentOverrideBuffer = nullptr;
- bool hasSkippedLayers = false;
- for (auto layer : layers) {
- if (!layer->getState().overrideInfo.buffer) {
- continue;
- }
-
-
- const GraphicBuffer* overrideBuffer =
- layer->getState().overrideInfo.buffer->getBuffer().get();
- if (overrideBuffer != nullptr && overrideBuffer == currentOverrideBuffer) {
- // Skip this layer since it is part of a previous cached set
- hasSkippedLayers = true;
- continue;
- }
-
-
- currentOverrideBuffer = overrideBuffer;
-
-
- const bool forcedOrRequestedClient =
- layer->getState().forceClientComposition || layer->requiresClientComposition();
-
-
- finalPlan.addLayerType(
- forcedOrRequestedClient
- ? aidl::android::hardware::graphics::composer3::Composition::CLIENT
- : layer->getLayerFE().getCompositionState()->compositionType);
- }
-
-
- mPredictor.recordResult(mPredictedPlan, mFlattenedHash, mCurrentLayers, hasSkippedLayers,
- finalPlan);
- }
调用mPredictor(Predictor)的recordResult方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/Predictor.cpp
- void Predictor::recordResult(std::optional<PredictedPlan> predictedPlan,
- NonBufferHash flattenedHash,
- const std::vector<const LayerState*>& layers, bool hasSkippedLayers,
- Plan result) {
- if (predictedPlan) {
- recordPredictedResult(*predictedPlan, layers, std::move(result));
- return;
- }
-
-
- ++mMissCount;
-
-
- if (!hasSkippedLayers && findSimilarPrediction(layers, result)) {
- return;
- }
-
-
- ALOGV("[%s] Adding novel candidate %zx", __func__, flattenedHash);
- mCandidates.emplace_front(flattenedHash, Prediction(layers, result));
- if (mCandidates.size() > MAX_CANDIDATES) {
- mCandidates.pop_back();
- }
- }
调用RenderSurface的prepareFrame方法:
- //frameworks/native/services/surfaceflinger/CompositionEngin/src/RenderSurface.cpp
- const sp<DisplaySurface> mDisplaySurface;
- void RenderSurface::prepareFrame(bool usesClientComposition, bool usesDeviceComposition) {
- const auto compositionType = [=] {
- using CompositionType = DisplaySurface::CompositionType;
-
-
- if (usesClientComposition && usesDeviceComposition) return CompositionType::Mixed;
- if (usesClientComposition) return CompositionType::Gpu;
- if (usesDeviceComposition) return CompositionType::Hwc;
-
-
- // Nothing to do -- when turning the screen off we get a frame like
- // this. Call it a HWC frame since we won't be doing any GPU work but
- // will do a prepare/set cycle.
- return CompositionType::Hwc;
- }();
-
-
- if (status_t result = mDisplaySurface->prepareFrame(compositionType); result != NO_ERROR) {
- ALOGE("updateCompositionType failed for %s: %d (%s)", mDisplay.getName().c_str(), result,
- strerror(-result));
- }
- }
调用mDisplaySurface(DisplaySurface)的prepareFrame方法,VirtualDisplaySurface继承于DisplaySurface,因此调用DisplaySurface的prepareFrame方法,DisplaySurface的prepareFrame方法用于准备帧
- //frameworks/native/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
- status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
- return NO_ERROR;
- }
-
-
- VDS_LOGW_IF(mDebugState != DebugState::Begun, "Unexpected %s in %s state", __func__,
- ftl::enum_string(mDebugState).c_str());
- mDebugState = DebugState::Prepared;
-
-
- mCompositionType = compositionType;
- if (mForceHwcCopy && mCompositionType == CompositionType::Gpu) {
- // Some hardware can do RGB->YUV conversion more efficiently in hardware
- // controlled by HWC than in hardware controlled by the video encoder.
- // Forcing GPU-composed frames to go through an extra copy by the HWC
- // allows the format conversion to happen there, rather than passing RGB
- // directly to the consumer.
- //
- // On the other hand, when the consumer prefers RGB or can consume RGB
- // inexpensively, this forces an unnecessary copy.
- mCompositionType = CompositionType::Mixed;
- }
-
-
- if (mCompositionType != mDebugLastCompositionType) {
- VDS_LOGV("%s: composition type changed to %s", __func__,
- toString(mCompositionType).c_str());
- mDebugLastCompositionType = mCompositionType;
- }
-
-
- if (mCompositionType != CompositionType::Gpu &&
- (mOutputFormat != mDefaultOutputFormat || mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) {
- // We must have just switched from GPU-only to MIXED or HWC
- // composition. Stop using the format and usage requested by the GPU
- // driver; they may be suboptimal when HWC is writing to the output
- // buffer. For example, if the output is going to a video encoder, and
- // HWC can write directly to YUV, some hardware can skip a
- // memory-to-memory RGB-to-YUV conversion step.
- //
- // If we just switched *to* GPU-only mode, we'll change the
- // format/usage and get a new buffer when the GPU driver calls
- // dequeueBuffer().
- mOutputFormat = mDefaultOutputFormat;
- mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
- refreshOutputBuffer();
- }
-
-
- return NO_ERROR;
- }
调用VirtualDisplaySurface的refreshOutputBuffer方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
- status_t VirtualDisplaySurface::refreshOutputBuffer() {
- LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
-
-
- if (mOutputProducerSlot >= 0) {
- mSource[SOURCE_SINK]->cancelBuffer(
- mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot),
- mOutputFence);
- }
-
-
- int sslot;
- status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage,
- &sslot, &mOutputFence);
- if (result < 0)
- return result;
- mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot);
-
-
- // On GPU-only frames, we don't have the right output buffer acquire fence
- // until after GPU calls queueBuffer(). So here we just set the buffer
- // (for use in HWC prepare) but not the fence; we'll call this again with
- // the proper fence once we have it.
- const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
- LOG_FATAL_IF(!halDisplayId);
- result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
- mProducerBuffers[mOutputProducerSlot]);
-
-
- return result;
- }
调用HWComposer的setOutputBuffer方法:
- //frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
- std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
- std::unique_ptr<HWC2::Display> hwcDisplay;
- status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
- const sp<GraphicBuffer>& buffer) {
- RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- const auto& displayData = mDisplayData[displayId];
-
-
- auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
- RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
- return NO_ERROR;
- }
调用HWC2::Display的setOutputBuffer方法,之后就是HWC的处理了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。