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 <chrono>
23 #include <thread>
24
25 #include "Scheduler/VsyncConfiguration.h"
26
27 using namespace testing;
28
29 namespace android::scheduler {
30
31 using namespace std::chrono_literals;
32
33 class TestableWorkDuration : public impl::WorkDuration {
34 public:
TestableWorkDuration(Fps currentFps,nsecs_t sfDuration,nsecs_t appDuration,nsecs_t sfEarlyDuration,nsecs_t appEarlyDuration,nsecs_t sfEarlyGlDuration,nsecs_t appEarlyGlDuration,nsecs_t hwcMinWorkDuration)35 TestableWorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration,
36 nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
37 nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration,
38 nsecs_t hwcMinWorkDuration)
39 : impl::WorkDuration(currentFps, sfDuration, appDuration, sfEarlyDuration,
40 appEarlyDuration, sfEarlyGlDuration, appEarlyGlDuration,
41 hwcMinWorkDuration) {}
42 };
43
44 class WorkDurationTest : public testing::Test {
45 protected:
WorkDurationTest()46 WorkDurationTest()
47 : mWorkDuration(60_Hz, 10'500'000, 20'500'000, 16'000'000, 16'500'000, 13'500'000,
48 21'000'000, 1234) {}
49
50 ~WorkDurationTest() = default;
51
52 TestableWorkDuration mWorkDuration;
53 };
54
55 /* ------------------------------------------------------------------------
56 * Test cases
57 */
TEST_F(WorkDurationTest,getConfigsForRefreshRate_60Hz)58 TEST_F(WorkDurationTest, getConfigsForRefreshRate_60Hz) {
59 mWorkDuration.setRefreshRateFps(60_Hz);
60 auto currentOffsets = mWorkDuration.getCurrentConfigs();
61 auto offsets = mWorkDuration.getConfigsForRefreshRate(60_Hz);
62
63 EXPECT_EQ(currentOffsets, offsets);
64 EXPECT_EQ(offsets.late.sfOffset, 6'166'667);
65 EXPECT_EQ(offsets.late.appOffset, 2'333'334);
66
67 EXPECT_EQ(offsets.late.sfWorkDuration, 10'500'000ns);
68 EXPECT_EQ(offsets.late.appWorkDuration, 20'500'000ns);
69
70 EXPECT_EQ(offsets.early.sfOffset, 666'667);
71 EXPECT_EQ(offsets.early.appOffset, 833'334);
72
73 EXPECT_EQ(offsets.early.sfWorkDuration, 16'000'000ns);
74 EXPECT_EQ(offsets.early.appWorkDuration, 16'500'000ns);
75
76 EXPECT_EQ(offsets.earlyGpu.sfOffset, 3'166'667);
77 EXPECT_EQ(offsets.earlyGpu.appOffset, 15'500'001);
78
79 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 13'500'000ns);
80 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'000'000ns);
81 }
82
TEST_F(WorkDurationTest,getConfigsForRefreshRate_90Hz)83 TEST_F(WorkDurationTest, getConfigsForRefreshRate_90Hz) {
84 mWorkDuration.setRefreshRateFps(90_Hz);
85 auto currentOffsets = mWorkDuration.getCurrentConfigs();
86 auto offsets = mWorkDuration.getConfigsForRefreshRate(90_Hz);
87
88 EXPECT_EQ(currentOffsets, offsets);
89 EXPECT_EQ(offsets.late.sfOffset, 611'111);
90 EXPECT_EQ(offsets.late.appOffset, 2'333'333);
91
92 EXPECT_EQ(offsets.late.sfWorkDuration, 10'500'000ns);
93 EXPECT_EQ(offsets.late.appWorkDuration, 20'500'000ns);
94
95 EXPECT_EQ(offsets.early.sfOffset, -4'888'889);
96 EXPECT_EQ(offsets.early.appOffset, 833'333);
97
98 EXPECT_EQ(offsets.early.sfWorkDuration, 16'000'000ns);
99 EXPECT_EQ(offsets.early.appWorkDuration, 16'500'000ns);
100
101 EXPECT_EQ(offsets.earlyGpu.sfOffset, -2'388'889);
102 EXPECT_EQ(offsets.earlyGpu.appOffset, 9'944'444);
103
104 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 13'500'000ns);
105 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'000'000ns);
106 }
107
TEST_F(WorkDurationTest,getConfigsForRefreshRate_DefaultOffsets)108 TEST_F(WorkDurationTest, getConfigsForRefreshRate_DefaultOffsets) {
109 TestableWorkDuration phaseOffsetsWithDefaultValues(60_Hz, -1, -1, -1, -1, -1, -1, 0);
110
111 auto validateOffsets = [](const auto& offsets, std::chrono::nanoseconds vsyncPeriod) {
112 EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
113 EXPECT_EQ(offsets.late.appOffset, 1'000'000);
114
115 EXPECT_EQ(offsets.late.sfWorkDuration, vsyncPeriod - 1'000'000ns);
116 EXPECT_EQ(offsets.late.appWorkDuration, vsyncPeriod);
117
118 EXPECT_EQ(offsets.early.sfOffset, 1'000'000);
119 EXPECT_EQ(offsets.early.appOffset, 1'000'000);
120
121 EXPECT_EQ(offsets.early.sfWorkDuration, vsyncPeriod - 1'000'000ns);
122 EXPECT_EQ(offsets.early.appWorkDuration, vsyncPeriod);
123
124 EXPECT_EQ(offsets.earlyGpu.sfOffset, 1'000'000);
125 EXPECT_EQ(offsets.earlyGpu.appOffset, 1'000'000);
126
127 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, vsyncPeriod - 1'000'000ns);
128 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, vsyncPeriod);
129
130 EXPECT_EQ(offsets.hwcMinWorkDuration, 0ns);
131 };
132
133 const auto testForRefreshRate = [&](Fps refreshRate) {
134 phaseOffsetsWithDefaultValues.setRefreshRateFps(refreshRate);
135 auto currentOffsets = phaseOffsetsWithDefaultValues.getCurrentConfigs();
136 auto offsets = phaseOffsetsWithDefaultValues.getConfigsForRefreshRate(refreshRate);
137 EXPECT_EQ(currentOffsets, offsets);
138 validateOffsets(offsets, std::chrono::nanoseconds(refreshRate.getPeriodNsecs()));
139 };
140
141 testForRefreshRate(90_Hz);
142 testForRefreshRate(60_Hz);
143 }
144
TEST_F(WorkDurationTest,getConfigsForRefreshRate_unknownRefreshRate)145 TEST_F(WorkDurationTest, getConfigsForRefreshRate_unknownRefreshRate) {
146 auto offsets = mWorkDuration.getConfigsForRefreshRate(14.7_Hz);
147
148 EXPECT_EQ(offsets.late.sfOffset, 57'527'208);
149 EXPECT_EQ(offsets.late.appOffset, 37'027'208);
150
151 EXPECT_EQ(offsets.late.sfWorkDuration, 10'500'000ns);
152 EXPECT_EQ(offsets.late.appWorkDuration, 20'500'000ns);
153
154 EXPECT_EQ(offsets.early.sfOffset, 52'027'208);
155 EXPECT_EQ(offsets.early.appOffset, 35'527'208);
156
157 EXPECT_EQ(offsets.early.sfWorkDuration, 16'000'000ns);
158 EXPECT_EQ(offsets.early.appWorkDuration, 16'500'000ns);
159
160 EXPECT_EQ(offsets.earlyGpu.sfOffset, 54'527'208);
161 EXPECT_EQ(offsets.earlyGpu.appOffset, 33'527'208);
162
163 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 13'500'000ns);
164 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'000'000ns);
165 }
166
TEST_F(WorkDurationTest,minHwcWorkDuration)167 TEST_F(WorkDurationTest, minHwcWorkDuration) {
168 EXPECT_EQ(mWorkDuration.getCurrentConfigs().hwcMinWorkDuration, 1234ns);
169 }
170
171 class TestablePhaseOffsets : public impl::PhaseOffsets {
172 public:
TestablePhaseOffsets(nsecs_t vsyncPhaseOffsetNs,nsecs_t sfVSyncPhaseOffsetNs,std::optional<nsecs_t> earlySfOffsetNs,std::optional<nsecs_t> earlyGpuSfOffsetNs,std::optional<nsecs_t> earlyAppOffsetNs,std::optional<nsecs_t> earlyGpuAppOffsetNs,nsecs_t highFpsVsyncPhaseOffsetNs,nsecs_t highFpsSfVSyncPhaseOffsetNs,std::optional<nsecs_t> highFpsEarlySfOffsetNs,std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,std::optional<nsecs_t> highFpsEarlyAppOffsetNs,std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs,nsecs_t thresholdForNextVsync,nsecs_t hwcMinWorkDuration)173 TestablePhaseOffsets(nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
174 std::optional<nsecs_t> earlySfOffsetNs,
175 std::optional<nsecs_t> earlyGpuSfOffsetNs,
176 std::optional<nsecs_t> earlyAppOffsetNs,
177 std::optional<nsecs_t> earlyGpuAppOffsetNs,
178 nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs,
179 std::optional<nsecs_t> highFpsEarlySfOffsetNs,
180 std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
181 std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
182 std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs,
183 nsecs_t thresholdForNextVsync, nsecs_t hwcMinWorkDuration)
184 : impl::PhaseOffsets(60_Hz, vsyncPhaseOffsetNs, sfVSyncPhaseOffsetNs, earlySfOffsetNs,
185 earlyGpuSfOffsetNs, earlyAppOffsetNs, earlyGpuAppOffsetNs,
186 highFpsVsyncPhaseOffsetNs, highFpsSfVSyncPhaseOffsetNs,
187 highFpsEarlySfOffsetNs, highFpsEarlyGpuSfOffsetNs,
188 highFpsEarlyAppOffsetNs, highFpsEarlyGpuAppOffsetNs,
189 thresholdForNextVsync, hwcMinWorkDuration) {}
190 };
191
192 class PhaseOffsetsTest : public testing::Test {
193 protected:
194 PhaseOffsetsTest() = default;
195 ~PhaseOffsetsTest() = default;
196
197 TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000, 8'000'000, 3'000'000,
198 4'000'000, 2'000'000, 1'000'000, 2'000'000, 3'000'000,
199 3'000'000, 4'000'000, 10'000'000, 1234};
200 };
201
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_unknownRefreshRate)202 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_unknownRefreshRate) {
203 auto offsets = mPhaseOffsets.getConfigsForRefreshRate(14.7_Hz);
204
205 EXPECT_EQ(offsets.late.sfOffset, 6'000'000);
206 EXPECT_EQ(offsets.late.appOffset, 2'000'000);
207
208 EXPECT_EQ(offsets.late.sfWorkDuration, 62'027'208ns);
209 EXPECT_EQ(offsets.late.appWorkDuration, 72'027'208ns);
210
211 EXPECT_EQ(offsets.early.sfOffset, 7'000'000);
212 EXPECT_EQ(offsets.early.appOffset, 3'000'000);
213
214 EXPECT_EQ(offsets.early.sfWorkDuration, 61'027'208ns);
215 EXPECT_EQ(offsets.early.appWorkDuration, 72'027'208ns);
216
217 EXPECT_EQ(offsets.earlyGpu.sfOffset, 8'000'000);
218 EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
219
220 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 60'027'208ns);
221 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 72'027'208ns);
222 }
223
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_60Hz)224 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_60Hz) {
225 auto offsets = mPhaseOffsets.getConfigsForRefreshRate(60_Hz);
226
227 EXPECT_EQ(offsets.late.sfOffset, 6'000'000);
228 EXPECT_EQ(offsets.late.appOffset, 2'000'000);
229
230 EXPECT_EQ(offsets.late.sfWorkDuration, 10'666'667ns);
231 EXPECT_EQ(offsets.late.appWorkDuration, 20'666'667ns);
232
233 EXPECT_EQ(offsets.early.sfOffset, 7'000'000);
234 EXPECT_EQ(offsets.early.appOffset, 3'000'000);
235
236 EXPECT_EQ(offsets.early.sfWorkDuration, 9'666'667ns);
237 EXPECT_EQ(offsets.early.appWorkDuration, 20'666'667ns);
238
239 EXPECT_EQ(offsets.earlyGpu.sfOffset, 8'000'000);
240 EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
241
242 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 8'666'667ns);
243 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 20'666'667ns);
244 }
245
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_90Hz)246 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_90Hz) {
247 auto offsets = mPhaseOffsets.getConfigsForRefreshRate(90_Hz);
248
249 EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
250 EXPECT_EQ(offsets.late.appOffset, 2'000'000);
251
252 EXPECT_EQ(offsets.late.sfWorkDuration, 10'111'111ns);
253 EXPECT_EQ(offsets.late.appWorkDuration, 21'222'222ns);
254
255 EXPECT_EQ(offsets.early.sfOffset, 2'000'000);
256 EXPECT_EQ(offsets.early.appOffset, 3'000'000);
257
258 EXPECT_EQ(offsets.early.sfWorkDuration, 9'111'111ns);
259 EXPECT_EQ(offsets.early.appWorkDuration, 21'222'222ns);
260
261 EXPECT_EQ(offsets.earlyGpu.sfOffset, 3'000'000);
262 EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
263
264 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 8'111'111ns);
265 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns);
266 }
267
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_DefaultValues_60Hz)268 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_60Hz) {
269 TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
270 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
271 auto offsets = phaseOffsets.getConfigsForRefreshRate(60_Hz);
272
273 EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
274 EXPECT_EQ(offsets.late.appOffset, 1'000'000);
275
276 EXPECT_EQ(offsets.late.sfWorkDuration, 15'666'667ns);
277 EXPECT_EQ(offsets.late.appWorkDuration, 16'666'667ns);
278
279 EXPECT_EQ(offsets.early.sfOffset, 1'000'000);
280 EXPECT_EQ(offsets.early.appOffset, 1'000'000);
281
282 EXPECT_EQ(offsets.early.sfWorkDuration, 15'666'667ns);
283 EXPECT_EQ(offsets.early.appWorkDuration, 16'666'667ns);
284
285 EXPECT_EQ(offsets.earlyGpu.sfOffset, 1'000'000);
286 EXPECT_EQ(offsets.earlyGpu.appOffset, 1'000'000);
287
288 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 15'666'667ns);
289 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 16'666'667ns);
290 }
291
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_DefaultValues_90Hz)292 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_90Hz) {
293 TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
294 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
295 auto offsets = phaseOffsets.getConfigsForRefreshRate(90_Hz);
296
297 EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
298 EXPECT_EQ(offsets.late.appOffset, 2'000'000);
299
300 EXPECT_EQ(offsets.late.sfWorkDuration, 10'111'111ns);
301 EXPECT_EQ(offsets.late.appWorkDuration, 21'222'222ns);
302
303 EXPECT_EQ(offsets.early.sfOffset, 1'000'000);
304 EXPECT_EQ(offsets.early.appOffset, 2'000'000);
305
306 EXPECT_EQ(offsets.early.sfWorkDuration, 10'111'111ns);
307 EXPECT_EQ(offsets.early.appWorkDuration, 21'222'222ns);
308
309 EXPECT_EQ(offsets.earlyGpu.sfOffset, 1'000'000);
310 EXPECT_EQ(offsets.earlyGpu.appOffset, 2'000'000);
311
312 EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 10'111'111ns);
313 EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns);
314 }
315
TEST_F(PhaseOffsetsTest,minHwcWorkDuration)316 TEST_F(PhaseOffsetsTest, minHwcWorkDuration) {
317 TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {}, 2'000'000,
318 1'000'000, {}, {}, {}, {}, 10'000'000, 1234};
319 EXPECT_EQ(phaseOffsets.getCurrentConfigs().hwcMinWorkDuration, 1234ns);
320 }
321
322 } // namespace android::scheduler
323