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