• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
26 #include "mock/MockTimeStats.h"
27 
28 using namespace std::chrono_literals;
29 using testing::_;
30 using testing::AtLeast;
31 
32 namespace android {
33 namespace scheduler {
34 
35 class RefreshRateStatsTest : public testing::Test {
36 protected:
37     static constexpr int CONFIG_ID_90 = 0;
38     static constexpr int CONFIG_ID_60 = 1;
39     static constexpr int64_t VSYNC_90 = 11111111;
40     static constexpr int64_t VSYNC_60 = 16666667;
41 
42     RefreshRateStatsTest();
43     ~RefreshRateStatsTest();
44 
45     mock::TimeStats mTimeStats;
46     RefreshRateConfigs mRefreshRateConfigs;
47     RefreshRateStats mRefreshRateStats{mRefreshRateConfigs, mTimeStats};
48 };
49 
RefreshRateStatsTest()50 RefreshRateStatsTest::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 
~RefreshRateStatsTest()56 RefreshRateStatsTest::~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 
62 namespace {
63 /* ------------------------------------------------------------------------
64  * Test cases
65  */
TEST_F(RefreshRateStatsTest,canCreateAndDestroyTest)66 TEST_F(RefreshRateStatsTest, canCreateAndDestroyTest) {
67     std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
68     mRefreshRateConfigs.populate(configs);
69 
70     // There is one default config, so the refresh rates should have one item.
71     EXPECT_EQ(1, mRefreshRateStats.getTotalTimes().size());
72 }
73 
TEST_F(RefreshRateStatsTest,oneConfigTest)74 TEST_F(RefreshRateStatsTest, oneConfigTest) {
75     auto display = new Hwc2::mock::Display();
76 
77     auto config = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
78     config.setVsyncPeriod(VSYNC_90);
79     std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
80     configs.push_back(config.build());
81 
82     mRefreshRateConfigs.populate(configs);
83 
84     EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
85     EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
86 
87     std::unordered_map<std::string, int64_t> times = mRefreshRateStats.getTotalTimes();
88     EXPECT_EQ(2, times.size());
89     EXPECT_NE(0u, times.count("ScreenOff"));
90     EXPECT_EQ(1u, times.count("90fps"));
91     EXPECT_EQ(0, times["90fps"]);
92     // Setting up tests on mobile harness can be flaky with time passing, so testing for
93     // exact time changes can result in flaxy numbers. To avoid that remember old
94     // numbers to make sure the correct values are increasing in the next test.
95     int screenOff = times["ScreenOff"];
96     int ninety = times["90fps"];
97 
98     // Screen is off by default.
99     std::this_thread::sleep_for(std::chrono::milliseconds(2));
100     times = mRefreshRateStats.getTotalTimes();
101     EXPECT_LT(screenOff, times["ScreenOff"]);
102     EXPECT_EQ(0, times["90fps"]);
103 
104     mRefreshRateStats.setConfigMode(CONFIG_ID_90);
105     mRefreshRateStats.setPowerMode(HWC_POWER_MODE_NORMAL);
106     screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
107     std::this_thread::sleep_for(std::chrono::milliseconds(2));
108     times = mRefreshRateStats.getTotalTimes();
109     EXPECT_EQ(screenOff, times["ScreenOff"]);
110     EXPECT_LT(ninety, times["90fps"]);
111 
112     mRefreshRateStats.setPowerMode(HWC_POWER_MODE_DOZE);
113     ninety = mRefreshRateStats.getTotalTimes()["90fps"];
114     std::this_thread::sleep_for(std::chrono::milliseconds(2));
115     times = mRefreshRateStats.getTotalTimes();
116     EXPECT_LT(screenOff, times["ScreenOff"]);
117     EXPECT_EQ(ninety, times["90fps"]);
118 
119     mRefreshRateStats.setConfigMode(CONFIG_ID_90);
120     screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
121     std::this_thread::sleep_for(std::chrono::milliseconds(2));
122     times = mRefreshRateStats.getTotalTimes();
123     // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
124     // does not update refresh rates that come from the config.
125     EXPECT_LT(screenOff, times["ScreenOff"]);
126     EXPECT_EQ(ninety, times["90fps"]);
127 }
128 
TEST_F(RefreshRateStatsTest,twoConfigsTest)129 TEST_F(RefreshRateStatsTest, twoConfigsTest) {
130     auto display = new Hwc2::mock::Display();
131 
132     auto config90 = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
133     config90.setVsyncPeriod(VSYNC_90);
134     std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
135     configs.push_back(config90.build());
136 
137     auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
138     config60.setVsyncPeriod(VSYNC_60);
139     configs.push_back(config60.build());
140 
141     mRefreshRateConfigs.populate(configs);
142 
143     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));
146 
147     std::unordered_map<std::string, int64_t> times = mRefreshRateStats.getTotalTimes();
148     EXPECT_EQ(3, times.size());
149     EXPECT_NE(0u, times.count("ScreenOff"));
150     EXPECT_EQ(1u, times.count("60fps"));
151     EXPECT_EQ(0, times["60fps"]);
152     EXPECT_EQ(1u, times.count("90fps"));
153     EXPECT_EQ(0, times["90fps"]);
154     // 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"];
158     int sixty = times["60fps"];
159     int ninety = times["90fps"];
160 
161     // Screen is off by default.
162     std::this_thread::sleep_for(std::chrono::milliseconds(2));
163     times = mRefreshRateStats.getTotalTimes();
164     EXPECT_LT(screenOff, times["ScreenOff"]);
165     EXPECT_EQ(sixty, times["60fps"]);
166     EXPECT_EQ(ninety, times["90fps"]);
167 
168     mRefreshRateStats.setConfigMode(CONFIG_ID_90);
169     mRefreshRateStats.setPowerMode(HWC_POWER_MODE_NORMAL);
170     screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
171     std::this_thread::sleep_for(std::chrono::milliseconds(2));
172     times = mRefreshRateStats.getTotalTimes();
173     EXPECT_EQ(screenOff, times["ScreenOff"]);
174     EXPECT_EQ(sixty, times["60fps"]);
175     EXPECT_LT(ninety, times["90fps"]);
176 
177     // When power mode is normal, time for configs updates.
178     mRefreshRateStats.setConfigMode(CONFIG_ID_60);
179     ninety = mRefreshRateStats.getTotalTimes()["90fps"];
180     std::this_thread::sleep_for(std::chrono::milliseconds(2));
181     times = mRefreshRateStats.getTotalTimes();
182     EXPECT_EQ(screenOff, times["ScreenOff"]);
183     EXPECT_EQ(ninety, times["90fps"]);
184     EXPECT_LT(sixty, times["60fps"]);
185 
186     mRefreshRateStats.setConfigMode(CONFIG_ID_90);
187     sixty = mRefreshRateStats.getTotalTimes()["60fps"];
188     std::this_thread::sleep_for(std::chrono::milliseconds(2));
189     times = mRefreshRateStats.getTotalTimes();
190     EXPECT_EQ(screenOff, times["ScreenOff"]);
191     EXPECT_LT(ninety, times["90fps"]);
192     EXPECT_EQ(sixty, times["60fps"]);
193 
194     mRefreshRateStats.setConfigMode(CONFIG_ID_60);
195     ninety = mRefreshRateStats.getTotalTimes()["90fps"];
196     std::this_thread::sleep_for(std::chrono::milliseconds(2));
197     times = mRefreshRateStats.getTotalTimes();
198     EXPECT_EQ(screenOff, times["ScreenOff"]);
199     EXPECT_EQ(ninety, times["90fps"]);
200     EXPECT_LT(sixty, times["60fps"]);
201 
202     // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
203     // does not update refresh rates that come from the config.
204     mRefreshRateStats.setPowerMode(HWC_POWER_MODE_DOZE);
205     mRefreshRateStats.setConfigMode(CONFIG_ID_90);
206     sixty = mRefreshRateStats.getTotalTimes()["60fps"];
207     std::this_thread::sleep_for(std::chrono::milliseconds(2));
208     times = mRefreshRateStats.getTotalTimes();
209     EXPECT_LT(screenOff, times["ScreenOff"]);
210     EXPECT_EQ(ninety, times["90fps"]);
211     EXPECT_EQ(sixty, times["60fps"]);
212 
213     mRefreshRateStats.setConfigMode(CONFIG_ID_60);
214     screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
215     std::this_thread::sleep_for(std::chrono::milliseconds(2));
216     times = mRefreshRateStats.getTotalTimes();
217     EXPECT_LT(screenOff, times["ScreenOff"]);
218     EXPECT_EQ(ninety, times["90fps"]);
219     EXPECT_EQ(sixty, times["60fps"]);
220 }
221 } // namespace
222 } // namespace scheduler
223 } // namespace android
224