| /* |
| * 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, /*weight*/ 1.0f, |
| /*focused*/ false}}; |
| }; |
| |
| 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::ExplicitDefault; |
| lr.desiredRefreshRate = 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<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::ExplicitDefault; |
| lr.desiredRefreshRate = 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<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"; |
| 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 = 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 = 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 = 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 = 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, 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, |
| bool focused = true) -> HwcConfigIndexType { |
| layers[0].vote = voteType; |
| layers[0].desiredRefreshRate = fps; |
| layers[0].focused = focused; |
| 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_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f)); |
| |
| // Layers not focused are not allowed to override primary config |
| EXPECT_EQ(HWC_CONFIG_ID_60, |
| getFrameRate(LayerVoteType::ExplicitDefault, 90.f, /*touch=*/false, |
| /*focused=*/false)); |
| EXPECT_EQ(HWC_CONFIG_ID_60, |
| getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90.f, /*touch=*/false, |
| /*focused=*/false)); |
| |
| // 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_60, |
| 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 |