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(Fps(60.0f), 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(Fps(60.0f));
60     auto currentOffsets = mWorkDuration.getCurrentConfigs();
61     auto offsets = mWorkDuration.getConfigsForRefreshRate(Fps(60.0f));
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(Fps(90.0f));
85     auto currentOffsets = mWorkDuration.getCurrentConfigs();
86     auto offsets = mWorkDuration.getConfigsForRefreshRate(Fps(90.0f));
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(Fps(60.0f), -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(Fps(90.0f));
142     testForRefreshRate(Fps(60.0f));
143 }
144 
TEST_F(WorkDurationTest,getConfigsForRefreshRate_unknownRefreshRate)145 TEST_F(WorkDurationTest, getConfigsForRefreshRate_unknownRefreshRate) {
146     auto offsets = mWorkDuration.getConfigsForRefreshRate(Fps(14.7f));
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(Fps(60.0f), vsyncPhaseOffsetNs, sfVSyncPhaseOffsetNs,
185                                earlySfOffsetNs, earlyGpuSfOffsetNs, earlyAppOffsetNs,
186                                earlyGpuAppOffsetNs, highFpsVsyncPhaseOffsetNs,
187                                highFpsSfVSyncPhaseOffsetNs, highFpsEarlySfOffsetNs,
188                                highFpsEarlyGpuSfOffsetNs, highFpsEarlyAppOffsetNs,
189                                highFpsEarlyGpuAppOffsetNs, thresholdForNextVsync,
190                                hwcMinWorkDuration) {}
191 };
192 
193 class PhaseOffsetsTest : public testing::Test {
194 protected:
195     PhaseOffsetsTest() = default;
196     ~PhaseOffsetsTest() = default;
197 
198     TestablePhaseOffsets mPhaseOffsets{2'000'000, 6'000'000, 7'000'000,  8'000'000, 3'000'000,
199                                        4'000'000, 2'000'000, 1'000'000,  2'000'000, 3'000'000,
200                                        3'000'000, 4'000'000, 10'000'000, 1234};
201 };
202 
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_unknownRefreshRate)203 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_unknownRefreshRate) {
204     auto offsets = mPhaseOffsets.getConfigsForRefreshRate(Fps(14.7f));
205 
206     EXPECT_EQ(offsets.late.sfOffset, 6'000'000);
207     EXPECT_EQ(offsets.late.appOffset, 2'000'000);
208 
209     EXPECT_EQ(offsets.late.sfWorkDuration, 62'027'208ns);
210     EXPECT_EQ(offsets.late.appWorkDuration, 72'027'208ns);
211 
212     EXPECT_EQ(offsets.early.sfOffset, 7'000'000);
213     EXPECT_EQ(offsets.early.appOffset, 3'000'000);
214 
215     EXPECT_EQ(offsets.early.sfWorkDuration, 61'027'208ns);
216     EXPECT_EQ(offsets.early.appWorkDuration, 72'027'208ns);
217 
218     EXPECT_EQ(offsets.earlyGpu.sfOffset, 8'000'000);
219     EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
220 
221     EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 60'027'208ns);
222     EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 72'027'208ns);
223 }
224 
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_60Hz)225 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_60Hz) {
226     auto offsets = mPhaseOffsets.getConfigsForRefreshRate(Fps(60.0f));
227 
228     EXPECT_EQ(offsets.late.sfOffset, 6'000'000);
229     EXPECT_EQ(offsets.late.appOffset, 2'000'000);
230 
231     EXPECT_EQ(offsets.late.sfWorkDuration, 10'666'667ns);
232     EXPECT_EQ(offsets.late.appWorkDuration, 20'666'667ns);
233 
234     EXPECT_EQ(offsets.early.sfOffset, 7'000'000);
235     EXPECT_EQ(offsets.early.appOffset, 3'000'000);
236 
237     EXPECT_EQ(offsets.early.sfWorkDuration, 9'666'667ns);
238     EXPECT_EQ(offsets.early.appWorkDuration, 20'666'667ns);
239 
240     EXPECT_EQ(offsets.earlyGpu.sfOffset, 8'000'000);
241     EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
242 
243     EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 8'666'667ns);
244     EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 20'666'667ns);
245 }
246 
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_90Hz)247 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_90Hz) {
248     auto offsets = mPhaseOffsets.getConfigsForRefreshRate(Fps(90.0f));
249 
250     EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
251     EXPECT_EQ(offsets.late.appOffset, 2'000'000);
252 
253     EXPECT_EQ(offsets.late.sfWorkDuration, 10'111'111ns);
254     EXPECT_EQ(offsets.late.appWorkDuration, 21'222'222ns);
255 
256     EXPECT_EQ(offsets.early.sfOffset, 2'000'000);
257     EXPECT_EQ(offsets.early.appOffset, 3'000'000);
258 
259     EXPECT_EQ(offsets.early.sfWorkDuration, 9'111'111ns);
260     EXPECT_EQ(offsets.early.appWorkDuration, 21'222'222ns);
261 
262     EXPECT_EQ(offsets.earlyGpu.sfOffset, 3'000'000);
263     EXPECT_EQ(offsets.earlyGpu.appOffset, 4'000'000);
264 
265     EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 8'111'111ns);
266     EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns);
267 }
268 
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_DefaultValues_60Hz)269 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_60Hz) {
270     TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {},         2'000'000,
271                                       1'000'000, {},        {}, {}, {}, 10'000'000, 1234};
272     auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(60.0f));
273 
274     EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
275     EXPECT_EQ(offsets.late.appOffset, 1'000'000);
276 
277     EXPECT_EQ(offsets.late.sfWorkDuration, 15'666'667ns);
278     EXPECT_EQ(offsets.late.appWorkDuration, 16'666'667ns);
279 
280     EXPECT_EQ(offsets.early.sfOffset, 1'000'000);
281     EXPECT_EQ(offsets.early.appOffset, 1'000'000);
282 
283     EXPECT_EQ(offsets.early.sfWorkDuration, 15'666'667ns);
284     EXPECT_EQ(offsets.early.appWorkDuration, 16'666'667ns);
285 
286     EXPECT_EQ(offsets.earlyGpu.sfOffset, 1'000'000);
287     EXPECT_EQ(offsets.earlyGpu.appOffset, 1'000'000);
288 
289     EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 15'666'667ns);
290     EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 16'666'667ns);
291 }
292 
TEST_F(PhaseOffsetsTest,getConfigsForRefreshRate_DefaultValues_90Hz)293 TEST_F(PhaseOffsetsTest, getConfigsForRefreshRate_DefaultValues_90Hz) {
294     TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {},         2'000'000,
295                                       1'000'000, {},        {}, {}, {}, 10'000'000, 1234};
296     auto offsets = phaseOffsets.getConfigsForRefreshRate(Fps(90.0f));
297 
298     EXPECT_EQ(offsets.late.sfOffset, 1'000'000);
299     EXPECT_EQ(offsets.late.appOffset, 2'000'000);
300 
301     EXPECT_EQ(offsets.late.sfWorkDuration, 10'111'111ns);
302     EXPECT_EQ(offsets.late.appWorkDuration, 21'222'222ns);
303 
304     EXPECT_EQ(offsets.early.sfOffset, 1'000'000);
305     EXPECT_EQ(offsets.early.appOffset, 2'000'000);
306 
307     EXPECT_EQ(offsets.early.sfWorkDuration, 10'111'111ns);
308     EXPECT_EQ(offsets.early.appWorkDuration, 21'222'222ns);
309 
310     EXPECT_EQ(offsets.earlyGpu.sfOffset, 1'000'000);
311     EXPECT_EQ(offsets.earlyGpu.appOffset, 2'000'000);
312 
313     EXPECT_EQ(offsets.earlyGpu.sfWorkDuration, 10'111'111ns);
314     EXPECT_EQ(offsets.earlyGpu.appWorkDuration, 21'222'222ns);
315 }
316 
TEST_F(PhaseOffsetsTest,minHwcWorkDuration)317 TEST_F(PhaseOffsetsTest, minHwcWorkDuration) {
318     TestablePhaseOffsets phaseOffsets{1'000'000, 1'000'000, {}, {}, {}, {},         2'000'000,
319                                       1'000'000, {},        {}, {}, {}, 10'000'000, 1234};
320     EXPECT_EQ(phaseOffsets.getCurrentConfigs().hwcMinWorkDuration, 1234ns);
321 }
322 
323 } // namespace android::scheduler
324