blob: f938ba1133c0429d9a68c237cabb4e725eff5efd [file] [log] [blame]
Ana Krulec4593b692019-01-11 22:07:25 -08001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Ana Krulec4593b692019-01-11 22:07:25 -080021#undef LOG_TAG
22#define LOG_TAG "SchedulerUnittests"
23
24#include <gmock/gmock.h>
25#include <log/log.h>
26#include <thread>
27
Marin Shalamanov68a94092020-11-24 17:48:00 +010028#include "Scheduler/HwcStrongTypes.h"
29#include "Scheduler/RefreshRateConfigs.h"
Ana Krulec4593b692019-01-11 22:07:25 -080030#include "Scheduler/RefreshRateStats.h"
Ady Abrahamabc27602020-04-08 17:20:29 -070031#include "mock/DisplayHardware/MockDisplay.h"
Alec Mourifb571ea2019-01-24 18:42:10 -080032#include "mock/MockTimeStats.h"
Ana Krulec4593b692019-01-11 22:07:25 -080033
34using namespace std::chrono_literals;
Peiyong Lin65248e02020-04-18 21:15:07 -070035using android::hardware::graphics::composer::hal::PowerMode;
Alec Mourifb571ea2019-01-24 18:42:10 -080036using testing::_;
Alec Mouria2957ea2019-03-16 21:05:23 -070037using testing::AtLeast;
Ana Krulec4593b692019-01-11 22:07:25 -080038
39namespace android {
40namespace scheduler {
41
42class RefreshRateStatsTest : public testing::Test {
43protected:
Ady Abraham2139f732019-11-13 18:56:40 -080044 static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
45 static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
Ady Abrahamabc27602020-04-08 17:20:29 -070046 static inline const auto CONFIG_GROUP_0 = 0;
Ana Krulec4593b692019-01-11 22:07:25 -080047 static constexpr int64_t VSYNC_90 = 11111111;
48 static constexpr int64_t VSYNC_60 = 16666667;
49
50 RefreshRateStatsTest();
51 ~RefreshRateStatsTest();
52
Ady Abrahamabc27602020-04-08 17:20:29 -070053 void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
Ana Krulec3f6a2062020-01-23 15:48:01 -080054 mRefreshRateConfigs =
55 std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
Marin Shalamanov68a94092020-11-24 17:48:00 +010056
57 const auto currFps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
58 mRefreshRateStats = std::make_unique<RefreshRateStats>(mTimeStats, currFps,
Peiyong Lin65248e02020-04-18 21:15:07 -070059 /*currentPowerMode=*/PowerMode::OFF);
Steven Thomas2bbaabe2019-08-28 16:08:35 -070060 }
61
Ady Abrahamabc27602020-04-08 17:20:29 -070062 Hwc2::mock::Display mDisplay;
Dominik Laskowski64536512019-03-28 09:53:04 -070063 mock::TimeStats mTimeStats;
Steven Thomas2bbaabe2019-08-28 16:08:35 -070064 std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
65 std::unique_ptr<RefreshRateStats> mRefreshRateStats;
Ady Abrahamabc27602020-04-08 17:20:29 -070066
67 std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
68 int32_t configGroup,
69 int64_t vsyncPeriod);
Ana Krulec4593b692019-01-11 22:07:25 -080070};
71
72RefreshRateStatsTest::RefreshRateStatsTest() {
73 const ::testing::TestInfo* const test_info =
74 ::testing::UnitTest::GetInstance()->current_test_info();
75 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
76}
77
78RefreshRateStatsTest::~RefreshRateStatsTest() {
79 const ::testing::TestInfo* const test_info =
80 ::testing::UnitTest::GetInstance()->current_test_info();
81 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
82}
83
Ady Abrahamabc27602020-04-08 17:20:29 -070084std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
85 HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
Peiyong Line9d809e2020-04-14 13:10:48 -070086 return HWC2::Display::Config::Builder(mDisplay, configId.value())
Marin Shalamanov68a94092020-11-24 17:48:00 +010087 .setVsyncPeriod(static_cast<int32_t>(vsyncPeriod))
Ady Abrahamabc27602020-04-08 17:20:29 -070088 .setConfigGroup(configGroup)
89 .build();
90}
91
Ana Krulec4593b692019-01-11 22:07:25 -080092namespace {
93/* ------------------------------------------------------------------------
94 * Test cases
95 */
Ana Krulec4593b692019-01-11 22:07:25 -080096TEST_F(RefreshRateStatsTest, oneConfigTest) {
Ady Abrahamabc27602020-04-08 17:20:29 -070097 init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90)});
Ana Krulec4593b692019-01-11 22:07:25 -080098
Dominik Laskowski64536512019-03-28 09:53:04 -070099 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
100 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
Alec Mourifb571ea2019-01-24 18:42:10 -0800101
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700102 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
103 ASSERT_EQ(1, times.size());
Alec Mouria2957ea2019-03-16 21:05:23 -0700104 EXPECT_NE(0u, times.count("ScreenOff"));
Ana Krulec4593b692019-01-11 22:07:25 -0800105 // Setting up tests on mobile harness can be flaky with time passing, so testing for
106 // exact time changes can result in flaxy numbers. To avoid that remember old
107 // numbers to make sure the correct values are increasing in the next test.
108 int screenOff = times["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800109
110 // Screen is off by default.
111 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700112 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700113 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200114 EXPECT_EQ(0u, times.count("90.00fps"));
Ana Krulec4593b692019-01-11 22:07:25 -0800115
Marin Shalamanov68a94092020-11-24 17:48:00 +0100116 const auto config0Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
117 mRefreshRateStats->setRefreshRate(config0Fps);
Peiyong Lin65248e02020-04-18 21:15:07 -0700118 mRefreshRateStats->setPowerMode(PowerMode::ON);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700119 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800120 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700121 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700122 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200123 ASSERT_EQ(1u, times.count("90.00fps"));
124 EXPECT_LT(0, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800125
Peiyong Lin65248e02020-04-18 21:15:07 -0700126 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Marin Shalamanov46084422020-10-13 12:33:42 +0200127 int ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800128 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700129 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700130 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200131 EXPECT_EQ(ninety, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800132
Marin Shalamanov68a94092020-11-24 17:48:00 +0100133 mRefreshRateStats->setRefreshRate(config0Fps);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700134 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800135 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700136 times = mRefreshRateStats->getTotalTimes();
Peiyong Lin65248e02020-04-18 21:15:07 -0700137 // Because the power mode is not PowerMode::ON, switching the config
Ana Krulec4593b692019-01-11 22:07:25 -0800138 // does not update refresh rates that come from the config.
Alec Mouria2957ea2019-03-16 21:05:23 -0700139 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200140 EXPECT_EQ(ninety, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800141}
142
143TEST_F(RefreshRateStatsTest, twoConfigsTest) {
Ady Abrahamabc27602020-04-08 17:20:29 -0700144 init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90),
145 createConfig(CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60)});
Ana Krulec4593b692019-01-11 22:07:25 -0800146
Dominik Laskowski64536512019-03-28 09:53:04 -0700147 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
148 EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
149 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
Alec Mourifb571ea2019-01-24 18:42:10 -0800150
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700151 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
152 ASSERT_EQ(1, times.size());
Alec Mouria2957ea2019-03-16 21:05:23 -0700153 EXPECT_NE(0u, times.count("ScreenOff"));
Ana Krulec4593b692019-01-11 22:07:25 -0800154 // Setting up tests on mobile harness can be flaky with time passing, so testing for
155 // exact time changes can result in flaxy numbers. To avoid that remember old
156 // numbers to make sure the correct values are increasing in the next test.
157 int screenOff = times["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800158
159 // Screen is off by default.
160 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700161 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700162 EXPECT_LT(screenOff, times["ScreenOff"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800163
Marin Shalamanov68a94092020-11-24 17:48:00 +0100164 const auto config0Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
165 const auto config1Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_1).getFps();
166 mRefreshRateStats->setRefreshRate(config0Fps);
Peiyong Lin65248e02020-04-18 21:15:07 -0700167 mRefreshRateStats->setPowerMode(PowerMode::ON);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700168 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800169 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700170 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700171 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200172 ASSERT_EQ(1u, times.count("90.00fps"));
173 EXPECT_LT(0, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800174
175 // When power mode is normal, time for configs updates.
Marin Shalamanov68a94092020-11-24 17:48:00 +0100176 mRefreshRateStats->setRefreshRate(config1Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200177 int ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800178 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700179 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700180 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200181 EXPECT_EQ(ninety, times["90.00fps"]);
182 ASSERT_EQ(1u, times.count("60.00fps"));
183 EXPECT_LT(0, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800184
Marin Shalamanov68a94092020-11-24 17:48:00 +0100185 mRefreshRateStats->setRefreshRate(config0Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200186 int sixty = mRefreshRateStats->getTotalTimes()["60.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800187 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700188 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700189 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200190 EXPECT_LT(ninety, times["90.00fps"]);
191 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800192
Marin Shalamanov68a94092020-11-24 17:48:00 +0100193 mRefreshRateStats->setRefreshRate(config1Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200194 ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800195 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700196 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700197 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200198 EXPECT_EQ(ninety, times["90.00fps"]);
199 EXPECT_LT(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800200
Peiyong Lin65248e02020-04-18 21:15:07 -0700201 // Because the power mode is not PowerMode::ON, switching the config
Ana Krulec4593b692019-01-11 22:07:25 -0800202 // does not update refresh rates that come from the config.
Peiyong Lin65248e02020-04-18 21:15:07 -0700203 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Marin Shalamanov68a94092020-11-24 17:48:00 +0100204 mRefreshRateStats->setRefreshRate(config0Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200205 sixty = mRefreshRateStats->getTotalTimes()["60.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800206 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700207 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700208 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200209 EXPECT_EQ(ninety, times["90.00fps"]);
210 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800211
Marin Shalamanov68a94092020-11-24 17:48:00 +0100212 mRefreshRateStats->setRefreshRate(config1Fps);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700213 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800214 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700215 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700216 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200217 EXPECT_EQ(ninety, times["90.00fps"]);
218 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800219}
220} // namespace
221} // namespace scheduler
222} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800223
224// TODO(b/129481165): remove the #pragma below and fix conversion issues
225#pragma clang diagnostic pop // ignored "-Wconversion"