| /* |
| * 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 <ftl/enum.h> |
| #include <gmock/gmock.h> |
| #include <log/log.h> |
| #include <ui/Size.h> |
| |
| #include "DisplayHardware/HWC2.h" |
| #include "FpsOps.h" |
| #include "Scheduler/RefreshRateConfigs.h" |
| #include "mock/DisplayHardware/MockDisplayMode.h" |
| |
| using namespace std::chrono_literals; |
| |
| namespace android::scheduler { |
| |
| namespace hal = android::hardware::graphics::composer::hal; |
| |
| using LayerVoteType = RefreshRateConfigs::LayerVoteType; |
| using LayerRequirement = RefreshRateConfigs::LayerRequirement; |
| |
| using mock::createDisplayMode; |
| |
| struct TestableRefreshRateConfigs : RefreshRateConfigs { |
| using RefreshRateConfigs::RefreshRateConfigs; |
| |
| DisplayModePtr getMinSupportedRefreshRate() const { |
| std::lock_guard lock(mLock); |
| return mMinRefreshRateModeIt->second; |
| } |
| |
| DisplayModePtr getMaxSupportedRefreshRate() const { |
| std::lock_guard lock(mLock); |
| return mMaxRefreshRateModeIt->second; |
| } |
| |
| DisplayModePtr getMinRefreshRateByPolicy() const { |
| std::lock_guard lock(mLock); |
| return getMinRefreshRateByPolicyLocked(); |
| } |
| |
| const std::vector<Fps>& knownFrameRates() const { return mKnownFrameRates; } |
| |
| using RefreshRateConfigs::GetBestRefreshRateCache; |
| auto& mutableGetBestRefreshRateCache() { return mGetBestRefreshRateCache; } |
| |
| auto getBestRefreshRateAndSignals(const std::vector<LayerRequirement>& layers, |
| GlobalSignals signals) const { |
| return RefreshRateConfigs::getBestRefreshRate(layers, signals); |
| } |
| |
| DisplayModePtr getBestRefreshRate(const std::vector<LayerRequirement>& layers = {}, |
| GlobalSignals signals = {}) const { |
| return getBestRefreshRateAndSignals(layers, signals).first; |
| } |
| }; |
| |
| class RefreshRateConfigsTest : public testing::Test { |
| protected: |
| RefreshRateConfigsTest(); |
| ~RefreshRateConfigsTest(); |
| |
| 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 inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz); |
| static inline const DisplayModePtr kMode60Frac = createDisplayMode(kModeId60Frac, 59.94_Hz); |
| static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz); |
| static inline const DisplayModePtr kMode90_G1 = createDisplayMode(kModeId90, 90_Hz, 1); |
| static inline const DisplayModePtr kMode90_4K = |
| createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160}); |
| static inline const DisplayModePtr kMode72 = createDisplayMode(kModeId72, 72_Hz); |
| static inline const DisplayModePtr kMode72_G1 = createDisplayMode(kModeId72, 72_Hz, 1); |
| static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz); |
| static inline const DisplayModePtr kMode120_G1 = createDisplayMode(kModeId120, 120_Hz, 1); |
| static inline const DisplayModePtr kMode30 = createDisplayMode(kModeId30, 30_Hz); |
| static inline const DisplayModePtr kMode30_G1 = createDisplayMode(kModeId30, 30_Hz, 1); |
| static inline const DisplayModePtr kMode30Frac = createDisplayMode(kModeId30Frac, 29.97_Hz); |
| static inline const DisplayModePtr kMode25 = createDisplayMode(kModeId25, 25_Hz); |
| static inline const DisplayModePtr kMode25_G1 = createDisplayMode(kModeId25, 25_Hz, 1); |
| static inline const DisplayModePtr kMode50 = createDisplayMode(kModeId50, 50_Hz); |
| static inline const DisplayModePtr kMode24 = createDisplayMode(kModeId24, 24_Hz); |
| static inline const DisplayModePtr kMode24Frac = createDisplayMode(kModeId24Frac, 23.976_Hz); |
| |
| // Test configurations. |
| static inline const DisplayModes kModes_60 = makeModes(kMode60); |
| 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); |
| |
| // 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); |
| }; |
| |
| RefreshRateConfigsTest::RefreshRateConfigsTest() { |
| 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()); |
| } |
| |
| RefreshRateConfigsTest::~RefreshRateConfigsTest() { |
| 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 { |
| |
| TEST_F(RefreshRateConfigsTest, oneMode_canSwitch) { |
| RefreshRateConfigs configs(kModes_60, kModeId60); |
| EXPECT_FALSE(configs.canSwitch()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, invalidPolicy) { |
| RefreshRateConfigs configs(kModes_60, kModeId60); |
| EXPECT_LT(configs.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}}), 0); |
| EXPECT_LT(configs.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}}), 0); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| const auto minRate = configs.getMinSupportedRefreshRate(); |
| const auto performanceRate = configs.getMaxSupportedRefreshRate(); |
| |
| EXPECT_EQ(kMode60, minRate); |
| EXPECT_EQ(kMode90, performanceRate); |
| |
| const auto minRateByPolicy = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRateByPolicy = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(minRateByPolicy, minRate); |
| EXPECT_EQ(performanceRateByPolicy, performanceRate); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap_differentGroups) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| const auto minRate = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate = configs.getMaxSupportedRefreshRate(); |
| const auto minRate60 = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate60 = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode60, minRate); |
| EXPECT_EQ(kMode60, minRate60); |
| EXPECT_EQ(kMode60, performanceRate60); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0); |
| configs.setActiveModeId(kModeId90); |
| |
| const auto minRate90 = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate90 = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode90_G1, performanceRate); |
| EXPECT_EQ(kMode90_G1, minRate90); |
| EXPECT_EQ(kMode90_G1, performanceRate90); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap_differentResolutions) { |
| TestableRefreshRateConfigs configs(kModes_60_90_4K, kModeId60); |
| |
| const auto minRate = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate = configs.getMaxSupportedRefreshRate(); |
| const auto minRate60 = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate60 = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode60, minRate); |
| EXPECT_EQ(kMode60, minRate60); |
| EXPECT_EQ(kMode60, performanceRate60); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0); |
| configs.setActiveModeId(kModeId90); |
| |
| const auto minRate90 = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate90 = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode90_4K, performanceRate); |
| EXPECT_EQ(kMode90_4K, minRate90); |
| EXPECT_EQ(kMode90_4K, performanceRate90); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_policyChange) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| const auto minRate = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode60, minRate); |
| EXPECT_EQ(kMode90, performanceRate); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0); |
| |
| const auto minRate60 = configs.getMinRefreshRateByPolicy(); |
| const auto performanceRate60 = configs.getMaxRefreshRateByPolicy(); |
| |
| EXPECT_EQ(kMode60, minRate60); |
| EXPECT_EQ(kMode60, performanceRate60); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_getActiveMode) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| { |
| const auto mode = configs.getActiveMode(); |
| EXPECT_EQ(mode->getId(), kModeId60); |
| } |
| |
| configs.setActiveModeId(kModeId90); |
| { |
| const auto mode = configs.getActiveMode(); |
| EXPECT_EQ(mode->getId(), kModeId90); |
| } |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0); |
| { |
| const auto mode = configs.getActiveMode(); |
| EXPECT_EQ(mode->getId(), kModeId90); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) { |
| { |
| TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate()); |
| |
| EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), NO_ERROR); |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate()); |
| } |
| { |
| // We select max even when this will cause a non-seamless switch. |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| constexpr bool kAllowGroupSwitching = true; |
| EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId90, kAllowGroupSwitching, {0_Hz, 90_Hz}}), |
| NO_ERROR); |
| EXPECT_EQ(kMode90_G1, configs.getBestRefreshRate()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| lr.vote = LayerVoteType::Min; |
| lr.name = "Min"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| lr.name = "Max"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| lr.name = "90Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| lr.name = "45Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| lr.name = "30Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.name = "24Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.name = ""; |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0); |
| |
| lr.vote = LayerVoteType::Min; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0); |
| |
| lr.vote = LayerVoteType::Min; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}}), 0); |
| lr.vote = LayerVoteType::Min; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60, {.frameRateMultipleThreshold = 90}); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| lr.vote = LayerVoteType::Min; |
| lr.name = "Min"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| lr.name = "Max"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| lr.name = "90Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| lr.name = "45Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| lr.name = "30Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.name = "24Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) { |
| TestableRefreshRateConfigs configs(kModes_60_72_90, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| lr.vote = LayerVoteType::Min; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90_120) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| |
| lr1.desiredRefreshRate = 24_Hz; |
| lr1.vote = LayerVoteType::Heuristic; |
| lr2.desiredRefreshRate = 48_Hz; |
| lr2.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| |
| lr1.desiredRefreshRate = 24_Hz; |
| lr1.vote = LayerVoteType::Heuristic; |
| lr2.desiredRefreshRate = 48_Hz; |
| lr2.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60, |
| {.frameRateMultipleThreshold = 120}); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| |
| lr1.desiredRefreshRate = 24_Hz; |
| lr1.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr1.name = "24Hz ExplicitExactOrMultiple"; |
| lr2.vote = LayerVoteType::Max; |
| lr2.name = "Max"; |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { |
| TestableRefreshRateConfigs configs(kModes_30_60, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| lr.vote = LayerVoteType::Min; |
| EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| lr.vote = LayerVoteType::Min; |
| lr.name = "Min"; |
| EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| lr.name = "Max"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 90_Hz; |
| lr.vote = LayerVoteType::Heuristic; |
| lr.name = "90Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Heuristic"; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| lr.desiredRefreshRate = 45_Hz; |
| lr.name = "45Hz Heuristic"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| lr.desiredRefreshRate = 30_Hz; |
| lr.name = "30Hz Heuristic"; |
| EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.name = "24Hz Heuristic"; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr.name = "24Hz ExplicitExactOrMultiple"; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true})); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_PriorityTest) { |
| TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Min; |
| lr2.vote = LayerVoteType::Heuristic; |
| lr2.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Min; |
| lr2.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr2.desiredRefreshRate = 24_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Max; |
| lr2.vote = LayerVoteType::Heuristic; |
| lr2.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Max; |
| lr2.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr2.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Heuristic; |
| lr1.desiredRefreshRate = 15_Hz; |
| lr2.vote = LayerVoteType::Heuristic; |
| lr2.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Heuristic; |
| lr1.desiredRefreshRate = 30_Hz; |
| lr2.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr2.desiredRefreshRate = 45_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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 = configs.getBestRefreshRate(layers); |
| EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses " |
| << to_string(mode->getFps()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) { |
| TestableRefreshRateConfigs configs(kModes_60_120, kModeId60, |
| {.frameRateMultipleThreshold = 120}); |
| |
| std::vector<LayerRequirement> 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 = configs.getBestRefreshRate(layers); |
| EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses " |
| << to_string(mode->getFps()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, twoModes_getBestRefreshRate_Explicit) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::ExplicitDefault; |
| lr1.desiredRefreshRate = 90_Hz; |
| lr2.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr2.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::Heuristic; |
| lr1.desiredRefreshRate = 90_Hz; |
| lr2.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr2.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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 = configs.getBestRefreshRate(layers, {}); |
| EXPECT_EQ(kMode90, mode) << lr.desiredRefreshRate << " chooses " |
| << to_string(mode->getFps()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_Multiples) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr1.desiredRefreshRate = 60_Hz; |
| lr1.name = "60Hz ExplicitExactOrMultiple"; |
| lr2.vote = LayerVoteType::Max; |
| lr2.name = "Max"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr1.desiredRefreshRate = 30_Hz; |
| lr1.name = "30Hz ExplicitExactOrMultiple"; |
| lr2.vote = LayerVoteType::Max; |
| lr2.name = "Max"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| |
| lr1.vote = LayerVoteType::ExplicitExactOrMultiple; |
| lr1.desiredRefreshRate = 60_Hz; |
| lr1.name = "60Hz ExplicitExactOrMultiple"; |
| lr2.vote = LayerVoteType::NoVote; |
| lr2.name = "NoVote"; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(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, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, touchConsidered) { |
| RefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| auto [_, signals] = configs.getBestRefreshRate({}, {}); |
| EXPECT_FALSE(signals.touch); |
| |
| std::tie(std::ignore, signals) = configs.getBestRefreshRate({}, {.touch = true}); |
| EXPECT_TRUE(signals.touch); |
| |
| std::vector<LayerRequirement> 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) = configs.getBestRefreshRate(layers, {.touch = true}); |
| EXPECT_TRUE(signals.touch); |
| |
| lr1.vote = LayerVoteType::ExplicitDefault; |
| 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) = configs.getBestRefreshRate(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) = configs.getBestRefreshRate(layers, {.touch = true}); |
| EXPECT_TRUE(signals.touch); |
| |
| lr1.vote = LayerVoteType::ExplicitDefault; |
| 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) = configs.getBestRefreshRate(layers, {.touch = true}); |
| EXPECT_FALSE(signals.touch); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) { |
| TestableRefreshRateConfigs configs(kModes_60_90_72_120, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| // Prepare a table with the vote and the expected refresh rate |
| const std::initializer_list<std::pair<Fps, Fps>> 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, configs.getBestRefreshRate(layers)->getFps()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, |
| getBestRefreshRate_ExplicitExactOrMultiple_WithFractionalRefreshRates) { |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| // Test that 23.976 will choose 24 if 23.976 is not supported |
| { |
| TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| // Test that 24 will choose 23.976 if 24 is not supported |
| { |
| TestableRefreshRateConfigs configs(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac, |
| kMode60, kMode60Frac), |
| kModeId60); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.name = "ExplicitExactOrMultiple 24 Hz"; |
| EXPECT_EQ(kModeId24Frac, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| // Test that 29.97 will prefer 59.94 over 60 and 30 |
| { |
| TestableRefreshRateConfigs configs(makeModes(kMode24, kMode24Frac, kMode25, kMode30, |
| kMode60, kMode60Frac), |
| kModeId60); |
| |
| lr.desiredRefreshRate = 29.97_Hz; |
| lr.name = "ExplicitExactOrMultiple 29.97 Hz"; |
| EXPECT_EQ(kModeId60Frac, configs.getBestRefreshRate(layers)->getId()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact_WithFractionalRefreshRates) { |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& lr = layers[0]; |
| |
| // Test that voting for supported refresh rate will select this refresh rate |
| { |
| TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers)->getFps()); |
| } |
| } |
| |
| // Test that 23.976 will choose 24 if 23.976 is not supported |
| { |
| TestableRefreshRateConfigs configs(makeModes(kMode24, kMode25, kMode30, kMode30Frac, |
| kMode60, kMode60Frac), |
| kModeId60); |
| |
| lr.vote = LayerVoteType::ExplicitExact; |
| lr.desiredRefreshRate = 23.976_Hz; |
| lr.name = "ExplicitExact 23.976 Hz"; |
| EXPECT_EQ(kModeId24, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| // Test that 24 will choose 23.976 if 24 is not supported |
| { |
| TestableRefreshRateConfigs configs(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac, |
| kMode60, kMode60Frac), |
| kModeId60); |
| |
| lr.desiredRefreshRate = 24_Hz; |
| lr.name = "ExplicitExact 24 Hz"; |
| EXPECT_EQ(kModeId24Frac, configs.getBestRefreshRate(layers)->getId()); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, |
| getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) { |
| RefreshRateConfigs configs(kModes_60_90, kModeId90); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0); |
| |
| std::vector<LayerRequirement> 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 [mode, signals] = configs.getBestRefreshRate(layers, {.touch = true, .idle = true}); |
| |
| EXPECT_EQ(mode, kMode60); |
| EXPECT_FALSE(signals.touch); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, |
| getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 90_Hz}}), 0); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers, {.idle = true})); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, |
| getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId90); |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0); |
| |
| const auto [mode, signals] = configs.getBestRefreshRateAndSignals({}, {}); |
| EXPECT_EQ(mode, kMode90); |
| EXPECT_FALSE(signals.touch); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| |
| lr.focused = true; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::ExplicitDefault; |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz ExplicitDefault"; |
| lr.focused = false; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.focused = true; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Heuristic; |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Heuristic"; |
| lr.focused = false; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.focused = true; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Max; |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Max"; |
| lr.focused = false; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.focused = true; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.vote = LayerVoteType::Min; |
| lr.desiredRefreshRate = 60_Hz; |
| lr.name = "60Hz Min"; |
| lr.focused = false; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| lr.focused = true; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingNotAllowed) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| // The default policy doesn't allow group switching. Verify that no |
| // group switches are performed. |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayer) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamless) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| // Verify that we won't change the group if seamless switch is required. |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| configs.setActiveModeId(kModeId90); |
| |
| // Verify that we won't do a seamless switch if we request the same mode as the default |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerDefaultSeamlessness) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| configs.setActiveModeId(kModeId90); |
| |
| // Verify that if the current config is in another group and there are no layers with |
| // seamlessness=SeamedAndSeamless we'll go back to the default group. |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| configs.setActiveModeId(kModeId90); |
| |
| // If there's a layer with seamlessness=SeamedAndSeamless, another layer with |
| // seamlessness=OnlySeamless can't change the mode group. |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| configs.setActiveModeId(kModeId90); |
| |
| // 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<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60); |
| |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| configs.setActiveModeId(kModeId90); |
| |
| // Layer with seamlessness=Default can change the mode group if there's a not |
| // focused layer with seamlessness=SeamedAndSeamless. This happens for example, |
| // when in split screen mode the user switches between the two visible applications. |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) { |
| TestableRefreshRateConfigs configs(kModes_30_60, kModeId60); |
| |
| // Allow group switching. |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| |
| configs.setActiveModeId(kModeId120); |
| EXPECT_EQ(kModeId120, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, nonSeamlessExactAndSeamlessMultipleLayers) { |
| TestableRefreshRateConfigs configs(kModes_25_30_50_60, kModeId60); |
| |
| // Allow group switching. |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)->getId()); |
| |
| auto& seamedLayer = layers[0]; |
| seamedLayer.desiredRefreshRate = 30_Hz; |
| seamedLayer.name = "30Hz ExplicitDefault"; |
| configs.setActiveModeId(kModeId30); |
| |
| EXPECT_EQ(kModeId25, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, minLayersDontTrigerSeamedSwitch) { |
| TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId90); |
| |
| // Allow group switching. |
| RefreshRateConfigs::Policy policy; |
| policy.defaultMode = configs.getCurrentPolicy().defaultMode; |
| policy.allowGroupSwitching = true; |
| EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0); |
| |
| std::vector<LayerRequirement> layers = { |
| {.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}}; |
| |
| EXPECT_EQ(kModeId90, configs.getBestRefreshRate(layers)->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { |
| TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| layers[0].name = "Test layer"; |
| |
| struct Args { |
| bool touch = false; |
| bool focused = true; |
| }; |
| |
| // Return the config ID from calling getBestRefreshRate() for a single layer with the |
| // given voteType and fps. |
| auto getFrameRate = [&](LayerVoteType voteType, Fps fps, Args args = {}) -> DisplayModeId { |
| layers[0].vote = voteType; |
| layers[0].desiredRefreshRate = fps; |
| layers[0].focused = args.focused; |
| return configs.getBestRefreshRate(layers, {.touch = args.touch})->getId(); |
| }; |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 60_Hz}, {30_Hz, 90_Hz}}), 0); |
| |
| EXPECT_EQ(kModeId60, configs.getBestRefreshRate()->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 config. |
| 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_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 60_Hz}}), 0); |
| |
| 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_F(RefreshRateConfigsTest, idle) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| layers[0].name = "Test layer"; |
| |
| const auto getIdleFrameRate = [&](LayerVoteType voteType, bool touchActive) -> DisplayModeId { |
| layers[0].vote = voteType; |
| layers[0].desiredRefreshRate = 90_Hz; |
| |
| const auto [refreshRate, signals] = |
| configs.getBestRefreshRateAndSignals(layers, {.touch = touchActive, .idle = true}); |
| |
| // Refresh rate will be chosen by either touch state or idle state. |
| EXPECT_EQ(!touchActive, signals.idle); |
| return refreshRate->getId(); |
| }; |
| |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0); |
| |
| // Idle should be lower priority than touch boost. |
| { |
| constexpr bool kTouchActive = true; |
| EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::NoVote, kTouchActive)); |
| EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Min, kTouchActive)); |
| EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Max, kTouchActive)); |
| EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Heuristic, kTouchActive)); |
| EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::ExplicitDefault, kTouchActive)); |
| EXPECT_EQ(kModeId90, |
| getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, kTouchActive)); |
| } |
| |
| // With no layers, idle should still be lower priority than touch boost. |
| EXPECT_EQ(kModeId90, configs.getBestRefreshRate({}, {.touch = true, .idle = true})->getId()); |
| |
| // Idle should be higher precedence than other layer frame rate considerations. |
| configs.setActiveModeId(kModeId90); |
| |
| { |
| constexpr bool kTouchActive = false; |
| EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::NoVote, kTouchActive)); |
| EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Min, kTouchActive)); |
| EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Max, kTouchActive)); |
| EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Heuristic, kTouchActive)); |
| EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::ExplicitDefault, kTouchActive)); |
| EXPECT_EQ(kModeId60, |
| getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, kTouchActive)); |
| } |
| |
| // Idle should be applied rather than the current config when there are no layers. |
| EXPECT_EQ(kModeId60, configs.getBestRefreshRate({}, {.idle = true})->getId()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, findClosestKnownFrameRate) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) { |
| const auto knownFrameRate = configs.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_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) { |
| TestableRefreshRateConfigs configs(kModes_60_90, kModeId60); |
| |
| struct Expectation { |
| Fps fps; |
| DisplayModePtr mode; |
| }; |
| |
| const std::initializer_list<Expectation> 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 = configs.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<LayerRequirement> layers = {{.weight = 1.f}}; |
| auto& layer = layers[0]; |
| layer.vote = LayerVoteType::Heuristic; |
| |
| for (const auto& [fps, mode] : knownFrameRatesExpectations) { |
| layer.desiredRefreshRate = fps; |
| EXPECT_EQ(mode, configs.getBestRefreshRate(layers)); |
| } |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60); |
| |
| std::vector<LayerRequirement> 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(kMode30, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz; |
| explicitExactLayer.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 72_Hz; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 90_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 120_Hz; |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60, |
| {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz; |
| explicitExactLayer.desiredRefreshRate = 60_Hz; |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 72_Hz; |
| EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 90_Hz; |
| EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers)); |
| |
| explicitExactLayer.desiredRefreshRate = 120_Hz; |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ReadsCache) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60); |
| |
| using GlobalSignals = RefreshRateConfigs::GlobalSignals; |
| const auto args = std::make_pair(std::vector<LayerRequirement>{}, |
| GlobalSignals{.touch = true, .idle = true}); |
| const auto result = std::make_pair(kMode90, GlobalSignals{.touch = true}); |
| |
| configs.mutableGetBestRefreshRateCache() = {args, result}; |
| |
| EXPECT_EQ(result, configs.getBestRefreshRateAndSignals(args.first, args.second)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) { |
| TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60); |
| |
| EXPECT_FALSE(configs.mutableGetBestRefreshRateCache()); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}}; |
| RefreshRateConfigs::GlobalSignals globalSignals{.touch = true, .idle = true}; |
| |
| const auto result = configs.getBestRefreshRateAndSignals(layers, globalSignals); |
| |
| const auto& cache = configs.mutableGetBestRefreshRateCache(); |
| ASSERT_TRUE(cache); |
| |
| EXPECT_EQ(cache->arguments, std::make_pair(layers, globalSignals)); |
| EXPECT_EQ(cache->result, result); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) { |
| TestableRefreshRateConfigs configs(kModes_60_120, kModeId60, {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers, {.touch = true})); |
| |
| explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote; |
| |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers)); |
| EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers, {.touch = true})); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_FractionalRefreshRates_ExactAndDefault) { |
| TestableRefreshRateConfigs configs(kModes_24_25_30_50_60_Frac, kModeId60, |
| {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers)); |
| } |
| |
| // b/190578904 |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_withCloseRefreshRates) { |
| constexpr int kMinRefreshRate = 10; |
| 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<float>(fps)))); |
| } |
| |
| const TestableRefreshRateConfigs configs(std::move(displayModes), |
| DisplayModeId(kMinRefreshRate)); |
| |
| std::vector<LayerRequirement> layers = {{.weight = 1.f}}; |
| const auto testRefreshRate = [&](Fps fps, LayerVoteType vote) { |
| layers[0].desiredRefreshRate = fps; |
| layers[0].vote = vote; |
| EXPECT_EQ(fps.getIntValue(), configs.getBestRefreshRate(layers)->getFps().getIntValue()) |
| << "Failed for " << ftl::enum_string(vote); |
| }; |
| |
| for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) { |
| const auto refreshRate = Fps::fromValue(static_cast<float>(fps)); |
| testRefreshRate(refreshRate, LayerVoteType::Heuristic); |
| testRefreshRate(refreshRate, LayerVoteType::ExplicitDefault); |
| testRefreshRate(refreshRate, LayerVoteType::ExplicitExactOrMultiple); |
| testRefreshRate(refreshRate, LayerVoteType::ExplicitExact); |
| } |
| } |
| |
| // b/190578904 |
| TEST_F(RefreshRateConfigsTest, getBestRefreshRate_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 RefreshRateConfigs::GlobalSignals globalSignals = {.touch = false, .idle = false}; |
| const TestableRefreshRateConfigs configs(std::move(displayModes), kActiveModeId); |
| |
| const std::vector<LayerRequirement> 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, configs.getBestRefreshRate(layers, globalSignals)->getFps()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, modeComparison) { |
| EXPECT_LT(kMode60->getFps(), kMode90->getFps()); |
| EXPECT_GE(kMode60->getFps(), kMode60->getFps()); |
| EXPECT_GE(kMode90->getFps(), kMode90->getFps()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) { |
| using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction; |
| |
| RefreshRateConfigs configs(kModes_60_90, kModeId90); |
| |
| // SetPolicy(60, 90), current 90Hz => TurnOn. |
| EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction()); |
| |
| // SetPolicy(60, 90), current 60Hz => TurnOn. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction()); |
| |
| // SetPolicy(60, 60), current 60Hz => TurnOff |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction()); |
| |
| // SetPolicy(90, 90), current 90Hz => TurnOff. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, testKernelIdleTimerActionFor120Hz) { |
| using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction; |
| |
| RefreshRateConfigs configs(kModes_60_120, kModeId120); |
| |
| // SetPolicy(0, 60), current 60Hz => TurnOn. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction()); |
| |
| // SetPolicy(60, 60), current 60Hz => TurnOff. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction()); |
| |
| // SetPolicy(60, 120), current 60Hz => TurnOn. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction()); |
| |
| // SetPolicy(120, 120), current 120Hz => TurnOff. |
| EXPECT_GE(configs.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}}), 0); |
| EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getFrameRateDivisor) { |
| RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId30); |
| |
| const auto frameRate = 30_Hz; |
| Fps displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(1, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate)); |
| |
| configs.setActiveModeId(kModeId60); |
| displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(2, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate)); |
| |
| configs.setActiveModeId(kModeId72); |
| displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate)); |
| |
| configs.setActiveModeId(kModeId90); |
| displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(3, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate)); |
| |
| configs.setActiveModeId(kModeId120); |
| displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate)); |
| |
| configs.setActiveModeId(kModeId90); |
| displayRefreshRate = configs.getActiveMode()->getFps(); |
| EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, 22.5_Hz)); |
| |
| EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(24_Hz, 25_Hz)); |
| EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(24_Hz, 23.976_Hz)); |
| EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(30_Hz, 29.97_Hz)); |
| EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(60_Hz, 59.94_Hz)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, isFractionalPairOrMultiple) { |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(23.976_Hz, 24_Hz)); |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(24_Hz, 23.976_Hz)); |
| |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 30_Hz)); |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(30_Hz, 29.97_Hz)); |
| |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(59.94_Hz, 60_Hz)); |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(60_Hz, 59.94_Hz)); |
| |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 60_Hz)); |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(60_Hz, 29.97_Hz)); |
| |
| EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(59.94_Hz, 30_Hz)); |
| EXPECT_TRUE(RefreshRateConfigs::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(RefreshRateConfigs::isFractionalPairOrMultiple(refreshRate, refreshRate)); |
| } |
| |
| EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(24_Hz, 25_Hz)); |
| EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(23.978_Hz, 25_Hz)); |
| EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz)); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) { |
| RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120); |
| |
| EXPECT_TRUE(configs.getFrameRateOverrides({}, 120_Hz, {}).empty()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { |
| RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120, |
| {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> 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 = configs.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 = configs.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::NoVote; |
| frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| |
| layers[0].vote = LayerVoteType::Min; |
| frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| |
| layers[0].vote = LayerVoteType::Max; |
| frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| |
| layers[0].vote = LayerVoteType::Heuristic; |
| frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { |
| RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120, |
| {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> 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 = configs.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 = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| } |
| |
| TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) { |
| RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120, |
| {.enableFrameRateOverride = true}); |
| |
| std::vector<LayerRequirement> layers = {{.ownerUid = 1234, .weight = 1.f}}; |
| layers[0].name = "Test layer"; |
| layers[0].desiredRefreshRate = 60_Hz; |
| layers[0].vote = LayerVoteType::ExplicitDefault; |
| |
| auto frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_EQ(1u, frameRateOverrides.size()); |
| ASSERT_EQ(1u, frameRateOverrides.count(1234)); |
| EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); |
| |
| frameRateOverrides = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_EQ(1u, frameRateOverrides.size()); |
| ASSERT_EQ(1u, frameRateOverrides.count(1234)); |
| EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); |
| |
| frameRateOverrides = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {}); |
| EXPECT_EQ(1u, frameRateOverrides.size()); |
| ASSERT_EQ(1u, frameRateOverrides.count(1234)); |
| EXPECT_EQ(60_Hz, frameRateOverrides.at(1234)); |
| |
| frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {.touch = true}); |
| EXPECT_TRUE(frameRateOverrides.empty()); |
| } |
| |
| } // namespace |
| } // namespace android::scheduler |