diff options
| author | 2024-03-15 01:35:35 +0000 | |
|---|---|---|
| committer | 2024-03-15 01:35:35 +0000 | |
| commit | 9672eff8020cbe884c3d8141966e96711d63eec2 (patch) | |
| tree | f5e139353667d2ac593d3ffe9d062671d158025a | |
| parent | e26310e499d36f2c869acfd559a095733014c954 (diff) | |
| parent | 19f01d0e17ab896e3a5ab1f90608175ffca95718 (diff) | |
Merge "NoPreference frame rate category is no-op" into main
| -rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateSelector.cpp | 18 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp | 143 |
2 files changed, 147 insertions, 14 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp index ad59f1a574..56c29e2574 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp @@ -506,6 +506,8 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi } int noVoteLayers = 0; + // Layers that prefer the same mode ("no-op"). + int noPreferenceLayers = 0; int minVoteLayers = 0; int maxVoteLayers = 0; int explicitDefaultVoteLayers = 0; @@ -549,10 +551,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi explicitCategoryVoteLayers++; } if (layer.frameRateCategory == FrameRateCategory::NoPreference) { - // Count this layer for Min vote as well. The explicit vote avoids - // touch boost and idle for choosing a category, while Min vote is for correct - // behavior when all layers are Min or no vote. - minVoteLayers++; + noPreferenceLayers++; } break; case LayerVoteType::Heuristic: @@ -612,6 +611,16 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi return {ranking, kNoSignals}; } + // If all layers are category NoPreference, use the current config. + if (noPreferenceLayers + noVoteLayers == layers.size()) { + ALOGV("All layers NoPreference"); + const auto ascendingWithPreferred = + rankFrameRates(anchorGroup, RefreshRateOrder::Ascending, activeMode.getId()); + ATRACE_FORMAT_INSTANT("%s (All layers NoPreference)", + to_string(ascendingWithPreferred.front().frameRateMode.fps).c_str()); + return {ascendingWithPreferred, kNoSignals}; + } + const bool smoothSwitchOnly = categorySmoothSwitchOnlyLayers > 0; const DisplayModeId activeModeId = activeMode.getId(); @@ -643,6 +652,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi ftl::enum_string(layer.frameRateCategory).c_str()); if (layer.isNoVote() || layer.frameRateCategory == FrameRateCategory::NoPreference || layer.vote == LayerVoteType::Min) { + ALOGV("%s scoring skipped due to vote", formatLayerInfo(layer, layer.weight).c_str()); continue; } diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp index fe0e3d11ae..a155f5da74 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp @@ -295,6 +295,12 @@ protected: << "Did not get expected frame rate for frameRate=" << to_string(testCase.desiredFrameRate) << " category=" << ftl::enum_string(testCase.frameRateCategory); + EXPECT_EQ(testCase.expectedModeId, + selector.getBestFrameRateMode(layers).modePtr->getId()) + << "Did not get expected DisplayModeId for modeId=" + << ftl::to_underlying(testCase.expectedModeId) + << " frameRate=" << to_string(testCase.desiredFrameRate) + << " category=" << ftl::enum_string(testCase.frameRateCategory); } } }; @@ -1534,7 +1540,7 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_30_60 {0_Hz, FrameRateCategory::High, 90_Hz}, {0_Hz, FrameRateCategory::Normal, 60_Hz}, {0_Hz, FrameRateCategory::Low, 30_Hz}, - {0_Hz, FrameRateCategory::NoPreference, 30_Hz}, + {0_Hz, FrameRateCategory::NoPreference, 60_Hz}, // Cases that have both desired frame rate and frame rate category requirements. {24_Hz, FrameRateCategory::High, 120_Hz}, @@ -1591,6 +1597,7 @@ TEST_P(RefreshRateSelectorTest, // Expected result Fps expectedFrameRate = 0_Hz; + DisplayModeId expectedModeId = kModeId90; }; testFrameRateCategoryWithMultipleLayers( @@ -1605,7 +1612,7 @@ TEST_P(RefreshRateSelectorTest, testFrameRateCategoryWithMultipleLayers( std::initializer_list<Case>{ - {0_Hz, FrameRateCategory::Normal, 60_Hz}, + {0_Hz, FrameRateCategory::Normal, 60_Hz, kModeId60}, {0_Hz, FrameRateCategory::High, 90_Hz}, {0_Hz, FrameRateCategory::NoPreference, 90_Hz}, }, @@ -1614,18 +1621,18 @@ TEST_P(RefreshRateSelectorTest, testFrameRateCategoryWithMultipleLayers( std::initializer_list<Case>{ {30_Hz, FrameRateCategory::High, 90_Hz}, - {24_Hz, FrameRateCategory::High, 120_Hz}, - {12_Hz, FrameRateCategory::Normal, 120_Hz}, - {30_Hz, FrameRateCategory::NoPreference, 120_Hz}, + {24_Hz, FrameRateCategory::High, 120_Hz, kModeId120}, + {12_Hz, FrameRateCategory::Normal, 120_Hz, kModeId120}, + {30_Hz, FrameRateCategory::NoPreference, 120_Hz, kModeId120}, }, selector); testFrameRateCategoryWithMultipleLayers( std::initializer_list<Case>{ - {24_Hz, FrameRateCategory::Default, 120_Hz}, - {30_Hz, FrameRateCategory::Default, 120_Hz}, - {120_Hz, FrameRateCategory::Default, 120_Hz}, + {24_Hz, FrameRateCategory::Default, 120_Hz, kModeId120}, + {30_Hz, FrameRateCategory::Default, 120_Hz, kModeId120}, + {120_Hz, FrameRateCategory::Default, 120_Hz, kModeId120}, }, selector); } @@ -1640,6 +1647,7 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategoryMultiL // Expected result Fps expectedFrameRate = 0_Hz; + DisplayModeId expectedModeId = kModeId120; }; testFrameRateCategoryWithMultipleLayers(std::initializer_list< @@ -1970,6 +1978,122 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_Touch } TEST_P(RefreshRateSelectorTest, + getBestFrameRateMode_withFrameRateCategory_idleTimer_60_120_nonVrr) { + SET_FLAG_FOR_TEST(flags::vrr_config, false); + using KernelIdleTimerAction = RefreshRateSelector::KernelIdleTimerAction; + struct LayerArg { + // Params + FrameRateCategory frameRateCategory = FrameRateCategory::Default; + LayerVoteType voteType = LayerVoteType::ExplicitDefault; + + // Expected result + Fps expectedFrameRate = 0_Hz; + DisplayModeId expectedModeId = kModeId60; + }; + + const auto runTest = [&](const TestableRefreshRateSelector& selector, + const std::initializer_list<LayerArg>& layerArgs, + const RefreshRateSelector::GlobalSignals& signals) { + std::vector<LayerRequirement> layers; + for (auto testCase : layerArgs) { + ALOGI("**** %s: Testing frameRateCategory=%s", __func__, + ftl::enum_string(testCase.frameRateCategory).c_str()); + + if (testCase.frameRateCategory != FrameRateCategory::Default) { + std::stringstream ss; + ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")"; + LayerRequirement layer = {.name = ss.str(), + .vote = LayerVoteType::ExplicitCategory, + .frameRateCategory = testCase.frameRateCategory, + .weight = 1.f}; + layers.push_back(layer); + } + + if (testCase.voteType != LayerVoteType::ExplicitDefault) { + std::stringstream ss; + ss << ftl::enum_string(testCase.voteType); + LayerRequirement layer = {.name = ss.str(), + .vote = testCase.voteType, + .weight = 1.f}; + layers.push_back(layer); + } + + EXPECT_EQ(testCase.expectedFrameRate, + selector.getBestFrameRateMode(layers, signals).modePtr->getPeakFps()) + << "Did not get expected frame rate for" + << " category=" << ftl::enum_string(testCase.frameRateCategory); + EXPECT_EQ(testCase.expectedModeId, + selector.getBestFrameRateMode(layers, signals).modePtr->getId()) + << "Did not get expected DisplayModeId for modeId=" + << ftl::to_underlying(testCase.expectedModeId) + << " category=" << ftl::enum_string(testCase.frameRateCategory); + } + }; + + { + // IdleTimer not configured + auto selector = createSelector(makeModes(kMode60, kMode120), kModeId120); + ASSERT_EQ(0ms, selector.getIdleTimerTimeout()); + + runTest(selector, + std::initializer_list<LayerArg>{ + // Rate does not change due to NoPreference. + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + {.voteType = LayerVoteType::NoVote, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + }, + {.idle = false}); + } + + // IdleTimer configured + constexpr std::chrono::milliseconds kIdleTimerTimeoutMs = 10ms; + auto selector = createSelector(makeModes(kMode60, kMode120), kModeId120, + Config{ + .idleTimerTimeout = kIdleTimerTimeoutMs, + }); + ASSERT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); + ASSERT_EQ(kIdleTimerTimeoutMs, selector.getIdleTimerTimeout()); + runTest(selector, + std::initializer_list<LayerArg>{ + // Rate won't change immediately and will stay 120 due to NoPreference, as + // idle timer did not timeout yet. + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + {.voteType = LayerVoteType::NoVote, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 120_Hz, + .expectedModeId = kModeId120}, + }, + {.idle = false}); + + // Idle timer is triggered using GlobalSignals. + ASSERT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); + ASSERT_EQ(kIdleTimerTimeoutMs, selector.getIdleTimerTimeout()); + runTest(selector, + std::initializer_list<LayerArg>{ + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 60_Hz, + .expectedModeId = kModeId60}, + {.voteType = LayerVoteType::NoVote, + .expectedFrameRate = 60_Hz, + .expectedModeId = kModeId60}, + {.frameRateCategory = FrameRateCategory::NoPreference, + .expectedFrameRate = 60_Hz, + .expectedModeId = kModeId60}, + }, + {.idle = true}); +} + +TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_smoothSwitchOnly_60_120_nonVrr) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; @@ -1992,8 +2116,7 @@ TEST_P(RefreshRateSelectorTest, const std::initializer_list<Case> testCases = { // These layers may switch modes because smoothSwitchOnly=false. {FrameRateCategory::Default, false, 120_Hz, kModeId120}, - // TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate. - {FrameRateCategory::NoPreference, false, 60_Hz, kModeId60}, + {FrameRateCategory::NoPreference, false, 120_Hz, kModeId120}, {FrameRateCategory::Low, false, 30_Hz, kModeId60}, {FrameRateCategory::Normal, false, 60_Hz, kModeId60}, {FrameRateCategory::High, false, 120_Hz, kModeId120}, |