Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +2 −3 Original line number Diff line number Diff line Loading @@ -73,9 +73,8 @@ private: void writeOutputIndependentGeometryStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); void writeOutputDependentPerFrameStateToHWC(HWC2::Layer*); void writeOutputIndependentPerFrameStateToHWC( HWC2::Layer*, const LayerFECompositionState&, Hwc2::IComposerClient::Composition compositionType, bool skipLayer); void writeOutputIndependentPerFrameStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); void writeSolidColorStateToHWC(HWC2::Layer*, const LayerFECompositionState&); void writeSidebandStateToHWC(HWC2::Layer*, const LayerFECompositionState&); void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +11 −29 Original line number Diff line number Diff line Loading @@ -127,22 +127,21 @@ private: class Builder { private: std::vector<CachedSet>::const_iterator mStart; int32_t mNumSets = 0; std::vector<size_t> mLengths; const CachedSet* mHolePunchCandidate = nullptr; const CachedSet* mBlurringLayer = nullptr; bool mBuilt = false; public: // Initializes a Builder a CachedSet to start from. // This start iterator must be an iterator for mLayers void init(const std::vector<CachedSet>::const_iterator& start) { mStart = start; mNumSets = 1; mLengths.push_back(start->getLayerCount()); } // Appends a new CachedSet to the end of the run // The provided length must be the size of the next sequential CachedSet in layers void increment() { mNumSets++; } void append(size_t length) { mLengths.push_back(length); } // Sets the hole punch candidate for the Run. void setHolePunchCandidate(const CachedSet* holePunchCandidate) { Loading @@ -155,36 +154,19 @@ private: // Builds a Run instance, if a valid Run may be built. std::optional<Run> validateAndBuild() { const bool built = mBuilt; mBuilt = true; if (mNumSets <= 0 || built) { if (mLengths.size() == 0) { return std::nullopt; } const bool requiresHolePunch = mHolePunchCandidate && mHolePunchCandidate->requiresHolePunch(); if (!requiresHolePunch) { // If we don't require a hole punch, then treat solid color layers at the front // to be "cheap", so remove them from the candidate cached set. while (mNumSets > 1 && mStart->getLayerCount() == 1 && mStart->getFirstLayer().getBuffer() == nullptr) { mStart++; mNumSets--; } // Only allow for single cached sets if a hole punch is required. If we're here, // then we don't require a hole punch, so don't build a run. if (mNumSets <= 1) { // Runs of length 1 which are hole punch candidates are allowed if the candidate is // going to be used. if (mLengths.size() == 1 && (!mHolePunchCandidate || !(mHolePunchCandidate->requiresHolePunch()))) { return std::nullopt; } } return Run(mStart, std::reduce(mStart, mStart + mNumSets, 0u, [](size_t length, const CachedSet& set) { return length + set.getLayerCount(); }), std::reduce(mLengths.cbegin(), mLengths.cend(), 0u, [](size_t left, size_t right) { return left + right; }), mHolePunchCandidate, mBlurringLayer); } Loading services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +9 −11 Original line number Diff line number Diff line Loading @@ -347,10 +347,6 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t auto requestedCompositionType = outputIndependentState->compositionType; if (requestedCompositionType == hal::Composition::SOLID_COLOR && state.overrideInfo.buffer) { requestedCompositionType = hal::Composition::DEVICE; } // TODO(b/181172795): We now update geometry for all flattened layers. We should update it // only when the geometry actually changes const bool isOverridden = Loading @@ -363,15 +359,13 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t } writeOutputDependentPerFrameStateToHWC(hwcLayer.get()); writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, requestedCompositionType, skipLayer); writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer); writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough, skipLayer); if (requestedCompositionType == hal::Composition::SOLID_COLOR) { // Always set the layer color after setting the composition type. writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState); } editState().hwc->stateOverridden = isOverridden; editState().hwc->layerSkipped = skipLayer; Loading Loading @@ -483,7 +477,7 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer) void OutputLayer::writeOutputIndependentPerFrameStateToHWC( HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState, hal::Composition compositionType, bool skipLayer) { bool skipLayer) { switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) { case hal::Error::NONE: break; Loading @@ -507,7 +501,7 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC( } // Content-specific per-frame state switch (compositionType) { switch (outputIndependentState.compositionType) { case hal::Composition::SOLID_COLOR: // For compatibility, should be written AFTER the composition type. break; Loading @@ -527,6 +521,10 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC( void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) { if (outputIndependentState.compositionType != hal::Composition::SOLID_COLOR) { return; } hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)), static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)), static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)), Loading services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -416,7 +416,11 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { builder.increment(); builder.append(currentSet->getLayerCount()); } else { // Runs can't start with a non-buffer layer if (currentSet->getFirstLayer().getBuffer() == nullptr) { ALOGV("[%s] Skipping initial non-buffer layer", __func__); } else { builder.init(currentSet); if (firstLayer) { Loading @@ -424,6 +428,7 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { } isPartOfRun = true; } } } else if (isPartOfRun) { builder.setHolePunchCandidate(&(*currentSet)); Loading services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +0 −16 Original line number Diff line number Diff line Loading @@ -1109,22 +1109,6 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { /*zIsOverridden*/ false, /*isPeekingThrough*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoForSolidColorIfPresent) { mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR; includeOverrideInfo(); expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha); expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion, kOverrideSurfaceDamage); expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence); expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE); EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ false, /*isPeekingThrough*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) { mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE; mOutputLayer.editState().hwc->stateOverridden = true; Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +2 −3 Original line number Diff line number Diff line Loading @@ -73,9 +73,8 @@ private: void writeOutputIndependentGeometryStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); void writeOutputDependentPerFrameStateToHWC(HWC2::Layer*); void writeOutputIndependentPerFrameStateToHWC( HWC2::Layer*, const LayerFECompositionState&, Hwc2::IComposerClient::Composition compositionType, bool skipLayer); void writeOutputIndependentPerFrameStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); void writeSolidColorStateToHWC(HWC2::Layer*, const LayerFECompositionState&); void writeSidebandStateToHWC(HWC2::Layer*, const LayerFECompositionState&); void writeBufferStateToHWC(HWC2::Layer*, const LayerFECompositionState&, bool skipLayer); Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +11 −29 Original line number Diff line number Diff line Loading @@ -127,22 +127,21 @@ private: class Builder { private: std::vector<CachedSet>::const_iterator mStart; int32_t mNumSets = 0; std::vector<size_t> mLengths; const CachedSet* mHolePunchCandidate = nullptr; const CachedSet* mBlurringLayer = nullptr; bool mBuilt = false; public: // Initializes a Builder a CachedSet to start from. // This start iterator must be an iterator for mLayers void init(const std::vector<CachedSet>::const_iterator& start) { mStart = start; mNumSets = 1; mLengths.push_back(start->getLayerCount()); } // Appends a new CachedSet to the end of the run // The provided length must be the size of the next sequential CachedSet in layers void increment() { mNumSets++; } void append(size_t length) { mLengths.push_back(length); } // Sets the hole punch candidate for the Run. void setHolePunchCandidate(const CachedSet* holePunchCandidate) { Loading @@ -155,36 +154,19 @@ private: // Builds a Run instance, if a valid Run may be built. std::optional<Run> validateAndBuild() { const bool built = mBuilt; mBuilt = true; if (mNumSets <= 0 || built) { if (mLengths.size() == 0) { return std::nullopt; } const bool requiresHolePunch = mHolePunchCandidate && mHolePunchCandidate->requiresHolePunch(); if (!requiresHolePunch) { // If we don't require a hole punch, then treat solid color layers at the front // to be "cheap", so remove them from the candidate cached set. while (mNumSets > 1 && mStart->getLayerCount() == 1 && mStart->getFirstLayer().getBuffer() == nullptr) { mStart++; mNumSets--; } // Only allow for single cached sets if a hole punch is required. If we're here, // then we don't require a hole punch, so don't build a run. if (mNumSets <= 1) { // Runs of length 1 which are hole punch candidates are allowed if the candidate is // going to be used. if (mLengths.size() == 1 && (!mHolePunchCandidate || !(mHolePunchCandidate->requiresHolePunch()))) { return std::nullopt; } } return Run(mStart, std::reduce(mStart, mStart + mNumSets, 0u, [](size_t length, const CachedSet& set) { return length + set.getLayerCount(); }), std::reduce(mLengths.cbegin(), mLengths.cend(), 0u, [](size_t left, size_t right) { return left + right; }), mHolePunchCandidate, mBlurringLayer); } Loading
services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +9 −11 Original line number Diff line number Diff line Loading @@ -347,10 +347,6 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t auto requestedCompositionType = outputIndependentState->compositionType; if (requestedCompositionType == hal::Composition::SOLID_COLOR && state.overrideInfo.buffer) { requestedCompositionType = hal::Composition::DEVICE; } // TODO(b/181172795): We now update geometry for all flattened layers. We should update it // only when the geometry actually changes const bool isOverridden = Loading @@ -363,15 +359,13 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t } writeOutputDependentPerFrameStateToHWC(hwcLayer.get()); writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, requestedCompositionType, skipLayer); writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer); writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough, skipLayer); if (requestedCompositionType == hal::Composition::SOLID_COLOR) { // Always set the layer color after setting the composition type. writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState); } editState().hwc->stateOverridden = isOverridden; editState().hwc->layerSkipped = skipLayer; Loading Loading @@ -483,7 +477,7 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer) void OutputLayer::writeOutputIndependentPerFrameStateToHWC( HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState, hal::Composition compositionType, bool skipLayer) { bool skipLayer) { switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) { case hal::Error::NONE: break; Loading @@ -507,7 +501,7 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC( } // Content-specific per-frame state switch (compositionType) { switch (outputIndependentState.compositionType) { case hal::Composition::SOLID_COLOR: // For compatibility, should be written AFTER the composition type. break; Loading @@ -527,6 +521,10 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC( void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) { if (outputIndependentState.compositionType != hal::Composition::SOLID_COLOR) { return; } hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)), static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)), static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)), Loading
services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -416,7 +416,11 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { builder.increment(); builder.append(currentSet->getLayerCount()); } else { // Runs can't start with a non-buffer layer if (currentSet->getFirstLayer().getBuffer() == nullptr) { ALOGV("[%s] Skipping initial non-buffer layer", __func__); } else { builder.init(currentSet); if (firstLayer) { Loading @@ -424,6 +428,7 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { } isPartOfRun = true; } } } else if (isPartOfRun) { builder.setHolePunchCandidate(&(*currentSet)); Loading
services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +0 −16 Original line number Diff line number Diff line Loading @@ -1109,22 +1109,6 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { /*zIsOverridden*/ false, /*isPeekingThrough*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoForSolidColorIfPresent) { mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR; includeOverrideInfo(); expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha); expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion, kOverrideSurfaceDamage); expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence); expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE); EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ false, /*isPeekingThrough*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) { mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE; mOutputLayer.editState().hwc->stateOverridden = true; Loading