diff options
7 files changed, 59 insertions, 2 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h index ce2b96fc2b..1f241b091c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h @@ -227,6 +227,7 @@ public: // Returns the bit-set of differing fields between this LayerState and another LayerState. // This bit-set is based on NonUniqueFields only, and excludes GraphicBuffers. ftl::Flags<LayerStateField> getDifferingFields(const LayerState& other) const; + bool isSourceCropSizeEqual(const LayerState& other) const; compositionengine::OutputLayer* getOutputLayer() const { return mOutputLayer; } int32_t getId() const { return mId.get(); } diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp index 13b6307aea..a18397d8ba 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp @@ -20,6 +20,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <android-base/properties.h> +#include <common/FlagManager.h> #include <compositionengine/impl/planner/Flattener.h> #include <compositionengine/impl/planner/LayerState.h> @@ -50,8 +51,19 @@ bool isSameStack(const std::vector<const LayerState*>& incomingLayers, for (size_t i = 0; i < incomingLayers.size(); i++) { // Checking the IDs here is very strict, but we do this as otherwise we may mistakenly try // to access destroyed OutputLayers later on. - if (incomingLayers[i]->getId() != existingLayers[i]->getId() || - incomingLayers[i]->getDifferingFields(*(existingLayers[i])) != LayerStateField::None) { + if (incomingLayers[i]->getId() != existingLayers[i]->getId()) { + return false; + } + + // Do not unflatten if source crop is only moved. + if (FlagManager::getInstance().cache_if_source_crop_layer_only_moved() && + incomingLayers[i]->isSourceCropSizeEqual(*(existingLayers[i])) && + incomingLayers[i]->getDifferingFields(*(existingLayers[i])) == + LayerStateField::SourceCrop) { + continue; + } + + if (incomingLayers[i]->getDifferingFields(*(existingLayers[i])) != LayerStateField::None) { return false; } } diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp index 8dab6ce61b..0e3fdbb0dc 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp @@ -76,6 +76,11 @@ size_t LayerState::getHash() const { return hash; } +bool LayerState::isSourceCropSizeEqual(const LayerState& other) const { + return mSourceCrop.get().getWidth() == other.mSourceCrop.get().getWidth() && + mSourceCrop.get().getHeight() == other.mSourceCrop.get().getHeight(); +} + ftl::Flags<LayerStateField> LayerState::getDifferingFields(const LayerState& other) const { ftl::Flags<LayerStateField> differences; auto myFields = getNonUniqueFields(); diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp index d9318af371..763b998b3d 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp @@ -14,6 +14,9 @@ * limitations under the License. */ +#include <common/include/common/test/FlagUtils.h> +#include "com_android_graphics_surfaceflinger_flags.h" + #include <compositionengine/impl/OutputCompositionState.h> #include <compositionengine/impl/planner/CachedSet.h> #include <compositionengine/impl/planner/Flattener.h> @@ -239,6 +242,30 @@ TEST_F(FlattenerTest, flattenLayers_ActiveLayersWithLowFpsAreFlattened) { expectAllLayersFlattened(layers); } +TEST_F(FlattenerTest, unflattenLayers_onlySourceCropMoved) { + SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags:: + cache_if_source_crop_layer_only_moved, + true); + + auto& layerState1 = mTestLayers[0]->layerState; + auto& layerState2 = mTestLayers[1]->layerState; + + const std::vector<const LayerState*> layers = { + layerState1.get(), + layerState2.get(), + }; + + initializeFlattener(layers); + + mTestLayers[0]->outputLayerCompositionState.sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f}; + mTestLayers[1]->outputLayerCompositionState.sourceCrop = FloatRect{8.f, 16.f, 108.f, 116.f}; + + // only source crop is moved, so no flatten + EXPECT_EQ(getNonBufferHash(layers), + mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); + mFlattener->renderCachedSets(mOutputState, std::nullopt, true); +} + TEST_F(FlattenerTest, flattenLayers_basicFlatten) { auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index 35dd428a7c..a5822323ce 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -122,6 +122,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(multithreaded_present); DUMP_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace); DUMP_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency); + DUMP_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG @@ -192,6 +193,8 @@ FLAG_MANAGER_READ_ONLY_FLAG(hdcp_level_hal, "") FLAG_MANAGER_READ_ONLY_FLAG(multithreaded_present, "debug.sf.multithreaded_present") FLAG_MANAGER_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace, "") FLAG_MANAGER_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency, "") +FLAG_MANAGER_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved, + "debug.sf.cache_source_crop_only_moved") /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "") diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index 6d5846ab3c..15ca345502 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -61,6 +61,7 @@ public: bool multithreaded_present() const; bool add_sf_skipped_frames_to_trace() const; bool use_known_refresh_rate_for_fps_consistency() const; + bool cache_if_source_crop_layer_only_moved() const; protected: // overridden for unit tests diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig index c12579192f..3fb763ec12 100644 --- a/services/surfaceflinger/surfaceflinger_flags.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags.aconfig @@ -92,3 +92,11 @@ flag { bug: "299201319" is_fixed_read_only: true } + +flag { + name: "cache_if_source_crop_layer_only_moved" + namespace: "core_graphics" + description: "do not flatten layers if source crop is only moved" + bug: "305718400" + is_fixed_read_only: true +} |