Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +1 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public: compositionengine::OutputLayer* getBlurLayer() const; bool hasUnsupportedDataspace() const; bool hasKnownColorShift() const; bool hasProtectedLayers() const; Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +12 −2 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ enum class LayerStateField : uint32_t { BlurRegions = 1u << 18, HasProtectedContent = 1u << 19, CachingHint = 1u << 20, DimmingEnabled = 1u << 21, }; // clang-format on Loading Loading @@ -248,6 +249,10 @@ public: ui::Dataspace getDataspace() const { return mOutputDataspace.get(); } hardware::graphics::composer::hal::PixelFormat getPixelFormat() const { return mPixelFormat.get(); } float getHdrSdrRatio() const { return getOutputLayer()->getLayerFE().getCompositionState()->currentHdrSdrRatio; }; Loading @@ -258,6 +263,8 @@ public: gui::CachingHint getCachingHint() const { return mCachingHint.get(); } bool isDimmingEnabled() const { return mIsDimmingEnabled.get(); } float getFps() const { return getOutputLayer()->getLayerFE().getCompositionState()->fps; } void dump(std::string& result) const; Loading Loading @@ -498,7 +505,10 @@ private: return std::vector<std::string>{toString(cachingHint)}; }}; static const constexpr size_t kNumNonUniqueFields = 19; OutputLayerState<bool, LayerStateField::DimmingEnabled> mIsDimmingEnabled{ [](auto layer) { return layer->getLayerFE().getCompositionState()->dimmingEnabled; }}; static const constexpr size_t kNumNonUniqueFields = 20; std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() { std::array<const StateInterface*, kNumNonUniqueFields> constFields = Loading @@ -516,7 +526,7 @@ private: &mAlpha, &mLayerMetadata, &mVisibleRegion, &mOutputDataspace, &mPixelFormat, &mColorTransform, &mCompositionType, &mSidebandStream, &mBuffer, &mSolidColor, &mBackgroundBlurRadius, &mBlurRegions, &mFrameNumber, &mIsProtected, &mCachingHint}; &mFrameNumber, &mIsProtected, &mCachingHint, &mIsDimmingEnabled}; } }; Loading services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +15 −11 Original line number Diff line number Diff line Loading @@ -27,8 +27,7 @@ #include <renderengine/DisplaySettings.h> #include <renderengine/RenderEngine.h> #include <ui/DebugUtils.h> #include <utils/Trace.h> #include <ui/HdrRenderTypeUtils.h> #include <utils/Trace.h> namespace android::compositionengine::impl::planner { Loading Loading @@ -306,7 +305,7 @@ bool CachedSet::requiresHolePunch() const { return false; } if (hasUnsupportedDataspace()) { if (hasKnownColorShift()) { return false; } Loading Loading @@ -366,12 +365,21 @@ compositionengine::OutputLayer* CachedSet::getBlurLayer() const { return mBlurLayer ? mBlurLayer->getOutputLayer() : nullptr; } bool CachedSet::hasUnsupportedDataspace() const { bool CachedSet::hasKnownColorShift() const { return std::any_of(mLayers.cbegin(), mLayers.cend(), [](const Layer& layer) { auto dataspace = layer.getState()->getDataspace(); const auto transfer = static_cast<ui::Dataspace>(dataspace & ui::Dataspace::TRANSFER_MASK); if (transfer == ui::Dataspace::TRANSFER_ST2084 || transfer == ui::Dataspace::TRANSFER_HLG) { // Skip HDR. // Layers are never dimmed when rendering a cached set, meaning that we may ask HWC to // dim a cached set. But this means that we can never cache any HDR layers so that we // don't accidentally dim those layers. const auto hdrType = getHdrRenderType(dataspace, layer.getState()->getPixelFormat(), layer.getState()->getHdrSdrRatio()); if (hdrType != HdrRenderType::SDR) { return true; } // Layers that have dimming disabled pretend that they're HDR. if (!layer.getState()->isDimmingEnabled()) { return true; } Loading @@ -380,10 +388,6 @@ bool CachedSet::hasUnsupportedDataspace() const { // to avoid flickering/color differences. return true; } // TODO(b/274804887): temp fix of overdimming issue, skip caching if hsdr/sdr ratio > 1.01f if (layer.getState()->getHdrSdrRatio() > 1.01f) { return true; } return false; }); } Loading services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -439,7 +439,7 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { if (!layerDeniedFromCaching && layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { !currentSet->hasKnownColorShift()) { if (isPartOfRun) { builder.increment(); } else { Loading services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,55 @@ TEST_F(FlattenerTest, flattenLayers_skipsHDR2) { EXPECT_EQ(nullptr, overrideBuffer3); } TEST_F(FlattenerTest, flattenLayers_skipsLayersDisablingDimming) { auto& layerState1 = mTestLayers[0]->layerState; const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; auto& layerState2 = mTestLayers[1]->layerState; const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer; // The third layer disables dimming, which means it should not be cached auto& layerState3 = mTestLayers[2]->layerState; const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer; mTestLayers[2]->layerFECompositionState.dimmingEnabled = false; mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer); const std::vector<const LayerState*> layers = { layerState1.get(), layerState2.get(), layerState3.get(), }; initializeFlattener(layers); mTime += 200ms; initializeOverrideBuffer(layers); EXPECT_EQ(getNonBufferHash(layers), mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); // This will render a CachedSet. EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)) .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE)))); mFlattener->renderCachedSets(mOutputState, std::nullopt, true); // We've rendered a CachedSet, but we haven't merged it in. EXPECT_EQ(nullptr, overrideBuffer1); EXPECT_EQ(nullptr, overrideBuffer2); EXPECT_EQ(nullptr, overrideBuffer3); // This time we merge the CachedSet in, so we have a new hash, and we should // only have two sets. EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0); initializeOverrideBuffer(layers); EXPECT_NE(getNonBufferHash(layers), mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); mFlattener->renderCachedSets(mOutputState, std::nullopt, true); EXPECT_NE(nullptr, overrideBuffer1); EXPECT_EQ(overrideBuffer1, overrideBuffer2); EXPECT_EQ(nullptr, overrideBuffer3); } TEST_F(FlattenerTest, flattenLayers_skipsColorLayers) { auto& layerState1 = mTestLayers[0]->layerState; const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +1 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public: compositionengine::OutputLayer* getBlurLayer() const; bool hasUnsupportedDataspace() const; bool hasKnownColorShift() const; bool hasProtectedLayers() const; Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +12 −2 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ enum class LayerStateField : uint32_t { BlurRegions = 1u << 18, HasProtectedContent = 1u << 19, CachingHint = 1u << 20, DimmingEnabled = 1u << 21, }; // clang-format on Loading Loading @@ -248,6 +249,10 @@ public: ui::Dataspace getDataspace() const { return mOutputDataspace.get(); } hardware::graphics::composer::hal::PixelFormat getPixelFormat() const { return mPixelFormat.get(); } float getHdrSdrRatio() const { return getOutputLayer()->getLayerFE().getCompositionState()->currentHdrSdrRatio; }; Loading @@ -258,6 +263,8 @@ public: gui::CachingHint getCachingHint() const { return mCachingHint.get(); } bool isDimmingEnabled() const { return mIsDimmingEnabled.get(); } float getFps() const { return getOutputLayer()->getLayerFE().getCompositionState()->fps; } void dump(std::string& result) const; Loading Loading @@ -498,7 +505,10 @@ private: return std::vector<std::string>{toString(cachingHint)}; }}; static const constexpr size_t kNumNonUniqueFields = 19; OutputLayerState<bool, LayerStateField::DimmingEnabled> mIsDimmingEnabled{ [](auto layer) { return layer->getLayerFE().getCompositionState()->dimmingEnabled; }}; static const constexpr size_t kNumNonUniqueFields = 20; std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() { std::array<const StateInterface*, kNumNonUniqueFields> constFields = Loading @@ -516,7 +526,7 @@ private: &mAlpha, &mLayerMetadata, &mVisibleRegion, &mOutputDataspace, &mPixelFormat, &mColorTransform, &mCompositionType, &mSidebandStream, &mBuffer, &mSolidColor, &mBackgroundBlurRadius, &mBlurRegions, &mFrameNumber, &mIsProtected, &mCachingHint}; &mFrameNumber, &mIsProtected, &mCachingHint, &mIsDimmingEnabled}; } }; Loading
services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +15 −11 Original line number Diff line number Diff line Loading @@ -27,8 +27,7 @@ #include <renderengine/DisplaySettings.h> #include <renderengine/RenderEngine.h> #include <ui/DebugUtils.h> #include <utils/Trace.h> #include <ui/HdrRenderTypeUtils.h> #include <utils/Trace.h> namespace android::compositionengine::impl::planner { Loading Loading @@ -306,7 +305,7 @@ bool CachedSet::requiresHolePunch() const { return false; } if (hasUnsupportedDataspace()) { if (hasKnownColorShift()) { return false; } Loading Loading @@ -366,12 +365,21 @@ compositionengine::OutputLayer* CachedSet::getBlurLayer() const { return mBlurLayer ? mBlurLayer->getOutputLayer() : nullptr; } bool CachedSet::hasUnsupportedDataspace() const { bool CachedSet::hasKnownColorShift() const { return std::any_of(mLayers.cbegin(), mLayers.cend(), [](const Layer& layer) { auto dataspace = layer.getState()->getDataspace(); const auto transfer = static_cast<ui::Dataspace>(dataspace & ui::Dataspace::TRANSFER_MASK); if (transfer == ui::Dataspace::TRANSFER_ST2084 || transfer == ui::Dataspace::TRANSFER_HLG) { // Skip HDR. // Layers are never dimmed when rendering a cached set, meaning that we may ask HWC to // dim a cached set. But this means that we can never cache any HDR layers so that we // don't accidentally dim those layers. const auto hdrType = getHdrRenderType(dataspace, layer.getState()->getPixelFormat(), layer.getState()->getHdrSdrRatio()); if (hdrType != HdrRenderType::SDR) { return true; } // Layers that have dimming disabled pretend that they're HDR. if (!layer.getState()->isDimmingEnabled()) { return true; } Loading @@ -380,10 +388,6 @@ bool CachedSet::hasUnsupportedDataspace() const { // to avoid flickering/color differences. return true; } // TODO(b/274804887): temp fix of overdimming issue, skip caching if hsdr/sdr ratio > 1.01f if (layer.getState()->getHdrSdrRatio() > 1.01f) { return true; } return false; }); } Loading
services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -439,7 +439,7 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { if (!layerDeniedFromCaching && layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { !currentSet->hasKnownColorShift()) { if (isPartOfRun) { builder.increment(); } else { Loading
services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,55 @@ TEST_F(FlattenerTest, flattenLayers_skipsHDR2) { EXPECT_EQ(nullptr, overrideBuffer3); } TEST_F(FlattenerTest, flattenLayers_skipsLayersDisablingDimming) { auto& layerState1 = mTestLayers[0]->layerState; const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; auto& layerState2 = mTestLayers[1]->layerState; const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer; // The third layer disables dimming, which means it should not be cached auto& layerState3 = mTestLayers[2]->layerState; const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer; mTestLayers[2]->layerFECompositionState.dimmingEnabled = false; mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer); const std::vector<const LayerState*> layers = { layerState1.get(), layerState2.get(), layerState3.get(), }; initializeFlattener(layers); mTime += 200ms; initializeOverrideBuffer(layers); EXPECT_EQ(getNonBufferHash(layers), mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); // This will render a CachedSet. EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)) .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE)))); mFlattener->renderCachedSets(mOutputState, std::nullopt, true); // We've rendered a CachedSet, but we haven't merged it in. EXPECT_EQ(nullptr, overrideBuffer1); EXPECT_EQ(nullptr, overrideBuffer2); EXPECT_EQ(nullptr, overrideBuffer3); // This time we merge the CachedSet in, so we have a new hash, and we should // only have two sets. EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0); initializeOverrideBuffer(layers); EXPECT_NE(getNonBufferHash(layers), mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); mFlattener->renderCachedSets(mOutputState, std::nullopt, true); EXPECT_NE(nullptr, overrideBuffer1); EXPECT_EQ(overrideBuffer1, overrideBuffer2); EXPECT_EQ(nullptr, overrideBuffer3); } TEST_F(FlattenerTest, flattenLayers_skipsColorLayers) { auto& layerState1 = mTestLayers[0]->layerState; const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; Loading