Fix HighHint touch signal for override.
Frame rate override was triggering even as HighHint was using touch
boost behavior in RefreshRateSelector, because the global touch signal
was not set to true. Thus set it to true, and it will not override the
touch boost.
Bug: 321107394
Test: atest libsurfaceflinger_unittest
Test: Manual youtube test and scrolling
Test: manual sysui testing
Change-Id: Ib150663db7d2f304154cf2beab9da22bb44d5d88
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 7614453..bdeff8d 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -854,7 +854,7 @@
ALOGV("Touch Boost");
ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])",
to_string(touchRefreshRates.front().frameRateMode.fps).c_str());
- return {touchRefreshRates, GlobalSignals{.touch = signals.touch}};
+ return {touchRefreshRates, GlobalSignals{.touch = true}};
}
// If we never scored any layers, and we don't favor high refresh rates, prefer to stay with the
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index c03cbd7..39a8aac 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -103,7 +103,7 @@
auto& mutableGetRankedRefreshRatesCache() { return mGetRankedFrameRatesCache; }
auto getRankedFrameRates(const std::vector<LayerRequirement>& layers,
- GlobalSignals signals) const {
+ GlobalSignals signals = {}) const {
const auto result = RefreshRateSelector::getRankedFrameRates(layers, signals);
EXPECT_TRUE(std::is_sorted(result.ranking.begin(), result.ranking.end(),
@@ -1619,10 +1619,11 @@
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
- auto actualFrameRateMode = selector.getBestFrameRateMode(layers);
+ auto actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
- EXPECT_EQ(120_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId120, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
// No touch boost, for example a game that uses setFrameRate(30, default compatibility).
lr1.vote = LayerVoteType::ExplicitCategory;
@@ -1631,9 +1632,10 @@
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitDefault";
- actualFrameRateMode = selector.getBestFrameRateMode(layers);
- EXPECT_EQ(30_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId30, actualFrameRateMode.modePtr->getId());
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ EXPECT_EQ(30_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
@@ -1641,10 +1643,11 @@
lr2.vote = LayerVoteType::ExplicitCategory;
lr2.frameRateCategory = FrameRateCategory::HighHint;
lr2.name = "ExplicitCategory HighHint#2";
- actualFrameRateMode = selector.getBestFrameRateMode(layers);
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
- EXPECT_EQ(120_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId120, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
@@ -1652,10 +1655,11 @@
lr2.vote = LayerVoteType::ExplicitCategory;
lr2.frameRateCategory = FrameRateCategory::Low;
lr2.name = "ExplicitCategory Low";
- actualFrameRateMode = selector.getBestFrameRateMode(layers);
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
- EXPECT_EQ(120_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId120, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
@@ -1663,10 +1667,11 @@
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitExactOrMultiple";
- actualFrameRateMode = selector.getBestFrameRateMode(layers);
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
- EXPECT_EQ(120_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId120, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
@@ -1674,14 +1679,17 @@
lr2.vote = LayerVoteType::ExplicitExact;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitExact";
- actualFrameRateMode = selector.getBestFrameRateMode(layers);
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
if (selector.supportsAppFrameRateOverrideByContent()) {
// Gets touch boost
- EXPECT_EQ(120_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId120, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId120,
+ actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
} else {
- EXPECT_EQ(30_Hz, actualFrameRateMode.fps);
- EXPECT_EQ(kModeId30, actualFrameRateMode.modePtr->getId());
+ EXPECT_EQ(30_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+ EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
+ EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch);
}
}
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 10c5848..b059525 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -339,6 +339,61 @@
EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
}
+TEST_F(SchedulerTest, chooseDisplayModesSingleDisplayHighHintTouchSignal) {
+ mScheduler->registerDisplay(kDisplayId1,
+ std::make_shared<RefreshRateSelector>(kDisplay1Modes,
+ kDisplay1Mode60->getId()));
+
+ using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
+
+ std::vector<RefreshRateSelector::LayerRequirement> layers =
+ std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
+ auto& lr1 = layers[0];
+ auto& lr2 = layers[1];
+
+ // Scenario that is similar to game. Expects no touch boost.
+ lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
+ lr1.frameRateCategory = FrameRateCategory::HighHint;
+ lr1.name = "ExplicitCategory HighHint";
+ lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitDefault;
+ lr2.desiredRefreshRate = 30_Hz;
+ lr2.name = "30Hz ExplicitDefault";
+ mScheduler->setContentRequirements(layers);
+ auto modeChoices = mScheduler->chooseDisplayModes();
+ ASSERT_EQ(1u, modeChoices.size());
+ auto choice = modeChoices.get(kDisplayId1);
+ ASSERT_TRUE(choice);
+ EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, {.touch = false}));
+
+ // Scenario that is similar to video playback and interaction. Expects touch boost.
+ lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
+ lr1.frameRateCategory = FrameRateCategory::HighHint;
+ lr1.name = "ExplicitCategory HighHint";
+ lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitExactOrMultiple;
+ lr2.desiredRefreshRate = 30_Hz;
+ lr2.name = "30Hz ExplicitExactOrMultiple";
+ mScheduler->setContentRequirements(layers);
+ modeChoices = mScheduler->chooseDisplayModes();
+ ASSERT_EQ(1u, modeChoices.size());
+ choice = modeChoices.get(kDisplayId1);
+ ASSERT_TRUE(choice);
+ EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
+
+ // Scenario with explicit category and HighHint. Expects touch boost.
+ lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
+ lr1.frameRateCategory = FrameRateCategory::HighHint;
+ lr1.name = "ExplicitCategory HighHint";
+ lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
+ lr2.frameRateCategory = FrameRateCategory::Low;
+ lr2.name = "ExplicitCategory Low";
+ mScheduler->setContentRequirements(layers);
+ modeChoices = mScheduler->chooseDisplayModes();
+ ASSERT_EQ(1u, modeChoices.size());
+ choice = modeChoices.get(kDisplayId1);
+ ASSERT_TRUE(choice);
+ EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
+}
+
TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
mScheduler->registerDisplay(kDisplayId1,
std::make_shared<RefreshRateSelector>(kDisplay1Modes,