/* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "SchedulerUnittests" #include #include #include #include #include #include #include #include #include "DisplayHardware/HWC2.h" #include "FpsOps.h" #include "Scheduler/RefreshRateSelector.h" #include "mock/DisplayHardware/MockDisplayMode.h" #include "mock/MockFrameRateMode.h" #include "libsurfaceflinger_unittest_main.h" using namespace std::chrono_literals; namespace android::scheduler { namespace hal = android::hardware::graphics::composer::hal; using Config = RefreshRateSelector::Config; using LayerRequirement = RefreshRateSelector::LayerRequirement; using LayerVoteType = RefreshRateSelector::LayerVoteType; using SetPolicyResult = RefreshRateSelector::SetPolicyResult; using mock::createDisplayMode; struct TestableRefreshRateSelector : RefreshRateSelector { using RefreshRateSelector::FrameRateRanking; using RefreshRateSelector::RefreshRateOrder; using RefreshRateSelector::RefreshRateSelector; void setActiveMode(DisplayModeId modeId, Fps renderFrameRate) { ftl::FakeGuard guard(kMainThreadContext); return RefreshRateSelector::setActiveMode(modeId, renderFrameRate); } const DisplayMode& getActiveMode() const { std::lock_guard lock(mLock); return *RefreshRateSelector::getActiveModeLocked().modePtr; } ftl::NonNull getMinSupportedRefreshRate() const { std::lock_guard lock(mLock); return ftl::as_non_null(mMinRefreshRateModeIt->second); } ftl::NonNull getMaxSupportedRefreshRate() const { std::lock_guard lock(mLock); return ftl::as_non_null(mMaxRefreshRateModeIt->second); } ftl::NonNull getMinRefreshRateByPolicy() const { std::lock_guard lock(mLock); return ftl::as_non_null(getMinRefreshRateByPolicyLocked()); } ftl::NonNull getMaxRefreshRateByPolicy() const { std::lock_guard lock(mLock); return ftl::as_non_null( getMaxRefreshRateByPolicyLocked(getActiveModeLocked().modePtr->getGroup())); } FrameRateRanking rankRefreshRates(std::optional anchorGroupOpt, RefreshRateOrder refreshRateOrder) const { std::lock_guard lock(mLock); return RefreshRateSelector::rankFrameRates(anchorGroupOpt, refreshRateOrder); } const std::vector& knownFrameRates() const { return mKnownFrameRates; } using RefreshRateSelector::GetRankedFrameRatesCache; auto& mutableGetRankedRefreshRatesCache() { return mGetRankedFrameRatesCache; } auto getRankedFrameRates(const std::vector& layers, GlobalSignals signals) const { const auto result = RefreshRateSelector::getRankedFrameRates(layers, signals); EXPECT_TRUE(std::is_sorted(result.ranking.begin(), result.ranking.end(), ScoredFrameRate::DescendingScore{})); return result; } auto getRankedRefreshRatesAsPair(const std::vector& layers, GlobalSignals signals) const { const auto [ranking, consideredSignals] = getRankedFrameRates(layers, signals); return std::make_pair(ranking, consideredSignals); } ftl::NonNull getBestFrameRateMode( const std::vector& layers = {}, GlobalSignals signals = {}) const { return getRankedFrameRates(layers, signals).ranking.front().frameRateMode.modePtr; } ScoredFrameRate getBestScoredFrameRate(const std::vector& layers = {}, GlobalSignals signals = {}) const { return getRankedFrameRates(layers, signals).ranking.front(); } SetPolicyResult setPolicy(const PolicyVariant& policy) { ftl::FakeGuard guard(kMainThreadContext); return RefreshRateSelector::setPolicy(policy); } SetPolicyResult setDisplayManagerPolicy(const DisplayManagerPolicy& policy) { return setPolicy(policy); } const auto& getPrimaryFrameRates() const { return mPrimaryFrameRates; } }; class RefreshRateSelectorTest : public testing::TestWithParam { protected: using RefreshRateOrder = TestableRefreshRateSelector::RefreshRateOrder; RefreshRateSelectorTest(); ~RefreshRateSelectorTest(); static constexpr DisplayModeId kModeId60{0}; static constexpr DisplayModeId kModeId90{1}; static constexpr DisplayModeId kModeId72{2}; static constexpr DisplayModeId kModeId120{3}; static constexpr DisplayModeId kModeId30{4}; static constexpr DisplayModeId kModeId25{5}; static constexpr DisplayModeId kModeId50{6}; static constexpr DisplayModeId kModeId24{7}; static constexpr DisplayModeId kModeId24Frac{8}; static constexpr DisplayModeId kModeId30Frac{9}; static constexpr DisplayModeId kModeId60Frac{10}; static constexpr DisplayModeId kModeId35{11}; static constexpr DisplayModeId kModeId1{12}; static constexpr DisplayModeId kModeId5{13}; static constexpr DisplayModeId kModeId10{14}; static inline const ftl::NonNull kMode60 = ftl::as_non_null(createDisplayMode(kModeId60, 60_Hz)); static inline const ftl::NonNull kMode60Frac = ftl::as_non_null(createDisplayMode(kModeId60Frac, 59.94_Hz)); static inline const ftl::NonNull kMode90 = ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz)); static inline const ftl::NonNull kMode90_G1 = ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 1)); static inline const ftl::NonNull kMode90_4K = ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160})); static inline const ftl::NonNull kMode72 = ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz)); static inline const ftl::NonNull kMode72_G1 = ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz, 1)); static inline const ftl::NonNull kMode120 = ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz)); static inline const ftl::NonNull kMode120_G1 = ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz, 1)); static inline const ftl::NonNull kMode30 = ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz)); static inline const ftl::NonNull kMode30_G1 = ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz, 1)); static inline const ftl::NonNull kMode30Frac = ftl::as_non_null(createDisplayMode(kModeId30Frac, 29.97_Hz)); static inline const ftl::NonNull kMode25 = ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz)); static inline const ftl::NonNull kMode25_G1 = ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz, 1)); static inline const ftl::NonNull kMode35 = ftl::as_non_null(createDisplayMode(kModeId35, 35_Hz)); static inline const ftl::NonNull kMode50 = ftl::as_non_null(createDisplayMode(kModeId50, 50_Hz)); static inline const ftl::NonNull kMode24 = ftl::as_non_null(createDisplayMode(kModeId24, 24_Hz)); static inline const ftl::NonNull kMode24Frac = ftl::as_non_null(createDisplayMode(kModeId24Frac, 23.976_Hz)); static inline const ftl::NonNull kMode1 = ftl::as_non_null(createDisplayMode(kModeId1, 1_Hz)); static inline const ftl::NonNull kMode5 = ftl::as_non_null(createDisplayMode(kModeId5, 5_Hz)); static inline const ftl::NonNull kMode10 = ftl::as_non_null(createDisplayMode(kModeId10, 10_Hz)); // Test configurations. static inline const DisplayModes kModes_60 = makeModes(kMode60); static inline const DisplayModes kModes_35_60_90 = makeModes(kMode35, kMode60, kMode90); static inline const DisplayModes kModes_60_90 = makeModes(kMode60, kMode90); static inline const DisplayModes kModes_60_90_G1 = makeModes(kMode60, kMode90_G1); static inline const DisplayModes kModes_60_90_4K = makeModes(kMode60, kMode90_4K); static inline const DisplayModes kModes_60_72_90 = makeModes(kMode60, kMode90, kMode72); static inline const DisplayModes kModes_60_90_72_120 = makeModes(kMode60, kMode90, kMode72, kMode120); static inline const DisplayModes kModes_30_60_72_90_120 = makeModes(kMode60, kMode90, kMode72, kMode120, kMode30); static inline const DisplayModes kModes_30_60 = makeModes(kMode60, kMode90_G1, kMode72_G1, kMode120_G1, kMode30); static inline const DisplayModes kModes_30_60_72_90 = makeModes(kMode60, kMode90, kMode72, kMode120_G1, kMode30); static inline const DisplayModes kModes_30_60_90 = makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30); static inline const DisplayModes kModes_25_30_50_60 = makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30_G1, kMode25_G1, kMode50); static inline const DisplayModes kModes_60_120 = makeModes(kMode60, kMode120); static inline const DisplayModes kModes_1_5_10 = makeModes(kMode1, kMode5, kMode10); // This is a typical TV configuration. static inline const DisplayModes kModes_24_25_30_50_60_Frac = makeModes(kMode24, kMode24Frac, kMode25, kMode30, kMode30Frac, kMode50, kMode60, kMode60Frac); static TestableRefreshRateSelector createSelector(DisplayModes modes, DisplayModeId activeModeId, Config config = {}) { config.enableFrameRateOverride = GetParam(); return TestableRefreshRateSelector(modes, activeModeId, config); } }; RefreshRateSelectorTest::RefreshRateSelectorTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); } RefreshRateSelectorTest::~RefreshRateSelectorTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } namespace { INSTANTIATE_TEST_SUITE_P(PerOverrideConfig, RefreshRateSelectorTest, testing::Values(Config::FrameRateOverride::Disabled, Config::FrameRateOverride::AppOverrideNativeRefreshRates, Config::FrameRateOverride::AppOverride, Config::FrameRateOverride::Enabled)); TEST_P(RefreshRateSelectorTest, oneMode_canSwitch) { auto selector = createSelector(kModes_60, kModeId60); if (GetParam() == Config::FrameRateOverride::Enabled) { EXPECT_TRUE(selector.canSwitch()); } else { EXPECT_FALSE(selector.canSwitch()); } } TEST_P(RefreshRateSelectorTest, invalidPolicy) { auto selector = createSelector(kModes_60, kModeId60); EXPECT_EQ(SetPolicyResult::Invalid, selector.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}})); EXPECT_EQ(SetPolicyResult::Invalid, selector.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}})); } TEST_P(RefreshRateSelectorTest, unchangedPolicy) { auto selector = createSelector(kModes_60_90, kModeId60); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}})); EXPECT_EQ(SetPolicyResult::Unchanged, selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}})); // Override to the same policy. EXPECT_EQ(SetPolicyResult::Unchanged, selector.setPolicy(RefreshRateSelector::OverridePolicy{kModeId90, {60_Hz, 90_Hz}})); // Clear override to restore DisplayManagerPolicy. EXPECT_EQ(SetPolicyResult::Unchanged, selector.setPolicy(RefreshRateSelector::NoOverridePolicy{})); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {30_Hz, 90_Hz}})); } TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap) { auto selector = createSelector(kModes_60_90, kModeId60); const auto minRate = selector.getMinSupportedRefreshRate(); const auto performanceRate = selector.getMaxSupportedRefreshRate(); EXPECT_EQ(kMode60, minRate); EXPECT_EQ(kMode90, performanceRate); const auto minRateByPolicy = selector.getMinRefreshRateByPolicy(); const auto performanceRateByPolicy = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(minRateByPolicy, minRate); EXPECT_EQ(performanceRateByPolicy, performanceRate); } TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap_differentGroups) { auto selector = createSelector(kModes_60_90_G1, kModeId60); const auto minRate = selector.getMinRefreshRateByPolicy(); const auto performanceRate = selector.getMaxSupportedRefreshRate(); const auto minRate60 = selector.getMinRefreshRateByPolicy(); const auto performanceRate60 = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode60, minRate); EXPECT_EQ(kMode60, minRate60); EXPECT_EQ(kMode60, performanceRate60); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}})); selector.setActiveMode(kModeId90, 90_Hz); const auto minRate90 = selector.getMinRefreshRateByPolicy(); const auto performanceRate90 = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode90_G1, performanceRate); EXPECT_EQ(kMode90_G1, minRate90); EXPECT_EQ(kMode90_G1, performanceRate90); } TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap_differentResolutions) { auto selector = createSelector(kModes_60_90_4K, kModeId60); const auto minRate = selector.getMinRefreshRateByPolicy(); const auto performanceRate = selector.getMaxSupportedRefreshRate(); const auto minRate60 = selector.getMinRefreshRateByPolicy(); const auto performanceRate60 = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode60, minRate); EXPECT_EQ(kMode60, minRate60); EXPECT_EQ(kMode60, performanceRate60); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}})); selector.setActiveMode(kModeId90, 90_Hz); const auto minRate90 = selector.getMinRefreshRateByPolicy(); const auto performanceRate90 = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode90_4K, performanceRate); EXPECT_EQ(kMode90_4K, minRate90); EXPECT_EQ(kMode90_4K, performanceRate90); } TEST_P(RefreshRateSelectorTest, twoModes_policyChange) { auto selector = createSelector(kModes_60_90, kModeId60); const auto minRate = selector.getMinRefreshRateByPolicy(); const auto performanceRate = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode60, minRate); EXPECT_EQ(kMode90, performanceRate); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); const auto minRate60 = selector.getMinRefreshRateByPolicy(); const auto performanceRate60 = selector.getMaxRefreshRateByPolicy(); EXPECT_EQ(kMode60, minRate60); EXPECT_EQ(kMode60, performanceRate60); } TEST_P(RefreshRateSelectorTest, twoModes_getActiveMode) { auto selector = createSelector(kModes_60_90, kModeId60); { const auto& mode = selector.getActiveMode(); EXPECT_EQ(mode.getId(), kModeId60); } selector.setActiveMode(kModeId90, 90_Hz); { const auto& mode = selector.getActiveMode(); EXPECT_EQ(mode.getId(), kModeId90); } EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}})); { const auto& mode = selector.getActiveMode(); EXPECT_EQ(mode.getId(), kModeId90); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_noLayers) { { auto selector = createSelector(kModes_60_72_90, kModeId72); // If there are no layers we select the default frame rate, which is the max of the primary // range. EXPECT_EQ(kMode90, selector.getBestFrameRateMode()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); EXPECT_EQ(kMode60, selector.getBestFrameRateMode()); } { // We select max even when this will cause a non-seamless switch. auto selector = createSelector(kModes_60_90_G1, kModeId60); constexpr bool kAllowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId90, {0_Hz, 90_Hz}, kAllowGroupSwitching})); EXPECT_EQ(kMode90_G1, selector.getBestFrameRateMode()); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_exactDontChangeRefreshRateWhenNotInPolicy) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId72); std::vector layers = {{.weight = 1.f}}; layers[0].vote = LayerVoteType::ExplicitExact; layers[0].desiredRefreshRate = 120_Hz; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId72, {0_Hz, 90_Hz}})); EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_60_90) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; lr.name = "45Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; lr.name = "30Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; lr.name = "24Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.name = ""; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); lr.vote = LayerVoteType::Min; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}})); lr.vote = LayerVoteType::Min; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}})); lr.vote = LayerVoteType::Min; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_multipleThreshold_60_90) { auto selector = createSelector(kModes_60_90, kModeId60, {.frameRateMultipleThreshold = 90}); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; lr.name = "45Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; lr.name = "30Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; lr.name = "24Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_60_72_90) { auto selector = createSelector(kModes_60_72_90, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_72_90_120) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 48_Hz; lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 48_Hz; lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_90_120_DifferentTypes) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_90_120_DifferentTypes_multipleThreshold) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60, {.frameRateMultipleThreshold = 120}); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; auto& lr3 = layers[2]; lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 120_Hz; lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "120Hz ExplicitDefault"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 120_Hz; lr2.vote = LayerVoteType::ExplicitExact; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 10_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 120_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); lr1.desiredRefreshRate = 30_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 30_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "30Hz ExplicitExactOrMultiple"; lr3.vote = LayerVoteType::Heuristic; lr3.desiredRefreshRate = 120_Hz; lr3.name = "120Hz Heuristic"; EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60) { auto selector = createSelector(kModes_30_60, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_72_90) { auto selector = createSelector(kModes_30_60_72_90, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 90_Hz; lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Heuristic"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr.desiredRefreshRate = 45_Hz; lr.name = "45Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr.desiredRefreshRate = 30_Hz; lr.name = "30Hz Heuristic"; EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr.desiredRefreshRate = 24_Hz; lr.name = "24Hz Heuristic"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr.desiredRefreshRate = 24_Hz; lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.name = "24Hz ExplicitExactOrMultiple"; EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_PriorityTest) { auto selector = createSelector(kModes_30_60_90, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::Max; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 24_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Max; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Max; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = 15_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = 30_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 45_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_24FpsVideo) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps::fromValue(fps); const auto mode = selector.getBestFrameRateMode(layers); EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses " << to_string(mode->getFps()); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_24FpsVideo_multipleThreshold_60_120) { auto selector = createSelector(kModes_60_120, kModeId60, {.frameRateMultipleThreshold = 120}); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps::fromValue(fps); const auto mode = selector.getBestFrameRateMode(layers); EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses " << to_string(mode->getFps()); } } TEST_P(RefreshRateSelectorTest, twoModes_getBestFrameRateMode_Explicit) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = 60_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 90_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = 90_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = 60_Hz; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_75HzContent) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 75.0f; fps < 100.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps::fromValue(fps); const auto mode = selector.getBestFrameRateMode(layers, {}); EXPECT_EQ(kMode90, mode) << lr.desiredRefreshRate << " chooses " << to_string(mode->getFps()); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_Multiples) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 90_Hz; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::ExplicitDefault; lr2.desiredRefreshRate = 90_Hz; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 30_Hz; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 90_Hz; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 30_Hz; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, scrollWhileWatching60fps_60_90) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); // The other layer starts to provide buffers lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 90_Hz; lr2.name = "90Hz Heuristic"; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, getMaxRefreshRatesByPolicy) { // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the // different group. auto selector = createSelector(kModes_30_60_90, kModeId60); const auto refreshRates = selector.rankRefreshRates(selector.getActiveMode().getGroup(), RefreshRateOrder::Descending); const auto expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {30_Hz, kMode30}}; case Config::FrameRateOverride::Enabled: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90}, {30_Hz, kMode30}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, getMinRefreshRatesByPolicy) { // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the // different group. auto selector = createSelector(kModes_30_60_90, kModeId60); const auto refreshRates = selector.rankRefreshRates(selector.getActiveMode().getGroup(), RefreshRateOrder::Ascending); const auto expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}}; case Config::FrameRateOverride::Enabled: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, getMinRefreshRatesByPolicyOutsideTheGroup) { // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the // different group. auto selector = createSelector(kModes_30_60_90, kModeId72); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}})); const auto refreshRates = selector.rankRefreshRates(/*anchorGroupOpt*/ std::nullopt, RefreshRateOrder::Ascending); const auto expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}}; case Config::FrameRateOverride::Enabled: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, getMaxRefreshRatesByPolicyOutsideTheGroup) { // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the // different group. auto selector = createSelector(kModes_30_60_90, kModeId72); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}})); const auto refreshRates = selector.rankRefreshRates(/*anchorGroupOpt*/ std::nullopt, RefreshRateOrder::Descending); const auto expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {30_Hz, kMode30}}; case Config::FrameRateOverride::Enabled: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90}, {30_Hz, kMode30}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, powerOnImminentConsidered) { auto selector = createSelector(kModes_60_90, kModeId60); auto [refreshRates, signals] = selector.getRankedFrameRates({}, {}); EXPECT_FALSE(signals.powerOnImminent); auto expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{90_Hz, kMode90}, {60_Hz, kMode60}}; case Config::FrameRateOverride::Enabled: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90}, {30_Hz, kMode60}, {22.5_Hz, kMode90}, {20_Hz, kMode60}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } std::tie(refreshRates, signals) = selector.getRankedRefreshRatesAsPair({}, {.powerOnImminent = true}); EXPECT_TRUE(signals.powerOnImminent); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } std::vector layers = {{.weight = 1.f}}; auto& lr1 = layers[0]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; std::tie(refreshRates, signals) = selector.getRankedRefreshRatesAsPair(layers, {.powerOnImminent = true}); EXPECT_TRUE(signals.powerOnImminent); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } std::tie(refreshRates, signals) = selector.getRankedRefreshRatesAsPair(layers, {.powerOnImminent = false}); EXPECT_FALSE(signals.powerOnImminent); expectedRefreshRates = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{60_Hz, kMode60}, {90_Hz, kMode90}}; case Config::FrameRateOverride::Enabled: return {{60_Hz, kMode60}, {90_Hz, kMode90}, {45_Hz, kMode90}, {30_Hz, kMode60}, {22.5_Hz, kMode90}, {20_Hz, kMode60}}; } }(); ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size()); for (size_t i = 0; i < expectedRefreshRates.size(); ++i) { EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode) << "Expected " << expectedRefreshRates[i].fps.getIntValue() << " (" << expectedRefreshRates[i].modePtr->getFps().getIntValue() << ")" << " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " (" << refreshRates[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, touchConsidered) { auto selector = createSelector(kModes_60_90, kModeId60); auto [_, signals] = selector.getRankedFrameRates({}, {}); EXPECT_FALSE(signals.touch); std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair({}, {.touch = true}); EXPECT_TRUE(signals.touch); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz Heuristic"; std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true}); EXPECT_TRUE(signals.touch); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitDefault"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz Heuristic"; std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true}); EXPECT_FALSE(signals.touch); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz Heuristic"; std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true}); EXPECT_TRUE(signals.touch); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = 60_Hz; lr1.name = "60Hz ExplicitDefault"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz Heuristic"; std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true}); EXPECT_FALSE(signals.touch); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitDefault) { auto selector = createSelector(kModes_60_90_72_120, kModeId60); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; // Prepare a table with the vote and the expected refresh rate const std::initializer_list> testCases = { {130_Hz, 120_Hz}, {120_Hz, 120_Hz}, {119_Hz, 120_Hz}, {110_Hz, 120_Hz}, {100_Hz, 90_Hz}, {90_Hz, 90_Hz}, {89_Hz, 90_Hz}, {80_Hz, 72_Hz}, {73_Hz, 72_Hz}, {72_Hz, 72_Hz}, {71_Hz, 72_Hz}, {70_Hz, 72_Hz}, {65_Hz, 60_Hz}, {60_Hz, 60_Hz}, {59_Hz, 60_Hz}, {58_Hz, 60_Hz}, {55_Hz, 90_Hz}, {50_Hz, 90_Hz}, {45_Hz, 90_Hz}, {42_Hz, 120_Hz}, {40_Hz, 120_Hz}, {39_Hz, 120_Hz}, {37_Hz, 72_Hz}, {36_Hz, 72_Hz}, {35_Hz, 72_Hz}, {30_Hz, 60_Hz}, }; for (auto [desired, expected] : testCases) { lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = desired; std::stringstream ss; ss << "ExplicitDefault " << desired; lr.name = ss.str(); EXPECT_EQ(expected, selector.getBestFrameRateMode(layers)->getFps()); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExactOrMultiple_WithFractionalRefreshRates) { std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; // Test that 23.976 will choose 24 if 23.976 is not supported { auto selector = createSelector(makeModes(kMode24, kMode25, kMode30, kMode30Frac, kMode60, kMode60Frac), kModeId60); lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 23.976_Hz; lr.name = "ExplicitExactOrMultiple 23.976 Hz"; EXPECT_EQ(kModeId24, selector.getBestFrameRateMode(layers)->getId()); } // Test that 24 will choose 23.976 if 24 is not supported { auto selector = createSelector(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac, kMode60, kMode60Frac), kModeId60); lr.desiredRefreshRate = 24_Hz; lr.name = "ExplicitExactOrMultiple 24 Hz"; EXPECT_EQ(kModeId24Frac, selector.getBestFrameRateMode(layers)->getId()); } // Test that 29.97 will prefer 59.94 over 60 and 30 { auto selector = createSelector(makeModes(kMode24, kMode24Frac, kMode25, kMode30, kMode60, kMode60Frac), kModeId60); lr.desiredRefreshRate = 29.97_Hz; lr.name = "ExplicitExactOrMultiple 29.97 Hz"; EXPECT_EQ(kModeId60Frac, selector.getBestFrameRateMode(layers)->getId()); } // Test that 29.97 will choose 30 if 59.94 is not supported { auto selector = createSelector(makeModes(kMode30, kMode60), kModeId60); lr.desiredRefreshRate = 29.97_Hz; lr.name = "ExplicitExactOrMultiple 29.97 Hz"; EXPECT_EQ(kModeId30, selector.getBestFrameRateMode(layers)->getId()); } // Test that 59.94 will choose 60 if 59.94 is not supported { auto selector = createSelector(makeModes(kMode60, kMode30Frac, kMode30), kModeId60); lr.desiredRefreshRate = 59.94_Hz; lr.name = "ExplicitExactOrMultiple 59.94 Hz"; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExact_WithFractionalRefreshRates) { std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; // Test that voting for supported refresh rate will select this refresh rate { auto selector = createSelector(kModes_24_25_30_50_60_Frac, kModeId60); for (auto desired : {23.976_Hz, 24_Hz, 25_Hz, 29.97_Hz, 30_Hz, 50_Hz, 59.94_Hz, 60_Hz}) { lr.vote = LayerVoteType::ExplicitExact; lr.desiredRefreshRate = desired; std::stringstream ss; ss << "ExplicitExact " << desired; lr.name = ss.str(); EXPECT_EQ(lr.desiredRefreshRate, selector.getBestFrameRateMode(layers)->getFps()); } } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) { auto selector = createSelector(kModes_60_90, kModeId90); constexpr FpsRange k90 = {90_Hz, 90_Hz}; constexpr FpsRange k60_90 = {60_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {k90, k90}, {k60_90, k60_90}})); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz ExplicitDefault"; lr.focused = true; const auto [rankedFrameRate, signals] = selector.getRankedFrameRates(layers, {.touch = true, .idle = true}); EXPECT_EQ(rankedFrameRate.begin()->frameRateMode.modePtr, kMode60); EXPECT_FALSE(signals.touch); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) { auto selector = createSelector(kModes_60_90, kModeId60); constexpr FpsRange k60 = {60_Hz, 60_Hz}; constexpr FpsRange k60_90 = {60_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {k60, k60}, {k60_90, k60_90}})); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 90_Hz; lr.name = "90Hz ExplicitDefault"; lr.focused = true; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.idle = true})); } TEST_P(RefreshRateSelectorTest, testDisplayModeOrdering) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; auto& lr3 = layers[2]; auto& lr4 = layers[3]; auto& lr5 = layers[4]; lr1.desiredRefreshRate = 90_Hz; lr1.name = "90Hz"; lr1.focused = true; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz"; lr2.focused = true; lr3.desiredRefreshRate = 72_Hz; lr3.name = "72Hz"; lr3.focused = true; lr4.desiredRefreshRate = 120_Hz; lr4.name = "120Hz"; lr4.focused = true; lr5.desiredRefreshRate = 30_Hz; lr5.name = "30Hz"; lr5.focused = true; auto expectedRanking = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60}, {30_Hz, kMode30}}; case Config::FrameRateOverride::Enabled: return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60}, {45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}}; } }(); auto actualRanking = selector.getRankedFrameRates(layers, {}).ranking; ASSERT_EQ(expectedRanking.size(), actualRanking.size()); for (size_t i = 0; i < expectedRanking.size(); ++i) { EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode) << "Expected " << expectedRanking[i].fps.getIntValue() << " (" << expectedRanking[i].modePtr->getFps().getIntValue() << ")" << " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " (" << actualRanking[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } lr1.vote = LayerVoteType::Max; lr1.name = "Max"; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz"; lr3.desiredRefreshRate = 72_Hz; lr3.name = "72Hz"; lr4.desiredRefreshRate = 90_Hz; lr4.name = "90Hz"; lr5.desiredRefreshRate = 120_Hz; lr5.name = "120Hz"; expectedRanking = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60}, {30_Hz, kMode30}}; case Config::FrameRateOverride::Enabled: return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60}, {45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}}; } }(); actualRanking = selector.getRankedFrameRates(layers, {}).ranking; ASSERT_EQ(expectedRanking.size(), actualRanking.size()); for (size_t i = 0; i < expectedRanking.size(); ++i) { EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode) << "Expected " << expectedRanking[i].fps.getIntValue() << " (" << expectedRanking[i].modePtr->getFps().getIntValue() << ")" << " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " (" << actualRanking[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = 30_Hz; lr1.name = "30Hz"; lr2.desiredRefreshRate = 120_Hz; lr2.name = "120Hz"; lr3.desiredRefreshRate = 60_Hz; lr3.name = "60Hz"; lr5.desiredRefreshRate = 72_Hz; lr5.name = "72Hz"; expectedRanking = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}, {120_Hz, kMode120}, {72_Hz, kMode72}}; case Config::FrameRateOverride::Enabled: return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}, {120_Hz, kMode120}, {45_Hz, kMode90}, {40_Hz, kMode120}, {72_Hz, kMode72}, {36_Hz, kMode72}}; } }(); actualRanking = selector.getRankedFrameRates(layers, {}).ranking; ASSERT_EQ(expectedRanking.size(), actualRanking.size()); for (size_t i = 0; i < expectedRanking.size(); ++i) { EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode) << "Expected " << expectedRanking[i].fps.getIntValue() << " (" << expectedRanking[i].modePtr->getFps().getIntValue() << ")" << " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " (" << actualRanking[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } lr1.desiredRefreshRate = 120_Hz; lr1.name = "120Hz"; lr1.weight = 0.0f; lr2.desiredRefreshRate = 60_Hz; lr2.name = "60Hz"; lr2.vote = LayerVoteType::NoVote; lr3.name = "60Hz-2"; lr3.vote = LayerVoteType::Heuristic; lr4.vote = LayerVoteType::ExplicitExact; lr5.desiredRefreshRate = 120_Hz; lr5.name = "120Hz-2"; expectedRanking = []() -> std::vector { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {120_Hz, kMode120}, {72_Hz, kMode72}, {30_Hz, kMode30}}; case Config::FrameRateOverride::Enabled: return {{90_Hz, kMode90}, {60_Hz, kMode60}, {120_Hz, kMode120}, {72_Hz, kMode72}, {45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}}; } }(); actualRanking = selector.getRankedFrameRates(layers, {}).ranking; ASSERT_EQ(expectedRanking.size(), actualRanking.size()); for (size_t i = 0; i < expectedRanking.size(); ++i) { EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode) << "Expected " << expectedRanking[i].fps.getIntValue() << " (" << expectedRanking[i].modePtr->getFps().getIntValue() << ")" << " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " (" << actualRanking[i].frameRateMode.modePtr->getFps().getIntValue() << ")"; } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) { auto selector = createSelector(kModes_60_90, kModeId90); constexpr FpsRange k90 = {90_Hz, 90_Hz}; constexpr FpsRange k60_90 = {60_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {k90, k90}, {k60_90, k60_90}})); const auto [ranking, signals] = selector.getRankedFrameRates({}, {}); EXPECT_EQ(ranking.front().frameRateMode.modePtr, kMode90); EXPECT_FALSE(signals.touch); std::vector layers = {{.weight = 1.f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz ExplicitExactOrMultiple"; lr.focused = false; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.focused = true; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz ExplicitDefault"; lr.focused = false; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.focused = true; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Heuristic; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Heuristic"; lr.focused = false; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.focused = true; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Max; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Max"; lr.focused = false; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.focused = true; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.vote = LayerVoteType::Min; lr.desiredRefreshRate = 60_Hz; lr.name = "60Hz Min"; lr.focused = false; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); lr.focused = true; EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers)); } TEST_P(RefreshRateSelectorTest, groupSwitchingNotAllowed) { auto selector = createSelector(kModes_60_90_G1, kModeId60); // The default policy doesn't allow group switching. Verify that no // group switches are performed. std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 90_Hz; layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayer) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 90_Hz; layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerOnlySeamless) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); // Verify that we won't change the group if seamless switch is required. std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 90_Hz; layer.seamlessness = Seamlessness::OnlySeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); selector.setActiveMode(kModeId90, 90_Hz); // Verify that we won't do a seamless switch if we request the same mode as the default std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 60_Hz; layer.seamlessness = Seamlessness::OnlySeamless; layer.name = "60Hz ExplicitDefault"; layer.focused = true; EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerDefaultSeamlessness) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); selector.setActiveMode(kModeId90, 90_Hz); // Verify that if the active mode is in another group and there are no layers with // Seamlessness::SeamedAndSeamless, we should switch back to the default group. std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 60_Hz; layer.seamlessness = Seamlessness::Default; layer.name = "60Hz ExplicitDefault"; layer.focused = true; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); selector.setActiveMode(kModeId90, 90_Hz); // If there's a layer with Seamlessness::SeamedAndSeamless, another layer with // Seamlessness::OnlySeamless can't change the mode group. std::vector layers = {{.weight = 1.f}}; layers[0].vote = LayerVoteType::ExplicitDefault; layers[0].desiredRefreshRate = 60_Hz; layers[0].seamlessness = Seamlessness::OnlySeamless; layers[0].name = "60Hz ExplicitDefault"; layers[0].focused = true; layers.push_back(LayerRequirement{.weight = 0.5f}); layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].seamlessness = Seamlessness::SeamedAndSeamless; layers[1].desiredRefreshRate = 90_Hz; layers[1].name = "90Hz ExplicitDefault"; layers[1].focused = false; EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); selector.setActiveMode(kModeId90, 90_Hz); // If there's a focused layer with Seamlessness::SeamedAndSeamless, another layer with // Seamlessness::Default can't change the mode group back to the group of the default // mode. // For example, this may happen when a video playback requests and gets a seamed switch, // but another layer (with default seamlessness) starts animating. The animating layer // should not cause a seamed switch. std::vector layers = {{.weight = 1.f}}; layers[0].seamlessness = Seamlessness::Default; layers[0].desiredRefreshRate = 60_Hz; layers[0].focused = true; layers[0].vote = LayerVoteType::ExplicitDefault; layers[0].name = "60Hz ExplicitDefault"; layers.push_back(LayerRequirement{.weight = 0.1f}); layers[1].seamlessness = Seamlessness::SeamedAndSeamless; layers[1].desiredRefreshRate = 90_Hz; layers[1].focused = true; layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].name = "90Hz ExplicitDefault"; EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) { auto selector = createSelector(kModes_60_90_G1, kModeId60); RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); selector.setActiveMode(kModeId90, 90_Hz); // Layer with Seamlessness::Default can change the mode group if there's an // unfocused layer with Seamlessness::SeamedAndSeamless. For example, this happens // when in split screen mode the user switches between the two visible applications. std::vector layers = {{.weight = 1.f}}; layers[0].seamlessness = Seamlessness::Default; layers[0].desiredRefreshRate = 60_Hz; layers[0].focused = true; layers[0].vote = LayerVoteType::ExplicitDefault; layers[0].name = "60Hz ExplicitDefault"; layers.push_back(LayerRequirement{.weight = 0.7f}); layers[1].seamlessness = Seamlessness::SeamedAndSeamless; layers[1].desiredRefreshRate = 90_Hz; layers[1].focused = false; layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].name = "90Hz ExplicitDefault"; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, nonSeamlessVotePrefersSeamlessSwitches) { auto selector = createSelector(kModes_30_60, kModeId60); // Allow group switching. RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitExactOrMultiple; layer.desiredRefreshRate = 60_Hz; layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "60Hz ExplicitExactOrMultiple"; layer.focused = true; EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); selector.setActiveMode(kModeId120, 120_Hz); EXPECT_EQ(kModeId120, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, nonSeamlessExactAndSeamlessMultipleLayers) { auto selector = createSelector(kModes_25_30_50_60, kModeId60); // Allow group switching. RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); std::vector layers = {{.name = "60Hz ExplicitDefault", .vote = LayerVoteType::ExplicitDefault, .desiredRefreshRate = 60_Hz, .seamlessness = Seamlessness::SeamedAndSeamless, .weight = 0.5f, .focused = false}, {.name = "25Hz ExplicitExactOrMultiple", .vote = LayerVoteType::ExplicitExactOrMultiple, .desiredRefreshRate = 25_Hz, .seamlessness = Seamlessness::OnlySeamless, .weight = 1.f, .focused = true}}; EXPECT_EQ(kModeId50, selector.getBestFrameRateMode(layers)->getId()); auto& seamedLayer = layers[0]; seamedLayer.desiredRefreshRate = 30_Hz; seamedLayer.name = "30Hz ExplicitDefault"; selector.setActiveMode(kModeId30, 30_Hz); EXPECT_EQ(kModeId25, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, minLayersDontTrigerSeamedSwitch) { auto selector = createSelector(kModes_60_90_G1, kModeId90); // Allow group switching. RefreshRateSelector::DisplayManagerPolicy policy; policy.defaultMode = selector.getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy)); std::vector layers = { {.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}}; EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers)->getId()); } TEST_P(RefreshRateSelectorTest, primaryVsAppRequestPolicy) { auto selector = createSelector(kModes_30_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; struct Args { bool touch = false; bool focused = true; }; // Returns the mode selected by getBestFrameRateMode for a single layer with the given // arguments. const auto getFrameRate = [&](LayerVoteType voteType, Fps fps, Args args = {}) -> DisplayModeId { layers[0].vote = voteType; layers[0].desiredRefreshRate = fps; layers[0].focused = args.focused; return selector.getBestFrameRateMode(layers, {.touch = args.touch})->getId(); }; constexpr FpsRange k30_60 = {30_Hz, 60_Hz}; constexpr FpsRange k30_90 = {30_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {k30_60, k30_60}, {k30_90, k30_90}})); EXPECT_EQ(kModeId60, selector.getBestFrameRateMode()->getId()); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz)); EXPECT_EQ(kModeId30, getFrameRate(LayerVoteType::Min, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Heuristic, 90_Hz)); EXPECT_EQ(kModeId90, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz)); // Unfocused layers are not allowed to override primary range. EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz, {.focused = false})); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz, {.focused = false})); // Touch boost should be restricted to the primary range. EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz, {.touch = true})); // When we're higher than the primary range max due to a layer frame rate setting, touch boost // shouldn't drag us back down to the primary range max. EXPECT_EQ(kModeId90, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz, {.touch = true})); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz, {.touch = true})); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Min, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Heuristic, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz)); EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz)); } TEST_P(RefreshRateSelectorTest, idle) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; const auto getIdleDisplayModeId = [&](LayerVoteType voteType, bool touchActive) -> DisplayModeId { layers[0].vote = voteType; layers[0].desiredRefreshRate = 90_Hz; const auto [ranking, signals] = selector.getRankedFrameRates(layers, {.touch = touchActive, .idle = true}); // Refresh rate will be chosen by either touch state or idle state. EXPECT_EQ(!touchActive, signals.idle); return ranking.front().frameRateMode.modePtr->getId(); }; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}})); // Idle should be lower priority than touch boost. { constexpr bool kTouchActive = true; EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive)); EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive)); EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive)); EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive)); EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive)); EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive)); } // With no layers, idle should still be lower priority than touch boost. EXPECT_EQ(kModeId90, selector.getBestFrameRateMode({}, {.touch = true, .idle = true})->getId()); // Idle should be higher precedence than other layer frame rate considerations. selector.setActiveMode(kModeId90, 90_Hz); { constexpr bool kTouchActive = false; EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive)); EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive)); EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive)); EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive)); EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive)); EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive)); } // Idle should be applied rather than the active mode when there are no layers. EXPECT_EQ(kModeId60, selector.getBestFrameRateMode({}, {.idle = true})->getId()); } TEST_P(RefreshRateSelectorTest, findClosestKnownFrameRate) { auto selector = createSelector(kModes_60_90, kModeId60); for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) { const auto knownFrameRate = selector.findClosestKnownFrameRate(Fps::fromValue(fps)); const Fps expectedFrameRate = [fps] { if (fps < 26.91f) return 24_Hz; if (fps < 37.51f) return 30_Hz; if (fps < 52.51f) return 45_Hz; if (fps < 66.01f) return 60_Hz; if (fps < 81.01f) return 72_Hz; return 90_Hz; }(); EXPECT_EQ(expectedFrameRate, knownFrameRate); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_KnownFrameRate) { auto selector = createSelector(kModes_60_90, kModeId60); struct Expectation { Fps fps; ftl::NonNull mode; }; const std::initializer_list knownFrameRatesExpectations = { {24_Hz, kMode60}, {30_Hz, kMode60}, {45_Hz, kMode90}, {60_Hz, kMode60}, {72_Hz, kMode90}, {90_Hz, kMode90}, }; // Make sure the test tests all the known frame rate const auto& knownFrameRates = selector.knownFrameRates(); const bool equal = std::equal(knownFrameRates.begin(), knownFrameRates.end(), knownFrameRatesExpectations.begin(), [](Fps fps, const Expectation& expected) { return isApproxEqual(fps, expected.fps); }); EXPECT_TRUE(equal); std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::Heuristic; for (const auto& [fps, mode] : knownFrameRatesExpectations) { layer.desiredRefreshRate = fps; EXPECT_EQ(mode, selector.getBestFrameRateMode(layers)); } } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExact) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 0.5f}}; auto& explicitExactLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactLayer.vote = LayerVoteType::ExplicitExact; explicitExactLayer.name = "ExplicitExact"; explicitExactLayer.desiredRefreshRate = 30_Hz; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz; if (GetParam() == Config::FrameRateOverride::Disabled) { EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz, selector.getBestScoredFrameRate(layers, {.touch = true}) .frameRateMode); } else { EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers, {.touch = true}) .frameRateMode); } explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz; explicitExactLayer.desiredRefreshRate = 60_Hz; if (GetParam() == Config::FrameRateOverride::Disabled) { EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } else { EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } explicitExactLayer.desiredRefreshRate = 72_Hz; EXPECT_FRAME_RATE_MODE(kMode72, 72_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); explicitExactLayer.desiredRefreshRate = 90_Hz; EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); explicitExactLayer.desiredRefreshRate = 120_Hz; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ReadsCache) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); using GlobalSignals = RefreshRateSelector::GlobalSignals; const auto args = std::make_pair(std::vector{}, GlobalSignals{.touch = true, .idle = true}); const RefreshRateSelector::RankedFrameRates result = {{RefreshRateSelector::ScoredFrameRate{ {90_Hz, kMode90}}}, GlobalSignals{.touch = true}}; selector.mutableGetRankedRefreshRatesCache() = {args, result}; EXPECT_EQ(result, selector.getRankedFrameRates(args.first, args.second)); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_WritesCache) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId60); EXPECT_FALSE(selector.mutableGetRankedRefreshRatesCache()); std::vector layers = {{.weight = 1.f}, {.weight = 0.5f}}; RefreshRateSelector::GlobalSignals globalSignals{.touch = true, .idle = true}; const auto result = selector.getRankedFrameRates(layers, globalSignals); const auto& cache = selector.mutableGetRankedRefreshRatesCache(); ASSERT_TRUE(cache); EXPECT_EQ(cache->arguments, std::make_pair(layers, globalSignals)); EXPECT_EQ(cache->result, result); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExactTouchBoost) { auto selector = createSelector(kModes_60_120, kModeId60); std::vector layers = {{.weight = 1.f}, {.weight = 0.5f}}; auto& explicitExactLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz; explicitExactLayer.vote = LayerVoteType::ExplicitExact; explicitExactLayer.name = "ExplicitExact"; explicitExactLayer.desiredRefreshRate = 30_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); if (GetParam() == Config::FrameRateOverride::Disabled) { EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers, {.touch = true})); } else { EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers, {.touch = true})); } explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers, {.touch = true})); } TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_FractionalRefreshRates_ExactAndDefault) { auto selector = createSelector(kModes_24_25_30_50_60_Frac, kModeId60); std::vector layers = {{.weight = 0.5f}, {.weight = 0.5f}}; auto& explicitDefaultLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz; explicitDefaultLayer.vote = LayerVoteType::ExplicitDefault; explicitDefaultLayer.name = "ExplicitDefault"; explicitDefaultLayer.desiredRefreshRate = 59.94_Hz; EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers)); } // b/190578904 TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withCloseRefreshRates) { if (g_noSlowTests) { GTEST_SKIP(); } const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue(); constexpr int kMaxRefreshRate = 240; DisplayModes displayModes; for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) { const DisplayModeId modeId(fps); displayModes.try_emplace(modeId, createDisplayMode(modeId, Fps::fromValue(static_cast(fps)))); } const auto selector = createSelector(std::move(displayModes), DisplayModeId(kMinRefreshRate)); std::vector layers = {{.weight = 1.f}}; const auto testRefreshRate = [&](Fps fps, LayerVoteType vote) { layers[0].desiredRefreshRate = fps; layers[0].vote = vote; EXPECT_EQ(fps.getIntValue(), selector.getBestFrameRateMode(layers)->getFps().getIntValue()) << "Failed for " << ftl::enum_string(vote); }; for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) { const auto refreshRate = Fps::fromValue(static_cast(fps)); testRefreshRate(refreshRate, LayerVoteType::Heuristic); testRefreshRate(refreshRate, LayerVoteType::ExplicitDefault); testRefreshRate(refreshRate, LayerVoteType::ExplicitExactOrMultiple); testRefreshRate(refreshRate, LayerVoteType::ExplicitExact); } } // b/190578904 TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_conflictingVotes) { constexpr DisplayModeId kActiveModeId{0}; DisplayModes displayModes = makeModes(createDisplayMode(kActiveModeId, 43_Hz), createDisplayMode(DisplayModeId(1), 53_Hz), createDisplayMode(DisplayModeId(2), 55_Hz), createDisplayMode(DisplayModeId(3), 60_Hz)); const RefreshRateSelector::GlobalSignals globalSignals = {.touch = false, .idle = false}; const auto selector = createSelector(std::move(displayModes), kActiveModeId); const std::vector layers = { { .vote = LayerVoteType::ExplicitDefault, .desiredRefreshRate = 43_Hz, .seamlessness = Seamlessness::SeamedAndSeamless, .weight = 0.41f, }, { .vote = LayerVoteType::ExplicitExactOrMultiple, .desiredRefreshRate = 53_Hz, .seamlessness = Seamlessness::SeamedAndSeamless, .weight = 0.41f, }, }; EXPECT_EQ(53_Hz, selector.getBestFrameRateMode(layers, globalSignals)->getFps()); } TEST_P(RefreshRateSelectorTest, modeComparison) { EXPECT_LT(kMode60->getFps(), kMode90->getFps()); EXPECT_GE(kMode60->getFps(), kMode60->getFps()); EXPECT_GE(kMode90->getFps(), kMode90->getFps()); } TEST_P(RefreshRateSelectorTest, testKernelIdleTimerAction) { using KernelIdleTimerAction = RefreshRateSelector::KernelIdleTimerAction; auto selector = createSelector(kModes_60_90, kModeId90); EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction()); } TEST_P(RefreshRateSelectorTest, testKernelIdleTimerActionFor120Hz) { using KernelIdleTimerAction = RefreshRateSelector::KernelIdleTimerAction; auto selector = createSelector(kModes_60_120, kModeId120); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction()); EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}})); EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction()); } TEST_P(RefreshRateSelectorTest, getFrameRateDivisor) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId30); const auto frameRate = 30_Hz; Fps displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(1, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate)); selector.setActiveMode(kModeId60, 60_Hz); displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(2, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate)); selector.setActiveMode(kModeId72, 72_Hz); displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate)); selector.setActiveMode(kModeId90, 90_Hz); displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(3, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate)); selector.setActiveMode(kModeId120, 120_Hz); displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate)); selector.setActiveMode(kModeId90, 90_Hz); displayRefreshRate = selector.getActiveMode().getFps(); EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, 22.5_Hz)); EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(24_Hz, 25_Hz)); EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(24_Hz, 23.976_Hz)); EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(30_Hz, 29.97_Hz)); EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(60_Hz, 59.94_Hz)); } TEST_P(RefreshRateSelectorTest, isFractionalPairOrMultiple) { EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(23.976_Hz, 24_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(24_Hz, 23.976_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 30_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(30_Hz, 29.97_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(59.94_Hz, 60_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(60_Hz, 59.94_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 60_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(60_Hz, 29.97_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(59.94_Hz, 30_Hz)); EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(30_Hz, 59.94_Hz)); const auto refreshRates = {23.976_Hz, 24_Hz, 25_Hz, 29.97_Hz, 30_Hz, 50_Hz, 59.94_Hz, 60_Hz}; for (auto refreshRate : refreshRates) { EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(refreshRate, refreshRate)); } EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(24_Hz, 25_Hz)); EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(23.978_Hz, 25_Hz)); EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz)); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_noLayers) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); EXPECT_TRUE(selector.getFrameRateOverrides({}, 120_Hz, {}).empty()); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_NonExplicit) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::NoVote; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); layers[0].vote = LayerVoteType::Min; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); layers[0].vote = LayerVoteType::Max; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); layers[0].vote = LayerVoteType::Heuristic; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_Disabled) { if (GetParam() != Config::FrameRateOverride::Disabled) { return; } auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); layers[0].vote = LayerVoteType::ExplicitExact; EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty()); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_60on120) { if (GetParam() == Config::FrameRateOverride::Disabled) { return; } ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates || GetParam() == Config::FrameRateOverride::AppOverride || GetParam() == Config::FrameRateOverride::Enabled); auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExact; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_twoUids) { if (GetParam() == Config::FrameRateOverride::Disabled) { return; } ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates || GetParam() == Config::FrameRateOverride::AppOverride || GetParam() == Config::FrameRateOverride::Enabled); auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.ownerUid = 1234, .weight = 1.f}, {.ownerUid = 5678, .weight = 1.f}}; layers[0].name = "Test layer 1234"; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; layers[1].name = "Test layer 5678"; layers[1].desiredRefreshRate = 30_Hz; layers[1].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(2u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); ASSERT_EQ(1u, frameRateOverrides.count(5678)); EXPECT_EQ(30_Hz, frameRateOverrides.at(5678)); layers[1].vote = LayerVoteType::Heuristic; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); layers[1].ownerUid = 1234; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_TRUE(frameRateOverrides.empty()); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_touch) { if (GetParam() == Config::FrameRateOverride::Disabled) { return; } ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates || GetParam() == Config::FrameRateOverride::AppOverride || GetParam() == Config::FrameRateOverride::Enabled); auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.ownerUid = 1234, .weight = 1.f}}; layers[0].name = "Test layer"; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExact; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); EXPECT_TRUE(frameRateOverrides.empty()); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_DivisorIsNotDisplayRefreshRate) { if (GetParam() == Config::FrameRateOverride::Disabled) { return; } ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates || GetParam() == Config::FrameRateOverride::AppOverride || GetParam() == Config::FrameRateOverride::Enabled); auto selector = createSelector(kModes_60_120, kModeId120); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 30_Hz; const auto expetedFps = GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ? 60_Hz : 30_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(expetedFps, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(expetedFps, frameRateOverrides.at(1234)); layers[0].vote = LayerVoteType::ExplicitExact; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); ASSERT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(expetedFps, frameRateOverrides.at(1234)); } TEST_P(RefreshRateSelectorTest, renderFrameRateInvalidPolicy) { auto selector = createSelector(kModes_60_120, kModeId120); // The render frame rate cannot be greater than the physical refresh rate { const FpsRange physical = {60_Hz, 60_Hz}; const FpsRange render = {60_Hz, 120_Hz}; EXPECT_EQ(SetPolicyResult::Invalid, selector.setDisplayManagerPolicy( {kModeId60, {physical, render}, {physical, render}})); } } TEST_P(RefreshRateSelectorTest, renderFrameRateRestrictsPhysicalRefreshRate) { auto selector = createSelector(kModes_60_120, kModeId120); { const FpsRange physical = {0_Hz, 120_Hz}; const FpsRange render = {0_Hz, 60_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId60, {physical, render}, {physical, render}})); const auto expectedMaxMode = GetParam() == Config::FrameRateOverride::Enabled ? kMode120 : kMode60; EXPECT_EQ(expectedMaxMode, selector.getMaxRefreshRateByPolicy()); EXPECT_EQ(kMode60, selector.getMinRefreshRateByPolicy()); } { const FpsRange physical = {0_Hz, 120_Hz}; const FpsRange render = {120_Hz, 120_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId60, {physical, render}, {physical, render}})); EXPECT_EQ(kMode120, selector.getMaxRefreshRateByPolicy()); EXPECT_EQ(kMode120, selector.getMinRefreshRateByPolicy()); } } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_InPolicy) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); std::vector layers = {{.weight = 1.f}}; { const FpsRange physical = {120_Hz, 120_Hz}; const FpsRange render = {60_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId120, {physical, render}, {physical, render}})); } layers[0].name = "30Hz"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 30_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); EXPECT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); { const FpsRange physical = {120_Hz, 120_Hz}; const FpsRange render = {30_Hz, 90_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId120, {physical, render}, {physical, render}})); } frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); EXPECT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(30_Hz, frameRateOverrides.at(1234)); { const FpsRange physical = {120_Hz, 120_Hz}; const FpsRange render = {30_Hz, 30_Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {kModeId120, {physical, render}, {physical, render}})); } layers[0].name = "60Hz"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = 60_Hz; layers[0].vote = LayerVoteType::ExplicitDefault; frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {}); EXPECT_EQ(1u, frameRateOverrides.size()); EXPECT_EQ(1u, frameRateOverrides.count(1234)); EXPECT_EQ(30_Hz, frameRateOverrides.at(1234)); } TEST_P(RefreshRateSelectorTest, renderFrameRates) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); // [renderRate, refreshRate] const auto expected = []() -> std::vector> { switch (GetParam()) { case Config::FrameRateOverride::Disabled: case Config::FrameRateOverride::AppOverrideNativeRefreshRates: case Config::FrameRateOverride::AppOverride: return {{30_Hz, 30_Hz}, {60_Hz, 60_Hz}, {72_Hz, 72_Hz}, {90_Hz, 90_Hz}, {120_Hz, 120_Hz}}; case Config::FrameRateOverride::Enabled: return {{30_Hz, 30_Hz}, {36_Hz, 72_Hz}, {40_Hz, 120_Hz}, {45_Hz, 90_Hz}, {60_Hz, 60_Hz}, {72_Hz, 72_Hz}, {90_Hz, 90_Hz}, {120_Hz, 120_Hz}}; } }(); const auto& primaryRefreshRates = selector.getPrimaryFrameRates(); ASSERT_EQ(expected.size(), primaryRefreshRates.size()); for (size_t i = 0; i < expected.size(); i++) { const auto [expectedRenderRate, expectedRefreshRate] = expected[i]; EXPECT_EQ(expectedRenderRate, primaryRefreshRates[i].fps); EXPECT_EQ(expectedRefreshRate, primaryRefreshRates[i].modePtr->getFps()); } } TEST_P(RefreshRateSelectorTest, refreshRateIsCappedWithRenderFrameRate) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } auto selector = createSelector(kModes_60_120, kModeId60); constexpr FpsRange k0_120Hz = {0_Hz, 120_Hz}; constexpr FpsRange k0_60Hz = {0_Hz, 60_Hz}; constexpr FpsRanges kAppRequest = {/*physical*/ k0_120Hz, /*render*/ k0_120Hz}; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode); { constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz, /*render*/ k0_120Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60, /*primaryRanges*/ kPrimary, /*appRequestRanges*/ kAppRequest})); } EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode); { constexpr FpsRanges kPrimary = {/*physical*/ k0_60Hz, /*render*/ k0_60Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60, /*primaryRanges*/ kPrimary, /*appRequestRanges*/ kAppRequest})); } EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode); { constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz, /*render*/ k0_60Hz}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60, /*primaryRanges*/ kPrimary, /*appRequestRanges*/ kAppRequest})); } EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode); } TEST_P(RefreshRateSelectorTest, renderFrameRates_60_120) { auto selector = createSelector(kModes_60_120, kModeId120); std::vector layers = {{.weight = 1.f}}; auto& layer = layers[0]; const auto expectedRenderRate = GetParam() == Config::FrameRateOverride::Enabled ? 30_Hz : 60_Hz; layer.name = "30Hz ExplicitDefault"; layer.desiredRefreshRate = 30_Hz; layer.vote = LayerVoteType::ExplicitDefault; EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers).frameRateMode); layer.name = "30Hz Heuristic"; layer.desiredRefreshRate = 30_Hz; layer.vote = LayerVoteType::Heuristic; EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers).frameRateMode); layer.name = "30Hz ExplicitExactOrMultiple"; layer.desiredRefreshRate = 30_Hz; layer.vote = LayerVoteType::ExplicitExactOrMultiple; EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, idleWhenLowestRefreshRateIsNotDivisor) { auto selector = createSelector(kModes_35_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; const auto getIdleDisplayModeId = [&](LayerVoteType voteType, bool touchActive) -> DisplayModeId { layers[0].vote = voteType; layers[0].desiredRefreshRate = 90_Hz; const auto [ranking, signals] = selector.getRankedFrameRates(layers, {.touch = touchActive, .idle = true}); // Refresh rate will be chosen by either touch state or idle state. EXPECT_EQ(!touchActive, signals.idle); return ranking.front().frameRateMode.modePtr->getId(); }; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 90_Hz}})); // With no layers, idle should still be lower priority than touch boost. EXPECT_EQ(kModeId90, selector.getBestFrameRateMode({}, {.touch = true, .idle = true})->getId()); // Idle should be higher precedence than other layer frame rate considerations. selector.setActiveMode(kModeId90, 90_Hz); { constexpr bool kTouchActive = false; EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive)); EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive)); EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive)); EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive)); EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive)); EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive)); } // Idle should be applied rather than the active mode when there are no layers. EXPECT_EQ(kModeId35, selector.getBestFrameRateMode({}, {.idle = true})->getId()); } TEST_P(RefreshRateSelectorTest, policyCanBeInfinity) { auto selector = createSelector(kModes_60_120, kModeId120); constexpr Fps inf = Fps::fromValue(std::numeric_limits::infinity()); using namespace fps_approx_ops; selector.setDisplayManagerPolicy({kModeId60, {0_Hz, inf}}); // With no layers, idle should still be lower priority than touch boost. EXPECT_EQ(kMode120, selector.getMaxRefreshRateByPolicy()); EXPECT_EQ(kMode60, selector.getMinRefreshRateByPolicy()); } TEST_P(RefreshRateSelectorTest, SupportsLowPhysicalRefreshRates) { auto selector = createSelector(kModes_1_5_10, kModeId10); EXPECT_EQ(kMode10, selector.getMaxRefreshRateByPolicy()); EXPECT_EQ(kMode1, selector.getMinRefreshRateByPolicy()); } // TODO(b/266481656): Once this bug is fixed, we can remove this test TEST_P(RefreshRateSelectorTest, noLowerFrameRateOnMinVote) { auto selector = createSelector(kModes_60_90, kModeId60); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].vote = LayerVoteType::Min; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); constexpr FpsRanges kCappedAt60 = {{30_Hz, 90_Hz}, {30_Hz, 60_Hz}}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {DisplayModeId(kModeId60), kCappedAt60, kCappedAt60})); EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, frameRateIsCappedByPolicy) { if (GetParam() != Config::FrameRateOverride::Enabled) { return; } auto selector = createSelector(kModes_60_90, kModeId60); constexpr FpsRanges kCappedAt30 = {{60_Hz, 90_Hz}, {30_Hz, 30_Hz}}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy( {DisplayModeId(kModeId60), kCappedAt30, kCappedAt30})); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].vote = LayerVoteType::Min; EXPECT_FRAME_RATE_MODE(kMode60, 30_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, frameRateNotInRange) { auto selector = createSelector(kModes_60_90, kModeId60); constexpr FpsRanges k60Only = {{60_Hz, 90_Hz}, {60_Hz, 60_Hz}}; constexpr FpsRanges kAll = {{0_Hz, 90_Hz}, {0_Hz, 90_Hz}}; EXPECT_EQ(SetPolicyResult::Changed, selector.setDisplayManagerPolicy({DisplayModeId(kModeId60), k60Only, kAll})); std::vector layers = {{.weight = 1.f}}; layers[0].name = "Test layer"; layers[0].vote = LayerVoteType::Heuristic; layers[0].desiredRefreshRate = 45_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } } // namespace } // namespace android::scheduler