2078 lines
82 KiB
C++
2078 lines
82 KiB
C++
/*
|
|
* 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 <ftl/enum.h>
|
|
#include <gmock/gmock.h>
|
|
#include <log/log.h>
|
|
#include <ui/Size.h>
|
|
|
|
#include "DisplayHardware/HWC2.h"
|
|
#include "FpsOps.h"
|
|
#include "Scheduler/RefreshRateConfigs.h"
|
|
#include "mock/DisplayHardware/MockDisplayMode.h"
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
namespace android::scheduler {
|
|
|
|
namespace hal = android::hardware::graphics::composer::hal;
|
|
|
|
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
|
|
using LayerRequirement = RefreshRateConfigs::LayerRequirement;
|
|
|
|
using mock::createDisplayMode;
|
|
|
|
struct TestableRefreshRateConfigs : RefreshRateConfigs {
|
|
using RefreshRateConfigs::RefreshRateConfigs;
|
|
|
|
DisplayModePtr getMinSupportedRefreshRate() const {
|
|
std::lock_guard lock(mLock);
|
|
return mMinRefreshRateModeIt->second;
|
|
}
|
|
|
|
DisplayModePtr getMaxSupportedRefreshRate() const {
|
|
std::lock_guard lock(mLock);
|
|
return mMaxRefreshRateModeIt->second;
|
|
}
|
|
|
|
DisplayModePtr getMinRefreshRateByPolicy() const {
|
|
std::lock_guard lock(mLock);
|
|
return getMinRefreshRateByPolicyLocked();
|
|
}
|
|
|
|
const std::vector<Fps>& knownFrameRates() const { return mKnownFrameRates; }
|
|
|
|
using RefreshRateConfigs::GetBestRefreshRateCache;
|
|
auto& mutableGetBestRefreshRateCache() { return mGetBestRefreshRateCache; }
|
|
|
|
auto getBestRefreshRateAndSignals(const std::vector<LayerRequirement>& layers,
|
|
GlobalSignals signals) const {
|
|
return RefreshRateConfigs::getBestRefreshRate(layers, signals);
|
|
}
|
|
|
|
DisplayModePtr getBestRefreshRate(const std::vector<LayerRequirement>& layers = {},
|
|
GlobalSignals signals = {}) const {
|
|
return getBestRefreshRateAndSignals(layers, signals).first;
|
|
}
|
|
};
|
|
|
|
class RefreshRateConfigsTest : public testing::Test {
|
|
protected:
|
|
RefreshRateConfigsTest();
|
|
~RefreshRateConfigsTest();
|
|
|
|
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 inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz);
|
|
static inline const DisplayModePtr kMode60Frac = createDisplayMode(kModeId60Frac, 59.94_Hz);
|
|
static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz);
|
|
static inline const DisplayModePtr kMode90_G1 = createDisplayMode(kModeId90, 90_Hz, 1);
|
|
static inline const DisplayModePtr kMode90_4K =
|
|
createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160});
|
|
static inline const DisplayModePtr kMode72 = createDisplayMode(kModeId72, 72_Hz);
|
|
static inline const DisplayModePtr kMode72_G1 = createDisplayMode(kModeId72, 72_Hz, 1);
|
|
static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz);
|
|
static inline const DisplayModePtr kMode120_G1 = createDisplayMode(kModeId120, 120_Hz, 1);
|
|
static inline const DisplayModePtr kMode30 = createDisplayMode(kModeId30, 30_Hz);
|
|
static inline const DisplayModePtr kMode30_G1 = createDisplayMode(kModeId30, 30_Hz, 1);
|
|
static inline const DisplayModePtr kMode30Frac = createDisplayMode(kModeId30Frac, 29.97_Hz);
|
|
static inline const DisplayModePtr kMode25 = createDisplayMode(kModeId25, 25_Hz);
|
|
static inline const DisplayModePtr kMode25_G1 = createDisplayMode(kModeId25, 25_Hz, 1);
|
|
static inline const DisplayModePtr kMode50 = createDisplayMode(kModeId50, 50_Hz);
|
|
static inline const DisplayModePtr kMode24 = createDisplayMode(kModeId24, 24_Hz);
|
|
static inline const DisplayModePtr kMode24Frac = createDisplayMode(kModeId24Frac, 23.976_Hz);
|
|
|
|
// Test configurations.
|
|
static inline const DisplayModes kModes_60 = makeModes(kMode60);
|
|
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);
|
|
|
|
// 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);
|
|
};
|
|
|
|
RefreshRateConfigsTest::RefreshRateConfigsTest() {
|
|
const ::testing::TestInfo* const test_info =
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
|
|
}
|
|
|
|
RefreshRateConfigsTest::~RefreshRateConfigsTest() {
|
|
const ::testing::TestInfo* const test_info =
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
|
|
}
|
|
|
|
namespace {
|
|
|
|
TEST_F(RefreshRateConfigsTest, oneMode_canSwitch) {
|
|
RefreshRateConfigs configs(kModes_60, kModeId60);
|
|
EXPECT_FALSE(configs.canSwitch());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, invalidPolicy) {
|
|
RefreshRateConfigs configs(kModes_60, kModeId60);
|
|
EXPECT_LT(configs.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}}), 0);
|
|
EXPECT_LT(configs.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}}), 0);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
const auto minRate = configs.getMinSupportedRefreshRate();
|
|
const auto performanceRate = configs.getMaxSupportedRefreshRate();
|
|
|
|
EXPECT_EQ(kMode60, minRate);
|
|
EXPECT_EQ(kMode90, performanceRate);
|
|
|
|
const auto minRateByPolicy = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRateByPolicy = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(minRateByPolicy, minRate);
|
|
EXPECT_EQ(performanceRateByPolicy, performanceRate);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap_differentGroups) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
const auto minRate = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate = configs.getMaxSupportedRefreshRate();
|
|
const auto minRate60 = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate60 = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode60, minRate);
|
|
EXPECT_EQ(kMode60, minRate60);
|
|
EXPECT_EQ(kMode60, performanceRate60);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0);
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
const auto minRate90 = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate90 = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode90_G1, performanceRate);
|
|
EXPECT_EQ(kMode90_G1, minRate90);
|
|
EXPECT_EQ(kMode90_G1, performanceRate90);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap_differentResolutions) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_4K, kModeId60);
|
|
|
|
const auto minRate = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate = configs.getMaxSupportedRefreshRate();
|
|
const auto minRate60 = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate60 = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode60, minRate);
|
|
EXPECT_EQ(kMode60, minRate60);
|
|
EXPECT_EQ(kMode60, performanceRate60);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0);
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
const auto minRate90 = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate90 = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode90_4K, performanceRate);
|
|
EXPECT_EQ(kMode90_4K, minRate90);
|
|
EXPECT_EQ(kMode90_4K, performanceRate90);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_policyChange) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
const auto minRate = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode60, minRate);
|
|
EXPECT_EQ(kMode90, performanceRate);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
|
|
|
|
const auto minRate60 = configs.getMinRefreshRateByPolicy();
|
|
const auto performanceRate60 = configs.getMaxRefreshRateByPolicy();
|
|
|
|
EXPECT_EQ(kMode60, minRate60);
|
|
EXPECT_EQ(kMode60, performanceRate60);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_getActiveMode) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
{
|
|
const auto mode = configs.getActiveMode();
|
|
EXPECT_EQ(mode->getId(), kModeId60);
|
|
}
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
{
|
|
const auto mode = configs.getActiveMode();
|
|
EXPECT_EQ(mode->getId(), kModeId90);
|
|
}
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
|
|
{
|
|
const auto mode = configs.getActiveMode();
|
|
EXPECT_EQ(mode->getId(), kModeId90);
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) {
|
|
{
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate());
|
|
|
|
EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), NO_ERROR);
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate());
|
|
}
|
|
{
|
|
// We select max even when this will cause a non-seamless switch.
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
constexpr bool kAllowGroupSwitching = true;
|
|
EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId90, kAllowGroupSwitching, {0_Hz, 90_Hz}}),
|
|
NO_ERROR);
|
|
EXPECT_EQ(kMode90_G1, configs.getBestRefreshRate());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
lr.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
lr.name = "90Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
lr.name = "45Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
lr.name = "30Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.name = "24Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.name = "";
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
|
|
|
|
lr.vote = LayerVoteType::Min;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
|
|
|
|
lr.vote = LayerVoteType::Min;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}}), 0);
|
|
lr.vote = LayerVoteType::Min;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
lr.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
lr.name = "90Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
lr.name = "45Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
lr.name = "30Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.name = "24Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) {
|
|
TestableRefreshRateConfigs configs(kModes_60_72_90, kModeId60);
|
|
|
|
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
|
|
auto& lr = layers[0];
|
|
|
|
lr.vote = LayerVoteType::Min;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90_120) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.desiredRefreshRate = 24_Hz;
|
|
lr1.vote = LayerVoteType::Heuristic;
|
|
lr2.desiredRefreshRate = 48_Hz;
|
|
lr2.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.desiredRefreshRate = 24_Hz;
|
|
lr1.vote = LayerVoteType::Heuristic;
|
|
lr2.desiredRefreshRate = 48_Hz;
|
|
lr2.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.desiredRefreshRate = 24_Hz;
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.name = "24Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::Max;
|
|
lr2.name = "Max";
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) {
|
|
TestableRefreshRateConfigs configs(kModes_30_60, kModeId60);
|
|
|
|
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
|
|
auto& lr = layers[0];
|
|
|
|
lr.vote = LayerVoteType::Min;
|
|
EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
lr.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 90_Hz;
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
lr.name = "90Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Heuristic";
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr.desiredRefreshRate = 45_Hz;
|
|
lr.name = "45Hz Heuristic";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr.desiredRefreshRate = 30_Hz;
|
|
lr.name = "30Hz Heuristic";
|
|
EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.name = "24Hz Heuristic";
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr.name = "24Hz ExplicitExactOrMultiple";
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_PriorityTest) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Min;
|
|
lr2.vote = LayerVoteType::Heuristic;
|
|
lr2.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Min;
|
|
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr2.desiredRefreshRate = 24_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Max;
|
|
lr2.vote = LayerVoteType::Heuristic;
|
|
lr2.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Max;
|
|
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr2.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Heuristic;
|
|
lr1.desiredRefreshRate = 15_Hz;
|
|
lr2.vote = LayerVoteType::Heuristic;
|
|
lr2.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Heuristic;
|
|
lr1.desiredRefreshRate = 30_Hz;
|
|
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr2.desiredRefreshRate = 45_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) {
|
|
TestableRefreshRateConfigs configs(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 = configs.getBestRefreshRate(layers);
|
|
EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses "
|
|
<< to_string(mode->getFps());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) {
|
|
TestableRefreshRateConfigs configs(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 = configs.getBestRefreshRate(layers);
|
|
EXPECT_EQ(kMode60, mode) << lr.desiredRefreshRate << " chooses "
|
|
<< to_string(mode->getFps());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, twoModes_getBestRefreshRate_Explicit) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitDefault;
|
|
lr1.desiredRefreshRate = 90_Hz;
|
|
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr2.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::Heuristic;
|
|
lr1.desiredRefreshRate = 90_Hz;
|
|
lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr2.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) {
|
|
TestableRefreshRateConfigs configs(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 = configs.getBestRefreshRate(layers, {});
|
|
EXPECT_EQ(kMode90, mode) << lr.desiredRefreshRate << " chooses "
|
|
<< to_string(mode->getFps());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_Multiples) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.desiredRefreshRate = 60_Hz;
|
|
lr1.name = "60Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::Max;
|
|
lr2.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.desiredRefreshRate = 30_Hz;
|
|
lr1.name = "30Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::Max;
|
|
lr2.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.desiredRefreshRate = 60_Hz;
|
|
lr1.name = "60Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::NoVote;
|
|
lr2.name = "NoVote";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.desiredRefreshRate = 60_Hz;
|
|
lr1.name = "60Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::Max;
|
|
lr2.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
lr1.desiredRefreshRate = 60_Hz;
|
|
lr1.name = "60Hz ExplicitExactOrMultiple";
|
|
lr2.vote = LayerVoteType::Max;
|
|
lr2.name = "Max";
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
// 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, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, touchConsidered) {
|
|
RefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
auto [_, signals] = configs.getBestRefreshRate({}, {});
|
|
EXPECT_FALSE(signals.touch);
|
|
|
|
std::tie(std::ignore, signals) = configs.getBestRefreshRate({}, {.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) = configs.getBestRefreshRate(layers, {.touch = true});
|
|
EXPECT_TRUE(signals.touch);
|
|
|
|
lr1.vote = LayerVoteType::ExplicitDefault;
|
|
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) = configs.getBestRefreshRate(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) = configs.getBestRefreshRate(layers, {.touch = true});
|
|
EXPECT_TRUE(signals.touch);
|
|
|
|
lr1.vote = LayerVoteType::ExplicitDefault;
|
|
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) = configs.getBestRefreshRate(layers, {.touch = true});
|
|
EXPECT_FALSE(signals.touch);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) {
|
|
TestableRefreshRateConfigs configs(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();
|
|
|
|
EXPECT_EQ(expected, configs.getBestRefreshRate(layers)->getFps());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest,
|
|
getBestRefreshRate_ExplicitExactOrMultiple_WithFractionalRefreshRates) {
|
|
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
|
|
auto& lr = layers[0];
|
|
|
|
// Test that 23.976 will choose 24 if 23.976 is not supported
|
|
{
|
|
TestableRefreshRateConfigs configs(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(kModeId24, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
// Test that 24 will choose 23.976 if 24 is not supported
|
|
{
|
|
TestableRefreshRateConfigs configs(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac,
|
|
kMode60, kMode60Frac),
|
|
kModeId60);
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.name = "ExplicitExactOrMultiple 24 Hz";
|
|
EXPECT_EQ(kModeId24Frac, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
// Test that 29.97 will prefer 59.94 over 60 and 30
|
|
{
|
|
TestableRefreshRateConfigs configs(makeModes(kMode24, kMode24Frac, kMode25, kMode30,
|
|
kMode60, kMode60Frac),
|
|
kModeId60);
|
|
|
|
lr.desiredRefreshRate = 29.97_Hz;
|
|
lr.name = "ExplicitExactOrMultiple 29.97 Hz";
|
|
EXPECT_EQ(kModeId60Frac, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_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
|
|
{
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers)->getFps());
|
|
}
|
|
}
|
|
|
|
// Test that 23.976 will choose 24 if 23.976 is not supported
|
|
{
|
|
TestableRefreshRateConfigs configs(makeModes(kMode24, kMode25, kMode30, kMode30Frac,
|
|
kMode60, kMode60Frac),
|
|
kModeId60);
|
|
|
|
lr.vote = LayerVoteType::ExplicitExact;
|
|
lr.desiredRefreshRate = 23.976_Hz;
|
|
lr.name = "ExplicitExact 23.976 Hz";
|
|
EXPECT_EQ(kModeId24, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
// Test that 24 will choose 23.976 if 24 is not supported
|
|
{
|
|
TestableRefreshRateConfigs configs(makeModes(kMode24Frac, kMode25, kMode30, kMode30Frac,
|
|
kMode60, kMode60Frac),
|
|
kModeId60);
|
|
|
|
lr.desiredRefreshRate = 24_Hz;
|
|
lr.name = "ExplicitExact 24 Hz";
|
|
EXPECT_EQ(kModeId24Frac, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest,
|
|
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) {
|
|
RefreshRateConfigs configs(kModes_60_90, kModeId90);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
|
|
|
|
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 [mode, signals] = configs.getBestRefreshRate(layers, {.touch = true, .idle = true});
|
|
|
|
EXPECT_EQ(mode, kMode60);
|
|
EXPECT_FALSE(signals.touch);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest,
|
|
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 90_Hz}}), 0);
|
|
|
|
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, configs.getBestRefreshRate(layers, {.idle = true}));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest,
|
|
getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId90);
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
|
|
|
|
const auto [mode, signals] = configs.getBestRefreshRateAndSignals({}, {});
|
|
EXPECT_EQ(mode, 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, configs.getBestRefreshRate(layers));
|
|
|
|
lr.focused = true;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::ExplicitDefault;
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz ExplicitDefault";
|
|
lr.focused = false;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.focused = true;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Heuristic;
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Heuristic";
|
|
lr.focused = false;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.focused = true;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Max;
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Max";
|
|
lr.focused = false;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.focused = true;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.vote = LayerVoteType::Min;
|
|
lr.desiredRefreshRate = 60_Hz;
|
|
lr.name = "60Hz Min";
|
|
lr.focused = false;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
lr.focused = true;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingNotAllowed) {
|
|
TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayer) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamless) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
// 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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
// 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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerDefaultSeamlessness) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
// Verify that if the current config is in another group and there are no layers with
|
|
// seamlessness=SeamedAndSeamless we'll go back to the default group.
|
|
|
|
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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
// 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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
// 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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
|
|
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
// Layer with seamlessness=Default can change the mode group if there's a not
|
|
// focused layer with seamlessness=SeamedAndSeamless. This happens for example,
|
|
// when in split screen mode the user switches between the two visible applications.
|
|
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, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) {
|
|
TestableRefreshRateConfigs configs(kModes_30_60, kModeId60);
|
|
|
|
// Allow group switching.
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
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, configs.getBestRefreshRate(layers)->getId());
|
|
|
|
configs.setActiveModeId(kModeId120);
|
|
EXPECT_EQ(kModeId120, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, nonSeamlessExactAndSeamlessMultipleLayers) {
|
|
TestableRefreshRateConfigs configs(kModes_25_30_50_60, kModeId60);
|
|
|
|
// Allow group switching.
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
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, configs.getBestRefreshRate(layers)->getId());
|
|
|
|
auto& seamedLayer = layers[0];
|
|
seamedLayer.desiredRefreshRate = 30_Hz;
|
|
seamedLayer.name = "30Hz ExplicitDefault";
|
|
configs.setActiveModeId(kModeId30);
|
|
|
|
EXPECT_EQ(kModeId25, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, minLayersDontTrigerSeamedSwitch) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId90);
|
|
|
|
// Allow group switching.
|
|
RefreshRateConfigs::Policy policy;
|
|
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
|
|
policy.allowGroupSwitching = true;
|
|
EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
|
|
|
|
std::vector<LayerRequirement> layers = {
|
|
{.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}};
|
|
|
|
EXPECT_EQ(kModeId90, configs.getBestRefreshRate(layers)->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) {
|
|
TestableRefreshRateConfigs configs(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;
|
|
};
|
|
|
|
// Return the config ID from calling getBestRefreshRate() for a single layer with the
|
|
// given voteType and fps.
|
|
auto getFrameRate = [&](LayerVoteType voteType, Fps fps, Args args = {}) -> DisplayModeId {
|
|
layers[0].vote = voteType;
|
|
layers[0].desiredRefreshRate = fps;
|
|
layers[0].focused = args.focused;
|
|
return configs.getBestRefreshRate(layers, {.touch = args.touch})->getId();
|
|
};
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 60_Hz}, {30_Hz, 90_Hz}}), 0);
|
|
|
|
EXPECT_EQ(kModeId60, configs.getBestRefreshRate()->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 config.
|
|
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_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 60_Hz}}), 0);
|
|
|
|
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_F(RefreshRateConfigsTest, idle) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
|
|
layers[0].name = "Test layer";
|
|
|
|
const auto getIdleFrameRate = [&](LayerVoteType voteType, bool touchActive) -> DisplayModeId {
|
|
layers[0].vote = voteType;
|
|
layers[0].desiredRefreshRate = 90_Hz;
|
|
|
|
const auto [refreshRate, signals] =
|
|
configs.getBestRefreshRateAndSignals(layers, {.touch = touchActive, .idle = true});
|
|
|
|
// Refresh rate will be chosen by either touch state or idle state.
|
|
EXPECT_EQ(!touchActive, signals.idle);
|
|
return refreshRate->getId();
|
|
};
|
|
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
|
|
|
|
// Idle should be lower priority than touch boost.
|
|
{
|
|
constexpr bool kTouchActive = true;
|
|
EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::NoVote, kTouchActive));
|
|
EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Min, kTouchActive));
|
|
EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Max, kTouchActive));
|
|
EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::Heuristic, kTouchActive));
|
|
EXPECT_EQ(kModeId90, getIdleFrameRate(LayerVoteType::ExplicitDefault, kTouchActive));
|
|
EXPECT_EQ(kModeId90,
|
|
getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, kTouchActive));
|
|
}
|
|
|
|
// With no layers, idle should still be lower priority than touch boost.
|
|
EXPECT_EQ(kModeId90, configs.getBestRefreshRate({}, {.touch = true, .idle = true})->getId());
|
|
|
|
// Idle should be higher precedence than other layer frame rate considerations.
|
|
configs.setActiveModeId(kModeId90);
|
|
|
|
{
|
|
constexpr bool kTouchActive = false;
|
|
EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::NoVote, kTouchActive));
|
|
EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Min, kTouchActive));
|
|
EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Max, kTouchActive));
|
|
EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::Heuristic, kTouchActive));
|
|
EXPECT_EQ(kModeId60, getIdleFrameRate(LayerVoteType::ExplicitDefault, kTouchActive));
|
|
EXPECT_EQ(kModeId60,
|
|
getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, kTouchActive));
|
|
}
|
|
|
|
// Idle should be applied rather than the current config when there are no layers.
|
|
EXPECT_EQ(kModeId60, configs.getBestRefreshRate({}, {.idle = true})->getId());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, findClosestKnownFrameRate) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
for (float fps = 1.0f; fps <= 120.0f; fps += 0.1f) {
|
|
const auto knownFrameRate = configs.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_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) {
|
|
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
|
|
|
|
struct Expectation {
|
|
Fps fps;
|
|
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 = configs.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, configs.getBestRefreshRate(layers));
|
|
}
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) {
|
|
TestableRefreshRateConfigs configs(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];
|
|
|
|
explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
|
|
explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
|
|
explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz;
|
|
|
|
explicitExactLayer.vote = LayerVoteType::ExplicitExact;
|
|
explicitExactLayer.name = "ExplicitExact";
|
|
explicitExactLayer.desiredRefreshRate = 30_Hz;
|
|
|
|
EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode30, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz;
|
|
explicitExactLayer.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 72_Hz;
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 90_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 120_Hz;
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) {
|
|
TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60,
|
|
{.enableFrameRateOverride = true});
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz;
|
|
explicitExactLayer.desiredRefreshRate = 60_Hz;
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 72_Hz;
|
|
EXPECT_EQ(kMode72, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 90_Hz;
|
|
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
|
|
|
|
explicitExactLayer.desiredRefreshRate = 120_Hz;
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ReadsCache) {
|
|
TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60);
|
|
|
|
using GlobalSignals = RefreshRateConfigs::GlobalSignals;
|
|
const auto args = std::make_pair(std::vector<LayerRequirement>{},
|
|
GlobalSignals{.touch = true, .idle = true});
|
|
const auto result = std::make_pair(kMode90, GlobalSignals{.touch = true});
|
|
|
|
configs.mutableGetBestRefreshRateCache() = {args, result};
|
|
|
|
EXPECT_EQ(result, configs.getBestRefreshRateAndSignals(args.first, args.second));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) {
|
|
TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60);
|
|
|
|
EXPECT_FALSE(configs.mutableGetBestRefreshRateCache());
|
|
|
|
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}};
|
|
RefreshRateConfigs::GlobalSignals globalSignals{.touch = true, .idle = true};
|
|
|
|
const auto result = configs.getBestRefreshRateAndSignals(layers, globalSignals);
|
|
|
|
const auto& cache = configs.mutableGetBestRefreshRateCache();
|
|
ASSERT_TRUE(cache);
|
|
|
|
EXPECT_EQ(cache->arguments, std::make_pair(layers, globalSignals));
|
|
EXPECT_EQ(cache->result, result);
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) {
|
|
TestableRefreshRateConfigs configs(kModes_60_120, kModeId60, {.enableFrameRateOverride = true});
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
|
|
explicitExactOrMultipleLayer.vote = LayerVoteType::NoVote;
|
|
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
|
|
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers, {.touch = true}));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_FractionalRefreshRates_ExactAndDefault) {
|
|
TestableRefreshRateConfigs configs(kModes_24_25_30_50_60_Frac, kModeId60,
|
|
{.enableFrameRateOverride = true});
|
|
|
|
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, configs.getBestRefreshRate(layers));
|
|
}
|
|
|
|
// b/190578904
|
|
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_withCloseRefreshRates) {
|
|
constexpr int kMinRefreshRate = 10;
|
|
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 TestableRefreshRateConfigs configs(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(), configs.getBestRefreshRate(layers)->getFps().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_F(RefreshRateConfigsTest, getBestRefreshRate_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 RefreshRateConfigs::GlobalSignals globalSignals = {.touch = false, .idle = false};
|
|
const TestableRefreshRateConfigs configs(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, configs.getBestRefreshRate(layers, globalSignals)->getFps());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, modeComparison) {
|
|
EXPECT_LT(kMode60->getFps(), kMode90->getFps());
|
|
EXPECT_GE(kMode60->getFps(), kMode60->getFps());
|
|
EXPECT_GE(kMode90->getFps(), kMode90->getFps());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) {
|
|
using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction;
|
|
|
|
RefreshRateConfigs configs(kModes_60_90, kModeId90);
|
|
|
|
// SetPolicy(60, 90), current 90Hz => TurnOn.
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(60, 90), current 60Hz => TurnOn.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(60, 60), current 60Hz => TurnOff
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(90, 90), current 90Hz => TurnOff.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerActionFor120Hz) {
|
|
using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction;
|
|
|
|
RefreshRateConfigs configs(kModes_60_120, kModeId120);
|
|
|
|
// SetPolicy(0, 60), current 60Hz => TurnOn.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(60, 60), current 60Hz => TurnOff.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(60, 120), current 60Hz => TurnOn.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
|
|
|
|
// SetPolicy(120, 120), current 120Hz => TurnOff.
|
|
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}}), 0);
|
|
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getFrameRateDivisor) {
|
|
RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId30);
|
|
|
|
const auto frameRate = 30_Hz;
|
|
Fps displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(1, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate));
|
|
|
|
configs.setActiveModeId(kModeId60);
|
|
displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(2, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate));
|
|
|
|
configs.setActiveModeId(kModeId72);
|
|
displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate));
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(3, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate));
|
|
|
|
configs.setActiveModeId(kModeId120);
|
|
displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, frameRate));
|
|
|
|
configs.setActiveModeId(kModeId90);
|
|
displayRefreshRate = configs.getActiveMode()->getFps();
|
|
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivisor(displayRefreshRate, 22.5_Hz));
|
|
|
|
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(24_Hz, 25_Hz));
|
|
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(24_Hz, 23.976_Hz));
|
|
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(30_Hz, 29.97_Hz));
|
|
EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivisor(60_Hz, 59.94_Hz));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, isFractionalPairOrMultiple) {
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(23.976_Hz, 24_Hz));
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(24_Hz, 23.976_Hz));
|
|
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 30_Hz));
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(30_Hz, 29.97_Hz));
|
|
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(59.94_Hz, 60_Hz));
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(60_Hz, 59.94_Hz));
|
|
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 60_Hz));
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(60_Hz, 29.97_Hz));
|
|
|
|
EXPECT_TRUE(RefreshRateConfigs::isFractionalPairOrMultiple(59.94_Hz, 30_Hz));
|
|
EXPECT_TRUE(RefreshRateConfigs::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(RefreshRateConfigs::isFractionalPairOrMultiple(refreshRate, refreshRate));
|
|
}
|
|
|
|
EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(24_Hz, 25_Hz));
|
|
EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(23.978_Hz, 25_Hz));
|
|
EXPECT_FALSE(RefreshRateConfigs::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz));
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
|
|
RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120);
|
|
|
|
EXPECT_TRUE(configs.getFrameRateOverrides({}, 120_Hz, {}).empty());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
|
|
RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120,
|
|
{.enableFrameRateOverride = true});
|
|
|
|
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 = configs.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 = configs.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::NoVote;
|
|
frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
|
|
layers[0].vote = LayerVoteType::Min;
|
|
frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
|
|
layers[0].vote = LayerVoteType::Max;
|
|
frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
|
|
layers[0].vote = LayerVoteType::Heuristic;
|
|
frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
|
|
RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120,
|
|
{.enableFrameRateOverride = true});
|
|
|
|
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 = configs.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 = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
}
|
|
|
|
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) {
|
|
RefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId120,
|
|
{.enableFrameRateOverride = true});
|
|
|
|
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 = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_EQ(1u, frameRateOverrides.size());
|
|
ASSERT_EQ(1u, frameRateOverrides.count(1234));
|
|
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
|
|
|
|
frameRateOverrides = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_EQ(1u, frameRateOverrides.size());
|
|
ASSERT_EQ(1u, frameRateOverrides.count(1234));
|
|
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
|
|
|
|
frameRateOverrides = configs.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 = configs.getFrameRateOverrides(layers, 120_Hz, {});
|
|
EXPECT_EQ(1u, frameRateOverrides.size());
|
|
ASSERT_EQ(1u, frameRateOverrides.count(1234));
|
|
EXPECT_EQ(60_Hz, frameRateOverrides.at(1234));
|
|
|
|
frameRateOverrides = configs.getFrameRateOverrides(layers, 120_Hz, {.touch = true});
|
|
EXPECT_TRUE(frameRateOverrides.empty());
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace android::scheduler
|