Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -834,13 +834,16 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const bool touchBoostForExplicitExact = [&] { if (supportsAppFrameRateOverrideByContent()) { // Enable touch boost if there are other layers besides exact return explicitExact + noVoteLayers != layers.size(); return explicitExact + noVoteLayers + explicitGteLayers != layers.size(); } else { // Enable touch boost if there are no exact layers return explicitExact == 0; } }(); const bool touchBoostForCategory = explicitCategoryVoteLayers + noVoteLayers + explicitGteLayers != layers.size(); const auto touchRefreshRates = rankFrameRates(anchorGroup, RefreshRateOrder::Descending); using fps_approx_ops::operator<; Loading @@ -851,6 +854,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const bool hasInteraction = signals.touch || interactiveLayers > 0; if (hasInteraction && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact && touchBoostForCategory && scores.front().frameRateMode.fps < touchRefreshRates.front().frameRateMode.fps) { ALOGV("Touch Boost"); ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])", Loading services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +148 −0 Original line number Diff line number Diff line Loading @@ -1665,6 +1665,7 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_HighH lr1.frameRateCategory = FrameRateCategory::HighHint; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.frameRateCategory = FrameRateCategory::Default; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExactOrMultiple"; actualRankedFrameRates = selector.getRankedFrameRates(layers); Loading @@ -1691,6 +1692,153 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_HighH EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId()); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::HighHint; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz Heuristic"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost 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; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Min; lr2.name = "Min"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost 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; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps); EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId()); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_TouchBoost) { auto selector = createSelector(makeModes(kMode24, kMode30, kMode60, kMode120), kModeId60); std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; auto actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); // No touch boost, for example a game that uses setFrameRate(30, default compatibility). lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitDefault; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitDefault"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitCategory; lr2.frameRateCategory = FrameRateCategory::HighHint; lr2.name = "ExplicitCategory HighHint"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitCategory; lr2.frameRateCategory = FrameRateCategory::Low; lr2.name = "ExplicitCategory Low"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.frameRateCategory = FrameRateCategory::Default; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExactOrMultiple"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitExact; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExact"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); if (selector.supportsAppFrameRateOverrideByContent()) { EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); } else { EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Min; lr2.name = "Min"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Heuristic; lr2.name = "30Hz Heuristic"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitGte; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitGte"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } TEST_P(RefreshRateSelectorTest, Loading Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -834,13 +834,16 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const bool touchBoostForExplicitExact = [&] { if (supportsAppFrameRateOverrideByContent()) { // Enable touch boost if there are other layers besides exact return explicitExact + noVoteLayers != layers.size(); return explicitExact + noVoteLayers + explicitGteLayers != layers.size(); } else { // Enable touch boost if there are no exact layers return explicitExact == 0; } }(); const bool touchBoostForCategory = explicitCategoryVoteLayers + noVoteLayers + explicitGteLayers != layers.size(); const auto touchRefreshRates = rankFrameRates(anchorGroup, RefreshRateOrder::Descending); using fps_approx_ops::operator<; Loading @@ -851,6 +854,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const bool hasInteraction = signals.touch || interactiveLayers > 0; if (hasInteraction && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact && touchBoostForCategory && scores.front().frameRateMode.fps < touchRefreshRates.front().frameRateMode.fps) { ALOGV("Touch Boost"); ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])", Loading
services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +148 −0 Original line number Diff line number Diff line Loading @@ -1665,6 +1665,7 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_HighH lr1.frameRateCategory = FrameRateCategory::HighHint; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.frameRateCategory = FrameRateCategory::Default; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExactOrMultiple"; actualRankedFrameRates = selector.getRankedFrameRates(layers); Loading @@ -1691,6 +1692,153 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_HighH EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId()); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::HighHint; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz Heuristic"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost 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; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Min; lr2.name = "Min"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost 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; lr1.name = "ExplicitCategory HighHint"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; actualRankedFrameRates = selector.getRankedFrameRates(layers); // Gets touch boost EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps); EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId()); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_TouchBoost) { auto selector = createSelector(makeModes(kMode24, kMode30, kMode60, kMode120), kModeId60); std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; auto actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); // No touch boost, for example a game that uses setFrameRate(30, default compatibility). lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitDefault; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitDefault"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitCategory; lr2.frameRateCategory = FrameRateCategory::HighHint; lr2.name = "ExplicitCategory HighHint"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitCategory; lr2.frameRateCategory = FrameRateCategory::Low; lr2.name = "ExplicitCategory Low"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.frameRateCategory = FrameRateCategory::Default; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExactOrMultiple"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitExact; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitExact"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); if (selector.supportsAppFrameRateOverrideByContent()) { EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); } else { EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Min; lr2.name = "Min"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::Heuristic; lr2.name = "30Hz Heuristic"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitCategory; lr1.frameRateCategory = FrameRateCategory::Normal; lr1.name = "ExplicitCategory Normal"; lr2.vote = LayerVoteType::ExplicitGte; lr2.desiredRefreshRate = 30_Hz; lr2.name = "30Hz ExplicitGte"; actualRankedFrameRates = selector.getRankedFrameRates(layers, {.touch = true}); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, actualRankedFrameRates.ranking.front().frameRateMode); EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch); } TEST_P(RefreshRateSelectorTest, Loading