blob: 4342dc983dc2f680fc4dadf1a2a87334a24a1419 [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
24#include "Scheduler/RefreshRateStats.h"
25#include "mock/DisplayHardware/MockDisplay.h"
Alec Mourifb571ea2019-01-24 18:42:10 -080026#include "mock/MockTimeStats.h"
Ana Krulec4593b692019-01-11 22:07:25 -080027
28using namespace std::chrono_literals;
Alec Mourifb571ea2019-01-24 18:42:10 -080029using testing::_;
Ana Krulec4593b692019-01-11 22:07:25 -080030
31namespace android {
32namespace scheduler {
33
34class RefreshRateStatsTest : public testing::Test {
35protected:
36 static constexpr int CONFIG_ID_90 = 0;
37 static constexpr int CONFIG_ID_60 = 1;
38 static constexpr int64_t VSYNC_90 = 11111111;
39 static constexpr int64_t VSYNC_60 = 16666667;
40
41 RefreshRateStatsTest();
42 ~RefreshRateStatsTest();
43
44 void init(std::vector<std::shared_ptr<const HWC2::Display::Config>> configs);
45
46 std::unique_ptr<RefreshRateStats> mRefreshRateStats;
Alec Mourifb571ea2019-01-24 18:42:10 -080047 std::shared_ptr<android::mock::TimeStats> mTimeStats;
Ady Abraham1902d072019-03-01 17:18:59 -080048 std::shared_ptr<RefreshRateConfigs> mRefreshRateConfigs;
Ana Krulec4593b692019-01-11 22:07:25 -080049};
50
51RefreshRateStatsTest::RefreshRateStatsTest() {
52 const ::testing::TestInfo* const test_info =
53 ::testing::UnitTest::GetInstance()->current_test_info();
54 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
55}
56
57RefreshRateStatsTest::~RefreshRateStatsTest() {
58 const ::testing::TestInfo* const test_info =
59 ::testing::UnitTest::GetInstance()->current_test_info();
60 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
61}
62
63void RefreshRateStatsTest::init(std::vector<std::shared_ptr<const HWC2::Display::Config>> configs) {
Alec Mourifb571ea2019-01-24 18:42:10 -080064 mTimeStats = std::make_shared<android::mock::TimeStats>();
Ady Abraham1902d072019-03-01 17:18:59 -080065 mRefreshRateConfigs = std::make_shared<RefreshRateConfigs>(configs);
66 mRefreshRateStats = std::make_unique<RefreshRateStats>(mRefreshRateConfigs, mTimeStats);
Ana Krulec4593b692019-01-11 22:07:25 -080067}
68
69namespace {
70/* ------------------------------------------------------------------------
71 * Test cases
72 */
73TEST_F(RefreshRateStatsTest, canCreateAndDestroyTest) {
74 std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
75 init(configs);
76
77 // There is one default config, so the refresh rates should have one item.
78 ASSERT_EQ(1, mRefreshRateStats->getTotalTimes().size());
79}
80
81TEST_F(RefreshRateStatsTest, oneConfigTest) {
82 auto display = new Hwc2::mock::Display();
83
84 auto config = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
85 config.setVsyncPeriod(VSYNC_90);
86 std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
87 configs.push_back(config.build());
88
89 init(configs);
90
Alec Mourifb571ea2019-01-24 18:42:10 -080091 EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(4);
92 EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(2);
93
Ana Krulec4593b692019-01-11 22:07:25 -080094 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
95 ASSERT_EQ(2, times.size());
96 ASSERT_EQ(0, times["ScreenOff"]);
97 ASSERT_EQ(0, times["90fps"]);
98 // Setting up tests on mobile harness can be flaky with time passing, so testing for
99 // exact time changes can result in flaxy numbers. To avoid that remember old
100 // numbers to make sure the correct values are increasing in the next test.
101 int screenOff = times["ScreenOff"];
102 int ninety = times["90fps"];
103
104 // Screen is off by default.
105 std::this_thread::sleep_for(std::chrono::milliseconds(2));
106 times = mRefreshRateStats->getTotalTimes();
107 ASSERT_LT(screenOff, times["ScreenOff"]);
108 ASSERT_EQ(0, times["90fps"]);
109 screenOff = times["ScreenOff"];
110
111 mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
112 std::this_thread::sleep_for(std::chrono::milliseconds(2));
113 times = mRefreshRateStats->getTotalTimes();
114 ASSERT_EQ(screenOff, times["ScreenOff"]);
115 ASSERT_LT(ninety, times["90fps"]);
116 ninety = times["90fps"];
117
118 mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
119 std::this_thread::sleep_for(std::chrono::milliseconds(2));
120 times = mRefreshRateStats->getTotalTimes();
121 ASSERT_LT(screenOff, times["ScreenOff"]);
122 ASSERT_EQ(ninety, times["90fps"]);
123 screenOff = times["ScreenOff"];
124
125 mRefreshRateStats->setConfigMode(CONFIG_ID_90);
126 std::this_thread::sleep_for(std::chrono::milliseconds(2));
127 times = mRefreshRateStats->getTotalTimes();
128 // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
129 // does not update refresh rates that come from the config.
130 ASSERT_LT(screenOff, times["ScreenOff"]);
131 ASSERT_EQ(ninety, times["90fps"]);
132}
133
134TEST_F(RefreshRateStatsTest, twoConfigsTest) {
135 auto display = new Hwc2::mock::Display();
136
137 auto config90 = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
138 config90.setVsyncPeriod(VSYNC_90);
139 std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
140 configs.push_back(config90.build());
141
142 auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
143 config60.setVsyncPeriod(VSYNC_60);
144 configs.push_back(config60.build());
145
146 init(configs);
147
Alec Mourifb571ea2019-01-24 18:42:10 -0800148 EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(6);
149 EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(4);
150 EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(4);
151
Ana Krulec4593b692019-01-11 22:07:25 -0800152 std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
153 ASSERT_EQ(3, times.size());
154 ASSERT_EQ(0, times["ScreenOff"]);
155 ASSERT_EQ(0, times["60fps"]);
156 ASSERT_EQ(0, times["90fps"]);
157 // Setting up tests on mobile harness can be flaky with time passing, so testing for
158 // exact time changes can result in flaxy numbers. To avoid that remember old
159 // numbers to make sure the correct values are increasing in the next test.
160 int screenOff = times["ScreenOff"];
161 int sixty = times["60fps"];
162 int ninety = times["90fps"];
163
164 // Screen is off by default.
165 std::this_thread::sleep_for(std::chrono::milliseconds(2));
166 times = mRefreshRateStats->getTotalTimes();
167 ASSERT_LT(screenOff, times["ScreenOff"]);
168 ASSERT_EQ(sixty, times["60fps"]);
169 ASSERT_EQ(ninety, times["90fps"]);
170 screenOff = times["ScreenOff"];
171
172 mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
173 std::this_thread::sleep_for(std::chrono::milliseconds(2));
174 times = mRefreshRateStats->getTotalTimes();
175 ASSERT_EQ(screenOff, times["ScreenOff"]);
176 ASSERT_EQ(sixty, times["60fps"]);
177 ASSERT_LT(ninety, times["90fps"]);
178 ninety = times["90fps"];
179
180 // When power mode is normal, time for configs updates.
181 mRefreshRateStats->setConfigMode(CONFIG_ID_60);
182 std::this_thread::sleep_for(std::chrono::milliseconds(2));
183 times = mRefreshRateStats->getTotalTimes();
184 ASSERT_EQ(screenOff, times["ScreenOff"]);
185 ASSERT_EQ(ninety, times["90fps"]);
186 ASSERT_LT(sixty, times["60fps"]);
187 sixty = times["60fps"];
188
189 mRefreshRateStats->setConfigMode(CONFIG_ID_90);
190 std::this_thread::sleep_for(std::chrono::milliseconds(2));
191 times = mRefreshRateStats->getTotalTimes();
192 ASSERT_EQ(screenOff, times["ScreenOff"]);
193 ASSERT_LT(ninety, times["90fps"]);
194 ASSERT_EQ(sixty, times["60fps"]);
195 ninety = times["90fps"];
196
197 mRefreshRateStats->setConfigMode(CONFIG_ID_60);
198 std::this_thread::sleep_for(std::chrono::milliseconds(2));
199 times = mRefreshRateStats->getTotalTimes();
200 ASSERT_EQ(screenOff, times["ScreenOff"]);
201 ASSERT_EQ(ninety, times["90fps"]);
202 ASSERT_LT(sixty, times["60fps"]);
203 sixty = times["60fps"];
204
205 // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
206 // does not update refresh rates that come from the config.
207 mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
208 mRefreshRateStats->setConfigMode(CONFIG_ID_90);
209 std::this_thread::sleep_for(std::chrono::milliseconds(2));
210 times = mRefreshRateStats->getTotalTimes();
211 ASSERT_LT(screenOff, times["ScreenOff"]);
212 ASSERT_EQ(ninety, times["90fps"]);
213 ASSERT_EQ(sixty, times["60fps"]);
214 screenOff = times["ScreenOff"];
215
216 mRefreshRateStats->setConfigMode(CONFIG_ID_60);
217 std::this_thread::sleep_for(std::chrono::milliseconds(2));
218 times = mRefreshRateStats->getTotalTimes();
219 ASSERT_LT(screenOff, times["ScreenOff"]);
220 ASSERT_EQ(ninety, times["90fps"]);
221 ASSERT_EQ(sixty, times["60fps"]);
222}
223} // namespace
224} // namespace scheduler
225} // namespace android