blob: e93d0d0805c1555c5c9cda21e0d5e8a89a03ffcf [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
17#undef LOG_TAG
18#define LOG_TAG "SchedulerUnittests"
19
20#include <gmock/gmock.h>
21#include <log/log.h>
22#include <thread>
23
Marin Shalamanov68a94092020-11-24 17:48:00 +010024#include "Scheduler/HwcStrongTypes.h"
25#include "Scheduler/RefreshRateConfigs.h"
Ana Krulec4593b692019-01-11 22:07:25 -080026#include "Scheduler/RefreshRateStats.h"
Ady Abrahamabc27602020-04-08 17:20:29 -070027#include "mock/DisplayHardware/MockDisplay.h"
Alec Mourifb571ea2019-01-24 18:42:10 -080028#include "mock/MockTimeStats.h"
Ana Krulec4593b692019-01-11 22:07:25 -080029
30using namespace std::chrono_literals;
Peiyong Lin65248e02020-04-18 21:15:07 -070031using android::hardware::graphics::composer::hal::PowerMode;
Alec Mourifb571ea2019-01-24 18:42:10 -080032using testing::_;
Alec Mouria2957ea2019-03-16 21:05:23 -070033using testing::AtLeast;
Ana Krulec4593b692019-01-11 22:07:25 -080034
35namespace android {
36namespace scheduler {
37
38class RefreshRateStatsTest : public testing::Test {
39protected:
Ady Abraham2139f732019-11-13 18:56:40 -080040 static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
41 static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
Ady Abrahamabc27602020-04-08 17:20:29 -070042 static inline const auto CONFIG_GROUP_0 = 0;
Ana Krulec4593b692019-01-11 22:07:25 -080043 static constexpr int64_t VSYNC_90 = 11111111;
44 static constexpr int64_t VSYNC_60 = 16666667;
45
46 RefreshRateStatsTest();
47 ~RefreshRateStatsTest();
48
Ady Abrahamabc27602020-04-08 17:20:29 -070049 void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
Ana Krulec3f6a2062020-01-23 15:48:01 -080050 mRefreshRateConfigs =
51 std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
Marin Shalamanov68a94092020-11-24 17:48:00 +010052
53 const auto currFps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
54 mRefreshRateStats = std::make_unique<RefreshRateStats>(mTimeStats, currFps,
Peiyong Lin65248e02020-04-18 21:15:07 -070055 /*currentPowerMode=*/PowerMode::OFF);
Steven Thomas2bbaabe2019-08-28 16:08:35 -070056 }
57
Ady Abrahamabc27602020-04-08 17:20:29 -070058 Hwc2::mock::Display mDisplay;
Dominik Laskowski64536512019-03-28 09:53:04 -070059 mock::TimeStats mTimeStats;
Steven Thomas2bbaabe2019-08-28 16:08:35 -070060 std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
61 std::unique_ptr<RefreshRateStats> mRefreshRateStats;
Ady Abrahamabc27602020-04-08 17:20:29 -070062
63 std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
64 int32_t configGroup,
65 int64_t vsyncPeriod);
Ana Krulec4593b692019-01-11 22:07:25 -080066};
67
68RefreshRateStatsTest::RefreshRateStatsTest() {
69 const ::testing::TestInfo* const test_info =
70 ::testing::UnitTest::GetInstance()->current_test_info();
71 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
72}
73
74RefreshRateStatsTest::~RefreshRateStatsTest() {
75 const ::testing::TestInfo* const test_info =
76 ::testing::UnitTest::GetInstance()->current_test_info();
77 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
78}
79
Ady Abrahamabc27602020-04-08 17:20:29 -070080std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
81 HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
Marin Shalamanovd52137e2020-12-02 12:19:13 +010082 return HWC2::Display::Config::Builder(mDisplay, static_cast<hal::HWConfigId>(configId.value()))
Marin Shalamanov68a94092020-11-24 17:48:00 +010083 .setVsyncPeriod(static_cast<int32_t>(vsyncPeriod))
Ady Abrahamabc27602020-04-08 17:20:29 -070084 .setConfigGroup(configGroup)
85 .build();
86}
87
Ana Krulec4593b692019-01-11 22:07:25 -080088namespace {
89/* ------------------------------------------------------------------------
90 * Test cases
91 */
Ana Krulec4593b692019-01-11 22:07:25 -080092TEST_F(RefreshRateStatsTest, oneConfigTest) {
Ady Abrahamabc27602020-04-08 17:20:29 -070093 init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90)});
Ana Krulec4593b692019-01-11 22:07:25 -080094
Dominik Laskowski64536512019-03-28 09:53:04 -070095 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
96 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
Alec Mourifb571ea2019-01-24 18:42:10 -080097
Steven Thomas2bbaabe2019-08-28 16:08:35 -070098 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
99 ASSERT_EQ(1, times.size());
Alec Mouria2957ea2019-03-16 21:05:23 -0700100 EXPECT_NE(0u, times.count("ScreenOff"));
Ana Krulec4593b692019-01-11 22:07:25 -0800101 // Setting up tests on mobile harness can be flaky with time passing, so testing for
102 // exact time changes can result in flaxy numbers. To avoid that remember old
103 // numbers to make sure the correct values are increasing in the next test.
Marin Shalamanovd52137e2020-12-02 12:19:13 +0100104 auto screenOff = times["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800105
106 // Screen is off by default.
107 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700108 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700109 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200110 EXPECT_EQ(0u, times.count("90.00fps"));
Ana Krulec4593b692019-01-11 22:07:25 -0800111
Marin Shalamanov68a94092020-11-24 17:48:00 +0100112 const auto config0Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
113 mRefreshRateStats->setRefreshRate(config0Fps);
Peiyong Lin65248e02020-04-18 21:15:07 -0700114 mRefreshRateStats->setPowerMode(PowerMode::ON);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700115 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800116 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700117 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700118 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200119 ASSERT_EQ(1u, times.count("90.00fps"));
120 EXPECT_LT(0, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800121
Peiyong Lin65248e02020-04-18 21:15:07 -0700122 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Marin Shalamanovd52137e2020-12-02 12:19:13 +0100123 auto ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800124 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700125 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700126 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200127 EXPECT_EQ(ninety, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800128
Marin Shalamanov68a94092020-11-24 17:48:00 +0100129 mRefreshRateStats->setRefreshRate(config0Fps);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700130 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800131 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700132 times = mRefreshRateStats->getTotalTimes();
Peiyong Lin65248e02020-04-18 21:15:07 -0700133 // Because the power mode is not PowerMode::ON, switching the config
Ana Krulec4593b692019-01-11 22:07:25 -0800134 // does not update refresh rates that come from the config.
Alec Mouria2957ea2019-03-16 21:05:23 -0700135 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200136 EXPECT_EQ(ninety, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800137}
138
139TEST_F(RefreshRateStatsTest, twoConfigsTest) {
Ady Abrahamabc27602020-04-08 17:20:29 -0700140 init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90),
141 createConfig(CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60)});
Ana Krulec4593b692019-01-11 22:07:25 -0800142
Dominik Laskowski64536512019-03-28 09:53:04 -0700143 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
144 EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
145 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
Alec Mourifb571ea2019-01-24 18:42:10 -0800146
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700147 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
148 ASSERT_EQ(1, times.size());
Alec Mouria2957ea2019-03-16 21:05:23 -0700149 EXPECT_NE(0u, times.count("ScreenOff"));
Ana Krulec4593b692019-01-11 22:07:25 -0800150 // Setting up tests on mobile harness can be flaky with time passing, so testing for
151 // exact time changes can result in flaxy numbers. To avoid that remember old
152 // numbers to make sure the correct values are increasing in the next test.
Marin Shalamanovd52137e2020-12-02 12:19:13 +0100153 auto screenOff = times["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800154
155 // Screen is off by default.
156 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700157 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700158 EXPECT_LT(screenOff, times["ScreenOff"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800159
Marin Shalamanov68a94092020-11-24 17:48:00 +0100160 const auto config0Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_0).getFps();
161 const auto config1Fps = mRefreshRateConfigs->getRefreshRateFromConfigId(CONFIG_ID_1).getFps();
162 mRefreshRateStats->setRefreshRate(config0Fps);
Peiyong Lin65248e02020-04-18 21:15:07 -0700163 mRefreshRateStats->setPowerMode(PowerMode::ON);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700164 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800165 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700166 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700167 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200168 ASSERT_EQ(1u, times.count("90.00fps"));
169 EXPECT_LT(0, times["90.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800170
171 // When power mode is normal, time for configs updates.
Marin Shalamanov68a94092020-11-24 17:48:00 +0100172 mRefreshRateStats->setRefreshRate(config1Fps);
Marin Shalamanovd52137e2020-12-02 12:19:13 +0100173 auto ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800174 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700175 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700176 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200177 EXPECT_EQ(ninety, times["90.00fps"]);
178 ASSERT_EQ(1u, times.count("60.00fps"));
179 EXPECT_LT(0, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800180
Marin Shalamanov68a94092020-11-24 17:48:00 +0100181 mRefreshRateStats->setRefreshRate(config0Fps);
Marin Shalamanovd52137e2020-12-02 12:19:13 +0100182 auto sixty = mRefreshRateStats->getTotalTimes()["60.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800183 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700184 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700185 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200186 EXPECT_LT(ninety, times["90.00fps"]);
187 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800188
Marin Shalamanov68a94092020-11-24 17:48:00 +0100189 mRefreshRateStats->setRefreshRate(config1Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200190 ninety = mRefreshRateStats->getTotalTimes()["90.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800191 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700192 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700193 EXPECT_EQ(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200194 EXPECT_EQ(ninety, times["90.00fps"]);
195 EXPECT_LT(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800196
Peiyong Lin65248e02020-04-18 21:15:07 -0700197 // Because the power mode is not PowerMode::ON, switching the config
Ana Krulec4593b692019-01-11 22:07:25 -0800198 // does not update refresh rates that come from the config.
Peiyong Lin65248e02020-04-18 21:15:07 -0700199 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Marin Shalamanov68a94092020-11-24 17:48:00 +0100200 mRefreshRateStats->setRefreshRate(config0Fps);
Marin Shalamanov46084422020-10-13 12:33:42 +0200201 sixty = mRefreshRateStats->getTotalTimes()["60.00fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800202 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700203 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700204 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200205 EXPECT_EQ(ninety, times["90.00fps"]);
206 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800207
Marin Shalamanov68a94092020-11-24 17:48:00 +0100208 mRefreshRateStats->setRefreshRate(config1Fps);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700209 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800210 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700211 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700212 EXPECT_LT(screenOff, times["ScreenOff"]);
Marin Shalamanov46084422020-10-13 12:33:42 +0200213 EXPECT_EQ(ninety, times["90.00fps"]);
214 EXPECT_EQ(sixty, times["60.00fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800215}
216} // namespace
217} // namespace scheduler
218} // namespace android