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