|  | /* | 
|  | * 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 <gmock/gmock.h> | 
|  | #include <log/log.h> | 
|  | #include <thread> | 
|  |  | 
|  | #include "../../Scheduler/RefreshRateConfigs.h" | 
|  | #include "DisplayHardware/HWC2.h" | 
|  | #include "Scheduler/RefreshRateConfigs.h" | 
|  | #include "mock/DisplayHardware/MockDisplay.h" | 
|  |  | 
|  | using namespace std::chrono_literals; | 
|  | using testing::_; | 
|  |  | 
|  | 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: | 
|  | RefreshRateConfigsTest(); | 
|  | ~RefreshRateConfigsTest(); | 
|  |  | 
|  | float findClosestKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs, float frameRate) { | 
|  | return refreshRateConfigs.findClosestKnownFrameRate(frameRate); | 
|  | } | 
|  |  | 
|  | std::vector<float> getKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs) { | 
|  | return refreshRateConfigs.mKnownFrameRates; | 
|  | } | 
|  |  | 
|  | // Test config IDs | 
|  | static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0); | 
|  | static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(1); | 
|  | static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(2); | 
|  | static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3); | 
|  | static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4); | 
|  |  | 
|  | // Test configs | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig60 = | 
|  | createConfig(HWC_CONFIG_ID_60, 0, static_cast<int64_t>(1e9f / 60)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig90 = | 
|  | createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentGroup = | 
|  | createConfig(HWC_CONFIG_ID_90, 1, static_cast<int64_t>(1e9f / 90)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentResolution = | 
|  | createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90), 111, 222); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig72 = | 
|  | createConfig(HWC_CONFIG_ID_72, 0, static_cast<int64_t>(1e9f / 72)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig72DifferentGroup = | 
|  | createConfig(HWC_CONFIG_ID_72, 1, static_cast<int64_t>(1e9f / 72)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig120 = | 
|  | createConfig(HWC_CONFIG_ID_120, 0, static_cast<int64_t>(1e9f / 120)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig120DifferentGroup = | 
|  | createConfig(HWC_CONFIG_ID_120, 1, static_cast<int64_t>(1e9f / 120)); | 
|  | std::shared_ptr<const HWC2::Display::Config> mConfig30 = | 
|  | createConfig(HWC_CONFIG_ID_30, 0, static_cast<int64_t>(1e9f / 30)); | 
|  |  | 
|  | // Test device configurations | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60OnlyConfigDevice = {mConfig60}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90Device = {mConfig60, mConfig90}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentGroups = | 
|  | {mConfig60, mConfig90DifferentGroup}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentResolutions = | 
|  | {mConfig60, mConfig90DifferentResolution}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_72_90Device = {mConfig60, | 
|  | mConfig90, | 
|  | mConfig72}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90_72_120Device = {mConfig60, | 
|  | mConfig90, | 
|  | mConfig72, | 
|  | mConfig120}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90_120Device = {mConfig60, | 
|  | mConfig90, | 
|  | mConfig72, | 
|  | mConfig120, | 
|  | mConfig30}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60Device = | 
|  | {mConfig60, mConfig90DifferentGroup, mConfig72DifferentGroup, mConfig120DifferentGroup, | 
|  | mConfig30}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90Device = | 
|  | {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup, mConfig30}; | 
|  | std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_90Device = | 
|  | {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30}; | 
|  |  | 
|  | // Expected RefreshRate objects | 
|  | RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, "60fps", 60, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60, | 
|  | createConfig(HWC_CONFIG_ID_60, 0, 16666665), "60fps", 60, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, "90fps", 90, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup, | 
|  | "90fps", 90, RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90, | 
|  | mConfig90DifferentResolution, "90fps", 90, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, "72fps", 72, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, "30fps", 30, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  | RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, "120fps", 120, | 
|  | RefreshRate::ConstructorTag(0)}; | 
|  |  | 
|  | Hwc2::mock::Display mDisplay; | 
|  |  | 
|  | private: | 
|  | std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId, | 
|  | int32_t configGroup, | 
|  | int64_t vsyncPeriod, | 
|  | int32_t hight = -1, | 
|  | int32_t width = -1); | 
|  | }; | 
|  |  | 
|  | using Builder = HWC2::Display::Config::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()); | 
|  | } | 
|  |  | 
|  | std::shared_ptr<const HWC2::Display::Config> RefreshRateConfigsTest::createConfig( | 
|  | HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod, int32_t hight, | 
|  | int32_t width) { | 
|  | return HWC2::Display::Config::Builder(mDisplay, hal::HWConfigId(configId.value())) | 
|  | .setVsyncPeriod(int32_t(vsyncPeriod)) | 
|  | .setConfigGroup(configGroup) | 
|  | .setHeight(hight) | 
|  | .setWidth(width) | 
|  | .build(); | 
|  | } | 
|  |  | 
|  | namespace { | 
|  | /* ------------------------------------------------------------------------ | 
|  | * Test cases | 
|  | */ | 
|  | TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, invalidPolicy) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  | ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HwcConfigIndexType(10), {60, 60}}), 0); | 
|  | ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {20, 40}}), 0); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | const auto& minRate = refreshRateConfigs->getMinRefreshRate(); | 
|  | const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate(); | 
|  |  | 
|  | ASSERT_EQ(mExpected60Config, minRate); | 
|  | ASSERT_EQ(mExpected90Config, performanceRate); | 
|  |  | 
|  | const auto& minRateByPolicy = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy(); | 
|  | ASSERT_EQ(minRateByPolicy, minRate); | 
|  | ASSERT_EQ(performanceRateByPolicy, performanceRate); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate(); | 
|  | const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | 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, {60, 90}}), 0); | 
|  | refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90); | 
|  |  | 
|  | const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | 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<RefreshRateConfigs>(m60_90DeviceWithDifferentResolutions, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate(); | 
|  | const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | 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, {60, 90}}), 0); | 
|  | refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90); | 
|  |  | 
|  | const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | 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<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | auto& performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy(); | 
|  |  | 
|  | ASSERT_EQ(mExpected60Config, minRate); | 
|  | ASSERT_EQ(mExpected90Config, performanceRate); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0); | 
|  |  | 
|  | auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy(); | 
|  | auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy(); | 
|  | ASSERT_EQ(mExpected60Config, minRate60); | 
|  | ASSERT_EQ(mExpected60Config, performanceRate60); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  | { | 
|  | auto& current = refreshRateConfigs->getCurrentRefreshRate(); | 
|  | EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_60); | 
|  | } | 
|  |  | 
|  | refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90); | 
|  | { | 
|  | auto& current = refreshRateConfigs->getCurrentRefreshRate(); | 
|  | EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90); | 
|  | } | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {90, 90}}), 0); | 
|  | { | 
|  | auto& current = refreshRateConfigs->getCurrentRefreshRate(); | 
|  | EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | const auto makeLayerRequirements = [](float refreshRate) -> std::vector<LayerRequirement> { | 
|  | return {{"testLayer", LayerVoteType::Heuristic, refreshRate, 1.0f}}; | 
|  | }; | 
|  |  | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f))); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f))); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {90, 90}}), 0); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f))); | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {0, 120}}), 0); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f))); | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f))); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f))); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(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<LayerRequirement>{}; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0); | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | lr.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | lr.name = "45Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | lr.name = "30Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 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, {60, 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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 24.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {90, 90}}), 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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 24.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {0, 120}}), 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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 24.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_72_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 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<RefreshRateConfigs>(m30_60_72_90_120Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected120Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 48.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected72Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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<RefreshRateConfigs>(m30_60_72_90_120Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitDefault; | 
|  | lr1.name = "24Hz ExplicitDefault"; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.name = "60Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected120Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.name = "24Hz ExplicitExactOrMultiple"; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.name = "60Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected120Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.name = "24Hz ExplicitExactOrMultiple"; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitDefault; | 
|  | lr2.name = "60Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected120Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.name = "24Hz ExplicitExactOrMultiple"; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.name = "24Hz ExplicitExactOrMultiple"; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitDefault; | 
|  | lr2.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected72Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitDefault; | 
|  | lr1.name = "24Hz ExplicitDefault"; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.name = "24Hz Heuristic"; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitDefault; | 
|  | lr2.name = "90Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected72Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.name = "24Hz ExplicitExactOrMultiple"; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitDefault; | 
|  | lr2.name = "90Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected72Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.desiredRefreshRate = 24.0f; | 
|  | lr1.vote = LayerVoteType::ExplicitDefault; | 
|  | lr1.name = "24Hz ExplicitDefault"; | 
|  | lr2.desiredRefreshRate = 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<RefreshRateConfigs>(m30_60Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 30.0f; | 
|  | EXPECT_EQ(mExpected30Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 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<RefreshRateConfigs>(m30_60_72_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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 = 90.0f; | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | lr.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.desiredRefreshRate = 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 = 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 = 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 = 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 = 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<RefreshRateConfigs>(m30_60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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 = 24.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Min; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 24.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Max; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Max; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 15.0f; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 30.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 45.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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; | 
|  | const auto& refreshRate = | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); | 
|  | EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent_Explicit) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | EXPECT_EQ(mExpected90Config, refreshRateConfigs->getRefreshRateForContent(layers)); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, refreshRateConfigs->getRefreshRateForContent(layers)); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 60.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitDefault; | 
|  | lr1.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::Heuristic; | 
|  | lr1.desiredRefreshRate = 90.0f; | 
|  | lr2.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr2.desiredRefreshRate = 60.0f; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, testInPolicy) { | 
|  | ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(60.000004f, 60.000004f)); | 
|  | ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(59.0f, 60.1f)); | 
|  | ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(75.0f, 90.0f)); | 
|  | ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(60.0011f, 90.0f)); | 
|  | ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(50.0f, 59.998f)); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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; | 
|  | 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<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::ExplicitDefault; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.name = "90Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 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 = 30.0f; | 
|  | lr1.name = "30Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 90.0f; | 
|  | lr2.name = "90Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 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<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 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 = 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 = 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 = 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 = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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<RefreshRateConfigs>(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>{LayerRequirement{.weight = 1.0f}, | 
|  | LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr1 = layers[0]; | 
|  | auto& lr2 = layers[1]; | 
|  |  | 
|  | lr1.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr1.desiredRefreshRate = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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 = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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 = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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 = 60.0f; | 
|  | lr1.name = "60Hz ExplicitExactOrMultiple"; | 
|  | lr2.vote = LayerVoteType::Heuristic; | 
|  | lr2.desiredRefreshRate = 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<RefreshRateConfigs>(m60_90_72_120Device, /*currentConfigId=*/ | 
|  | HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr = layers[0]; | 
|  |  | 
|  | // Prepare a table with the vote and the expected refresh rate | 
|  | const std::vector<std::pair<float, float>> 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 = 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_FLOAT_EQ(refreshRate.getFps(), test.second) | 
|  | << "Expecting " << test.first << "fps => " << test.second << "Hz"; | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, | 
|  | getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_90); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( | 
|  | {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}), | 
|  | 0); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr = layers[0]; | 
|  |  | 
|  | RefreshRateConfigs::GlobalSignals consideredSignals; | 
|  | lr.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz ExplicitExactOrMultiple"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true}, | 
|  | &consideredSignals)); | 
|  | EXPECT_EQ(false, consideredSignals.touch); | 
|  |  | 
|  | lr.vote = LayerVoteType::ExplicitDefault; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz ExplicitDefault"; | 
|  | 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<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( | 
|  | {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 90.f}}), | 
|  | 0); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr = layers[0]; | 
|  |  | 
|  | lr.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr.desiredRefreshRate = 90.0f; | 
|  | lr.name = "90Hz ExplicitExactOrMultiple"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true})); | 
|  |  | 
|  | lr.vote = LayerVoteType::ExplicitDefault; | 
|  | lr.desiredRefreshRate = 90.0f; | 
|  | lr.name = "90Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, | 
|  | getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitLayers) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_90); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( | 
|  | {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 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>{LayerRequirement{.weight = 1.0f}}; | 
|  | auto& lr = layers[0]; | 
|  |  | 
|  | lr.vote = LayerVoteType::ExplicitExactOrMultiple; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz ExplicitExactOrMultiple"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.vote = LayerVoteType::ExplicitDefault; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz ExplicitDefault"; | 
|  | EXPECT_EQ(mExpected60Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.vote = LayerVoteType::Heuristic; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz Heuristic"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.vote = LayerVoteType::Max; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz Max"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  |  | 
|  | lr.vote = LayerVoteType::Min; | 
|  | lr.desiredRefreshRate = 60.0f; | 
|  | lr.name = "60Hz Min"; | 
|  | EXPECT_EQ(mExpected90Config, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, groupSwitching) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; | 
|  | auto& layer = layers[0]; | 
|  | layer.vote = LayerVoteType::ExplicitDefault; | 
|  | layer.desiredRefreshRate = 90.0f; | 
|  | layer.name = "90Hz ExplicitDefault"; | 
|  |  | 
|  | ASSERT_EQ(HWC_CONFIG_ID_60, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) | 
|  | .getConfigId()); | 
|  |  | 
|  | RefreshRateConfigs::Policy policy; | 
|  | policy.defaultConfig = refreshRateConfigs->getCurrentPolicy().defaultConfig; | 
|  | policy.allowGroupSwitching = true; | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); | 
|  | ASSERT_EQ(HWC_CONFIG_ID_90, | 
|  | refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) | 
|  | .getConfigId()); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m30_60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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, float fps, | 
|  | bool touchActive = false) -> HwcConfigIndexType { | 
|  | layers[0].vote = voteType; | 
|  | layers[0].desiredRefreshRate = fps; | 
|  | return refreshRateConfigs->getBestRefreshRate(layers, {.touch = touchActive, .idle = false}) | 
|  | .getConfigId(); | 
|  | }; | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( | 
|  | {HWC_CONFIG_ID_60, {30.f, 60.f}, {30.f, 90.f}}), | 
|  | 0); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, | 
|  | refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false}) | 
|  | .getConfigId()); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f)); | 
|  |  | 
|  | // Touch boost should be restricted to the primary range. | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 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, 90.f, /*touch=*/true)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_90, | 
|  | getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f, /*touch=*/true)); | 
|  |  | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy( | 
|  | {HWC_CONFIG_ID_60, {60.f, 60.f}, {60.f, 60.f}}), | 
|  | 0); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Min, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitDefault, 90.f)); | 
|  | EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f)); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, idle) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; | 
|  | layers[0].name = "Test layer"; | 
|  |  | 
|  | const auto getIdleFrameRate = [&](LayerVoteType voteType, | 
|  | bool touchActive) -> HwcConfigIndexType { | 
|  | layers[0].vote = voteType; | 
|  | layers[0].desiredRefreshRate = 90.f; | 
|  | RefreshRateConfigs::GlobalSignals consideredSignals; | 
|  | const auto configId = | 
|  | refreshRateConfigs | 
|  | ->getBestRefreshRate(layers, {.touch = touchActive, .idle = true}, | 
|  | &consideredSignals) | 
|  | .getConfigId(); | 
|  | // 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, {60.f, 90.f}, {60.f, 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}) | 
|  | .getConfigId()); | 
|  |  | 
|  | // Idle should be higher precedence than other layer frame rate considerations. | 
|  | refreshRateConfigs->setCurrentConfigId(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}) | 
|  | .getConfigId()); | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, findClosestKnownFrameRate) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) { | 
|  | const auto knownFrameRate = findClosestKnownFrameRate(*refreshRateConfigs, fps); | 
|  | float expectedFrameRate; | 
|  | if (fps < 26.91f) { | 
|  | expectedFrameRate = 24.0f; | 
|  | } else if (fps < 37.51f) { | 
|  | expectedFrameRate = 30.0f; | 
|  | } else if (fps < 52.51f) { | 
|  | expectedFrameRate = 45.0f; | 
|  | } else if (fps < 66.01f) { | 
|  | expectedFrameRate = 60.0f; | 
|  | } else if (fps < 81.01f) { | 
|  | expectedFrameRate = 72.0f; | 
|  | } else { | 
|  | expectedFrameRate = 90.0f; | 
|  | } | 
|  | EXPECT_FLOAT_EQ(expectedFrameRate, knownFrameRate) | 
|  | << "findClosestKnownFrameRate(" << fps << ") = " << knownFrameRate; | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) { | 
|  | auto refreshRateConfigs = | 
|  | std::make_unique<RefreshRateConfigs>(m60_90Device, | 
|  | /*currentConfigId=*/HWC_CONFIG_ID_60); | 
|  |  | 
|  | struct ExpectedRate { | 
|  | float rate; | 
|  | const RefreshRate& expected; | 
|  | }; | 
|  |  | 
|  | /* clang-format off */ | 
|  | std::vector<ExpectedRate> knownFrameRatesExpectations = { | 
|  | {24.0f, mExpected60Config}, | 
|  | {30.0f, mExpected60Config}, | 
|  | {45.0f, mExpected90Config}, | 
|  | {60.0f, mExpected60Config}, | 
|  | {72.0f, mExpected90Config}, | 
|  | {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(), | 
|  | [](float a, const ExpectedRate& b) { return a == b.rate; }); | 
|  | EXPECT_TRUE(equal); | 
|  |  | 
|  | auto layers = std::vector<LayerRequirement>{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, 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<RefreshRateConfigs>(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, {60, 90}}), 0); | 
|  | EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction()); | 
|  |  | 
|  | // SetPolicy(60, 60), current 60Hz => NoChange, avoid extra calls. | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0); | 
|  | EXPECT_EQ(KernelIdleTimerAction::NoChange, refreshRateConfigs->getIdleTimerAction()); | 
|  |  | 
|  | // SetPolicy(90, 90), current 90Hz => TurnOff. | 
|  | ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {90, 90}}), 0); | 
|  | EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); | 
|  | } | 
|  |  | 
|  | } // namespace | 
|  | } // namespace scheduler | 
|  | } // namespace android |