Loading services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +3 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,9 @@ struct LayerFECompositionState { // The output-independent frame for the cursor Rect cursorFrame; // framerate of the layer as measured by LayerHistory float fps; virtual ~LayerFECompositionState(); // Debugging Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +7 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,13 @@ public: const bool mEnableHolePunch; }; // Constants not yet backed by a sysprop // CachedSets that contain no more than this many layers may be considered inactive on the basis // of FPS. static constexpr int kNumLayersFpsConsideration = 1; // Frames/Second threshold below which these CachedSets may be considered inactive. static constexpr float kFpsActiveThreshold = 1.f; Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables); void setDisplaySize(ui::Size size) { Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +1 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ public: bool isProtected() const { return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent; } float getFps() const { return getOutputLayer()->getLayerFE().getCompositionState()->fps; } void dump(std::string& result) const; std::optional<std::string> compare(const LayerState& other) const; Loading services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -409,10 +409,19 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { bool runHasFirstLayer = false; for (auto currentSet = mLayers.cbegin(); currentSet != mLayers.cend(); ++currentSet) { const bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; const bool layerHasBlur = currentSet->hasBlurBehind(); // Layers should also be considered inactive whenever their framerate is lower than 1fps. if (!layerIsInactive && currentSet->getLayerCount() == kNumLayersFpsConsideration) { auto layerFps = currentSet->getFirstLayer().getState()->getFps(); if (layerFps > 0 && layerFps <= kFpsActiveThreshold) { ATRACE_FORMAT("layer is considered inactive due to low FPS [%s] %f", currentSet->getFirstLayer().getName().c_str(), layerFps); layerIsInactive = true; } } if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { Loading services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,22 @@ TEST_F(FlattenerTest, flattenLayers_ActiveLayersAreNotFlattened) { mFlattener->renderCachedSets(mOutputState, std::nullopt); } TEST_F(FlattenerTest, flattenLayers_ActiveLayersWithLowFpsAreFlattened) { mTestLayers[0]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold / 2; mTestLayers[1]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold; auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; const std::vector<const LayerState*> layers = { layerState1.get(), layerState2.get(), }; initializeFlattener(layers); expectAllLayersFlattened(layers); } TEST_F(FlattenerTest, flattenLayers_basicFlatten) { auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +3 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,9 @@ struct LayerFECompositionState { // The output-independent frame for the cursor Rect cursorFrame; // framerate of the layer as measured by LayerHistory float fps; virtual ~LayerFECompositionState(); // Debugging Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +7 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,13 @@ public: const bool mEnableHolePunch; }; // Constants not yet backed by a sysprop // CachedSets that contain no more than this many layers may be considered inactive on the basis // of FPS. static constexpr int kNumLayersFpsConsideration = 1; // Frames/Second threshold below which these CachedSets may be considered inactive. static constexpr float kFpsActiveThreshold = 1.f; Flattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables); void setDisplaySize(ui::Size size) { Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +1 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ public: bool isProtected() const { return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent; } float getFps() const { return getOutputLayer()->getLayerFE().getCompositionState()->fps; } void dump(std::string& result) const; std::optional<std::string> compare(const LayerState& other) const; Loading
services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -409,10 +409,19 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { bool runHasFirstLayer = false; for (auto currentSet = mLayers.cbegin(); currentSet != mLayers.cend(); ++currentSet) { const bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; bool layerIsInactive = now - currentSet->getLastUpdate() > mTunables.mActiveLayerTimeout; const bool layerHasBlur = currentSet->hasBlurBehind(); // Layers should also be considered inactive whenever their framerate is lower than 1fps. if (!layerIsInactive && currentSet->getLayerCount() == kNumLayersFpsConsideration) { auto layerFps = currentSet->getFirstLayer().getState()->getFps(); if (layerFps > 0 && layerFps <= kFpsActiveThreshold) { ATRACE_FORMAT("layer is considered inactive due to low FPS [%s] %f", currentSet->getFirstLayer().getName().c_str(), layerFps); layerIsInactive = true; } } if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && !currentSet->hasUnsupportedDataspace()) { if (isPartOfRun) { Loading
services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,22 @@ TEST_F(FlattenerTest, flattenLayers_ActiveLayersAreNotFlattened) { mFlattener->renderCachedSets(mOutputState, std::nullopt); } TEST_F(FlattenerTest, flattenLayers_ActiveLayersWithLowFpsAreFlattened) { mTestLayers[0]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold / 2; mTestLayers[1]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold; auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; const std::vector<const LayerState*> layers = { layerState1.get(), layerState2.get(), }; initializeFlattener(layers); expectAllLayersFlattened(layers); } TEST_F(FlattenerTest, flattenLayers_basicFlatten) { auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; Loading