Propagate frame rate correctly to child layers
If a child layer has a valid frame rate, and its parent does not
have a valid frame rate, we need to override the parent's frame
rate to no vote.
If the parent has a valid vote, including no vote, children would
inherit this vote if it has no valid vote.
When we were updating the hierarchy, we incorrectly propagated
novote due to a child having a novote to all its siblings in the tree.
Fix this by tracking inherited frame rate separately.
Bug: 304208511
Test: presubmit
Change-Id: I873e75d678fba8c8217a1887f48726d1e4828049
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 80a51ea..59ccf96 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -84,6 +84,7 @@
bool isTrustedOverlay;
gui::GameMode gameMode;
scheduler::LayerInfo::FrameRate frameRate;
+ scheduler::LayerInfo::FrameRate inheritedFrameRate;
scheduler::LayerInfo::FrameRateSelectionStrategy frameRateSelectionStrategy;
scheduler::FrameRateCompatibility defaultFrameRateCompatibility =
scheduler::FrameRateCompatibility::Default;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 4db2b66..2a0857d 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -815,9 +815,14 @@
RequestedLayerState::Changes::Hierarchy)) {
bool shouldOverrideChildren = parentSnapshot.frameRateSelectionStrategy ==
scheduler::LayerInfo::FrameRateSelectionStrategy::OverrideChildren;
- snapshot.frameRate = !requested.requestedFrameRate.isValid() || shouldOverrideChildren
- ? parentSnapshot.frameRate
- : requested.requestedFrameRate;
+ if (!requested.requestedFrameRate.isValid() || shouldOverrideChildren) {
+ snapshot.inheritedFrameRate = parentSnapshot.inheritedFrameRate;
+ } else {
+ snapshot.inheritedFrameRate = requested.requestedFrameRate;
+ }
+ // Set the framerate as the inherited frame rate and allow children to override it if
+ // needed.
+ snapshot.frameRate = snapshot.inheritedFrameRate;
snapshot.changes |= RequestedLayerState::Changes::FrameRate;
}
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index fc4bb22..e784eb7 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -282,17 +282,7 @@
// │ └── 13
// └── 2
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged;
- transactions.back().states.front().state.frameRate = 90.0;
- transactions.back().states.front().state.frameRateCompatibility =
- ANATIVEWINDOW_FRAME_RATE_EXACT;
- transactions.back().states.front().state.changeFrameRateStrategy =
- ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS;
- transactions.back().states.front().layerId = 11;
- mLifecycleManager.applyTransactions(transactions);
+ setFrameRate(11, 90.0, ANATIVEWINDOW_FRAME_RATE_EXACT, ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS);
UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
EXPECT_EQ(getSnapshot(11)->frameRate.vote.rate.getIntValue(), 90);
@@ -303,6 +293,42 @@
EXPECT_EQ(getSnapshot(1)->frameRate.vote.type, scheduler::FrameRateCompatibility::NoVote);
}
+TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotesDoesNotAffectSiblings) {
+ // ROOT
+ // ├── 1 (verify layer has no vote)
+ // │ ├── 11 (frame rate set)
+ // │ │ └── 111
+ // │ ├── 12 (frame rate set)
+ // │ │ ├── 121
+ // │ │ └── 122
+ // │ │ └── 1221
+ // │ └── 13 (verify layer has default vote)
+ // └── 2
+
+ setFrameRate(11, 90.0, ANATIVEWINDOW_FRAME_RATE_EXACT, ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS);
+ setFrameRate(12, 45.0, ANATIVEWINDOW_FRAME_RATE_EXACT, ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS);
+
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+
+ EXPECT_EQ(getSnapshot(11)->frameRate.vote.rate.getIntValue(), 90);
+ EXPECT_EQ(getSnapshot(11)->frameRate.vote.type, scheduler::FrameRateCompatibility::Exact);
+ EXPECT_EQ(getSnapshot(111)->frameRate.vote.rate.getIntValue(), 90);
+ EXPECT_EQ(getSnapshot(111)->frameRate.vote.type, scheduler::FrameRateCompatibility::Exact);
+ EXPECT_EQ(getSnapshot(12)->frameRate.vote.rate.getIntValue(), 45);
+ EXPECT_EQ(getSnapshot(12)->frameRate.vote.type, scheduler::FrameRateCompatibility::Exact);
+ EXPECT_EQ(getSnapshot(121)->frameRate.vote.rate.getIntValue(), 45);
+ EXPECT_EQ(getSnapshot(121)->frameRate.vote.type, scheduler::FrameRateCompatibility::Exact);
+ EXPECT_EQ(getSnapshot(1221)->frameRate.vote.rate.getIntValue(), 45);
+ EXPECT_EQ(getSnapshot(1221)->frameRate.vote.type, scheduler::FrameRateCompatibility::Exact);
+
+ EXPECT_EQ(getSnapshot(1)->frameRate.vote.rate.getIntValue(), 0);
+ EXPECT_EQ(getSnapshot(1)->frameRate.vote.type, scheduler::FrameRateCompatibility::NoVote);
+ EXPECT_EQ(getSnapshot(13)->frameRate.vote.rate.getIntValue(), 0);
+ EXPECT_EQ(getSnapshot(13)->frameRate.vote.type, scheduler::FrameRateCompatibility::Default);
+ EXPECT_EQ(getSnapshot(2)->frameRate.vote.rate.getIntValue(), 0);
+ EXPECT_EQ(getSnapshot(2)->frameRate.vote.type, scheduler::FrameRateCompatibility::Default);
+}
+
TEST_F(LayerSnapshotTest, CanCropTouchableRegion) {
// ROOT
// ├── 1