blob: 3423bd590b7d5a349b44f8b370a66484633d5b08 [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wextra"
#undef LOG_TAG
#define LOG_TAG "SchedulerUnittests"
#include <gmock/gmock.h>
#include <log/log.h>
#include <thread>
#include <ui/Size.h>
#include "../../Scheduler/RefreshRateConfigs.h"
#include "DisplayHardware/HWC2.h"
#include "Scheduler/RefreshRateConfigs.h"
using namespace std::chrono_literals;
namespace android {
namespace scheduler {
namespace hal = android::hardware::graphics::composer::hal;
using RefreshRate = RefreshRateConfigs::RefreshRate;
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
using LayerRequirement = RefreshRateConfigs::LayerRequirement;
class RefreshRateConfigsTest : public testing::Test {
protected:
using GetBestRefreshRateInvocation = RefreshRateConfigs::GetBestRefreshRateInvocation;
RefreshRateConfigsTest();
~RefreshRateConfigsTest();
RefreshRate createRefreshRate(DisplayModePtr displayMode) {
return {displayMode->getId(), displayMode, displayMode->getFps(),
RefreshRate::ConstructorTag(0)};
}
Fps findClosestKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs, Fps frameRate) {
return refreshRateConfigs.findClosestKnownFrameRate(frameRate);
}
std::vector<Fps> getKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs) {
return refreshRateConfigs.mKnownFrameRates;
}
RefreshRate getMinRefreshRateByPolicy(const RefreshRateConfigs& refreshRateConfigs) {
std::lock_guard lock(refreshRateConfigs.mLock);
return refreshRateConfigs.getMinRefreshRateByPolicyLocked();
}
RefreshRate getMinSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) {
std::lock_guard lock(refreshRateConfigs.mLock);
return *refreshRateConfigs.mMinSupportedRefreshRate;
}
RefreshRate getMaxSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) {
std::lock_guard lock(refreshRateConfigs.mLock);
return *refreshRateConfigs.mMaxSupportedRefreshRate;
}
void setLastBestRefreshRateInvocation(RefreshRateConfigs& refreshRateConfigs,
const GetBestRefreshRateInvocation& invocation) {
std::lock_guard lock(refreshRateConfigs.mLock);
refreshRateConfigs.lastBestRefreshRateInvocation.emplace(
GetBestRefreshRateInvocation(invocation));
}
std::optional<GetBestRefreshRateInvocation> getLastBestRefreshRateInvocation(
const RefreshRateConfigs& refreshRateConfigs) {
std::lock_guard lock(refreshRateConfigs.mLock);
return refreshRateConfigs.lastBestRefreshRateInvocation;
}
// Test config IDs
static inline const DisplayModeId HWC_CONFIG_ID_60 = DisplayModeId(0);
static inline const DisplayModeId HWC_CONFIG_ID_90 = DisplayModeId(1);
static inline const DisplayModeId HWC_CONFIG_ID_72 = DisplayModeId(2);
static inline const DisplayModeId HWC_CONFIG_ID_120 = DisplayModeId(3);
static inline const DisplayModeId HWC_CONFIG_ID_30 = DisplayModeId(4);
static inline const DisplayModeId HWC_CONFIG_ID_25 = DisplayModeId(5);
static inline const DisplayModeId HWC_CONFIG_ID_50 = DisplayModeId(6);
// Test configs
DisplayModePtr mConfig60 = createDisplayMode(HWC_CONFIG_ID_60, 0, Fps(60.0f).getPeriodNsecs());
DisplayModePtr mConfig90 = createDisplayMode(HWC_CONFIG_ID_90, 0, Fps(90.0f).getPeriodNsecs());
DisplayModePtr mConfig90DifferentGroup =
createDisplayMode(HWC_CONFIG_ID_90, 1, Fps(90.0f).getPeriodNsecs());
DisplayModePtr mConfig90DifferentResolution =
createDisplayMode(HWC_CONFIG_ID_90, 0, Fps(90.0f).getPeriodNsecs(), ui::Size(111, 222));
DisplayModePtr mConfig72 = createDisplayMode(HWC_CONFIG_ID_72, 0, Fps(72.0f).getPeriodNsecs());
DisplayModePtr mConfig72DifferentGroup =
createDisplayMode(HWC_CONFIG_ID_72, 1, Fps(72.0f).getPeriodNsecs());
DisplayModePtr mConfig120 =
createDisplayMode(HWC_CONFIG_ID_120, 0, Fps(120.0f).getPeriodNsecs());
DisplayModePtr mConfig120DifferentGroup =
createDisplayMode(HWC_CONFIG_ID_120, 1, Fps(120.0f).getPeriodNsecs());
DisplayModePtr mConfig30 = createDisplayMode(HWC_CONFIG_ID_30, 0, Fps(30.0f).getPeriodNsecs());
DisplayModePtr mConfig30DifferentGroup =
createDisplayMode(HWC_CONFIG_ID_30, 1, Fps(30.0f).getPeriodNsecs());
DisplayModePtr mConfig25DifferentGroup =
createDisplayMode(HWC_CONFIG_ID_25, 1, Fps(25.0f).getPeriodNsecs());
DisplayModePtr mConfig50 = createDisplayMode(HWC_CONFIG_ID_50, 0, Fps(50.0f).getPeriodNsecs());
// Test device configurations
// The positions of the configs in the arrays below MUST match their IDs. For example,
// the first config should always be 60Hz, the second 90Hz etc.
DisplayModes m60OnlyConfigDevice = {mConfig60};
DisplayModes m60_90Device = {mConfig60, mConfig90};
DisplayModes m60_90DeviceWithDifferentGroups = {mConfig60, mConfig90DifferentGroup};
DisplayModes m60_90DeviceWithDifferentResolutions = {mConfig60, mConfig90DifferentResolution};
DisplayModes m60_72_90Device = {mConfig60, mConfig90, mConfig72};
DisplayModes m60_90_72_120Device = {mConfig60, mConfig90, mConfig72, mConfig120};
DisplayModes m30_60_72_90_120Device = {mConfig60, mConfig90, mConfig72, mConfig120, mConfig30};
DisplayModes m30_60Device = {mConfig60, mConfig90DifferentGroup, mConfig72DifferentGroup,
mConfig120DifferentGroup, mConfig30};
DisplayModes m30_60_72_90Device = {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup,
mConfig30};
DisplayModes m30_60_90Device = {mConfig60, mConfig90, mConfig72DifferentGroup,
mConfig120DifferentGroup, mConfig30};
DisplayModes m25_30_50_60Device = {mConfig60,
mConfig90,
mConfig72DifferentGroup,
mConfig120DifferentGroup,
mConfig30DifferentGroup,
mConfig25DifferentGroup,
mConfig50};
DisplayModes m60_120Device = {mConfig60, mConfig120};
// Expected RefreshRate objects
RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, Fps(60),
RefreshRate::ConstructorTag(0)};
RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60,
createDisplayMode(HWC_CONFIG_ID_60, 0, 16666665),
Fps(60), RefreshRate::ConstructorTag(0)};
RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, Fps(90),
RefreshRate::ConstructorTag(0)};
RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup,
Fps(90), RefreshRate::ConstructorTag(0)};
RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90,
mConfig90DifferentResolution, Fps(90),
RefreshRate::ConstructorTag(0)};
RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, Fps(72.0f),
RefreshRate::ConstructorTag(0)};
RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, Fps(30),
RefreshRate::ConstructorTag(0)};
RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120),
RefreshRate::ConstructorTag(0)};
private:
DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod,
ui::Size resolution = ui::Size());
};
using Builder = DisplayMode::Builder;
RefreshRateConfigsTest::RefreshRateConfigsTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
}
RefreshRateConfigsTest::~RefreshRateConfigsTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
DisplayModePtr RefreshRateConfigsTest::createDisplayMode(DisplayModeId modeId, int32_t group,
int64_t vsyncPeriod, ui::Size resolution) {
return DisplayMode::Builder(hal::HWConfigId(modeId.value()))
.setId(modeId)
.setVsyncPeriod(int32_t(vsyncPeriod))
.setGroup(group)
.setHeight(resolution.height)
.setWidth(resolution.width)
.build();
}
namespace {
/* ------------------------------------------------------------------------
* Test cases
*/
TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) {
auto refreshRateConfigs =
std::make_unique<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({DisplayModeId(10), {Fps(60), Fps(60)}}),
0);
ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(20), Fps(40)}}),
0);
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
const auto& minRate = getMinSupportedRefreshRate(*refreshRateConfigs);
const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected90Config, performanceRate);
const auto& minRateByPolicy = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(minRateByPolicy, minRate);
ASSERT_EQ(performanceRateByPolicy, performanceRate);
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected60Config, minRate60);
ASSERT_EQ(mExpected60Config, performanceRate60);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(60), Fps(90)}}),
0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate);
ASSERT_EQ(mExpected90DifferentGroupConfig, minRate90);
ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate90);
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentResolutions) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentResolutions,
/*currentConfigId=*/HWC_CONFIG_ID_60);
const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected60Config, minRate60);
ASSERT_EQ(mExpected60Config, performanceRate60);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(60), Fps(90)}}),
0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate);
ASSERT_EQ(mExpected90DifferentResolutionConfig, minRate90);
ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate90);
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_policyChange) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
auto minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
auto performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected90Config, performanceRate);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
auto minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
auto performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate60);
ASSERT_EQ(mExpected60Config, performanceRate60);
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
{
auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_60);
}
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
{
auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_90);
}
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}),
0);
{
auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getModeId(), HWC_CONFIG_ID_90);
}
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) {
auto refreshRateConfigs =
std::make_unique<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, {Fps(60), Fps(60)}}),
0);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
lr.name = "45Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
lr.name = "30Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
lr.name = "24Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.name = "";
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
lr.vote = LayerVoteType::Min;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Max;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_90, {Fps(90.0f), Fps(90.0f)}}),
0);
lr.vote = LayerVoteType::Min;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Max;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_60, {Fps(0.0f), Fps(120.0f)}}),
0);
lr.vote = LayerVoteType::Min;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Max;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) {
RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60, config);
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 = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
lr.name = "45Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
lr.name = "30Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
lr.name = "24Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90_120) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(24.0f);
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(48.0f);
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(48.0f);
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "60Hz ExplicitDefault";
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::Heuristic;
lr1.name = "24Hz Heuristic";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.name = "90Hz ExplicitExactOrMultiple";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) {
RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60, config);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
LayerRequirement{.weight = 1.0f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(60.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "60Hz ExplicitDefault";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::Heuristic;
lr1.name = "24Hz Heuristic";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.desiredRefreshRate = Fps(24.0f);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.name = "90Hz ExplicitExactOrMultiple";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
EXPECT_EQ(mExpected30Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(90.0f);
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Heuristic";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr.desiredRefreshRate = Fps(45.0f);
lr.name = "45Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr.desiredRefreshRate = Fps(30.0f);
lr.name = "30Hz Heuristic";
EXPECT_EQ(mExpected30Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
lr.name = "24Hz Heuristic";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr.desiredRefreshRate = Fps(24.0f);
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
lr.name = "24Hz ExplicitExactOrMultiple";
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_PriorityTest) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(24.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(24.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = Fps(15.0f);
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = Fps(30.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(45.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) {
auto refreshRateConfigs =
std::make_unique<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(fps);
const auto& refreshRate =
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
}
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) {
RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60, config);
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(fps);
const auto& refreshRate =
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
}
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(60.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(90.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = Fps(90.0f);
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = Fps(60.0f);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, testInPolicy) {
ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(Fps(60.000004f), Fps(60.000004f)));
ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(Fps(59.0f), Fps(60.1f)));
ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(75.0f), Fps(90.0f)));
ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(60.0011f), Fps(90.0f)));
ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(Fps(50.0f), Fps(59.998f)));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) {
auto refreshRateConfigs =
std::make_unique<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(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 = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(90.0f);
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.desiredRefreshRate = Fps(90.0f);
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(30.0f);
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(90.0f);
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(30.0f);
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
// The other layer starts to provide buffers
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(90.0f);
lr2.name = "90Hz Heuristic";
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, touchConsidered) {
RefreshRateConfigs::GlobalSignals consideredSignals;
auto refreshRateConfigs =
std::make_unique<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 = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
lr2.name = "60Hz Heuristic";
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
&consideredSignals);
EXPECT_EQ(true, consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
lr2.name = "60Hz Heuristic";
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
&consideredSignals);
EXPECT_EQ(false, consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
lr2.name = "60Hz Heuristic";
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
&consideredSignals);
EXPECT_EQ(true, consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = Fps(60.0f);
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = Fps(60.0f);
lr2.name = "60Hz Heuristic";
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
&consideredSignals);
EXPECT_EQ(false, consideredSignals.touch);
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) {
auto refreshRateConfigs =
std::make_unique<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 = Fps(test.first);
std::stringstream ss;
ss << "ExplicitDefault " << test.first << " fps";
lr.name = ss.str();
const auto& refreshRate =
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
EXPECT_TRUE(refreshRate.getFps().equalsWithMargin(Fps(test.second)))
<< "Expecting " << test.first << "fps => " << test.second << "Hz";
}
}
TEST_F(RefreshRateConfigsTest,
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_90);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_90, {Fps(90.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}),
0);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& lr = layers[0];
RefreshRateConfigs::GlobalSignals consideredSignals;
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz ExplicitDefault";
lr.focused = true;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true},
&consideredSignals));
EXPECT_EQ(false, consideredSignals.touch);
}
TEST_F(RefreshRateConfigsTest,
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_60, {Fps(60.f), Fps(60.f)}, {Fps(60.f), Fps(90.f)}}),
0);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = Fps(90.0f);
lr.name = "90Hz ExplicitDefault";
lr.focused = true;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true}));
}
TEST_F(RefreshRateConfigsTest,
getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_90);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_90, {Fps(90.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}),
0);
RefreshRateConfigs::GlobalSignals consideredSignals;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false},
&consideredSignals));
EXPECT_EQ(false, consideredSignals.touch);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz ExplicitExactOrMultiple";
lr.focused = false;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.focused = true;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz ExplicitDefault";
lr.focused = false;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.focused = true;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Heuristic;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Heuristic";
lr.focused = false;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.focused = true;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Max;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Max";
lr.focused = false;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.focused = true;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.vote = LayerVoteType::Min;
lr.desiredRefreshRate = Fps(60.0f);
lr.name = "60Hz Min";
lr.focused = false;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
lr.focused = true;
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, groupSwitchingNotAllowed) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
// The default policy doesn't allow group switching. Verify that no
// group switches are performed.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = Fps(90.0f);
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayer) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = Fps(90.0f);
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamless) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
// Verify that we won't change the group if seamless switch is required.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = Fps(90.0f);
layer.seamlessness = Seamlessness::OnlySeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
// Verify that we won't do a seamless switch if we request the same mode as the default
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = Fps(60.0f);
layer.seamlessness = Seamlessness::OnlySeamless;
layer.name = "60Hz ExplicitDefault";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerDefaultSeamlessness) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
// Verify that if the current config is in another group and there are no layers with
// seamlessness=SeamedAndSeamless we'll go back to the default group.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = Fps(60.0f);
layer.seamlessness = Seamlessness::Default;
layer.name = "60Hz ExplicitDefault";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
// If there's a layer with seamlessness=SeamedAndSeamless, another layer with
// seamlessness=OnlySeamless can't change the mode group.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].seamlessness = Seamlessness::OnlySeamless;
layers[0].name = "60Hz ExplicitDefault";
layers[0].focused = true;
layers.push_back(LayerRequirement{.weight = 0.5f});
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = Fps(90.0f);
layers[1].name = "90Hz ExplicitDefault";
layers[1].focused = false;
ASSERT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
// If there's a focused layer with seamlessness=SeamedAndSeamless, another layer with
// seamlessness=Default can't change the mode group back to the group of the default
// mode.
// For example, this may happen when a video playback requests and gets a seamed switch,
// but another layer (with default seamlessness) starts animating. The animating layer
// should not cause a seamed switch.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
layers[0].seamlessness = Seamlessness::Default;
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].focused = true;
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].name = "60Hz ExplicitDefault";
layers.push_back(LayerRequirement{.weight = 0.1f});
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = Fps(90.0f);
layers[1].focused = true;
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "90Hz ExplicitDefault";
ASSERT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
// Layer with seamlessness=Default can change the mode group if there's a not
// focused layer with seamlessness=SeamedAndSeamless. This happens for example,
// when in split screen mode the user switches between the two visible applications.
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
layers[0].seamlessness = Seamlessness::Default;
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].focused = true;
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].name = "60Hz ExplicitDefault";
layers.push_back(LayerRequirement{.weight = 0.7f});
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = Fps(90.0f);
layers[1].focused = false;
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "90Hz ExplicitDefault";
ASSERT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
// Allow group switching.
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitExactOrMultiple;
layer.desiredRefreshRate = Fps(60.0f);
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "60Hz ExplicitExactOrMultiple";
layer.focused = true;
ASSERT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_120);
ASSERT_EQ(HWC_CONFIG_ID_120,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, nonSeamlessExactAndSeamlessMultipleLayers) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m25_30_50_60Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
// Allow group switching.
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
auto layers = std::vector<
LayerRequirement>{LayerRequirement{.name = "60Hz ExplicitDefault",
.vote = LayerVoteType::ExplicitDefault,
.desiredRefreshRate = Fps(60.0f),
.seamlessness = Seamlessness::SeamedAndSeamless,
.weight = 0.5f,
.focused = false},
LayerRequirement{.name = "25Hz ExplicitExactOrMultiple",
.vote = LayerVoteType::ExplicitExactOrMultiple,
.desiredRefreshRate = Fps(25.0f),
.seamlessness = Seamlessness::OnlySeamless,
.weight = 1.0f,
.focused = true}};
ASSERT_EQ(HWC_CONFIG_ID_50,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
auto& seamedLayer = layers[0];
seamedLayer.name = "30Hz ExplicitDefault", seamedLayer.desiredRefreshRate = Fps(30.0f);
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_30);
ASSERT_EQ(HWC_CONFIG_ID_25,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, minLayersDontTrigerSeamedSwitch) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_90);
// Allow group switching.
RefreshRateConfigs::Policy policy;
policy.defaultMode = refreshRateConfigs->getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.name = "Min",
.vote = LayerVoteType::Min,
.weight = 1.f,
.focused = true}};
ASSERT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) {
auto refreshRateConfigs =
std::make_unique<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, Fps fps, bool touchActive = false,
bool focused = true) -> DisplayModeId {
layers[0].vote = voteType;
layers[0].desiredRefreshRate = fps;
layers[0].focused = focused;
return refreshRateConfigs->getBestRefreshRate(layers, {.touch = touchActive, .idle = false})
.getModeId();
};
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_60, {Fps(30.f), Fps(60.f)}, {Fps(30.f), Fps(90.f)}}),
0);
EXPECT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false})
.getModeId());
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_90, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f)));
// Layers not focused are not allowed to override primary config
EXPECT_EQ(HWC_CONFIG_ID_60,
getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f), /*touch=*/false,
/*focused=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60,
getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f), /*touch=*/false,
/*focused=*/false));
// Touch boost should be restricted to the primary range.
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f), /*touch=*/true));
// When we're higher than the primary range max due to a layer frame rate setting, touch boost
// shouldn't drag us back down to the primary range max.
EXPECT_EQ(HWC_CONFIG_ID_90,
getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f), /*touch=*/true));
EXPECT_EQ(HWC_CONFIG_ID_60,
getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f), /*touch=*/true));
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_60, {Fps(60.f), Fps(60.f)}, {Fps(60.f), Fps(60.f)}}),
0);
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Min, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Max, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::Heuristic, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitDefault, Fps(90.f)));
EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, Fps(90.f)));
}
TEST_F(RefreshRateConfigsTest, idle) {
auto refreshRateConfigs =
std::make_unique<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) -> DisplayModeId {
layers[0].vote = voteType;
layers[0].desiredRefreshRate = Fps(90.f);
RefreshRateConfigs::GlobalSignals consideredSignals;
const auto configId =
refreshRateConfigs
->getBestRefreshRate(layers, {.touch = touchActive, .idle = true},
&consideredSignals)
.getModeId();
// Refresh rate will be chosen by either touch state or idle state
EXPECT_EQ(!touchActive, consideredSignals.idle);
return configId;
};
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_60, {Fps(60.f), Fps(90.f)}, {Fps(60.f), Fps(90.f)}}),
0);
// Idle should be lower priority than touch boost.
EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/true));
EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/true));
EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/true));
EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/true));
EXPECT_EQ(HWC_CONFIG_ID_90,
getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/true));
EXPECT_EQ(HWC_CONFIG_ID_90,
getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/true));
// With no layers, idle should still be lower priority than touch boost.
EXPECT_EQ(HWC_CONFIG_ID_90,
refreshRateConfigs->getBestRefreshRate({}, {.touch = true, .idle = true})
.getModeId());
// Idle should be higher precedence than other layer frame rate considerations.
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60,
getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/false));
EXPECT_EQ(HWC_CONFIG_ID_60,
getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/false));
// Idle should be applied rather than the current config when there are no layers.
EXPECT_EQ(HWC_CONFIG_ID_60,
refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = true})
.getModeId());
}
TEST_F(RefreshRateConfigsTest, findClosestKnownFrameRate) {
auto refreshRateConfigs =
std::make_unique<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(fps));
Fps expectedFrameRate;
if (fps < 26.91f) {
expectedFrameRate = Fps(24.0f);
} else if (fps < 37.51f) {
expectedFrameRate = Fps(30.0f);
} else if (fps < 52.51f) {
expectedFrameRate = Fps(45.0f);
} else if (fps < 66.01f) {
expectedFrameRate = Fps(60.0f);
} else if (fps < 81.01f) {
expectedFrameRate = Fps(72.0f);
} else {
expectedFrameRate = Fps(90.0f);
}
EXPECT_TRUE(expectedFrameRate.equalsWithMargin(knownFrameRate))
<< "findClosestKnownFrameRate(" << fps << ") = " << knownFrameRate;
}
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
struct ExpectedRate {
Fps rate;
const RefreshRate& expected;
};
/* clang-format off */
std::vector<ExpectedRate> knownFrameRatesExpectations = {
{Fps(24.0f), mExpected60Config},
{Fps(30.0f), mExpected60Config},
{Fps(45.0f), mExpected90Config},
{Fps(60.0f), mExpected60Config},
{Fps(72.0f), mExpected90Config},
{Fps(90.0f), mExpected90Config},
};
/* clang-format on */
// Make sure the test tests all the known frame rate
const auto knownFrameRateList = getKnownFrameRate(*refreshRateConfigs);
const auto equal =
std::equal(knownFrameRateList.begin(), knownFrameRateList.end(),
knownFrameRatesExpectations.begin(),
[](Fps a, const ExpectedRate& b) { return a.equalsWithMargin(b.rate); });
EXPECT_TRUE(equal);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::Heuristic;
for (const auto& expectedRate : knownFrameRatesExpectations) {
layer.desiredRefreshRate = expectedRate.rate;
const auto& refreshRate =
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
EXPECT_EQ(expectedRate.expected, refreshRate);
}
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
LayerRequirement{.weight = 0.5f}};
auto& explicitExactLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
explicitExactLayer.name = "ExplicitExact";
explicitExactLayer.desiredRefreshRate = Fps(30);
EXPECT_EQ(mExpected30Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected30Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120);
explicitExactLayer.desiredRefreshRate = Fps(60);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(72);
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(90);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(120);
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) {
RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60, config);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
LayerRequirement{.weight = 0.5f}};
auto& explicitExactLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
explicitExactLayer.name = "ExplicitExact";
explicitExactLayer.desiredRefreshRate = Fps(30);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120);
explicitExactLayer.desiredRefreshRate = Fps(60);
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(72);
EXPECT_EQ(mExpected72Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(90);
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
explicitExactLayer.desiredRefreshRate = Fps(120);
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ReadsCached) {
using GlobalSignals = RefreshRateConfigs::GlobalSignals;
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
setLastBestRefreshRateInvocation(*refreshRateConfigs,
GetBestRefreshRateInvocation{.layerRequirements = std::vector<
LayerRequirement>(),
.globalSignals = {.touch = true,
.idle = true},
.outSignalsConsidered =
{.touch = true,
.idle = false},
.resultingBestRefreshRate =
createRefreshRate(
mConfig90)});
EXPECT_EQ(createRefreshRate(mConfig90),
refreshRateConfigs->getBestRefreshRate(std::vector<LayerRequirement>(),
{.touch = true, .idle = true}));
const GlobalSignals cachedSignalsConsidered{.touch = true, .idle = false};
setLastBestRefreshRateInvocation(*refreshRateConfigs,
GetBestRefreshRateInvocation{.layerRequirements = std::vector<
LayerRequirement>(),
.globalSignals = {.touch = true,
.idle = true},
.outSignalsConsidered =
cachedSignalsConsidered,
.resultingBestRefreshRate =
createRefreshRate(
mConfig30)});
GlobalSignals signalsConsidered;
EXPECT_EQ(createRefreshRate(mConfig30),
refreshRateConfigs->getBestRefreshRate(std::vector<LayerRequirement>(),
{.touch = true, .idle = true},
&signalsConsidered));
EXPECT_EQ(cachedSignalsConsidered, signalsConsidered);
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) {
using GlobalSignals = RefreshRateConfigs::GlobalSignals;
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
ASSERT_FALSE(getLastBestRefreshRateInvocation(*refreshRateConfigs).has_value());
GlobalSignals globalSignals{.touch = true, .idle = true};
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
LayerRequirement{.weight = 0.5f}};
const auto lastResult =
refreshRateConfigs->getBestRefreshRate(layers, globalSignals,
/* outSignalsConsidered */ nullptr);
const auto lastInvocation = getLastBestRefreshRateInvocation(*refreshRateConfigs);
ASSERT_TRUE(lastInvocation.has_value());
ASSERT_EQ(layers, lastInvocation->layerRequirements);
ASSERT_EQ(globalSignals, lastInvocation->globalSignals);
ASSERT_EQ(lastResult, lastInvocation->resultingBestRefreshRate);
// outSignalsConsidered needs to be populated even tho earlier we gave nullptr
// to getBestRefreshRate()
GlobalSignals detaultSignals;
ASSERT_FALSE(detaultSignals == lastInvocation->outSignalsConsidered);
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) {
RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_60, config);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
LayerRequirement{.weight = 0.5f}};
auto& explicitExactLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
explicitExactLayer.name = "ExplicitExact";
explicitExactLayer.desiredRefreshRate = Fps(30);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected120Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote;
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
}
TEST_F(RefreshRateConfigsTest, testComparisonOperator) {
EXPECT_TRUE(mExpected60Config < mExpected90Config);
EXPECT_FALSE(mExpected60Config < mExpected60Config);
EXPECT_FALSE(mExpected90Config < mExpected90Config);
}
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) {
using KernelIdleTimerAction = scheduler::RefreshRateConfigs::KernelIdleTimerAction;
auto refreshRateConfigs =
std::make_unique<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, {Fps(60), Fps(90)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(60, 60), current 60Hz => TurnOff
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(90, 90), current 90Hz => TurnOff.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
}
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerActionFor120Hz) {
using KernelIdleTimerAction = scheduler::RefreshRateConfigs::KernelIdleTimerAction;
// Tests with 120Hz
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m60_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_120);
// SetPolicy(0, 60), current 60Hz => TurnOn.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(0), Fps(60)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(60, 60), current 60Hz => TurnOff.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(60, 120), current 60Hz => TurnOn.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(120)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOn, refreshRateConfigs->getIdleTimerAction());
// SetPolicy(120, 120), current 120Hz => TurnOff.
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
{HWC_CONFIG_ID_120, {Fps(120), Fps(120)}}),
0);
EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
}
TEST_F(RefreshRateConfigsTest, getFrameRateDivider) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_30);
const auto frameRate = Fps(30.f);
Fps displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(1, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate));
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_60);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(2, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate));
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_72);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate));
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(3, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate));
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_120);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, frameRate));
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.5f)));
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.6f)));
}
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
HWC_CONFIG_ID_120);
auto layers = std::vector<LayerRequirement>{};
ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false)
.empty());
}
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
HWC_CONFIG_ID_120, config);
auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
layers[0].vote = LayerVoteType::NoVote;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_TRUE(frameRateOverrides.empty());
layers[0].vote = LayerVoteType::Min;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_TRUE(frameRateOverrides.empty());
layers[0].vote = LayerVoteType::Max;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_TRUE(frameRateOverrides.empty());
layers[0].vote = LayerVoteType::Heuristic;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_TRUE(frameRateOverrides.empty());
}
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
HWC_CONFIG_ID_120, config);
auto layers = std::vector<LayerRequirement>{
LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
LayerRequirement{.ownerUid = 5678, .weight = 1.0f},
};
layers[0].name = "Test layer 1234";
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "Test layer 5678";
layers[1].desiredRefreshRate = Fps(30.0f);
layers[1].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(2, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
ASSERT_EQ(1, frameRateOverrides.count(5678));
ASSERT_EQ(30.0f, frameRateOverrides.at(5678).getValue());
layers[1].vote = LayerVoteType::Heuristic;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
layers[1].ownerUid = 1234;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_TRUE(frameRateOverrides.empty());
}
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) {
RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
HWC_CONFIG_ID_120, config);
auto layers = std::vector<LayerRequirement>{
LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
};
layers[0].name = "Test layer";
layers[0].desiredRefreshRate = Fps(60.0f);
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
layers[0].vote = LayerVoteType::ExplicitExact;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
ASSERT_EQ(1, frameRateOverrides.size());
ASSERT_EQ(1, frameRateOverrides.count(1234));
ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
frameRateOverrides =
refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
ASSERT_TRUE(frameRateOverrides.empty());
}
TEST_F(RefreshRateConfigsTest, updateDisplayModes) {
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
/*currentConfigId=*/HWC_CONFIG_ID_30);
refreshRateConfigs->setDisplayManagerPolicy({DisplayModeId(HWC_CONFIG_ID_30),
/* allowGroupSwitching */ false,
/* range */ {Fps(30.0f), Fps(30.0f)}});
refreshRateConfigs->updateDisplayModes(m60_90Device, HWC_CONFIG_ID_60);
const auto currentRefreshRate = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_TRUE(currentRefreshRate.getFps().equalsWithMargin(Fps(60.0)));
EXPECT_EQ(currentRefreshRate.getModeId(), HWC_CONFIG_ID_60);
EXPECT_TRUE(
getMaxSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(90.0)));
EXPECT_TRUE(
getMinSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(60.0)));
}
} // namespace
} // namespace scheduler
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wextra"