blob: de66f8fb412b55bcd03cb0f33631e0ee8f23ae44 [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
28#include "Scheduler/RefreshRateStats.h"
Ady Abrahamabc27602020-04-08 17:20:29 -070029#include "mock/DisplayHardware/MockDisplay.h"
Alec Mourifb571ea2019-01-24 18:42:10 -080030#include "mock/MockTimeStats.h"
Ana Krulec4593b692019-01-11 22:07:25 -080031
32using namespace std::chrono_literals;
Peiyong Lin65248e02020-04-18 21:15:07 -070033using android::hardware::graphics::composer::hal::PowerMode;
Alec Mourifb571ea2019-01-24 18:42:10 -080034using testing::_;
Alec Mouria2957ea2019-03-16 21:05:23 -070035using testing::AtLeast;
Ana Krulec4593b692019-01-11 22:07:25 -080036
37namespace android {
38namespace scheduler {
39
40class RefreshRateStatsTest : public testing::Test {
41protected:
Ady Abraham2139f732019-11-13 18:56:40 -080042 static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
43 static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
Ady Abrahamabc27602020-04-08 17:20:29 -070044 static inline const auto CONFIG_GROUP_0 = 0;
Ana Krulec4593b692019-01-11 22:07:25 -080045 static constexpr int64_t VSYNC_90 = 11111111;
46 static constexpr int64_t VSYNC_60 = 16666667;
47
48 RefreshRateStatsTest();
49 ~RefreshRateStatsTest();
50
Ady Abrahamabc27602020-04-08 17:20:29 -070051 void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
Ana Krulec3f6a2062020-01-23 15:48:01 -080052 mRefreshRateConfigs =
53 std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
Peiyong Lin65248e02020-04-18 21:15:07 -070054 mRefreshRateStats = std::make_unique<RefreshRateStats>(*mRefreshRateConfigs, mTimeStats,
55 /*currentConfigId=*/CONFIG_ID_0,
56 /*currentPowerMode=*/PowerMode::OFF);
Steven Thomas2bbaabe2019-08-28 16:08:35 -070057 }
58
Ady Abrahamabc27602020-04-08 17:20:29 -070059 Hwc2::mock::Display mDisplay;
Dominik Laskowski64536512019-03-28 09:53:04 -070060 mock::TimeStats mTimeStats;
Steven Thomas2bbaabe2019-08-28 16:08:35 -070061 std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
62 std::unique_ptr<RefreshRateStats> mRefreshRateStats;
Ady Abrahamabc27602020-04-08 17:20:29 -070063
64 std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
65 int32_t configGroup,
66 int64_t vsyncPeriod);
Ana Krulec4593b692019-01-11 22:07:25 -080067};
68
69RefreshRateStatsTest::RefreshRateStatsTest() {
70 const ::testing::TestInfo* const test_info =
71 ::testing::UnitTest::GetInstance()->current_test_info();
72 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
73}
74
75RefreshRateStatsTest::~RefreshRateStatsTest() {
76 const ::testing::TestInfo* const test_info =
77 ::testing::UnitTest::GetInstance()->current_test_info();
78 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
79}
80
Ady Abrahamabc27602020-04-08 17:20:29 -070081std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
82 HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
Peiyong Line9d809e2020-04-14 13:10:48 -070083 return HWC2::Display::Config::Builder(mDisplay, configId.value())
Ady Abrahamabc27602020-04-08 17:20:29 -070084 .setVsyncPeriod(int32_t(vsyncPeriod))
85 .setConfigGroup(configGroup)
86 .build();
87}
88
Ana Krulec4593b692019-01-11 22:07:25 -080089namespace {
90/* ------------------------------------------------------------------------
91 * Test cases
92 */
Ana Krulec4593b692019-01-11 22:07:25 -080093TEST_F(RefreshRateStatsTest, oneConfigTest) {
Ady Abrahamabc27602020-04-08 17:20:29 -070094 init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90)});
Ana Krulec4593b692019-01-11 22:07:25 -080095
Dominik Laskowski64536512019-03-28 09:53:04 -070096 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
97 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
Alec Mourifb571ea2019-01-24 18:42:10 -080098
Steven Thomas2bbaabe2019-08-28 16:08:35 -070099 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
100 ASSERT_EQ(1, times.size());
Alec Mouria2957ea2019-03-16 21:05:23 -0700101 EXPECT_NE(0u, times.count("ScreenOff"));
Ana Krulec4593b692019-01-11 22:07:25 -0800102 // Setting up tests on mobile harness can be flaky with time passing, so testing for
103 // exact time changes can result in flaxy numbers. To avoid that remember old
104 // numbers to make sure the correct values are increasing in the next test.
105 int screenOff = times["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800106
107 // Screen is off by default.
108 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700109 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700110 EXPECT_LT(screenOff, times["ScreenOff"]);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700111 EXPECT_EQ(0u, times.count("90fps"));
Ana Krulec4593b692019-01-11 22:07:25 -0800112
Ady Abraham2139f732019-11-13 18:56:40 -0800113 mRefreshRateStats->setConfigMode(CONFIG_ID_0);
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"]);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700119 ASSERT_EQ(1u, times.count("90fps"));
120 EXPECT_LT(0, times["90fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800121
Peiyong Lin65248e02020-04-18 21:15:07 -0700122 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700123 int ninety = mRefreshRateStats->getTotalTimes()["90fps"];
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"]);
127 EXPECT_EQ(ninety, times["90fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800128
Ady Abraham2139f732019-11-13 18:56:40 -0800129 mRefreshRateStats->setConfigMode(CONFIG_ID_0);
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"]);
136 EXPECT_EQ(ninety, times["90fps"]);
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.
153 int 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
Ady Abraham2139f732019-11-13 18:56:40 -0800160 mRefreshRateStats->setConfigMode(CONFIG_ID_0);
Peiyong Lin65248e02020-04-18 21:15:07 -0700161 mRefreshRateStats->setPowerMode(PowerMode::ON);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700162 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800163 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700164 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700165 EXPECT_EQ(screenOff, times["ScreenOff"]);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700166 ASSERT_EQ(1u, times.count("90fps"));
167 EXPECT_LT(0, times["90fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800168
169 // When power mode is normal, time for configs updates.
Ady Abraham2139f732019-11-13 18:56:40 -0800170 mRefreshRateStats->setConfigMode(CONFIG_ID_1);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700171 int ninety = mRefreshRateStats->getTotalTimes()["90fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800172 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700173 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700174 EXPECT_EQ(screenOff, times["ScreenOff"]);
175 EXPECT_EQ(ninety, times["90fps"]);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700176 ASSERT_EQ(1u, times.count("60fps"));
177 EXPECT_LT(0, times["60fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800178
Ady Abraham2139f732019-11-13 18:56:40 -0800179 mRefreshRateStats->setConfigMode(CONFIG_ID_0);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700180 int sixty = mRefreshRateStats->getTotalTimes()["60fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800181 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700182 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700183 EXPECT_EQ(screenOff, times["ScreenOff"]);
184 EXPECT_LT(ninety, times["90fps"]);
185 EXPECT_EQ(sixty, times["60fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800186
Ady Abraham2139f732019-11-13 18:56:40 -0800187 mRefreshRateStats->setConfigMode(CONFIG_ID_1);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700188 ninety = mRefreshRateStats->getTotalTimes()["90fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800189 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700190 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700191 EXPECT_EQ(screenOff, times["ScreenOff"]);
192 EXPECT_EQ(ninety, times["90fps"]);
193 EXPECT_LT(sixty, times["60fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800194
Peiyong Lin65248e02020-04-18 21:15:07 -0700195 // Because the power mode is not PowerMode::ON, switching the config
Ana Krulec4593b692019-01-11 22:07:25 -0800196 // does not update refresh rates that come from the config.
Peiyong Lin65248e02020-04-18 21:15:07 -0700197 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
Ady Abraham2139f732019-11-13 18:56:40 -0800198 mRefreshRateStats->setConfigMode(CONFIG_ID_0);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700199 sixty = mRefreshRateStats->getTotalTimes()["60fps"];
Ana Krulec4593b692019-01-11 22:07:25 -0800200 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700201 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700202 EXPECT_LT(screenOff, times["ScreenOff"]);
203 EXPECT_EQ(ninety, times["90fps"]);
204 EXPECT_EQ(sixty, times["60fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800205
Ady Abraham2139f732019-11-13 18:56:40 -0800206 mRefreshRateStats->setConfigMode(CONFIG_ID_1);
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700207 screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
Ana Krulec4593b692019-01-11 22:07:25 -0800208 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Steven Thomas2bbaabe2019-08-28 16:08:35 -0700209 times = mRefreshRateStats->getTotalTimes();
Alec Mouria2957ea2019-03-16 21:05:23 -0700210 EXPECT_LT(screenOff, times["ScreenOff"]);
211 EXPECT_EQ(ninety, times["90fps"]);
212 EXPECT_EQ(sixty, times["60fps"]);
Ana Krulec4593b692019-01-11 22:07:25 -0800213}
214} // namespace
215} // namespace scheduler
216} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800217
218// TODO(b/129481165): remove the #pragma below and fix conversion issues
219#pragma clang diagnostic pop // ignored "-Wconversion"