diff options
author | 2023-11-20 21:51:09 -0800 | |
---|---|---|
committer | 2023-11-21 16:20:16 -0800 | |
commit | a021bb0f099587dc41b6eec042a004be9404cde1 (patch) | |
tree | d2eed5b49d5537ba7ea39ca014115eacb3667ac2 | |
parent | 43881b0fa27a23422041337c89d95098a2d4b618 (diff) |
Logic for selection strategy "DoNotPropagate"
This logic is for the new FrameRateSelectionStrategy::DoNotPropagate.
The default behavior ("Self") is to propagate parent vote to children
that has no votes, but if a layer has "DoNotPropagate", it will not
propagate its vote to children.
Bug: 309687765
Test: atest libsurfaceflinger_unittest
Test: atest CtsSurfaceControlTestsStaging
Change-Id: I284b639f2b1902c5e9d3dcd08ceaf3f76b73451e
-rw-r--r-- | libs/nativewindow/include/system/window.h | 15 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp | 22 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfo.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfo.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp | 58 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp | 88 |
8 files changed, 186 insertions, 18 deletions
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index b068f4807c..05838128d8 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1103,7 +1103,12 @@ enum { enum { /** * Default value. The layer uses its own frame rate specifications, assuming it has any - * specifications, instead of its parent's. + * specifications, instead of its parent's. If it does not have its own frame rate + * specifications, it will try to use its parent's. + * + * However, FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN on an ancestor layer + * supersedes this behavior, meaning that this layer will inherit the frame rate specifications + * of that ancestor layer. */ ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_SELF = 0, @@ -1114,6 +1119,14 @@ enum { * behavior for itself. */ ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1, + + /** + * The layer's frame rate specifications will never propagate to its descendant + * layers. + * FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN on an ancestor layer supersedes + * this behavior. + */ + ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_DO_NOT_PROPAGATE = 2, }; static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate, diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp index 743cbf3cb1..a57cd0ad35 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp @@ -814,9 +814,12 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a RequestedLayerState::Changes::Hierarchy) || snapshot.changes.any(RequestedLayerState::Changes::FrameRate | RequestedLayerState::Changes::Hierarchy)) { - bool shouldOverrideChildren = parentSnapshot.frameRateSelectionStrategy == + const bool shouldOverrideChildren = parentSnapshot.frameRateSelectionStrategy == scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren; - if (!requested.requestedFrameRate.isValid() || shouldOverrideChildren) { + const bool propagationAllowed = parentSnapshot.frameRateSelectionStrategy != + scheduler::LayerInfo::FrameRateSelectionStrategy::DoNotPropagate; + if ((!requested.requestedFrameRate.isValid() && propagationAllowed) || + shouldOverrideChildren) { snapshot.inheritedFrameRate = parentSnapshot.inheritedFrameRate; } else { snapshot.inheritedFrameRate = requested.requestedFrameRate; @@ -828,12 +831,15 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } if (forceUpdate || snapshot.clientChanges & layer_state_t::eFrameRateSelectionStrategyChanged) { - const auto strategy = scheduler::LayerInfo::convertFrameRateSelectionStrategy( - requested.frameRateSelectionStrategy); - snapshot.frameRateSelectionStrategy = - strategy == scheduler::LayerInfo::FrameRateSelectionStrategy::Self - ? parentSnapshot.frameRateSelectionStrategy - : strategy; + if (parentSnapshot.frameRateSelectionStrategy == + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren) { + snapshot.frameRateSelectionStrategy = + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren; + } else { + const auto strategy = scheduler::LayerInfo::convertFrameRateSelectionStrategy( + requested.frameRateSelectionStrategy); + snapshot.frameRateSelectionStrategy = strategy; + } } if (forceUpdate || snapshot.clientChanges & layer_state_t::eFrameRateSelectionPriority) { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f587e9db39..602dae0feb 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1273,14 +1273,15 @@ bool Layer::propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool overr auto now = systemTime(); *transactionNeeded |= setFrameRateForLayerTreeLegacy(frameRate, now); - // The frame rate is propagated to the children + // The frame rate is propagated to the children by default, but some properties may override it. bool childrenHaveFrameRate = false; + const bool overrideChildrenFrameRate = overrideChildren || shouldOverrideChildrenFrameRate(); + const bool canPropagateFrameRate = shouldPropagateFrameRate() || overrideChildrenFrameRate; for (const sp<Layer>& child : mCurrentChildren) { childrenHaveFrameRate |= - child->propagateFrameRateForLayerTree(frameRate, - overrideChildren || - shouldOverrideChildrenFrameRate(), - transactionNeeded); + child->propagateFrameRateForLayerTree(canPropagateFrameRate ? frameRate + : FrameRate(), + overrideChildrenFrameRate, transactionNeeded); } // If we don't have a valid frame rate specification, but the children do, we set this diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 28168c3f65..790dfb569e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -1178,6 +1178,11 @@ private: FrameRateSelectionStrategy::OverrideChildren; } + bool shouldPropagateFrameRate() const { + return getDrawingState().frameRateSelectionStrategy != + FrameRateSelectionStrategy::DoNotPropagate; + } + // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling, which is // a transform from the current layer coordinate space to display(screen) coordinate space. diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index bf3a7bc8b7..db0aebf2a2 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -530,6 +530,8 @@ LayerInfo::FrameRateSelectionStrategy LayerInfo::convertFrameRateSelectionStrate return FrameRateSelectionStrategy::Self; case ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN: return FrameRateSelectionStrategy::OverrideChildren; + case ANATIVEWINDOW_FRAME_RATE_SELECTION_STRATEGY_DO_NOT_PROPAGATE: + return FrameRateSelectionStrategy::DoNotPropagate; default: LOG_ALWAYS_FATAL("Invalid frame rate selection strategy value %d", strategy); return FrameRateSelectionStrategy::Self; diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h index d24fc33491..c7b53fceae 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.h +++ b/services/surfaceflinger/Scheduler/LayerInfo.h @@ -83,8 +83,9 @@ public: enum class FrameRateSelectionStrategy { Self, OverrideChildren, + DoNotPropagate, - ftl_last = OverrideChildren + ftl_last = DoNotPropagate }; // Encapsulates the frame rate specifications of the layer. This information will be used diff --git a/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp b/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp index 20ea0c080a..d791c4a3bc 100644 --- a/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp @@ -49,6 +49,7 @@ protected: const FrameRate FRAME_RATE_VOTE1 = FrameRate(11_Hz, FrameRateCompatibility::Default); const FrameRate FRAME_RATE_VOTE2 = FrameRate(22_Hz, FrameRateCompatibility::Default); const FrameRate FRAME_RATE_VOTE3 = FrameRate(33_Hz, FrameRateCompatibility::Default); + const FrameRate FRAME_RATE_DEFAULT = FrameRate(Fps(), FrameRateCompatibility::Default); const FrameRate FRAME_RATE_TREE = FrameRate(Fps(), FrameRateCompatibility::NoVote); FrameRateSelectionStrategyTest(); @@ -102,7 +103,7 @@ TEST_P(FrameRateSelectionStrategyTest, SetAndGet) { layer->getDrawingState().frameRateSelectionStrategy); } -TEST_P(FrameRateSelectionStrategyTest, SetChildAndGetParent) { +TEST_P(FrameRateSelectionStrategyTest, SetChildOverrideChildren) { EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); const auto& layerFactory = GetParam(); @@ -126,7 +127,7 @@ TEST_P(FrameRateSelectionStrategyTest, SetChildAndGetParent) { child2->getDrawingState().frameRateSelectionStrategy); } -TEST_P(FrameRateSelectionStrategyTest, SetParentAndGet) { +TEST_P(FrameRateSelectionStrategyTest, SetParentOverrideChildren) { EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); const auto& layerFactory = GetParam(); @@ -137,7 +138,6 @@ TEST_P(FrameRateSelectionStrategyTest, SetParentAndGet) { addChild(layer2, layer3); layer1->setFrameRate(FRAME_RATE_VOTE1.vote); - layer1->setFrameRate(FRAME_RATE_VOTE1.vote); layer1->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); layer2->setFrameRate(FRAME_RATE_VOTE2.vote); layer2->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); @@ -168,5 +168,57 @@ TEST_P(FrameRateSelectionStrategyTest, SetParentAndGet) { layer3->getDrawingState().frameRateSelectionStrategy); } +TEST_P(FrameRateSelectionStrategyTest, OverrideChildrenAndDoNotPropagate) { + EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); + + const auto& layerFactory = GetParam(); + auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); + auto layer2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); + auto layer3 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); + addChild(layer1, layer2); + addChild(layer2, layer3); + + layer1->setFrameRate(FRAME_RATE_VOTE1.vote); + layer2->setFrameRate(FRAME_RATE_VOTE2.vote); + layer2->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::DoNotPropagate); + commitTransaction(); + + EXPECT_EQ(FRAME_RATE_VOTE1, layer1->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::Self, + layer1->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_VOTE2, layer2->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::DoNotPropagate, + layer2->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_DEFAULT, layer3->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::Self, + layer3->getDrawingState().frameRateSelectionStrategy); + + layer1->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); + commitTransaction(); + + EXPECT_EQ(FRAME_RATE_VOTE1, layer1->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, + layer1->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_VOTE1, layer2->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::DoNotPropagate, + layer2->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_VOTE1, layer3->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::Self, + layer3->getDrawingState().frameRateSelectionStrategy); + + layer1->setFrameRate(FRAME_RATE_DEFAULT.vote); + commitTransaction(); + + EXPECT_EQ(FRAME_RATE_TREE, layer1->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, + layer1->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_VOTE2, layer2->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::DoNotPropagate, + layer2->getDrawingState().frameRateSelectionStrategy); + EXPECT_EQ(FRAME_RATE_VOTE2, layer3->getFrameRateForLayerTree()); + EXPECT_EQ(FrameRateSelectionStrategy::Self, + layer3->getDrawingState().frameRateSelectionStrategy); +} + } // namespace } // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 16143e3a7f..40d6ad31f4 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -928,6 +928,94 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); } +TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithOverrideChildrenAndDoNotPropagate) { + // ROOT + // ├── 1 + // │ ├── 11 (frame rate set to 11.f with strategy DoNotPropagate) + // │ │ └── 111 (frame rate is not inherited) + // │ ├── 12 (frame rate set to 244.f) + // │ │ ├── 121 + // │ │ └── 122 (strategy OverrideChildren and inherits frame rate 244.f) + // │ │ └── 1221 (frame rate set to 123.f but should be overridden by layer 122) + // │ └── 13 + // └── 2 + setFrameRate(11, 11.f, 0, 0); + setFrameRateSelectionStrategy(11, 2 /* DoNotPropagate */); + setFrameRate(12, 244.f, 0, 0); + setFrameRateSelectionStrategy(122, 1 /* OverrideChildren */); + setFrameRate(1221, 123.f, 0, 0); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + // verify parent 1 gets no vote + EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, + scheduler::FrameRateCompatibility::NoVote); + EXPECT_EQ(getSnapshot({.id = 1})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 11.f); + EXPECT_EQ(getSnapshot({.id = 11})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::DoNotPropagate); + EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 11 does does not propagate its framerate to 111. + EXPECT_FALSE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); + EXPECT_EQ(getSnapshot({.id = 111})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 12 and all descendants (121, 122, 1221) get the requested vote + EXPECT_EQ(getSnapshot({.id = 12})->frameRate.vote.rate.getValue(), 244.f); + EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 121})->frameRate.vote.rate.getValue(), 244.f); + EXPECT_EQ(getSnapshot({.id = 121})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::Self); + EXPECT_TRUE(getSnapshot({.id = 121})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 244.f); + EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.rate.getValue(), 244.f); + EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // ROOT + // ├── 1 (frame rate set to 1.f with strategy OverrideChildren) + // │ ├── 11 (frame rate set to 11.f with strategy DoNotPropagate, but overridden by 1) + // │ │ └── 111 (frame rate inherited from 11 due to override from 1) + // ⋮ ⋮ + setFrameRate(1, 1.f, 0, 0); + setFrameRateSelectionStrategy(1, 1 /* OverrideChildren */); + setFrameRate(11, 11.f, 0, 0); + setFrameRateSelectionStrategy(11, 2 /* DoNotPropagate */); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.rate.getValue(), 1.f); + EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, + scheduler::FrameRateCompatibility::Default); + EXPECT_EQ(getSnapshot({.id = 1})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); + + EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 1.f); + EXPECT_EQ(getSnapshot({.id = 11})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate)); + + // verify layer 11 does does not propagate its framerate to 111. + EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 1.f); + EXPECT_EQ(getSnapshot({.id = 111})->frameRateSelectionStrategy, + scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren); + EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate)); +} + TEST_F(LayerSnapshotTest, skipRoundCornersWhenProtected) { setRoundedCorners(1, 42.f); setRoundedCorners(2, 42.f); |