blob: 0a6e3054dd292579773d6e881f34b1278801e00d [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.
*/
#undef LOG_TAG
#define LOG_TAG "SchedulerUnittests"
#include <algorithm>
#include <array>
#include <ftl/enum.h>
#include <ftl/fake_guard.h>
#include <gmock/gmock.h>
#include <log/log.h>
#include <ui/Size.h>
#include <common/test/FlagUtils.h>
#include <scheduler/Fps.h>
#include <scheduler/FrameRateMode.h>
#include "DisplayHardware/HWC2.h"
#include "FpsOps.h"
#include "Scheduler/RefreshRateSelector.h"
#include "mock/DisplayHardware/MockDisplayMode.h"
#include "mock/MockFrameRateMode.h"
#include "libsurfaceflinger_unittest_main.h"
#include <com_android_graphics_surfaceflinger_flags.h>
using namespace com::android::graphics::surfaceflinger;
using namespace std::chrono_literals;
namespace android::scheduler {
namespace hal = android::hardware::graphics::composer::hal;
using Config = RefreshRateSelector::Config;
using LayerRequirement = RefreshRateSelector::LayerRequirement;
using LayerVoteType = RefreshRateSelector::LayerVoteType;
using SetPolicyResult = RefreshRateSelector::SetPolicyResult;
using mock::createDisplayMode;
using mock::createVrrDisplayMode;
struct TestableRefreshRateSelector : RefreshRateSelector {
using RefreshRateSelector::FrameRateRanking;
using RefreshRateSelector::RefreshRateOrder;
using RefreshRateSelector::RefreshRateSelector;
void setActiveMode(DisplayModeId modeId, Fps renderFrameRate) {
ftl::FakeGuard guard(kMainThreadContext);
return RefreshRateSelector::setActiveMode(modeId, renderFrameRate);
}
const DisplayMode& getActiveMode() const {
std::lock_guard lock(mLock);
return *RefreshRateSelector::getActiveModeLocked().modePtr;
}
ftl::NonNull<DisplayModePtr> getMinSupportedRefreshRate() const {
std::lock_guard lock(mLock);
return ftl::as_non_null(mMinRefreshRateModeIt->second);
}
ftl::NonNull<DisplayModePtr> getMaxSupportedRefreshRate() const {
std::lock_guard lock(mLock);
return ftl::as_non_null(mMaxRefreshRateModeIt->second);
}
ftl::NonNull<DisplayModePtr> getMinRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
return ftl::as_non_null(getMinRefreshRateByPolicyLocked());
}
ftl::NonNull<DisplayModePtr> getMaxRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
return ftl::as_non_null(
getMaxRefreshRateByPolicyLocked(getActiveModeLocked().modePtr->getGroup()));
}
FrameRateRanking rankRefreshRates(std::optional<int> anchorGroupOpt,
RefreshRateOrder refreshRateOrder) const {
std::lock_guard lock(mLock);
return RefreshRateSelector::rankFrameRates(anchorGroupOpt, refreshRateOrder);
}
const std::vector<Fps>& knownFrameRates() const { return mKnownFrameRates; }
using RefreshRateSelector::GetRankedFrameRatesCache;
auto& mutableGetRankedRefreshRatesCache() { return mGetRankedFrameRatesCache; }
auto getRankedFrameRates(const std::vector<LayerRequirement>& layers,
GlobalSignals signals = {}) const {
const auto result = RefreshRateSelector::getRankedFrameRates(layers, signals);
EXPECT_TRUE(std::is_sorted(result.ranking.begin(), result.ranking.end(),
ScoredFrameRate::DescendingScore{}));
return result;
}
auto getRankedRefreshRatesAsPair(const std::vector<LayerRequirement>& layers,
GlobalSignals signals) const {
const auto [ranking, consideredSignals] = getRankedFrameRates(layers, signals);
return std::make_pair(ranking, consideredSignals);
}
FrameRateMode getBestFrameRateMode(const std::vector<LayerRequirement>& layers = {},
GlobalSignals signals = {}) const {
return getRankedFrameRates(layers, signals).ranking.front().frameRateMode;
}
ScoredFrameRate getBestScoredFrameRate(const std::vector<LayerRequirement>& layers = {},
GlobalSignals signals = {}) const {
return getRankedFrameRates(layers, signals).ranking.front();
}
SetPolicyResult setPolicy(const PolicyVariant& policy) {
ftl::FakeGuard guard(kMainThreadContext);
return RefreshRateSelector::setPolicy(policy);
}
SetPolicyResult setDisplayManagerPolicy(const DisplayManagerPolicy& policy) {
return setPolicy(policy);
}
const auto& getPrimaryFrameRates() const { return mPrimaryFrameRates; }
};
class RefreshRateSelectorTest : public testing::TestWithParam<Config::FrameRateOverride> {
protected:
using RefreshRateOrder = TestableRefreshRateSelector::RefreshRateOrder;
RefreshRateSelectorTest();
~RefreshRateSelectorTest();
static constexpr DisplayModeId kModeId60{0};
static constexpr DisplayModeId kModeId90{1};
static constexpr DisplayModeId kModeId72{2};
static constexpr DisplayModeId kModeId120{3};
static constexpr DisplayModeId kModeId30{4};
static constexpr DisplayModeId kModeId25{5};
static constexpr DisplayModeId kModeId50{6};
static constexpr DisplayModeId kModeId24{7};
static constexpr DisplayModeId kModeId24Frac{8};
static constexpr DisplayModeId kModeId30Frac{9};
static constexpr DisplayModeId kModeId60Frac{10};
static constexpr DisplayModeId kModeId35{11};
static constexpr DisplayModeId kModeId1{12};
static constexpr DisplayModeId kModeId5{13};
static constexpr DisplayModeId kModeId10{14};
static inline const ftl::NonNull<DisplayModePtr> kMode60 =
ftl::as_non_null(createDisplayMode(kModeId60, 60_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode60Frac =
ftl::as_non_null(createDisplayMode(kModeId60Frac, 59.94_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode90 =
ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode90_G1 =
ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 1));
static inline const ftl::NonNull<DisplayModePtr> kMode90_4K =
ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160}));
static inline const ftl::NonNull<DisplayModePtr> kMode72 =
ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode72_G1 =
ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz, 1));
static inline const ftl::NonNull<DisplayModePtr> kMode120 =
ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode120_G1 =
ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz, 1));
static inline const ftl::NonNull<DisplayModePtr> kMode30 =
ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode30_G1 =
ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz, 1));
static inline const ftl::NonNull<DisplayModePtr> kMode30Frac =
ftl::as_non_null(createDisplayMode(kModeId30Frac, 29.97_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode25 =
ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode25_G1 =
ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz, 1));
static inline const ftl::NonNull<DisplayModePtr> kMode35 =
ftl::as_non_null(createDisplayMode(kModeId35, 35_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode50 =
ftl::as_non_null(createDisplayMode(kModeId50, 50_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode24 =
ftl::as_non_null(createDisplayMode(kModeId24, 24_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode24Frac =
ftl::as_non_null(createDisplayMode(kModeId24Frac, 23.976_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode1 =
ftl::as_non_null(createDisplayMode(kModeId1, 1_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode5 =
ftl::as_non_null(createDisplayMode(kModeId5, 5_Hz));
static inline const ftl::NonNull<DisplayModePtr> kMode10 =
ftl::as_non_null(createDisplayMode(kModeId10, 10_Hz));
// VRR modes
static inline const ftl::NonNull<DisplayModePtr> kVrrMode120TE240 = ftl::as_non_null(
createVrrDisplayMode(kModeId120, 240_Hz,
hal::VrrConfig{
.minFrameIntervalNs =
static_cast<Fps>(120_Hz).getPeriodNsecs()}));
static inline const ftl::NonNull<DisplayModePtr> kVrrMode60TE120 = ftl::as_non_null(
createVrrDisplayMode(kModeId60, 120_Hz,
hal::VrrConfig{.minFrameIntervalNs =
static_cast<Fps>(60_Hz).getPeriodNsecs()},
/*group=*/1));
// Test configurations.
static inline const DisplayModes kModes_60 = makeModes(kMode60);
static inline const DisplayModes kModes_35_60_90 = makeModes(kMode35, kMode60, kMode90);
static inline const DisplayModes kModes_60_90 = makeModes(kMode60, kMode90);
static inline const DisplayModes kModes_60_90_G1 = makeModes(kMode60, kMode90_G1);
static inline const DisplayModes kModes_60_90_4K = makeModes(kMode60, kMode90_4K);
static inline const DisplayModes kModes_60_72_90 = makeModes(kMode60, kMode90, kMode72);
static inline const DisplayModes kModes_60_90_72_120 =
makeModes(kMode60, kMode90, kMode72, kMode120);
static inline const DisplayModes kModes_30_60_72_90_120 =
makeModes(kMode60, kMode90, kMode72, kMode120, kMode30);
static inline const DisplayModes kModes_30_60 =
makeModes(kMode60, kMode90_G1, kMode72_G1, kMode120_G1, kMode30);
static inline const DisplayModes kModes_30_60_72_90 =
makeModes(kMode60, kMode90, kMode72, kMode120_G1, kMode30);
static inline const DisplayModes kModes_30_60_90 =
makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30);
static inline const DisplayModes kModes_25_30_50_60 =
makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30_G1, kMode25_G1, kMode50);
static inline const DisplayModes kModes_60_120 = makeModes(kMode60, kMode120);
static inline const DisplayModes kModes_1_5_10 = makeModes(kMode1, kMode5, kMode10);
static inline const DisplayModes kModes_60_90_120 = makeModes(kMode60, kMode90, kMode120);
// VRR display modes
static inline const DisplayModes kVrrMode_120 = makeModes(kVrrMode120TE240);
static inline const DisplayModes kVrrModes_60_120 =
makeModes(kVrrMode60TE120, kVrrMode120TE240);
// This is a typical TV configuration.
static inline const DisplayModes kModes_24_25_30_50_60_Frac =
makeModes(kMode24, kMode24Frac, kMode25, kMode30, kMode30Frac, kMode50, kMode60,
kMode60Frac);
static TestableRefreshRateSelector createSelector(DisplayModes modes,
DisplayModeId activeModeId,
Config config = {}) {
config.enableFrameRateOverride = GetParam();
return TestableRefreshRateSelector(modes, activeModeId, config);
}
};
RefreshRateSelectorTest::RefreshRateSelectorTest() {
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());
}
RefreshRateSelectorTest::~RefreshRateSelectorTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
namespace {
INSTANTIATE_TEST_SUITE_P(PerOverrideConfig, RefreshRateSelectorTest,
testing::Values(Config::FrameRateOverride::Disabled,
Config::FrameRateOverride::AppOverrideNativeRefreshRates,
Config::FrameRateOverride::AppOverride,
Config::FrameRateOverride::Enabled));
TEST_P(RefreshRateSelectorTest, oneMode_canSwitch) {
auto selector = createSelector(kModes_60, kModeId60);
if (GetParam() == Config::FrameRateOverride::Enabled) {
EXPECT_TRUE(selector.canSwitch());
} else {
EXPECT_FALSE(selector.canSwitch());
}
}
TEST_P(RefreshRateSelectorTest, invalidPolicy) {
auto selector = createSelector(kModes_60, kModeId60);
EXPECT_EQ(SetPolicyResult::Invalid,
selector.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}}));
EXPECT_EQ(SetPolicyResult::Invalid,
selector.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}}));
}
TEST_P(RefreshRateSelectorTest, unchangedPolicy) {
auto selector = createSelector(kModes_60_90, kModeId60);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
EXPECT_EQ(SetPolicyResult::Unchanged,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
// Override to the same policy.
EXPECT_EQ(SetPolicyResult::Unchanged,
selector.setPolicy(RefreshRateSelector::OverridePolicy{kModeId90, {60_Hz, 90_Hz}}));
// Clear override to restore DisplayManagerPolicy.
EXPECT_EQ(SetPolicyResult::Unchanged,
selector.setPolicy(RefreshRateSelector::NoOverridePolicy{}));
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {30_Hz, 90_Hz}}));
}
TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap) {
auto selector = createSelector(kModes_60_90, kModeId60);
const auto minRate = selector.getMinSupportedRefreshRate();
const auto performanceRate = selector.getMaxSupportedRefreshRate();
EXPECT_EQ(kMode60, minRate);
EXPECT_EQ(kMode90, performanceRate);
const auto minRateByPolicy = selector.getMinRefreshRateByPolicy();
const auto performanceRateByPolicy = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(minRateByPolicy, minRate);
EXPECT_EQ(performanceRateByPolicy, performanceRate);
}
TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap_differentGroups) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
const auto minRate = selector.getMinRefreshRateByPolicy();
const auto performanceRate = selector.getMaxSupportedRefreshRate();
const auto minRate60 = selector.getMinRefreshRateByPolicy();
const auto performanceRate60 = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode60, minRate);
EXPECT_EQ(kMode60, minRate60);
EXPECT_EQ(kMode60, performanceRate60);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
selector.setActiveMode(kModeId90, 90_Hz);
const auto minRate90 = selector.getMinRefreshRateByPolicy();
const auto performanceRate90 = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode90_G1, performanceRate);
EXPECT_EQ(kMode90_G1, minRate90);
EXPECT_EQ(kMode90_G1, performanceRate90);
}
TEST_P(RefreshRateSelectorTest, twoModes_storesFullRefreshRateMap_differentResolutions) {
auto selector = createSelector(kModes_60_90_4K, kModeId60);
const auto minRate = selector.getMinRefreshRateByPolicy();
const auto performanceRate = selector.getMaxSupportedRefreshRate();
const auto minRate60 = selector.getMinRefreshRateByPolicy();
const auto performanceRate60 = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode60, minRate);
EXPECT_EQ(kMode60, minRate60);
EXPECT_EQ(kMode60, performanceRate60);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
selector.setActiveMode(kModeId90, 90_Hz);
const auto minRate90 = selector.getMinRefreshRateByPolicy();
const auto performanceRate90 = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode90_4K, performanceRate);
EXPECT_EQ(kMode90_4K, minRate90);
EXPECT_EQ(kMode90_4K, performanceRate90);
}
TEST_P(RefreshRateSelectorTest, twoModes_policyChange) {
auto selector = createSelector(kModes_60_90, kModeId60);
const auto minRate = selector.getMinRefreshRateByPolicy();
const auto performanceRate = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode60, minRate);
EXPECT_EQ(kMode90, performanceRate);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
const auto minRate60 = selector.getMinRefreshRateByPolicy();
const auto performanceRate60 = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kMode60, minRate60);
EXPECT_EQ(kMode60, performanceRate60);
}
TEST_P(RefreshRateSelectorTest, twoModes_getActiveMode) {
auto selector = createSelector(kModes_60_90, kModeId60);
{
const auto& mode = selector.getActiveMode();
EXPECT_EQ(mode.getId(), kModeId60);
}
selector.setActiveMode(kModeId90, 90_Hz);
{
const auto& mode = selector.getActiveMode();
EXPECT_EQ(mode.getId(), kModeId90);
}
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
{
const auto& mode = selector.getActiveMode();
EXPECT_EQ(mode.getId(), kModeId90);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_noLayers) {
{
auto selector = createSelector(kModes_60_72_90, kModeId72);
// If there are no layers we select the default frame rate, which is the max of the primary
// range.
EXPECT_EQ(kMode90, selector.getBestFrameRateMode().modePtr);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(kMode60, selector.getBestFrameRateMode().modePtr);
}
{
// We select max even when this will cause a non-seamless switch.
auto selector = createSelector(kModes_60_90_G1, kModeId60);
constexpr bool kAllowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId90, {0_Hz, 90_Hz}, kAllowGroupSwitching}));
EXPECT_EQ(kMode90_G1, selector.getBestFrameRateMode().modePtr);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_exactDontChangeRefreshRateWhenNotInPolicy) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId72);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].vote = LayerVoteType::ExplicitExact;
layers[0].desiredRefreshRate = 120_Hz;
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId72, {0_Hz, 90_Hz}}));
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_60_90) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
lr.name = "Min";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
lr.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
lr.name = "45Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
lr.name = "30Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
lr.name = "24Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.name = "";
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_multipleThreshold_60_90) {
auto selector = createSelector(kModes_60_90, kModeId60, {.frameRateMultipleThreshold = 90});
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
lr.name = "Min";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
lr.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
lr.name = "45Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
lr.name = "30Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
lr.name = "24Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_60_72_90) {
auto selector = createSelector(kModes_60_72_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_72_90_120) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 48_Hz;
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 48_Hz;
lr2.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_90_120_DifferentTypes) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "60Hz ExplicitDefault";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::Heuristic;
lr1.name = "24Hz Heuristic";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.name = "90Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_30_60_90_120_DifferentTypes_multipleThreshold) {
auto selector =
createSelector(kModes_30_60_72_90_120, kModeId60, {.frameRateMultipleThreshold = 120});
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
auto& lr3 = layers[2];
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "60Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "60Hz ExplicitDefault";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::Heuristic;
lr1.name = "24Hz Heuristic";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.name = "24Hz ExplicitDefault";
lr2.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.name = "90Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 120_Hz;
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.name = "120Hz ExplicitDefault";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 24_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "24Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 120_Hz;
lr2.vote = LayerVoteType::ExplicitExact;
lr2.name = "120Hz ExplicitExact";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 10_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 120_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.name = "120Hz ExplicitExact";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.desiredRefreshRate = 30_Hz;
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.desiredRefreshRate = 30_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.name = "30Hz ExplicitExactOrMultiple";
lr3.vote = LayerVoteType::Heuristic;
lr3.desiredRefreshRate = 120_Hz;
lr3.name = "120Hz Heuristic";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60) {
auto selector = createSelector(kModes_30_60, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_30_60_72_90) {
auto selector = createSelector(kModes_30_60_72_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::Min;
lr.name = "Min";
EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
lr.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 90_Hz;
lr.vote = LayerVoteType::Heuristic;
lr.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Heuristic";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr.desiredRefreshRate = 45_Hz;
lr.name = "45Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr.desiredRefreshRate = 30_Hz;
lr.name = "30Hz Heuristic";
EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr.desiredRefreshRate = 24_Hz;
lr.name = "24Hz Heuristic";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr.desiredRefreshRate = 24_Hz;
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
lr.name = "24Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode72, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_PriorityTest) {
auto selector = createSelector(kModes_30_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::Max;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Min;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Max;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 15_Hz;
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 30_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 45_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_24FpsVideo) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
lr.desiredRefreshRate = Fps::fromValue(fps);
const auto mode = selector.getBestFrameRateMode(layers).modePtr;
EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses "
<< to_string(mode->getPeakFps()) << "("
<< to_string(mode->getVsyncRate()) << ")";
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_24FpsVideo_multipleThreshold_60_120) {
auto selector = createSelector(kModes_60_120, kModeId60, {.frameRateMultipleThreshold = 120});
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
lr.desiredRefreshRate = Fps::fromValue(fps);
const auto mode = selector.getBestFrameRateMode(layers).modePtr;
EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses "
<< to_string(mode->getPeakFps()) << "("
<< to_string(mode->getVsyncRate()) << ")";
}
}
TEST_P(RefreshRateSelectorTest, twoModes_getBestFrameRateMode_Explicit) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 60_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 90_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 90_Hz;
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60_Hz;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_75HzContent) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
for (float fps = 75.0f; fps < 100.0f; fps += 0.1f) {
lr.desiredRefreshRate = Fps::fromValue(fps);
const auto mode = selector.getBestFrameRateMode(layers, {}).modePtr;
EXPECT_EQ(kMode90, mode) << lr.desiredRefreshRate << " chooses "
<< to_string(mode->getPeakFps()) << "("
<< to_string(mode->getVsyncRate()) << ")";
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_Multiples) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 90_Hz;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.desiredRefreshRate = 90_Hz;
lr2.name = "90Hz ExplicitDefault";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 30_Hz;
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 90_Hz;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 30_Hz;
lr1.name = "30Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, scrollWhileWatching60fps_60_90) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Max;
lr2.name = "Max";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
// The other layer starts to provide buffers
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 90_Hz;
lr2.name = "90Hz Heuristic";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitGte) {
auto selector = createSelector(makeModes(kMode30, kMode60, kMode90, kMode120), kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 25_Hz;
lr1.name = "25Hz ExplicitGte";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(kMode30, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 91_Hz;
lr1.name = "91Hz ExplicitGte";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitDefault";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 90_Hz;
lr2.name = "90Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr1.vote = LayerVoteType::ExplicitGte;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitGte";
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 120_Hz;
lr2.name = "120Hz ExplicitExactOrMultiple";
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, getMaxRefreshRatesByPolicy) {
// The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
// different group.
auto selector = createSelector(kModes_30_60_90, kModeId60);
const auto refreshRates = selector.rankRefreshRates(selector.getActiveMode().getGroup(),
RefreshRateOrder::Descending);
const auto expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {30_Hz, kMode30}};
case Config::FrameRateOverride::Enabled:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90}, {30_Hz, kMode30}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest, getMinRefreshRatesByPolicy) {
// The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
// different group.
auto selector = createSelector(kModes_30_60_90, kModeId60);
const auto refreshRates = selector.rankRefreshRates(selector.getActiveMode().getGroup(),
RefreshRateOrder::Ascending);
const auto expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
case Config::FrameRateOverride::Enabled:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest, getMinRefreshRatesByPolicyOutsideTheGroup) {
// The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
// different group.
auto selector = createSelector(kModes_30_60_90, kModeId72);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}}));
const auto refreshRates =
selector.rankRefreshRates(/*anchorGroupOpt*/ std::nullopt, RefreshRateOrder::Ascending);
const auto expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
case Config::FrameRateOverride::Enabled:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest, getMaxRefreshRatesByPolicyOutsideTheGroup) {
// The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
// different group.
auto selector = createSelector(kModes_30_60_90, kModeId72);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}}));
const auto refreshRates = selector.rankRefreshRates(/*anchorGroupOpt*/ std::nullopt,
RefreshRateOrder::Descending);
const auto expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {30_Hz, kMode30}};
case Config::FrameRateOverride::Enabled:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90}, {30_Hz, kMode30}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest, powerOnImminentConsidered) {
auto selector = createSelector(kModes_60_90, kModeId60);
auto [refreshRates, signals] = selector.getRankedFrameRates({}, {});
EXPECT_FALSE(signals.powerOnImminent);
auto expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{90_Hz, kMode90}, {60_Hz, kMode60}};
case Config::FrameRateOverride::Enabled:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {45_Hz, kMode90},
{30_Hz, kMode60}, {22.5_Hz, kMode90}, {20_Hz, kMode60}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
std::tie(refreshRates, signals) =
selector.getRankedRefreshRatesAsPair({}, {.powerOnImminent = true});
EXPECT_TRUE(signals.powerOnImminent);
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr1 = layers[0];
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
std::tie(refreshRates, signals) =
selector.getRankedRefreshRatesAsPair(layers, {.powerOnImminent = true});
EXPECT_TRUE(signals.powerOnImminent);
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
std::tie(refreshRates, signals) =
selector.getRankedRefreshRatesAsPair(layers, {.powerOnImminent = false});
EXPECT_FALSE(signals.powerOnImminent);
expectedRefreshRates = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{60_Hz, kMode60}, {90_Hz, kMode90}};
case Config::FrameRateOverride::Enabled:
return {{60_Hz, kMode60}, {90_Hz, kMode90}, {45_Hz, kMode90},
{30_Hz, kMode60}, {22.5_Hz, kMode90}, {20_Hz, kMode60}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
EXPECT_EQ(expectedRefreshRates[i], refreshRates[i].frameRateMode)
<< "Expected " << expectedRefreshRates[i].fps.getIntValue() << " ("
<< expectedRefreshRates[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << refreshRates[i].frameRateMode.fps.getIntValue() << " ("
<< refreshRates[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest, touchConsidered) {
auto selector = createSelector(kModes_60_90, kModeId60);
auto [_, signals] = selector.getRankedFrameRates({}, {});
EXPECT_FALSE(signals.touch);
std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair({}, {.touch = true});
EXPECT_TRUE(signals.touch);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true});
EXPECT_TRUE(signals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitDefault";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true});
EXPECT_FALSE(signals.touch);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true});
EXPECT_TRUE(signals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitDefault";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
std::tie(std::ignore, signals) = selector.getRankedRefreshRatesAsPair(layers, {.touch = true});
EXPECT_FALSE(signals.touch);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_30_60_90_120) {
auto selector = createSelector(makeModes(kMode30, kMode60, kMode90, kMode120), kModeId60);
struct Case {
// Params
Fps desiredFrameRate = 0_Hz;
FrameRateCategory frameRateCategory = FrameRateCategory::Default;
// Expected result
Fps expectedFrameRate = 0_Hz;
};
// Prepare a table with the vote and the expected refresh rate
const std::initializer_list<Case> testCases = {
// Cases that only have frame rate category requirements, but no desired frame rate.
// When frame rates get an equal score, the lower is chosen, unless there are Max votes.
{0_Hz, FrameRateCategory::High, 90_Hz},
{0_Hz, FrameRateCategory::Normal, 60_Hz},
{0_Hz, FrameRateCategory::Low, 30_Hz},
{0_Hz, FrameRateCategory::NoPreference, 30_Hz},
// Cases that have both desired frame rate and frame rate category requirements.
{24_Hz, FrameRateCategory::High, 120_Hz},
{30_Hz, FrameRateCategory::High, 90_Hz},
{12_Hz, FrameRateCategory::Normal, 60_Hz},
{30_Hz, FrameRateCategory::NoPreference, 30_Hz},
// Cases that only have desired frame rate.
{30_Hz, FrameRateCategory::Default, 30_Hz},
};
for (auto testCase : testCases) {
std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
to_string(testCase.desiredFrameRate).c_str(),
ftl::enum_string(testCase.frameRateCategory).c_str());
if (testCase.desiredFrameRate.isValid()) {
std::stringstream ss;
ss << to_string(testCase.desiredFrameRate) << "ExplicitDefault";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitDefault,
.desiredRefreshRate = testCase.desiredFrameRate,
.weight = 1.f};
layers.push_back(layer);
}
if (testCase.frameRateCategory != FrameRateCategory::Default) {
std::stringstream ss;
ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitCategory,
.frameRateCategory = testCase.frameRateCategory,
.weight = 1.f};
layers.push_back(layer);
}
EXPECT_EQ(testCase.expectedFrameRate,
selector.getBestFrameRateMode(layers).modePtr->getPeakFps())
<< "Did not get expected frame rate for frameRate="
<< to_string(testCase.desiredFrameRate)
<< " category=" << ftl::enum_string(testCase.frameRateCategory);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_60_120) {
auto selector = createSelector(makeModes(kMode60, kMode120), kModeId60);
struct Case {
// Params
Fps desiredFrameRate = 0_Hz;
FrameRateCategory frameRateCategory = FrameRateCategory::Default;
// Expected result
Fps expectedFrameRate = 0_Hz;
};
// Prepare a table with the vote and the expected refresh rate
const std::initializer_list<Case> testCases = {
// Cases that only have frame rate category requirements, but no desired frame rate.
// When frame rates get an equal score, the lower is chosen, unless there are Max votes.
{0_Hz, FrameRateCategory::High, 120_Hz},
{0_Hz, FrameRateCategory::Normal, 60_Hz},
{0_Hz, FrameRateCategory::Low, 60_Hz},
{0_Hz, FrameRateCategory::NoPreference, 60_Hz},
// Cases that have both desired frame rate and frame rate category requirements.
{24_Hz, FrameRateCategory::High, 120_Hz},
{30_Hz, FrameRateCategory::High, 120_Hz},
{12_Hz, FrameRateCategory::Normal, 60_Hz},
{30_Hz, FrameRateCategory::NoPreference, 60_Hz},
// Cases that only have desired frame rate.
{30_Hz, FrameRateCategory::Default, 60_Hz},
};
for (auto testCase : testCases) {
std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
to_string(testCase.desiredFrameRate).c_str(),
ftl::enum_string(testCase.frameRateCategory).c_str());
if (testCase.desiredFrameRate.isValid()) {
std::stringstream ss;
ss << to_string(testCase.desiredFrameRate) << "ExplicitDefault";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitDefault,
.desiredRefreshRate = testCase.desiredFrameRate,
.weight = 1.f};
layers.push_back(layer);
}
if (testCase.frameRateCategory != FrameRateCategory::Default) {
std::stringstream ss;
ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitCategory,
.frameRateCategory = testCase.frameRateCategory,
.weight = 1.f};
layers.push_back(layer);
}
EXPECT_EQ(testCase.expectedFrameRate,
selector.getBestFrameRateMode(layers).modePtr->getPeakFps())
<< "Did not get expected frame rate for frameRate="
<< to_string(testCase.desiredFrameRate)
<< " category=" << ftl::enum_string(testCase.frameRateCategory);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_HighHint) {
auto selector = createSelector(makeModes(kMode24, kMode30, kMode60, kMode120), kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::NoVote;
lr2.name = "NoVote";
auto actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
// No touch boost, for example a game that uses setFrameRate(30, default compatibility).
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::ExplicitDefault;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitDefault";
actualRankedFrameRates = selector.getRankedFrameRates(layers);
EXPECT_EQ(30_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::ExplicitCategory;
lr2.frameRateCategory = FrameRateCategory::HighHint;
lr2.name = "ExplicitCategory HighHint#2";
actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::ExplicitCategory;
lr2.frameRateCategory = FrameRateCategory::Low;
lr2.name = "ExplicitCategory Low";
actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitExactOrMultiple";
actualRankedFrameRates = selector.getRankedFrameRates(layers);
// Gets touch boost
EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId120, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
lr1.vote = LayerVoteType::ExplicitCategory;
lr1.frameRateCategory = FrameRateCategory::HighHint;
lr1.name = "ExplicitCategory HighHint";
lr2.vote = LayerVoteType::ExplicitExact;
lr2.desiredRefreshRate = 30_Hz;
lr2.name = "30Hz ExplicitExact";
actualRankedFrameRates = selector.getRankedFrameRates(layers);
if (selector.supportsAppFrameRateOverrideByContent()) {
// Gets touch boost
EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId120,
actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_TRUE(actualRankedFrameRates.consideredSignals.touch);
} else {
EXPECT_EQ(30_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
EXPECT_EQ(kModeId30, actualRankedFrameRates.ranking.front().frameRateMode.modePtr->getId());
EXPECT_FALSE(actualRankedFrameRates.consideredSignals.touch);
}
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withFrameRateCategory_smoothSwitchOnly_60_120_nonVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, false);
// VRR compatibility is determined by the presence of a vrr config in the DisplayMode.
auto selector = createSelector(makeModes(kMode60, kMode120), kModeId120);
struct Case {
// Params
FrameRateCategory frameRateCategory = FrameRateCategory::Default;
bool smoothSwitchOnly = false;
// Expected result
Fps expectedFrameRate = 0_Hz;
DisplayModeId expectedModeId = kModeId60;
};
const std::initializer_list<Case> testCases = {
// These layers may switch modes because smoothSwitchOnly=false.
{FrameRateCategory::Default, false, 120_Hz, kModeId120},
// TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate.
{FrameRateCategory::NoPreference, false, 60_Hz, kModeId60},
{FrameRateCategory::Low, false, 30_Hz, kModeId60},
{FrameRateCategory::Normal, false, 60_Hz, kModeId60},
{FrameRateCategory::High, false, 120_Hz, kModeId120},
// These layers cannot change mode due to smoothSwitchOnly, and will definitely use
// active mode (120Hz).
{FrameRateCategory::NoPreference, true, 120_Hz, kModeId120},
{FrameRateCategory::Low, true, 120_Hz, kModeId120},
{FrameRateCategory::Normal, true, 40_Hz, kModeId120},
{FrameRateCategory::High, true, 120_Hz, kModeId120},
};
for (auto testCase : testCases) {
std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing frameRateCategory=%s (smooth=%d)", __func__,
ftl::enum_string(testCase.frameRateCategory).c_str(), testCase.smoothSwitchOnly);
if (testCase.frameRateCategory != FrameRateCategory::Default) {
std::stringstream ss;
ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory)
<< " smooth:" << testCase.smoothSwitchOnly << ")";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitCategory,
.frameRateCategory = testCase.frameRateCategory,
.frameRateCategorySmoothSwitchOnly =
testCase.smoothSwitchOnly,
.weight = 1.f};
layers.push_back(layer);
}
auto actualFrameRateMode = selector.getBestFrameRateMode(layers);
EXPECT_EQ(testCase.expectedFrameRate, actualFrameRateMode.fps)
<< "Did not get expected frame rate for category="
<< ftl::enum_string(testCase.frameRateCategory)
<< " (smooth=" << testCase.smoothSwitchOnly << ")";
EXPECT_EQ(testCase.expectedModeId, actualFrameRateMode.modePtr->getId())
<< "Did not get expected mode for category="
<< ftl::enum_string(testCase.frameRateCategory)
<< " (smooth=" << testCase.smoothSwitchOnly << ")";
}
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withFrameRateCategory_smoothSwitchOnly_60_120_vrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
// VRR compatibility is determined by the presence of a vrr config in the DisplayMode.
auto selector = createSelector(kVrrModes_60_120, kModeId120);
struct Case {
// Params
FrameRateCategory frameRateCategory = FrameRateCategory::Default;
bool smoothSwitchOnly = false;
// Expected result
Fps expectedFrameRate = 0_Hz;
};
// Note that `smoothSwitchOnly` should not have an effect.
const std::initializer_list<Case> testCases = {
{FrameRateCategory::Default, false, 120_Hz},
// TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate.
{FrameRateCategory::NoPreference, false, 120_Hz},
{FrameRateCategory::Low, false, 30_Hz},
{FrameRateCategory::Normal, false, 60_Hz},
{FrameRateCategory::High, false, 120_Hz},
{FrameRateCategory::Default, true, 120_Hz},
// TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate.
{FrameRateCategory::NoPreference, true, 120_Hz},
{FrameRateCategory::Low, true, 30_Hz},
{FrameRateCategory::Normal, true, 60_Hz},
{FrameRateCategory::High, true, 120_Hz},
};
for (auto testCase : testCases) {
std::vector<LayerRequirement> layers;
ALOGI("**** %s: Testing frameRateCategory=%s (smooth=%d)", __func__,
ftl::enum_string(testCase.frameRateCategory).c_str(), testCase.smoothSwitchOnly);
if (testCase.frameRateCategory != FrameRateCategory::Default) {
std::stringstream ss;
ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory)
<< " smooth:" << testCase.smoothSwitchOnly << ")";
LayerRequirement layer = {.name = ss.str(),
.vote = LayerVoteType::ExplicitCategory,
.frameRateCategory = testCase.frameRateCategory,
.frameRateCategorySmoothSwitchOnly =
testCase.smoothSwitchOnly,
.weight = 1.f};
layers.push_back(layer);
}
auto actualFrameRateMode = selector.getBestFrameRateMode(layers);
EXPECT_EQ(testCase.expectedFrameRate, actualFrameRateMode.fps)
<< "Did not get expected frame rate for category="
<< ftl::enum_string(testCase.frameRateCategory)
<< " (smooth=" << testCase.smoothSwitchOnly << ")";
// Expect all cases to be able to stay at the mode with TE 240 due to VRR compatibility.
EXPECT_EQ(kVrrMode120TE240->getId(), actualFrameRateMode.modePtr->getId())
<< "Did not get expected mode for category="
<< ftl::enum_string(testCase.frameRateCategory)
<< " (smooth=" << testCase.smoothSwitchOnly << ")";
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitDefault) {
auto selector = createSelector(kModes_60_90_72_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
// Prepare a table with the vote and the expected refresh rate
const std::initializer_list<std::pair<Fps, Fps>> testCases = {
{130_Hz, 120_Hz}, {120_Hz, 120_Hz}, {119_Hz, 120_Hz}, {110_Hz, 120_Hz},
{100_Hz, 90_Hz}, {90_Hz, 90_Hz}, {89_Hz, 90_Hz},
{80_Hz, 72_Hz}, {73_Hz, 72_Hz}, {72_Hz, 72_Hz}, {71_Hz, 72_Hz}, {70_Hz, 72_Hz},
{65_Hz, 60_Hz}, {60_Hz, 60_Hz}, {59_Hz, 60_Hz}, {58_Hz, 60_Hz},
{55_Hz, 90_Hz}, {50_Hz, 90_Hz}, {45_Hz, 90_Hz},
{42_Hz, 120_Hz}, {40_Hz, 120_Hz}, {39_Hz, 120_Hz},
{37_Hz, 72_Hz}, {36_Hz, 72_Hz}, {35_Hz, 72_Hz},
{30_Hz, 60_Hz},
};
for (auto [desired, expected] : testCases) {
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = desired;
std::stringstream ss;
ss << "ExplicitDefault " << desired;
lr.name = ss.str();
const auto bestMode = selector.getBestFrameRateMode(layers).modePtr;
EXPECT_EQ(expected, bestMode->getPeakFps())
<< "expected " << expected << " for " << desired << " but got "
<< bestMode->getPeakFps() << "(" << bestMode->getVsyncRate() << ")";
}
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_ExplicitExactOrMultiple_WithFractionalRefreshRates) {
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
// Test that 23.976 will prefer 60 over 59.94 and 30
{
auto selector = createSelector(makeModes(kMode24, kMode25, kMode30, kMode30Frac, kMode60,
kMode60Frac),
kModeId60);
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
lr.desiredRefreshRate = 23.976_Hz;
lr.name = "ExplicitExactOrMultiple 23.976 Hz";
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
// Test that 24 will choose 23.976 if 24 is not supported
{
auto selector = createSelector(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac,
kMode60, kMode60Frac),
kModeId60);
lr.desiredRefreshRate = 24_Hz;
lr.name = "ExplicitExactOrMultiple 24 Hz";
EXPECT_EQ(kModeId24Frac, selector.getBestFrameRateMode(layers).modePtr->getId());
}
// Test that 29.97 will prefer 59.94 over 60 and 30
{
auto selector = createSelector(makeModes(kMode24, kMode24Frac, kMode25, kMode30, kMode60,
kMode60Frac),
kModeId60);
lr.desiredRefreshRate = 29.97_Hz;
lr.name = "ExplicitExactOrMultiple 29.97 Hz";
EXPECT_EQ(kModeId60Frac, selector.getBestFrameRateMode(layers).modePtr->getId());
}
// Test that 29.97 will choose 60 if 59.94 is not supported
{
auto selector = createSelector(makeModes(kMode30, kMode60), kModeId60);
lr.desiredRefreshRate = 29.97_Hz;
lr.name = "ExplicitExactOrMultiple 29.97 Hz";
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
// Test that 59.94 will choose 60 if 59.94 is not supported
{
auto selector = createSelector(makeModes(kMode60, kMode30Frac, kMode30), kModeId60);
lr.desiredRefreshRate = 59.94_Hz;
lr.name = "ExplicitExactOrMultiple 59.94 Hz";
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExact_WithFractionalRefreshRates) {
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
// Test that voting for supported refresh rate will select this refresh rate
{
auto selector = createSelector(kModes_24_25_30_50_60_Frac, kModeId60);
for (auto desired : {23.976_Hz, 24_Hz, 25_Hz, 29.97_Hz, 30_Hz, 50_Hz, 59.94_Hz, 60_Hz}) {
lr.vote = LayerVoteType::ExplicitExact;
lr.desiredRefreshRate = desired;
std::stringstream ss;
ss << "ExplicitExact " << desired;
lr.name = ss.str();
EXPECT_EQ(lr.desiredRefreshRate,
selector.getBestFrameRateMode(layers).modePtr->getPeakFps());
}
}
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) {
auto selector = createSelector(kModes_60_90, kModeId90);
constexpr FpsRange k90 = {90_Hz, 90_Hz};
constexpr FpsRange k60_90 = {60_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {k90, k90}, {k60_90, k60_90}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz ExplicitDefault";
lr.focused = true;
const auto [rankedFrameRate, signals] =
selector.getRankedFrameRates(layers, {.touch = true, .idle = true});
EXPECT_EQ(rankedFrameRate.begin()->frameRateMode.modePtr, kMode60);
EXPECT_FALSE(signals.touch);
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) {
auto selector = createSelector(kModes_60_90, kModeId60);
constexpr FpsRange k60 = {60_Hz, 60_Hz};
constexpr FpsRange k60_90 = {60_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {k60, k60}, {k60_90, k60_90}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = 90_Hz;
lr.name = "90Hz ExplicitDefault";
lr.focused = true;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers, {.idle = true}).modePtr);
}
TEST_P(RefreshRateSelectorTest, testDisplayModeOrdering) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f},
{.weight = 1.f},
{.weight = 1.f},
{.weight = 1.f},
{.weight = 1.f}};
auto& lr1 = layers[0];
auto& lr2 = layers[1];
auto& lr3 = layers[2];
auto& lr4 = layers[3];
auto& lr5 = layers[4];
lr1.desiredRefreshRate = 90_Hz;
lr1.name = "90Hz";
lr1.focused = true;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz";
lr2.focused = true;
lr3.desiredRefreshRate = 72_Hz;
lr3.name = "72Hz";
lr3.focused = true;
lr4.desiredRefreshRate = 120_Hz;
lr4.name = "120Hz";
lr4.focused = true;
lr5.desiredRefreshRate = 30_Hz;
lr5.name = "30Hz";
lr5.focused = true;
auto expectedRanking = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{120_Hz, kMode120},
{90_Hz, kMode90},
{72_Hz, kMode72},
{60_Hz, kMode60},
{30_Hz, kMode30}};
case Config::FrameRateOverride::Enabled:
return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60},
{45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}};
}
}();
auto actualRanking = selector.getRankedFrameRates(layers, {}).ranking;
ASSERT_EQ(expectedRanking.size(), actualRanking.size());
for (size_t i = 0; i < expectedRanking.size(); ++i) {
EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode)
<< "Expected " << expectedRanking[i].fps.getIntValue() << " ("
<< expectedRanking[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " ("
<< actualRanking[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
lr1.vote = LayerVoteType::Max;
lr1.name = "Max";
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz";
lr3.desiredRefreshRate = 72_Hz;
lr3.name = "72Hz";
lr4.desiredRefreshRate = 90_Hz;
lr4.name = "90Hz";
lr5.desiredRefreshRate = 120_Hz;
lr5.name = "120Hz";
expectedRanking = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{120_Hz, kMode120},
{90_Hz, kMode90},
{72_Hz, kMode72},
{60_Hz, kMode60},
{30_Hz, kMode30}};
case Config::FrameRateOverride::Enabled:
return {{120_Hz, kMode120}, {90_Hz, kMode90}, {72_Hz, kMode72}, {60_Hz, kMode60},
{45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}};
}
}();
actualRanking = selector.getRankedFrameRates(layers, {}).ranking;
ASSERT_EQ(expectedRanking.size(), actualRanking.size());
for (size_t i = 0; i < expectedRanking.size(); ++i) {
EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode)
<< "Expected " << expectedRanking[i].fps.getIntValue() << " ("
<< expectedRanking[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " ("
<< actualRanking[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
lr1.vote = LayerVoteType::Heuristic;
lr1.desiredRefreshRate = 30_Hz;
lr1.name = "30Hz";
lr2.desiredRefreshRate = 120_Hz;
lr2.name = "120Hz";
lr3.desiredRefreshRate = 60_Hz;
lr3.name = "60Hz";
lr5.desiredRefreshRate = 72_Hz;
lr5.name = "72Hz";
expectedRanking = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, kMode30},
{60_Hz, kMode60},
{90_Hz, kMode90},
{120_Hz, kMode120},
{72_Hz, kMode72}};
case Config::FrameRateOverride::Enabled:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}, {120_Hz, kMode120},
{45_Hz, kMode90}, {40_Hz, kMode120}, {72_Hz, kMode72}, {36_Hz, kMode72}};
}
}();
actualRanking = selector.getRankedFrameRates(layers, {}).ranking;
ASSERT_EQ(expectedRanking.size(), actualRanking.size());
for (size_t i = 0; i < expectedRanking.size(); ++i) {
EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode)
<< "Expected " << expectedRanking[i].fps.getIntValue() << " ("
<< expectedRanking[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " ("
<< actualRanking[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
lr1.desiredRefreshRate = 120_Hz;
lr1.name = "120Hz";
lr1.weight = 0.0f;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz";
lr2.vote = LayerVoteType::NoVote;
lr3.name = "60Hz-2";
lr3.vote = LayerVoteType::Heuristic;
lr4.vote = LayerVoteType::ExplicitExact;
lr5.desiredRefreshRate = 120_Hz;
lr5.name = "120Hz-2";
expectedRanking = []() -> std::vector<FrameRateMode> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{90_Hz, kMode90},
{60_Hz, kMode60},
{120_Hz, kMode120},
{72_Hz, kMode72},
{30_Hz, kMode30}};
case Config::FrameRateOverride::Enabled:
return {{90_Hz, kMode90}, {60_Hz, kMode60}, {120_Hz, kMode120}, {72_Hz, kMode72},
{45_Hz, kMode90}, {40_Hz, kMode120}, {36_Hz, kMode72}, {30_Hz, kMode30}};
}
}();
actualRanking = selector.getRankedFrameRates(layers, {}).ranking;
ASSERT_EQ(expectedRanking.size(), actualRanking.size());
for (size_t i = 0; i < expectedRanking.size(); ++i) {
EXPECT_EQ(expectedRanking[i], actualRanking[i].frameRateMode)
<< "Expected " << expectedRanking[i].fps.getIntValue() << " ("
<< expectedRanking[i].modePtr->getVsyncRate().getIntValue() << ")"
<< " Actual " << actualRanking[i].frameRateMode.fps.getIntValue() << " ("
<< actualRanking[i].frameRateMode.modePtr->getVsyncRate().getIntValue() << ")";
}
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) {
auto selector = createSelector(kModes_60_90, kModeId90);
constexpr FpsRange k90 = {90_Hz, 90_Hz};
constexpr FpsRange k60_90 = {60_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {k90, k90}, {k60_90, k60_90}}));
const auto [ranking, signals] = selector.getRankedFrameRates({}, {});
EXPECT_EQ(ranking.front().frameRateMode.modePtr, kMode90);
EXPECT_FALSE(signals.touch);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz ExplicitExactOrMultiple";
lr.focused = false;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.focused = true;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::ExplicitDefault;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz ExplicitDefault";
lr.focused = false;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.focused = true;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Heuristic;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Heuristic";
lr.focused = false;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.focused = true;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Max;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Max";
lr.focused = false;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.focused = true;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.vote = LayerVoteType::Min;
lr.desiredRefreshRate = 60_Hz;
lr.name = "60Hz Min";
lr.focused = false;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
lr.focused = true;
EXPECT_EQ(kMode90, selector.getBestFrameRateMode(layers).modePtr);
}
TEST_P(RefreshRateSelectorTest, groupSwitchingNotAllowed) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
// The default policy doesn't allow group switching. Verify that no
// group switches are performed.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = 90_Hz;
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayer) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = 90_Hz;
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerOnlySeamless) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
// Verify that we won't change the group if seamless switch is required.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = 90_Hz;
layer.seamlessness = Seamlessness::OnlySeamless;
layer.name = "90Hz ExplicitDefault";
layer.focused = true;
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
selector.setActiveMode(kModeId90, 90_Hz);
// Verify that we won't do a seamless switch if we request the same mode as the default
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = 60_Hz;
layer.seamlessness = Seamlessness::OnlySeamless;
layer.name = "60Hz ExplicitDefault";
layer.focused = true;
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithOneLayerDefaultSeamlessness) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
selector.setActiveMode(kModeId90, 90_Hz);
// Verify that if the active mode is in another group and there are no layers with
// Seamlessness::SeamedAndSeamless, we should switch back to the default group.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitDefault;
layer.desiredRefreshRate = 60_Hz;
layer.seamlessness = Seamlessness::Default;
layer.name = "60Hz ExplicitDefault";
layer.focused = true;
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
selector.setActiveMode(kModeId90, 90_Hz);
// If there's a layer with Seamlessness::SeamedAndSeamless, another layer with
// Seamlessness::OnlySeamless can't change the mode group.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].seamlessness = Seamlessness::OnlySeamless;
layers[0].name = "60Hz ExplicitDefault";
layers[0].focused = true;
layers.push_back(LayerRequirement{.weight = 0.5f});
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = 90_Hz;
layers[1].name = "90Hz ExplicitDefault";
layers[1].focused = false;
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
selector.setActiveMode(kModeId90, 90_Hz);
// If there's a focused layer with Seamlessness::SeamedAndSeamless, another layer with
// Seamlessness::Default can't change the mode group back to the group of the default
// mode.
// For example, this may happen when a video playback requests and gets a seamed switch,
// but another layer (with default seamlessness) starts animating. The animating layer
// should not cause a seamed switch.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].seamlessness = Seamlessness::Default;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].focused = true;
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].name = "60Hz ExplicitDefault";
layers.push_back(LayerRequirement{.weight = 0.1f});
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = 90_Hz;
layers[1].focused = true;
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "90Hz ExplicitDefault";
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) {
auto selector = createSelector(kModes_60_90_G1, kModeId60);
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
selector.setActiveMode(kModeId90, 90_Hz);
// Layer with Seamlessness::Default can change the mode group if there's an
// unfocused layer with Seamlessness::SeamedAndSeamless. For example, this happens
// when in split screen mode the user switches between the two visible applications.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].seamlessness = Seamlessness::Default;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].focused = true;
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].name = "60Hz ExplicitDefault";
layers.push_back(LayerRequirement{.weight = 0.7f});
layers[1].seamlessness = Seamlessness::SeamedAndSeamless;
layers[1].desiredRefreshRate = 90_Hz;
layers[1].focused = false;
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "90Hz ExplicitDefault";
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, nonSeamlessVotePrefersSeamlessSwitches) {
auto selector = createSelector(kModes_30_60, kModeId60);
// Allow group switching.
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::ExplicitExactOrMultiple;
layer.desiredRefreshRate = 60_Hz;
layer.seamlessness = Seamlessness::SeamedAndSeamless;
layer.name = "60Hz ExplicitExactOrMultiple";
layer.focused = true;
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers).modePtr->getId());
selector.setActiveMode(kModeId120, 120_Hz);
EXPECT_EQ(kModeId120, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, nonSeamlessExactAndSeamlessMultipleLayers) {
auto selector = createSelector(kModes_25_30_50_60, kModeId60);
// Allow group switching.
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.name = "60Hz ExplicitDefault",
.vote = LayerVoteType::ExplicitDefault,
.desiredRefreshRate = 60_Hz,
.seamlessness = Seamlessness::SeamedAndSeamless,
.weight = 0.5f,
.focused = false},
{.name = "25Hz ExplicitExactOrMultiple",
.vote = LayerVoteType::ExplicitExactOrMultiple,
.desiredRefreshRate = 25_Hz,
.seamlessness = Seamlessness::OnlySeamless,
.weight = 1.f,
.focused = true}};
EXPECT_EQ(kModeId50, selector.getBestFrameRateMode(layers).modePtr->getId());
auto& seamedLayer = layers[0];
seamedLayer.desiredRefreshRate = 30_Hz;
seamedLayer.name = "30Hz ExplicitDefault";
selector.setActiveMode(kModeId30, 30_Hz);
EXPECT_EQ(kModeId25, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, minLayersDontTrigerSeamedSwitch) {
auto selector = createSelector(kModes_60_90_G1, kModeId90);
// Allow group switching.
RefreshRateSelector::DisplayManagerPolicy policy;
policy.defaultMode = selector.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
std::vector<LayerRequirement> layers = {
{.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}};
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode(layers).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, primaryVsAppRequestPolicy) {
auto selector = createSelector(kModes_30_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
struct Args {
bool touch = false;
bool focused = true;
};
// Returns the mode selected by getBestFrameRateMode for a single layer with the given
// arguments.
const auto getFrameRate = [&](LayerVoteType voteType, Fps fps,
Args args = {}) -> DisplayModeId {
layers[0].vote = voteType;
layers[0].desiredRefreshRate = fps;
layers[0].focused = args.focused;
return selector.getBestFrameRateMode(layers, {.touch = args.touch}).modePtr->getId();
};
constexpr FpsRange k30_60 = {30_Hz, 60_Hz};
constexpr FpsRange k30_90 = {30_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {k30_60, k30_60}, {k30_90, k30_90}}));
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode().modePtr->getId());
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz));
EXPECT_EQ(kModeId30, getFrameRate(LayerVoteType::Min, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Heuristic, 90_Hz));
EXPECT_EQ(kModeId90, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz));
// Unfocused layers are not allowed to override primary range.
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz, {.focused = false}));
EXPECT_EQ(kModeId60,
getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz, {.focused = false}));
// Touch boost should be restricted to the primary range.
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz, {.touch = true}));
// When we're higher than the primary range max due to a layer frame rate setting, touch boost
// shouldn't drag us back down to the primary range max.
EXPECT_EQ(kModeId90, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz, {.touch = true}));
EXPECT_EQ(kModeId60,
getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz, {.touch = true}));
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Min, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Max, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Heuristic, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitDefault, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz));
}
TEST_P(RefreshRateSelectorTest, idle) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
const auto getIdleDisplayModeId = [&](LayerVoteType voteType,
bool touchActive) -> DisplayModeId {
layers[0].vote = voteType;
layers[0].desiredRefreshRate = 90_Hz;
const auto [ranking, signals] =
selector.getRankedFrameRates(layers, {.touch = touchActive, .idle = true});
// Refresh rate will be chosen by either touch state or idle state.
EXPECT_EQ(!touchActive, signals.idle);
return ranking.front().frameRateMode.modePtr->getId();
};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}));
// Idle should be lower priority than touch boost.
{
constexpr bool kTouchActive = true;
EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive));
EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive));
EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive));
EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive));
EXPECT_EQ(kModeId90, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive));
EXPECT_EQ(kModeId90,
getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive));
}
// With no layers, idle should still be lower priority than touch boost.
EXPECT_EQ(kModeId90,
selector.getBestFrameRateMode({}, {.touch = true, .idle = true}).modePtr->getId());
// Idle should be higher precedence than other layer frame rate considerations.
selector.setActiveMode(kModeId90, 90_Hz);
{
constexpr bool kTouchActive = false;
EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive));
EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive));
EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive));
EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive));
EXPECT_EQ(kModeId60, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive));
EXPECT_EQ(kModeId60,
getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive));
}
// Idle should be applied rather than the active mode when there are no layers.
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode({}, {.idle = true}).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, findClosestKnownFrameRate) {
auto selector = createSelector(kModes_60_90, kModeId60);
for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) {
const auto knownFrameRate = selector.findClosestKnownFrameRate(Fps::fromValue(fps));
const Fps expectedFrameRate = [fps] {
if (fps < 26.91f) return 24_Hz;
if (fps < 37.51f) return 30_Hz;
if (fps < 52.51f) return 45_Hz;
if (fps < 66.01f) return 60_Hz;
if (fps < 81.01f) return 72_Hz;
return 90_Hz;
}();
EXPECT_EQ(expectedFrameRate, knownFrameRate);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_KnownFrameRate) {
auto selector = createSelector(kModes_60_90, kModeId60);
struct Expectation {
Fps fps;
ftl::NonNull<DisplayModePtr> mode;
};
const std::initializer_list<Expectation> knownFrameRatesExpectations = {
{24_Hz, kMode60}, {30_Hz, kMode60}, {45_Hz, kMode90},
{60_Hz, kMode60}, {72_Hz, kMode90}, {90_Hz, kMode90},
};
// Make sure the test tests all the known frame rate
const auto& knownFrameRates = selector.knownFrameRates();
const bool equal = std::equal(knownFrameRates.begin(), knownFrameRates.end(),
knownFrameRatesExpectations.begin(),
[](Fps fps, const Expectation& expected) {
return isApproxEqual(fps, expected.fps);
});
EXPECT_TRUE(equal);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
layer.vote = LayerVoteType::Heuristic;
for (const auto& [fps, mode] : knownFrameRatesExpectations) {
layer.desiredRefreshRate = fps;
EXPECT_EQ(mode, selector.getBestFrameRateMode(layers).modePtr);
}
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExact) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}};
auto& explicitExactLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
explicitExactLayer.name = "ExplicitExact";
explicitExactLayer.desiredRefreshRate = 30_Hz;
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz;
if (GetParam() == Config::FrameRateOverride::Disabled) {
EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz,
selector.getBestScoredFrameRate(layers, {.touch = true})
.frameRateMode);
} else {
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz,
selector.getBestScoredFrameRate(layers, {.touch = true})
.frameRateMode);
}
explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz;
explicitExactLayer.desiredRefreshRate = 60_Hz;
if (GetParam() == Config::FrameRateOverride::Disabled) {
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
} else {
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
}
explicitExactLayer.desiredRefreshRate = 72_Hz;
EXPECT_FRAME_RATE_MODE(kMode72, 72_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
explicitExactLayer.desiredRefreshRate = 90_Hz;
EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
explicitExactLayer.desiredRefreshRate = 120_Hz;
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ReadsCache) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
using GlobalSignals = RefreshRateSelector::GlobalSignals;
const auto args = std::make_pair(std::vector<LayerRequirement>{},
GlobalSignals{.touch = true, .idle = true});
const RefreshRateSelector::RankedFrameRates result = {{RefreshRateSelector::ScoredFrameRate{
{90_Hz, kMode90}}},
GlobalSignals{.touch = true}};
selector.mutableGetRankedRefreshRatesCache() = {args, result};
EXPECT_EQ(result, selector.getRankedFrameRates(args.first, args.second));
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_WritesCache) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId60);
EXPECT_FALSE(selector.mutableGetRankedRefreshRatesCache());
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}};
RefreshRateSelector::GlobalSignals globalSignals{.touch = true, .idle = true};
const auto result = selector.getRankedFrameRates(layers, globalSignals);
const auto& cache = selector.mutableGetRankedRefreshRatesCache();
ASSERT_TRUE(cache);
EXPECT_EQ(cache->arguments, std::make_pair(layers, globalSignals));
EXPECT_EQ(cache->result, result);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitExactTouchBoost) {
auto selector = createSelector(kModes_60_120, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}};
auto& explicitExactLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz;
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
explicitExactLayer.name = "ExplicitExact";
explicitExactLayer.desiredRefreshRate = 30_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
if (GetParam() == Config::FrameRateOverride::Disabled) {
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
} else {
EXPECT_EQ(kMode120, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
}
explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers, {.touch = true}).modePtr);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_FractionalRefreshRates_ExactAndDefault) {
auto selector = createSelector(kModes_24_25_30_50_60_Frac, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 0.5f}, {.weight = 0.5f}};
auto& explicitDefaultLayer = layers[0];
auto& explicitExactOrMultipleLayer = layers[1];
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz;
explicitDefaultLayer.vote = LayerVoteType::ExplicitDefault;
explicitDefaultLayer.name = "ExplicitDefault";
explicitDefaultLayer.desiredRefreshRate = 59.94_Hz;
EXPECT_EQ(kMode60, selector.getBestFrameRateMode(layers).modePtr);
}
// b/190578904
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withCloseRefreshRates) {
if (g_noSlowTests) {
GTEST_SKIP();
}
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;
DisplayModes displayModes;
for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) {
const DisplayModeId modeId(fps);
displayModes.try_emplace(modeId,
createDisplayMode(modeId,
Fps::fromValue(static_cast<float>(fps))));
}
const auto selector = createSelector(std::move(displayModes), DisplayModeId(kMinRefreshRate));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
const auto testRefreshRate = [&](Fps fps, LayerVoteType vote) {
layers[0].desiredRefreshRate = fps;
layers[0].vote = vote;
EXPECT_EQ(fps.getIntValue(),
selector.getBestFrameRateMode(layers).modePtr->getPeakFps().getIntValue())
<< "Failed for " << ftl::enum_string(vote);
};
for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) {
const auto refreshRate = Fps::fromValue(static_cast<float>(fps));
testRefreshRate(refreshRate, LayerVoteType::Heuristic);
testRefreshRate(refreshRate, LayerVoteType::ExplicitDefault);
testRefreshRate(refreshRate, LayerVoteType::ExplicitExactOrMultiple);
testRefreshRate(refreshRate, LayerVoteType::ExplicitExact);
}
}
// b/190578904
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_conflictingVotes) {
constexpr DisplayModeId kActiveModeId{0};
DisplayModes displayModes = makeModes(createDisplayMode(kActiveModeId, 43_Hz),
createDisplayMode(DisplayModeId(1), 53_Hz),
createDisplayMode(DisplayModeId(2), 55_Hz),
createDisplayMode(DisplayModeId(3), 60_Hz));
const RefreshRateSelector::GlobalSignals globalSignals = {.touch = false, .idle = false};
const auto selector = createSelector(std::move(displayModes), kActiveModeId);
const std::vector<LayerRequirement> layers = {
{
.vote = LayerVoteType::ExplicitDefault,
.desiredRefreshRate = 43_Hz,
.seamlessness = Seamlessness::SeamedAndSeamless,
.weight = 0.41f,
},
{
.vote = LayerVoteType::ExplicitExactOrMultiple,
.desiredRefreshRate = 53_Hz,
.seamlessness = Seamlessness::SeamedAndSeamless,
.weight = 0.41f,
},
};
EXPECT_EQ(53_Hz, selector.getBestFrameRateMode(layers, globalSignals).modePtr->getPeakFps());
}
TEST_P(RefreshRateSelectorTest, modeComparison) {
EXPECT_LT(kMode60->getPeakFps(), kMode90->getPeakFps());
EXPECT_GE(kMode60->getPeakFps(), kMode60->getPeakFps());
EXPECT_GE(kMode90->getPeakFps(), kMode90->getPeakFps());
}
TEST_P(RefreshRateSelectorTest, testKernelIdleTimerAction) {
using KernelIdleTimerAction = RefreshRateSelector::KernelIdleTimerAction;
auto selector = createSelector(kModes_60_90, kModeId90);
EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction());
}
TEST_P(RefreshRateSelectorTest, testKernelIdleTimerActionFor120Hz) {
using KernelIdleTimerAction = RefreshRateSelector::KernelIdleTimerAction;
auto selector = createSelector(kModes_60_120, kModeId120);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, selector.getIdleTimerAction());
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, selector.getIdleTimerAction());
}
TEST_P(RefreshRateSelectorTest, getFrameRateDivisor) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId30);
const auto frameRate = 30_Hz;
Fps displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(1, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
selector.setActiveMode(kModeId60, 60_Hz);
displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(2, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
selector.setActiveMode(kModeId72, 72_Hz);
displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
selector.setActiveMode(kModeId90, 90_Hz);
displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(3, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
selector.setActiveMode(kModeId120, 120_Hz);
displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
selector.setActiveMode(kModeId90, 90_Hz);
displayRefreshRate = selector.getActiveMode().getPeakFps();
EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, 22.5_Hz));
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(24_Hz, 25_Hz));
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(24_Hz, 23.976_Hz));
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(30_Hz, 29.97_Hz));
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(60_Hz, 59.94_Hz));
}
TEST_P(RefreshRateSelectorTest, isFractionalPairOrMultiple) {
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(23.976_Hz, 24_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(24_Hz, 23.976_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 30_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(30_Hz, 29.97_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(59.94_Hz, 60_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(60_Hz, 59.94_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 60_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(60_Hz, 29.97_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(59.94_Hz, 30_Hz));
EXPECT_TRUE(RefreshRateSelector::isFractionalPairOrMultiple(30_Hz, 59.94_Hz));
const auto refreshRates = {23.976_Hz, 24_Hz, 25_Hz, 29.97_Hz, 30_Hz, 50_Hz, 59.94_Hz, 60_Hz};
for (auto refreshRate : refreshRates) {
EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(refreshRate, refreshRate));
}
EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(24_Hz, 25_Hz));
EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(23.978_Hz, 25_Hz));
EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz));
}
TEST_P(RefreshRateSelectorTest, test23976Chooses120) {
auto selector = createSelector(kModes_60_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "23.976 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 23.976_Hz;
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test23976Chooses60IfThresholdIs120) {
auto selector =
createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120});
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "23.976 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 23.976_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test25Chooses60) {
auto selector = createSelector(kModes_60_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "25 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 25.00_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test2997Chooses60) {
auto selector = createSelector(kModes_60_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "29.97 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 29.97_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test50Chooses120) {
auto selector = createSelector(kModes_60_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "50 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 50.00_Hz;
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test50Chooses60IfThresholdIs120) {
auto selector =
createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120});
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "50 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 50.00_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, test5994Chooses60) {
auto selector = createSelector(kModes_60_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "59.94 ExplicitExactOrMultiple";
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[0].desiredRefreshRate = 59.94_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_noLayers) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
EXPECT_TRUE(selector.getFrameRateOverrides({}, 120_Hz, {}).empty());
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_NonExplicit) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::NoVote;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
layers[0].vote = LayerVoteType::Min;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
layers[0].vote = LayerVoteType::Max;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
layers[0].vote = LayerVoteType::Heuristic;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_Disabled) {
if (GetParam() != Config::FrameRateOverride::Disabled) {
return;
}
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
layers[0].vote = LayerVoteType::ExplicitExact;
EXPECT_TRUE(selector.getFrameRateOverrides(layers, 120_Hz, {}).empty());
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_60on120) {
if (GetParam() == Config::FrameRateOverride::Disabled) {
return;
}
ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ||
GetParam() == Config::FrameRateOverride::AppOverride ||
GetParam() == Config::FrameRateOverride::Enabled);
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExact;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_twoUids) {
if (GetParam() == Config::FrameRateOverride::Disabled) {
return;
}
ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ||
GetParam() == Config::FrameRateOverride::AppOverride ||
GetParam() == Config::FrameRateOverride::Enabled);
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.ownerUid = 1234, .weight = 1.f},
{.ownerUid = 5678, .weight = 1.f}};
layers[0].name = "Test layer 1234";
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[1].name = "Test layer 5678";
layers[1].desiredRefreshRate = 30_Hz;
layers[1].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(2u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
ASSERT_EQ(1u, frameRateOverrides.count(5678));
EXPECT_EQ(30_Hz, frameRateOverrides.at(5678));
layers[1].vote = LayerVoteType::Heuristic;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
layers[1].ownerUid = 1234;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_withFrameRateCategory) {
if (GetParam() == Config::FrameRateOverride::Disabled) {
return;
}
ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ||
GetParam() == Config::FrameRateOverride::AppOverride ||
GetParam() == Config::FrameRateOverride::Enabled);
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.ownerUid = 1234, .weight = 1.f},
{.ownerUid = 1234, .weight = 1.f}};
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitCategory High";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::High;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitCategory Normal";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::Normal;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitCategory Low";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::Low;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitCategory NoPreference";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::NoPreference;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case *without* touch boost has frame rate override.
// For example, game and touch interaction.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitDefault 60";
layers[1].vote = LayerVoteType::ExplicitDefault;
layers[1].desiredRefreshRate = 60_Hz;
layers[1].frameRateCategory = FrameRateCategory::Default;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitExactOrMultiple 30";
layers[1].vote = LayerVoteType::ExplicitExactOrMultiple;
layers[1].desiredRefreshRate = 30_Hz;
layers[1].frameRateCategory = FrameRateCategory::Default;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitExact 60";
layers[1].vote = LayerVoteType::ExplicitExact;
layers[1].desiredRefreshRate = 60_Hz;
layers[1].frameRateCategory = FrameRateCategory::Default;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// HighHint case with touch boost and thus should skip frame rate override.
layers[0].name = "ExplicitCategory HighHint";
layers[0].vote = LayerVoteType::ExplicitCategory;
layers[0].desiredRefreshRate = 0_Hz;
layers[0].frameRateCategory = FrameRateCategory::HighHint;
layers[1].name = "ExplicitGte 60";
layers[1].vote = LayerVoteType::ExplicitGte;
layers[1].desiredRefreshRate = 60_Hz;
layers[1].frameRateCategory = FrameRateCategory::Default;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_TRUE(frameRateOverrides.empty());
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
// ExplicitCategory case that expects no global touch boost and thus has frame rate override.
layers[0].name = "ExplicitDefault 60";
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].frameRateCategory = FrameRateCategory::Default;
layers[1].name = "ExplicitCategory High";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::High;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(120_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(120_Hz, frameRateOverrides.at(1234));
// ExplicitCategory case that expects no global touch boost and thus has frame rate override.
layers[0].name = "ExplicitDefault 60";
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].frameRateCategory = FrameRateCategory::Default;
layers[1].name = "ExplicitCategory Normal";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::Normal;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
// ExplicitCategory case that expects no global touch boost and thus has frame rate override.
layers[0].name = "ExplicitDefault 60";
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].frameRateCategory = FrameRateCategory::Default;
layers[1].name = "ExplicitCategory Low";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::Low;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
// ExplicitCategory case that expects no global touch boost and thus has frame rate override.
layers[0].name = "ExplicitDefault 60";
layers[0].vote = LayerVoteType::ExplicitDefault;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].frameRateCategory = FrameRateCategory::Default;
layers[1].name = "ExplicitCategory NoPreference";
layers[1].vote = LayerVoteType::ExplicitCategory;
layers[1].desiredRefreshRate = 0_Hz;
layers[1].frameRateCategory = FrameRateCategory::NoPreference;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_touch) {
if (GetParam() == Config::FrameRateOverride::Disabled) {
return;
}
ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ||
GetParam() == Config::FrameRateOverride::AppOverride ||
GetParam() == Config::FrameRateOverride::Enabled);
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.ownerUid = 1234, .weight = 1.f}};
layers[0].name = "Test layer";
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExact;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_TRUE(frameRateOverrides.empty());
layers[0].vote = LayerVoteType::ExplicitGte;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_DivisorIsNotDisplayRefreshRate) {
if (GetParam() == Config::FrameRateOverride::Disabled) {
return;
}
ASSERT_TRUE(GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ||
GetParam() == Config::FrameRateOverride::AppOverride ||
GetParam() == Config::FrameRateOverride::Enabled);
auto selector = createSelector(kModes_60_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 30_Hz;
const auto expetedFps =
GetParam() == Config::FrameRateOverride::AppOverrideNativeRefreshRates ? 60_Hz : 30_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(expetedFps, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(expetedFps, frameRateOverrides.at(1234));
layers[0].vote = LayerVoteType::ExplicitExact;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(expetedFps, frameRateOverrides.at(1234));
}
TEST_P(RefreshRateSelectorTest, renderFrameRateInvalidPolicy) {
auto selector = createSelector(kModes_60_120, kModeId120);
// The render frame rate cannot be greater than the physical refresh rate
{
const FpsRange physical = {60_Hz, 60_Hz};
const FpsRange render = {60_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Invalid,
selector.setDisplayManagerPolicy(
{kModeId60, {physical, render}, {physical, render}}));
}
}
TEST_P(RefreshRateSelectorTest, renderFrameRateRestrictsPhysicalRefreshRate) {
auto selector = createSelector(kModes_60_120, kModeId120);
{
const FpsRange physical = {0_Hz, 120_Hz};
const FpsRange render = {0_Hz, 60_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId60, {physical, render}, {physical, render}}));
const auto expectedMaxMode =
GetParam() == Config::FrameRateOverride::Enabled ? kMode120 : kMode60;
EXPECT_EQ(expectedMaxMode, selector.getMaxRefreshRateByPolicy());
EXPECT_EQ(kMode60, selector.getMinRefreshRateByPolicy());
}
{
const FpsRange physical = {0_Hz, 120_Hz};
const FpsRange render = {120_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId60, {physical, render}, {physical, render}}));
EXPECT_EQ(kMode120, selector.getMaxRefreshRateByPolicy());
EXPECT_EQ(kMode120, selector.getMinRefreshRateByPolicy());
}
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_InPolicy) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
{
const FpsRange physical = {120_Hz, 120_Hz};
const FpsRange render = {60_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {physical, render}, {physical, render}}));
}
layers[0].name = "30Hz";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 30_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
EXPECT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
{
const FpsRange physical = {120_Hz, 120_Hz};
const FpsRange render = {30_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {physical, render}, {physical, render}}));
}
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
EXPECT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(30_Hz, frameRateOverrides.at(1234));
{
const FpsRange physical = {120_Hz, 120_Hz};
const FpsRange render = {30_Hz, 30_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {physical, render}, {physical, render}}));
}
layers[0].name = "60Hz";
layers[0].ownerUid = 1234;
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitDefault;
frameRateOverrides = selector.getFrameRateOverrides(layers, 120_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
EXPECT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(30_Hz, frameRateOverrides.at(1234));
}
TEST_P(RefreshRateSelectorTest, renderFrameRates) {
auto selector = createSelector(kModes_30_60_72_90_120, kModeId120);
// [renderRate, refreshRate]
const auto expected = []() -> std::vector<std::pair<Fps, Fps>> {
switch (GetParam()) {
case Config::FrameRateOverride::Disabled:
case Config::FrameRateOverride::AppOverrideNativeRefreshRates:
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, 30_Hz},
{60_Hz, 60_Hz},
{72_Hz, 72_Hz},
{90_Hz, 90_Hz},
{120_Hz, 120_Hz}};
case Config::FrameRateOverride::Enabled:
return {{30_Hz, 30_Hz}, {36_Hz, 72_Hz}, {40_Hz, 120_Hz}, {45_Hz, 90_Hz},
{60_Hz, 60_Hz}, {72_Hz, 72_Hz}, {90_Hz, 90_Hz}, {120_Hz, 120_Hz}};
}
}();
const auto& primaryRefreshRates = selector.getPrimaryFrameRates();
ASSERT_EQ(expected.size(), primaryRefreshRates.size());
for (size_t i = 0; i < expected.size(); i++) {
const auto [expectedRenderRate, expectedRefreshRate] = expected[i];
EXPECT_EQ(expectedRenderRate, primaryRefreshRates[i].fps);
EXPECT_EQ(expectedRefreshRate, primaryRefreshRates[i].modePtr->getPeakFps());
}
}
TEST_P(RefreshRateSelectorTest, refreshRateIsCappedWithRenderFrameRate) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
auto selector = createSelector(kModes_60_120, kModeId60);
constexpr FpsRange k0_120Hz = {0_Hz, 120_Hz};
constexpr FpsRange k0_60Hz = {0_Hz, 60_Hz};
constexpr FpsRanges kAppRequest = {/*physical*/ k0_120Hz,
/*render*/ k0_120Hz};
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz,
/*render*/ k0_120Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60,
/*primaryRanges*/
kPrimary,
/*appRequestRanges*/
kAppRequest}));
}
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_60Hz,
/*render*/ k0_60Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60,
/*primaryRanges*/
kPrimary,
/*appRequestRanges*/
kAppRequest}));
}
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz,
/*render*/ k0_60Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({/*defaultMode*/ kModeId60,
/*primaryRanges*/
kPrimary,
/*appRequestRanges*/
kAppRequest}));
}
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode);
}
TEST_P(RefreshRateSelectorTest, renderFrameRates_60_120) {
auto selector = createSelector(kModes_60_120, kModeId120);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
const auto expectedRenderRate =
GetParam() == Config::FrameRateOverride::Enabled ? 30_Hz : 60_Hz;
layer.name = "30Hz ExplicitDefault";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::ExplicitDefault;
EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
selector.getBestScoredFrameRate(layers).frameRateMode);
layer.name = "30Hz Heuristic";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::Heuristic;
EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
selector.getBestScoredFrameRate(layers).frameRateMode);
layer.name = "30Hz ExplicitExactOrMultiple";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::ExplicitExactOrMultiple;
EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, idleWhenLowestRefreshRateIsNotDivisor) {
auto selector = createSelector(kModes_35_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
const auto getIdleDisplayModeId = [&](LayerVoteType voteType,
bool touchActive) -> DisplayModeId {
layers[0].vote = voteType;
layers[0].desiredRefreshRate = 90_Hz;
const auto [ranking, signals] =
selector.getRankedFrameRates(layers, {.touch = touchActive, .idle = true});
// Refresh rate will be chosen by either touch state or idle state.
EXPECT_EQ(!touchActive, signals.idle);
return ranking.front().frameRateMode.modePtr->getId();
};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId60, {0_Hz, 90_Hz}}));
// With no layers, idle should still be lower priority than touch boost.
EXPECT_EQ(kModeId90,
selector.getBestFrameRateMode({}, {.touch = true, .idle = true}).modePtr->getId());
// Idle should be higher precedence than other layer frame rate considerations.
selector.setActiveMode(kModeId90, 90_Hz);
{
constexpr bool kTouchActive = false;
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive));
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Min, kTouchActive));
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Max, kTouchActive));
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::Heuristic, kTouchActive));
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::ExplicitDefault, kTouchActive));
EXPECT_EQ(kModeId35,
getIdleDisplayModeId(LayerVoteType::ExplicitExactOrMultiple, kTouchActive));
}
// Idle should be applied rather than the active mode when there are no layers.
EXPECT_EQ(kModeId35, selector.getBestFrameRateMode({}, {.idle = true}).modePtr->getId());
}
TEST_P(RefreshRateSelectorTest, policyCanBeInfinity) {
auto selector = createSelector(kModes_60_120, kModeId120);
constexpr Fps inf = Fps::fromValue(std::numeric_limits<float>::infinity());
using namespace fps_approx_ops;
selector.setDisplayManagerPolicy({kModeId60, {0_Hz, inf}});
// With no layers, idle should still be lower priority than touch boost.
EXPECT_EQ(kMode120, selector.getMaxRefreshRateByPolicy());
EXPECT_EQ(kMode60, selector.getMinRefreshRateByPolicy());
}
TEST_P(RefreshRateSelectorTest, SupportsLowPhysicalRefreshRates) {
auto selector = createSelector(kModes_1_5_10, kModeId10);
EXPECT_EQ(kMode10, selector.getMaxRefreshRateByPolicy());
EXPECT_EQ(kMode1, selector.getMinRefreshRateByPolicy());
}
// TODO(b/266481656): Once this bug is fixed, we can remove this test
// And test for VRR when we remove this work around for VRR.
TEST_P(RefreshRateSelectorTest, noLowerFrameRateOnMinVote) {
auto selector = createSelector(kModes_60_90, kModeId60);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].vote = LayerVoteType::Min;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
constexpr FpsRanges kCappedAt60 = {{30_Hz, 90_Hz}, {30_Hz, 60_Hz}};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{DisplayModeId(kModeId60), kCappedAt60, kCappedAt60}));
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, frameRateIsCappedByPolicy) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
auto selector = createSelector(kModes_60_90, kModeId60);
constexpr FpsRanges kCappedAt30 = {{60_Hz, 90_Hz}, {30_Hz, 30_Hz}};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{DisplayModeId(kModeId60), kCappedAt30, kCappedAt30}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].vote = LayerVoteType::Min;
EXPECT_FRAME_RATE_MODE(kMode60, 30_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, frameRateNotInRange) {
auto selector = createSelector(kModes_60_90, kModeId60);
constexpr FpsRanges k60Only = {{60_Hz, 90_Hz}, {60_Hz, 60_Hz}};
constexpr FpsRanges kAll = {{0_Hz, 90_Hz}, {0_Hz, 90_Hz}};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({DisplayModeId(kModeId60), k60Only, kAll}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].vote = LayerVoteType::Heuristic;
layers[0].desiredRefreshRate = 45_Hz;
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, frameRateIsLowerThanMinSupported) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
auto selector = createSelector(kModes_60_90, kModeId60);
constexpr Fps kMin = RefreshRateSelector::kMinSupportedFrameRate;
constexpr FpsRanges kLowerThanMin = {{60_Hz, 90_Hz}, {kMin / 2, kMin / 2}};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{DisplayModeId(kModeId60), kLowerThanMin, kLowerThanMin}));
}
// b/296079213
TEST_P(RefreshRateSelectorTest, frameRateOverrideInBlockingZone60_120) {
auto selector = createSelector(kModes_60_120, kModeId120);
const FpsRange only120 = {120_Hz, 120_Hz};
const FpsRange allRange = {0_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, allRange}, {allRange, allRange}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "30Hz ExplicitExactOrMultiple";
layers[0].desiredRefreshRate = 30_Hz;
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
if (GetParam() != Config::FrameRateOverride::Enabled) {
EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
} else {
EXPECT_FRAME_RATE_MODE(kMode120, 30_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
}
}
TEST_P(RefreshRateSelectorTest, frameRateOverrideInBlockingZone60_90) {
auto selector = createSelector(kModes_60_90, kModeId90);
const FpsRange only90 = {90_Hz, 90_Hz};
const FpsRange allRange = {0_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId90, {only90, allRange}, {allRange, allRange}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "30Hz ExplicitExactOrMultiple";
layers[0].desiredRefreshRate = 30_Hz;
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
if (GetParam() != Config::FrameRateOverride::Enabled) {
EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
} else {
EXPECT_FRAME_RATE_MODE(kMode90, 30_Hz,
selector.getBestScoredFrameRate(layers).frameRateMode);
}
}
TEST_P(RefreshRateSelectorTest, frameRateOverrideInBlockingZone60_90_NonDivisor) {
auto selector = createSelector(kModes_60_90, kModeId90);
const FpsRange only90 = {90_Hz, 90_Hz};
const FpsRange allRange = {0_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId90, {only90, allRange}, {allRange, allRange}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "60Hz ExplicitExactOrMultiple";
layers[0].desiredRefreshRate = 60_Hz;
layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
// VRR tests
TEST_P(RefreshRateSelectorTest, singleMinMaxRateForVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
auto selector = createSelector(kVrrMode_120, kModeId120);
EXPECT_TRUE(selector.supportsFrameRateOverride());
const auto minRate = selector.getMinSupportedRefreshRate();
const auto performanceRate = selector.getMaxSupportedRefreshRate();
const auto minRateByPolicy = selector.getMinRefreshRateByPolicy();
const auto performanceRateByPolicy = selector.getMaxRefreshRateByPolicy();
EXPECT_EQ(kVrrMode120TE240, minRate);
EXPECT_EQ(kVrrMode120TE240, performanceRate);
EXPECT_EQ(kVrrMode120TE240, minRateByPolicy);
EXPECT_EQ(kVrrMode120TE240, performanceRateByPolicy);
}
TEST_P(RefreshRateSelectorTest, renderRateChangesWithPolicyChangeForVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
auto selector = createSelector(kVrrModes_60_120, kModeId120);
const FpsRange only120 = {120_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, only120}, {only120, only120}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 120_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range120 = {0_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range120}, {only120, range120}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 120_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range90 = {0_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range90}, {only120, range90}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 80_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range80 = {0_Hz, 80_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range80}, {only120, range80}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 80_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range60 = {0_Hz, 60_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range60}, {only120, range60}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 60_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range48 = {0_Hz, 48_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range48}, {only120, range48}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 48_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
const FpsRange range30 = {0_Hz, 30_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range30}, {only120, range30}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 30_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, modeChangesWithPolicyChangeForVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
auto selector = createSelector(kVrrModes_60_120, kModeId120);
const FpsRange range120 = {0_Hz, 120_Hz};
const FpsRange range60 = {0_Hz, 60_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {range120, range60}, {range120, range60}}));
EXPECT_FRAME_RATE_MODE(kVrrMode120TE240, 60_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId60, {range60, range60}, {range60, range60}}));
EXPECT_FRAME_RATE_MODE(kVrrMode60TE120, 60_Hz,
selector.getBestScoredFrameRate({}).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, getFrameRateOverridesForVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
auto selector = createSelector(kVrrMode_120, kModeId120);
// TODO(b/297600226) Run at lower than 30 Fps for dVRR
const std::vector<Fps> desiredRefreshRates = {30_Hz, 34.285_Hz, 40_Hz, 48_Hz,
60_Hz, 80_Hz, 120_Hz};
const std::vector<LayerVoteType> layerVotes = {LayerVoteType::ExplicitDefault,
LayerVoteType::ExplicitExactOrMultiple,
LayerVoteType::ExplicitExact};
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
layers[0].name = "Test layer";
layers[0].ownerUid = 1234;
for (auto desiredRefreshRate : desiredRefreshRates) {
layers[0].desiredRefreshRate = desiredRefreshRate;
for (auto vote : layerVotes) {
layers[0].vote = vote;
auto frameRateOverrides = selector.getFrameRateOverrides(layers, 240_Hz, {});
EXPECT_EQ(1u, frameRateOverrides.size());
ASSERT_EQ(1u, frameRateOverrides.count(1234));
EXPECT_EQ(desiredRefreshRate, frameRateOverrides.at(1234));
}
}
}
TEST_P(RefreshRateSelectorTest, renderFrameRatesForVrr) {
if (GetParam() != Config::FrameRateOverride::Enabled) {
return;
}
SET_FLAG_FOR_TEST(flags::vrr_config, true);
auto selector = createSelector(kVrrMode_120, kModeId120);
const FpsRange only120 = {120_Hz, 120_Hz};
const FpsRange range120 = {0_Hz, 120_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {only120, range120}, {only120, range120}}));
std::vector<Fps> expected = {20_Hz, 21.818_Hz, 24_Hz, 26.666_Hz, 30_Hz, 34.285_Hz,
40_Hz, 48_Hz, 60_Hz, 80_Hz, 120_Hz};
auto primaryRefreshRates = selector.getPrimaryFrameRates();
ASSERT_EQ(expected.size(), primaryRefreshRates.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(expected[i], primaryRefreshRates[i].fps);
EXPECT_EQ(120_Hz, primaryRefreshRates[i].modePtr->getPeakFps());
}
// Render range (0,90)
const FpsRange range90 = {0_Hz, 90_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {range120, range90}, {range120, range90}}));
expected = {20_Hz, 21.818_Hz, 24_Hz, 26.666_Hz, 30_Hz, 34.285_Hz, 40_Hz, 48_Hz, 60_Hz, 80_Hz};
primaryRefreshRates = selector.getPrimaryFrameRates();
ASSERT_EQ(expected.size(), primaryRefreshRates.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(expected[i], primaryRefreshRates[i].fps);
EXPECT_EQ(120_Hz, primaryRefreshRates[i].modePtr->getPeakFps());
}
// Render range (0,60)
const FpsRange range60 = {0_Hz, 60_Hz};
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy(
{kModeId120, {range120, range60}, {range120, range60}}));
expected = {20_Hz, 21.818_Hz, 24_Hz, 26.666_Hz, 30_Hz, 34.285_Hz, 40_Hz, 48_Hz, 60_Hz};
primaryRefreshRates = selector.getPrimaryFrameRates();
ASSERT_EQ(expected.size(), primaryRefreshRates.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(expected[i], primaryRefreshRates[i].fps);
EXPECT_EQ(120_Hz, primaryRefreshRates[i].modePtr->getPeakFps());
}
}
} // namespace
} // namespace android::scheduler