/* * 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. */ // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra" #undef LOG_TAG #define LOG_TAG "SchedulerUnittests" #include #include #include #include #include "../../Scheduler/RefreshRateConfigs.h" #include "DisplayHardware/HWC2.h" #include "Scheduler/RefreshRateConfigs.h" using namespace std::chrono_literals; namespace android { namespace scheduler { namespace hal = android::hardware::graphics::composer::hal; using RefreshRate = RefreshRateConfigs::RefreshRate; using LayerVoteType = RefreshRateConfigs::LayerVoteType; using LayerRequirement = RefreshRateConfigs::LayerRequirement; class RefreshRateConfigsTest : public testing::Test { protected: using GetBestRefreshRateInvocation = RefreshRateConfigs::GetBestRefreshRateInvocation; RefreshRateConfigsTest(); ~RefreshRateConfigsTest(); RefreshRate createRefreshRate(DisplayModePtr displayMode) { return {displayMode->getId(), displayMode, displayMode->getFps(), RefreshRate::ConstructorTag(0)}; } Fps findClosestKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs, Fps frameRate) { return refreshRateConfigs.findClosestKnownFrameRate(frameRate); } std::vector getKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs) { return refreshRateConfigs.mKnownFrameRates; } RefreshRate getMinRefreshRateByPolicy(const RefreshRateConfigs& refreshRateConfigs) { std::lock_guard lock(refreshRateConfigs.mLock); return refreshRateConfigs.getMinRefreshRateByPolicyLocked(); } RefreshRate getMinSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) { std::lock_guard lock(refreshRateConfigs.mLock); return *refreshRateConfigs.mMinSupportedRefreshRate; } RefreshRate getMaxSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) { std::lock_guard lock(refreshRateConfigs.mLock); return *refreshRateConfigs.mMaxSupportedRefreshRate; } void setLastBestRefreshRateInvocation(RefreshRateConfigs& refreshRateConfigs, const GetBestRefreshRateInvocation& invocation) { std::lock_guard lock(refreshRateConfigs.mLock); refreshRateConfigs.lastBestRefreshRateInvocation.emplace( GetBestRefreshRateInvocation(invocation)); } std::optional getLastBestRefreshRateInvocation( const RefreshRateConfigs& refreshRateConfigs) { std::lock_guard lock(refreshRateConfigs.mLock); return refreshRateConfigs.lastBestRefreshRateInvocation; } // Test config IDs static inline const DisplayModeId HWC_CONFIG_ID_60 = DisplayModeId(0); static inline const DisplayModeId HWC_CONFIG_ID_90 = DisplayModeId(1); static inline const DisplayModeId HWC_CONFIG_ID_72 = DisplayModeId(2); static inline const DisplayModeId HWC_CONFIG_ID_120 = DisplayModeId(3); static inline const DisplayModeId HWC_CONFIG_ID_30 = DisplayModeId(4); static inline const DisplayModeId HWC_CONFIG_ID_25 = DisplayModeId(5); static inline const DisplayModeId HWC_CONFIG_ID_50 = DisplayModeId(6); // Test configs DisplayModePtr mConfig60 = createDisplayMode(HWC_CONFIG_ID_60, 0, Fps(60.0f).getPeriodNsecs()); DisplayModePtr mConfig90 = createDisplayMode(HWC_CONFIG_ID_90, 0, Fps(90.0f).getPeriodNsecs()); DisplayModePtr mConfig90DifferentGroup = createDisplayMode(HWC_CONFIG_ID_90, 1, Fps(90.0f).getPeriodNsecs()); DisplayModePtr mConfig90DifferentResolution = createDisplayMode(HWC_CONFIG_ID_90, 0, Fps(90.0f).getPeriodNsecs(), ui::Size(111, 222)); DisplayModePtr mConfig72 = createDisplayMode(HWC_CONFIG_ID_72, 0, Fps(72.0f).getPeriodNsecs()); DisplayModePtr mConfig72DifferentGroup = createDisplayMode(HWC_CONFIG_ID_72, 1, Fps(72.0f).getPeriodNsecs()); DisplayModePtr mConfig120 = createDisplayMode(HWC_CONFIG_ID_120, 0, Fps(120.0f).getPeriodNsecs()); DisplayModePtr mConfig120DifferentGroup = createDisplayMode(HWC_CONFIG_ID_120, 1, Fps(120.0f).getPeriodNsecs()); DisplayModePtr mConfig30 = createDisplayMode(HWC_CONFIG_ID_30, 0, Fps(30.0f).getPeriodNsecs()); DisplayModePtr mConfig30DifferentGroup = createDisplayMode(HWC_CONFIG_ID_30, 1, Fps(30.0f).getPeriodNsecs()); DisplayModePtr mConfig25DifferentGroup = createDisplayMode(HWC_CONFIG_ID_25, 1, Fps(25.0f).getPeriodNsecs()); DisplayModePtr mConfig50 = createDisplayMode(HWC_CONFIG_ID_50, 0, Fps(50.0f).getPeriodNsecs()); // Test device configurations // The positions of the configs in the arrays below MUST match their IDs. For example, // the first config should always be 60Hz, the second 90Hz etc. DisplayModes m60OnlyConfigDevice = {mConfig60}; DisplayModes m60_90Device = {mConfig60, mConfig90}; DisplayModes m60_90DeviceWithDifferentGroups = {mConfig60, mConfig90DifferentGroup}; DisplayModes m60_90DeviceWithDifferentResolutions = {mConfig60, mConfig90DifferentResolution}; DisplayModes m60_72_90Device = {mConfig60, mConfig90, mConfig72}; DisplayModes m60_90_72_120Device = {mConfig60, mConfig90, mConfig72, mConfig120}; DisplayModes m30_60_72_90_120Device = {mConfig60, mConfig90, mConfig72, mConfig120, mConfig30}; DisplayModes m30_60Device = {mConfig60, mConfig90DifferentGroup, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30}; DisplayModes m30_60_72_90Device = {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup, mConfig30}; DisplayModes m30_60_90Device = {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30}; DisplayModes m25_30_50_60Device = {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30DifferentGroup, mConfig25DifferentGroup, mConfig50}; DisplayModes m60_120Device = {mConfig60, mConfig120}; // Expected RefreshRate objects RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, Fps(60), RefreshRate::ConstructorTag(0)}; RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60, createDisplayMode(HWC_CONFIG_ID_60, 0, 16666665), Fps(60), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, Fps(90), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup, Fps(90), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90, mConfig90DifferentResolution, Fps(90), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, Fps(72.0f), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, Fps(30), RefreshRate::ConstructorTag(0)}; RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120), RefreshRate::ConstructorTag(0)}; private: DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod, ui::Size resolution = ui::Size()); }; using Builder = DisplayMode::Builder; 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()); } DisplayModePtr RefreshRateConfigsTest::createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod, ui::Size resolution) { return DisplayMode::Builder(hal::HWConfigId(modeId.value())) .setId(modeId) .setVsyncPeriod(int32_t(vsyncPeriod)) .setGroup(group) .setHeight(resolution.height) .setWidth(resolution.width) .build(); } namespace { /* ------------------------------------------------------------------------ * Test cases */ TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) { auto refreshRateConfigs = std::make_unique(m60OnlyConfigDevice, /*currentConfigId=*/HWC_CONFIG_ID_60); } TEST_F(RefreshRateConfigsTest, invalidPolicy) { auto refreshRateConfigs = std::make_unique(m60OnlyConfigDevice, /*currentConfigId=*/HWC_CONFIG_ID_60); ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({DisplayModeId(10), {Fps(60), Fps(60)}}), 0); ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(20), Fps(40)}}), 0); } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); const auto& minRate = getMinSupportedRefreshRate(*refreshRateConfigs); const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs); ASSERT_EQ(mExpected60Config, minRate); ASSERT_EQ(mExpected90Config, performanceRate); const auto& minRateByPolicy = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(minRateByPolicy, minRate); ASSERT_EQ(performanceRateByPolicy, performanceRate); } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs); const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected60Config, minRate); ASSERT_EQ(mExpected60Config, minRate60); ASSERT_EQ(mExpected60Config, performanceRate60); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(60), Fps(90)}}), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate); ASSERT_EQ(mExpected90DifferentGroupConfig, minRate90); ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate90); } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentResolutions) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentResolutions, /*currentConfigId=*/HWC_CONFIG_ID_60); const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs); const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected60Config, minRate); ASSERT_EQ(mExpected60Config, minRate60); ASSERT_EQ(mExpected60Config, performanceRate60); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(60), Fps(90)}}), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs); const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate); ASSERT_EQ(mExpected90DifferentResolutionConfig, minRate90); ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate90); } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_policyChange) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto minRate = getMinRefreshRateByPolicy(*refreshRateConfigs); auto performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected60Config, minRate); ASSERT_EQ(mExpected90Config, performanceRate); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}), 0); auto minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs); auto performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy(); ASSERT_EQ(mExpected60Config, minRate60); ASSERT_EQ(mExpected60Config, performanceRate60); } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); { auto current = refreshRateConfigs->getCurrentRefreshRate(); EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_60); } refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); { auto current = refreshRateConfigs->getCurrentRefreshRate(); EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_90); } ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}), 0); { auto current = refreshRateConfigs->getCurrentRefreshRate(); EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_90); } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) { auto refreshRateConfigs = std::make_unique(m60_72_90Device, /*currentConfigId=*/ HWC_CONFIG_ID_72); // If there are no layers we select the default frame rate, which is the max of the primary // range. auto layers = std::vector{}; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}), 0); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); lr.name = "45Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); lr.name = "30Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.name = "24Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.name = ""; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}), 0); lr.vote = LayerVoteType::Min; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_90, {Fps(90.0f), Fps(90.0f)}}), 0); lr.vote = LayerVoteType::Min; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_60, {Fps(0.0f), Fps(120.0f)}}), 0); lr.vote = LayerVoteType::Min; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90}; auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); lr.name = "45Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); lr.name = "30Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.name = "24Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) { auto refreshRateConfigs = std::make_unique(m60_72_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90_120) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(48.0f); lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(48.0f); lr2.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { auto refreshRateConfigs = std::make_unique(m30_60Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90) { auto refreshRateConfigs = std::make_unique(m30_60_72_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); lr.name = "45Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); lr.name = "30Hz Heuristic"; EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.name = "24Hz Heuristic"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.name = "24Hz ExplicitExactOrMultiple"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_PriorityTest) { auto refreshRateConfigs = std::make_unique(m30_60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::Max; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Min; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(24.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Max; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Max; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = Fps(15.0f); lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = Fps(30.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(45.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps(fps); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps(fps); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); } } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(90.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::Heuristic; lr1.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.desiredRefreshRate = Fps(60.0f); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, testInPolicy) { ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(Fps(60.000004f), Fps(60.000004f))); ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(Fps(59.0f), Fps(60.1f))); ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(75.0f), Fps(90.0f))); ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(60.0011f), Fps(90.0f))); ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(50.0f), Fps(59.998f))); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 75.0f; fps < 100.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps(fps); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(mExpected90Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_Multiples) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(90.0f); lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::ExplicitDefault; lr2.desiredRefreshRate = Fps(90.0f); lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(30.0f); lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(90.0f); lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(30.0f); lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::NoVote; lr2.name = "NoVote"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Max; lr2.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); // The other layer starts to provide buffers lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(90.0f); lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, touchConsidered) { RefreshRateConfigs::GlobalSignals consideredSignals; auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false}, &consideredSignals); EXPECT_EQ(false, consideredSignals.touch); refreshRateConfigs->getBestRefreshRate({}, {.touch = true, .idle = false}, &consideredSignals); EXPECT_EQ(true, consideredSignals.touch); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); lr2.name = "60Hz Heuristic"; refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}, &consideredSignals); EXPECT_EQ(true, consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); lr2.name = "60Hz Heuristic"; refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}, &consideredSignals); EXPECT_EQ(false, consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); lr2.name = "60Hz Heuristic"; refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}, &consideredSignals); EXPECT_EQ(true, consideredSignals.touch); lr1.vote = LayerVoteType::ExplicitDefault; lr1.desiredRefreshRate = Fps(60.0f); lr1.name = "60Hz ExplicitExactOrMultiple"; lr2.vote = LayerVoteType::Heuristic; lr2.desiredRefreshRate = Fps(60.0f); lr2.name = "60Hz Heuristic"; refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}, &consideredSignals); EXPECT_EQ(false, consideredSignals.touch); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) { auto refreshRateConfigs = std::make_unique(m60_90_72_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; // Prepare a table with the vote and the expected refresh rate const std::vector> testCases = { {130, 120}, {120, 120}, {119, 120}, {110, 120}, {100, 90}, {90, 90}, {89, 90}, {80, 72}, {73, 72}, {72, 72}, {71, 72}, {70, 72}, {65, 60}, {60, 60}, {59, 60}, {58, 60}, {55, 90}, {50, 90}, {45, 90}, {42, 120}, {40, 120}, {39, 120}, {37, 72}, {36, 72}, {35, 72}, {30, 60}, }; for (const auto& test : testCases) { lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = Fps(test.first); std::stringstream ss; ss << "ExplicitDefault " << test.first << " fps"; lr.name = ss.str(); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_TRUE(refreshRate.getFps().equalsWithMargin(Fps(test.second))) << "Expecting " << test.first << "fps => " << test.second << "Hz"; } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_90); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_90, {Fps(90.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}), 0); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; RefreshRateConfigs::GlobalSignals consideredSignals; lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz ExplicitDefault"; lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true}, &consideredSignals)); EXPECT_EQ(false, consideredSignals.touch); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_60, {Fps(60.f), Fps(60.f)}, {Fps(60.f), Fps(90.f)}}), 0); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = Fps(90.0f); lr.name = "90Hz ExplicitDefault"; lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_90); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_90, {Fps(90.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}), 0); RefreshRateConfigs::GlobalSignals consideredSignals; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false}, &consideredSignals)); EXPECT_EQ(false, consideredSignals.touch); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz ExplicitExactOrMultiple"; lr.focused = false; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::ExplicitDefault; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz ExplicitDefault"; lr.focused = false; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.focused = true; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Heuristic; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; lr.focused = false; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Max"; lr.focused = false; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Min; lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Min"; lr.focused = false; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.focused = true; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, groupSwitchingNotAllowed) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); // The default policy doesn't allow group switching. Verify that no // group switches are performed. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = Fps(90.0f); layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayer) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = Fps(90.0f); layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamless) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); // Verify that we won't change the group if seamless switch is required. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = Fps(90.0f); layer.seamlessness = Seamlessness::OnlySeamless; layer.name = "90Hz ExplicitDefault"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); // Verify that we won't do a seamless switch if we request the same mode as the default auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = Fps(60.0f); layer.seamlessness = Seamlessness::OnlySeamless; layer.name = "60Hz ExplicitDefault"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerDefaultSeamlessness) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); // 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. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = Fps(60.0f); layer.seamlessness = Seamlessness::Default; layer.name = "60Hz ExplicitDefault"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); // If there's a layer with seamlessness=SeamedAndSeamless, another layer with // seamlessness=OnlySeamless can't change the mode group. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].vote = LayerVoteType::ExplicitDefault; layers[0].desiredRefreshRate = Fps(60.0f); 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 = Fps(90.0f); layers[1].name = "90Hz ExplicitDefault"; layers[1].focused = false; ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); // 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. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].seamlessness = Seamlessness::Default; layers[0].desiredRefreshRate = Fps(60.0f); 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 = Fps(90.0f); layers[1].focused = true; layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].name = "90Hz ExplicitDefault"; ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_60); RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); // 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. auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].seamlessness = Seamlessness::Default; layers[0].desiredRefreshRate = Fps(60.0f); 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 = Fps(90.0f); layers[1].focused = false; layers[1].vote = LayerVoteType::ExplicitDefault; layers[1].name = "90Hz ExplicitDefault"; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) { auto refreshRateConfigs = std::make_unique(m30_60Device, /*currentConfigId=*/HWC_CONFIG_ID_60); // Allow group switching. RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitExactOrMultiple; layer.desiredRefreshRate = Fps(60.0f); layer.seamlessness = Seamlessness::SeamedAndSeamless; layer.name = "60Hz ExplicitExactOrMultiple"; layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_120); ASSERT_EQ(HWC_CONFIG_ID_120, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, nonSeamlessExactAndSeamlessMultipleLayers) { auto refreshRateConfigs = std::make_unique(m25_30_50_60Device, /*currentConfigId=*/HWC_CONFIG_ID_60); // Allow group switching. RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); auto layers = std::vector< LayerRequirement>{LayerRequirement{.name = "60Hz ExplicitDefault", .vote = LayerVoteType::ExplicitDefault, .desiredRefreshRate = Fps(60.0f), .seamlessness = Seamlessness::SeamedAndSeamless, .weight = 0.5f, .focused = false}, LayerRequirement{.name = "25Hz ExplicitExactOrMultiple", .vote = LayerVoteType::ExplicitExactOrMultiple, .desiredRefreshRate = Fps(25.0f), .seamlessness = Seamlessness::OnlySeamless, .weight = 1.0f, .focused = true}}; ASSERT_EQ(HWC_CONFIG_ID_50, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); auto& seamedLayer = layers[0]; seamedLayer.name = "30Hz ExplicitDefault", seamedLayer.desiredRefreshRate = Fps(30.0f); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_30); ASSERT_EQ(HWC_CONFIG_ID_25, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, minLayersDontTrigerSeamedSwitch) { auto refreshRateConfigs = std::make_unique(m60_90DeviceWithDifferentGroups, /*currentConfigId=*/HWC_CONFIG_ID_90); // Allow group switching. RefreshRateConfigs::Policy policy; policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode; policy.allowGroupSwitching = true; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); auto layers = std::vector{LayerRequirement{.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}}; ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getModeId()); } TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { auto refreshRateConfigs = std::make_unique(m30_60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; // Return the config ID from calling getBestRefreshRate() for a single layer with the // given voteType and fps. auto getFrameRate = [&](LayerVoteType voteType, Fps fps, bool touchActive = false, bool focused = true) -> DisplayModeId { layers[0].vote = voteType; layers[0].desiredRefreshRate = fps; layers[0].focused = focused; return refreshRateConfigs->getBestRefreshRate(layers, {.touch = touchActive, .idle = false}) .getModeId(); }; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_60, {Fps(30.f), Fps(60.f)}, {Fps(30.f), Fps(90.f)}}), 0); EXPECT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false}) .getModeId()); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f))); // Layers not focused are not allowed to override primary config EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f), /*touch=*/false, /*focused=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f), /*touch=*/false, /*focused=*/false)); // Touch boost should be restricted to the primary range. EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f), /*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(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f), /*touch=*/true)); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f), /*touch=*/true)); ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_60, {Fps(60.f), Fps(60.f)}, {Fps(60.f), Fps(60.f)}}), 0); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Min, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f))); EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f))); } TEST_F(RefreshRateConfigsTest, idle) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; const auto getIdleFrameRate = [&](LayerVoteType voteType, bool touchActive) -> DisplayModeId { layers[0].vote = voteType; layers[0].desiredRefreshRate = Fps(90.f); RefreshRateConfigs::GlobalSignals consideredSignals; const auto configId = refreshRateConfigs ->getBestRefreshRate(layers, {.touch = touchActive, .idle = true}, &consideredSignals) .getModeId(); // Refresh rate will be chosen by either touch state or idle state EXPECT_EQ(!touchActive, consideredSignals.idle); return configId; }; ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_60, {Fps(60.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}), 0); // Idle should be lower priority than touch boost. EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/true)); EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/true)); EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/true)); EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/true)); EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/true)); EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/true)); // With no layers, idle should still be lower priority than touch boost. EXPECT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate({}, {.touch = true, .idle = true}) .getModeId()); // Idle should be higher precedence than other layer frame rate considerations. refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/false)); EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/false)); // Idle should be applied rather than the current config when there are no layers. EXPECT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = true}) .getModeId()); } TEST_F(RefreshRateConfigsTest, findClosestKnownFrameRate) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) { const auto knownFrameRate = findClosestKnownFrameRate(*refreshRateConfigs, Fps(fps)); Fps expectedFrameRate; if (fps < 26.91f) { expectedFrameRate = Fps(24.0f); } else if (fps < 37.51f) { expectedFrameRate = Fps(30.0f); } else if (fps < 52.51f) { expectedFrameRate = Fps(45.0f); } else if (fps < 66.01f) { expectedFrameRate = Fps(60.0f); } else if (fps < 81.01f) { expectedFrameRate = Fps(72.0f); } else { expectedFrameRate = Fps(90.0f); } EXPECT_TRUE(expectedFrameRate.equalsWithMargin(knownFrameRate)) << "findClosestKnownFrameRate(" << fps << ") = " << knownFrameRate; } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) { auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60); struct ExpectedRate { Fps rate; const RefreshRate& expected; }; /* clang-format off */ std::vector knownFrameRatesExpectations = { {Fps(24.0f), mExpected60Config}, {Fps(30.0f), mExpected60Config}, {Fps(45.0f), mExpected90Config}, {Fps(60.0f), mExpected60Config}, {Fps(72.0f), mExpected90Config}, {Fps(90.0f), mExpected90Config}, }; /* clang-format on */ // Make sure the test tests all the known frame rate const auto knownFrameRateList = getKnownFrameRate(*refreshRateConfigs); const auto equal = std::equal(knownFrameRateList.begin(), knownFrameRateList.end(), knownFrameRatesExpectations.begin(), [](Fps a, const ExpectedRate& b) { return a.equalsWithMargin(b.rate); }); EXPECT_TRUE(equal); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; auto& layer = layers[0]; layer.vote = LayerVoteType::Heuristic; for (const auto& expectedRate : knownFrameRatesExpectations) { layer.desiredRefreshRate = expectedRate.rate; const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(expectedRate.expected, refreshRate); } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; auto& explicitExactLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60); explicitExactLayer.vote = LayerVoteType::ExplicitExact; explicitExactLayer.name = "ExplicitExact"; explicitExactLayer.desiredRefreshRate = Fps(30); EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected30Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120); explicitExactLayer.desiredRefreshRate = Fps(60); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(72); EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(90); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(120); EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; auto& explicitExactLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60); explicitExactLayer.vote = LayerVoteType::ExplicitExact; explicitExactLayer.name = "ExplicitExact"; explicitExactLayer.desiredRefreshRate = Fps(30); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120); explicitExactLayer.desiredRefreshRate = Fps(60); EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(72); EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(90); EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); explicitExactLayer.desiredRefreshRate = Fps(120); EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ReadsCached) { using GlobalSignals = RefreshRateConfigs::GlobalSignals; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60); setLastBestRefreshRateInvocation(*refreshRateConfigs, GetBestRefreshRateInvocation{.layerRequirements = std::vector< LayerRequirement>(), .globalSignals = {.touch = true, .idle = true}, .outSignalsConsidered = {.touch = true, .idle = false}, .resultingBestRefreshRate = createRefreshRate( mConfig90)}); EXPECT_EQ(createRefreshRate(mConfig90), refreshRateConfigs->getBestRefreshRate(std::vector(), {.touch = true, .idle = true})); const GlobalSignals cachedSignalsConsidered{.touch = true, .idle = false}; setLastBestRefreshRateInvocation(*refreshRateConfigs, GetBestRefreshRateInvocation{.layerRequirements = std::vector< LayerRequirement>(), .globalSignals = {.touch = true, .idle = true}, .outSignalsConsidered = cachedSignalsConsidered, .resultingBestRefreshRate = createRefreshRate( mConfig30)}); GlobalSignals signalsConsidered; EXPECT_EQ(createRefreshRate(mConfig30), refreshRateConfigs->getBestRefreshRate(std::vector(), {.touch = true, .idle = true}, &signalsConsidered)); EXPECT_EQ(cachedSignalsConsidered, signalsConsidered); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) { using GlobalSignals = RefreshRateConfigs::GlobalSignals; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60); ASSERT_FALSE(getLastBestRefreshRateInvocation(*refreshRateConfigs).has_value()); GlobalSignals globalSignals{.touch = true, .idle = true}; auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; const auto lastResult = refreshRateConfigs->getBestRefreshRate(layers, globalSignals, /* outSignalsConsidered */ nullptr); const auto lastInvocation = getLastBestRefreshRateInvocation(*refreshRateConfigs); ASSERT_TRUE(lastInvocation.has_value()); ASSERT_EQ(layers, lastInvocation->layerRequirements); ASSERT_EQ(globalSignals, lastInvocation->globalSignals); ASSERT_EQ(lastResult, lastInvocation->resultingBestRefreshRate); // outSignalsConsidered needs to be populated even tho earlier we gave nullptr // to getBestRefreshRate() GlobalSignals detaultSignals; ASSERT_FALSE(detaultSignals == lastInvocation->outSignalsConsidered); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; auto& explicitExactLayer = layers[0]; auto& explicitExactOrMultipleLayer = layers[1]; explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60); explicitExactLayer.vote = LayerVoteType::ExplicitExact; explicitExactLayer.name = "ExplicitExact"; explicitExactLayer.desiredRefreshRate = Fps(30); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); } TEST_F(RefreshRateConfigsTest, testComparisonOperator) { EXPECT_TRUE(mExpected60Config < mExpected90Config); EXPECT_FALSE(mExpected60Config < mExpected60Config); EXPECT_FALSE(mExpected90Config < mExpected90Config); } TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) { using KernelIdleTimerAction = scheduler::RefreshRateConfigs::KernelIdleTimerAction; auto refreshRateConfigs = std::make_unique(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_90); // SetPolicy(60, 90), current 90Hz => TurnOn. EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(60, 90), current 60Hz => TurnOn. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(90)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(60, 60), current 60Hz => TurnOff ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(90, 90), current 90Hz => TurnOff. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); } TEST_F(RefreshRateConfigsTest, testKernelIdleTimerActionFor120Hz) { using KernelIdleTimerAction = scheduler::RefreshRateConfigs::KernelIdleTimerAction; // Tests with 120Hz auto refreshRateConfigs = std::make_unique(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_120); // SetPolicy(0, 60), current 60Hz => TurnOn. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(0), Fps(60)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(60, 60), current 60Hz => TurnOff. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(60, 120), current 60Hz => TurnOn. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(120)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction()); // SetPolicy(120, 120), current 120Hz => TurnOff. ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( {HWC_CONFIG_ID_120, {Fps(120), Fps(120)}}), 0); EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); } TEST_F(RefreshRateConfigsTest, getFrameRateDivider) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_30); const auto frameRate = Fps(30.f); Fps displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(1, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate)); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_60); displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(2, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate)); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_72); displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate)); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(3, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate)); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_120); displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate)); refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90); displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps(); EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.5f))); EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.6f))); } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120); auto layers = std::vector{}; ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false) .empty()); } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, config); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = Fps(60.0f); layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::NoVote; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Min; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Max; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Heuristic; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, config); auto layers = std::vector{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, LayerRequirement{.ownerUid = 5678, .weight = 1.0f}, }; layers[0].name = "Test layer 1234"; layers[0].desiredRefreshRate = Fps(60.0f); layers[0].vote = LayerVoteType::ExplicitDefault; layers[1].name = "Test layer 5678"; layers[1].desiredRefreshRate = Fps(30.0f); layers[1].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(2, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); ASSERT_EQ(1, frameRateOverrides.count(5678)); ASSERT_EQ(30.0f, frameRateOverrides.at(5678).getValue()); layers[1].vote = LayerVoteType::Heuristic; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[1].ownerUid = 1234; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, config); auto layers = std::vector{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, }; layers[0].name = "Test layer"; layers[0].desiredRefreshRate = Fps(60.0f); layers[0].vote = LayerVoteType::ExplicitDefault; auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::ExplicitExact; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); ASSERT_TRUE(frameRateOverrides.empty()); } TEST_F(RefreshRateConfigsTest, updateDisplayModes) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_30); refreshRateConfigs->setDisplayManagerPolicy({DisplayModeId(HWC_CONFIG_ID_30), /* allowGroupSwitching */ false, /* range */ {Fps(30.0f), Fps(30.0f)}}); refreshRateConfigs->updateDisplayModes(m60_90Device, HWC_CONFIG_ID_60); const auto currentRefreshRate = refreshRateConfigs->getCurrentRefreshRate(); EXPECT_TRUE(currentRefreshRate.getFps().equalsWithMargin(Fps(60.0))); EXPECT_EQ(currentRefreshRate.getModeId(), HWC_CONFIG_ID_60); EXPECT_TRUE( getMaxSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(90.0))); EXPECT_TRUE( getMinSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(60.0))); } } // namespace } // namespace scheduler } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wextra"