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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wextra"
20
21 #undef LOG_TAG
22 #define LOG_TAG "LibSurfaceFlingerUnittests"
23 #define LOG_NDEBUG 0
24
25 #include "Scheduler/TimeKeeper.h"
26 #include "Scheduler/VSyncDispatch.h"
27 #include "Scheduler/VSyncReactor.h"
28 #include "Scheduler/VSyncTracker.h"
29
30 #include <gmock/gmock.h>
31 #include <gtest/gtest.h>
32 #include <ui/Fence.h>
33 #include <ui/FenceTime.h>
34 #include <array>
35
36 using namespace testing;
37 using namespace std::literals;
38 namespace android::scheduler {
39
40 class MockVSyncTracker : public VSyncTracker {
41 public:
MockVSyncTracker()42 MockVSyncTracker() { ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true)); }
43 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
44 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
45 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
46 MOCK_METHOD1(setPeriod, void(nsecs_t));
47 MOCK_METHOD0(resetModel, void());
48 MOCK_CONST_METHOD0(needsMoreSamples, bool());
49 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
50 MOCK_CONST_METHOD1(dump, void(std::string&));
51 };
52
53 class MockClock : public Clock {
54 public:
55 MOCK_CONST_METHOD0(now, nsecs_t());
56 };
57
58 class ClockWrapper : public Clock {
59 public:
ClockWrapper(std::shared_ptr<Clock> const & clock)60 ClockWrapper(std::shared_ptr<Clock> const& clock) : mClock(clock) {}
61
now() const62 nsecs_t now() const { return mClock->now(); }
63
64 private:
65 std::shared_ptr<Clock> const mClock;
66 };
67
68 class MockVSyncDispatch : public VSyncDispatch {
69 public:
70 MOCK_METHOD2(registerCallback,
71 CallbackToken(std::function<void(nsecs_t, nsecs_t, nsecs_t)> const&, std::string));
72 MOCK_METHOD1(unregisterCallback, void(CallbackToken));
73 MOCK_METHOD2(schedule, ScheduleResult(CallbackToken, ScheduleTiming));
74 MOCK_METHOD1(cancel, CancelResult(CallbackToken token));
75 MOCK_CONST_METHOD1(dump, void(std::string&));
76 };
77
generateInvalidFence()78 std::shared_ptr<android::FenceTime> generateInvalidFence() {
79 sp<Fence> fence = new Fence();
80 return std::make_shared<android::FenceTime>(fence);
81 }
82
generatePendingFence()83 std::shared_ptr<android::FenceTime> generatePendingFence() {
84 sp<Fence> fence = new Fence(dup(fileno(tmpfile())));
85 return std::make_shared<android::FenceTime>(fence);
86 }
87
signalFenceWithTime(std::shared_ptr<android::FenceTime> const & fence,nsecs_t time)88 void signalFenceWithTime(std::shared_ptr<android::FenceTime> const& fence, nsecs_t time) {
89 android::FenceTime::Snapshot snap(time);
90 fence->applyTrustedSnapshot(snap);
91 }
92
generateSignalledFenceWithTime(nsecs_t time)93 std::shared_ptr<android::FenceTime> generateSignalledFenceWithTime(nsecs_t time) {
94 sp<Fence> fence = new Fence(dup(fileno(tmpfile())));
95 std::shared_ptr<android::FenceTime> ft = std::make_shared<android::FenceTime>(fence);
96 signalFenceWithTime(ft, time);
97 return ft;
98 }
99
100 class VSyncReactorTest : public testing::Test {
101 protected:
VSyncReactorTest()102 VSyncReactorTest()
103 : mMockTracker(std::make_shared<NiceMock<MockVSyncTracker>>()),
104 mMockClock(std::make_shared<NiceMock<MockClock>>()),
105 mReactor(std::make_unique<ClockWrapper>(mMockClock), *mMockTracker, kPendingLimit,
106 false /* supportKernelIdleTimer */) {
107 ON_CALL(*mMockClock, now()).WillByDefault(Return(mFakeNow));
108 ON_CALL(*mMockTracker, currentPeriod()).WillByDefault(Return(period));
109 }
110
111 std::shared_ptr<MockVSyncTracker> mMockTracker;
112 std::shared_ptr<MockClock> mMockClock;
113 static constexpr size_t kPendingLimit = 3;
114 static constexpr nsecs_t mDummyTime = 47;
115 static constexpr nsecs_t mPhase = 3000;
116 static constexpr nsecs_t mAnotherPhase = 5200;
117 static constexpr nsecs_t period = 10000;
118 static constexpr nsecs_t mFakeVSyncTime = 2093;
119 static constexpr nsecs_t mFakeWakeupTime = 1892;
120 static constexpr nsecs_t mFakeNow = 2214;
121 static constexpr const char mName[] = "callbacky";
122 VSyncDispatch::CallbackToken const mFakeToken{2398};
123
124 nsecs_t lastCallbackTime = 0;
125 // StubCallback outerCb;
126 std::function<void(nsecs_t, nsecs_t)> innerCb;
127
128 VSyncReactor mReactor;
129 };
130
TEST_F(VSyncReactorTest,addingNullFenceCheck)131 TEST_F(VSyncReactorTest, addingNullFenceCheck) {
132 EXPECT_FALSE(mReactor.addPresentFence(nullptr));
133 }
134
TEST_F(VSyncReactorTest,addingInvalidFenceSignalsNeedsMoreInfo)135 TEST_F(VSyncReactorTest, addingInvalidFenceSignalsNeedsMoreInfo) {
136 EXPECT_TRUE(mReactor.addPresentFence(generateInvalidFence()));
137 }
138
TEST_F(VSyncReactorTest,addingSignalledFenceAddsToTracker)139 TEST_F(VSyncReactorTest, addingSignalledFenceAddsToTracker) {
140 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime));
141 EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime)));
142 }
143
TEST_F(VSyncReactorTest,addingPendingFenceAddsSignalled)144 TEST_F(VSyncReactorTest, addingPendingFenceAddsSignalled) {
145 nsecs_t anotherDummyTime = 2919019201;
146
147 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(0);
148 auto pendingFence = generatePendingFence();
149 EXPECT_FALSE(mReactor.addPresentFence(pendingFence));
150 Mock::VerifyAndClearExpectations(mMockTracker.get());
151
152 signalFenceWithTime(pendingFence, mDummyTime);
153
154 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime));
155 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(anotherDummyTime));
156 EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(anotherDummyTime)));
157 }
158
TEST_F(VSyncReactorTest,limitsPendingFences)159 TEST_F(VSyncReactorTest, limitsPendingFences) {
160 std::array<std::shared_ptr<android::FenceTime>, kPendingLimit * 2> fences;
161 std::array<nsecs_t, fences.size()> fakeTimes;
162 std::generate(fences.begin(), fences.end(), [] { return generatePendingFence(); });
163 std::generate(fakeTimes.begin(), fakeTimes.end(), [i = 10]() mutable {
164 i++;
165 return i * i;
166 });
167
168 for (auto const& fence : fences) {
169 mReactor.addPresentFence(fence);
170 }
171
172 for (auto i = fences.size() - kPendingLimit; i < fences.size(); i++) {
173 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(fakeTimes[i]));
174 }
175
176 for (auto i = 0u; i < fences.size(); i++) {
177 signalFenceWithTime(fences[i], fakeTimes[i]);
178 }
179 mReactor.addPresentFence(generatePendingFence());
180 }
181
TEST_F(VSyncReactorTest,ignoresPresentFencesWhenToldTo)182 TEST_F(VSyncReactorTest, ignoresPresentFencesWhenToldTo) {
183 static constexpr size_t aFewTimes = 8;
184 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime)).Times(1);
185
186 mReactor.setIgnorePresentFences(true);
187 for (auto i = 0; i < aFewTimes; i++) {
188 mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime));
189 }
190
191 mReactor.setIgnorePresentFences(false);
192 EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime)));
193 }
194
TEST_F(VSyncReactorTest,ignoresProperlyAfterAPeriodConfirmation)195 TEST_F(VSyncReactorTest, ignoresProperlyAfterAPeriodConfirmation) {
196 bool periodFlushed = true;
197 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2);
198 mReactor.setIgnorePresentFences(true);
199
200 nsecs_t const newPeriod = 5000;
201 mReactor.startPeriodTransition(newPeriod);
202
203 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed));
204 EXPECT_FALSE(periodFlushed);
205 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, std::nullopt, &periodFlushed));
206 EXPECT_TRUE(periodFlushed);
207
208 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
209 }
210
TEST_F(VSyncReactorTest,setPeriodCalledOnceConfirmedChange)211 TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) {
212 nsecs_t const newPeriod = 5000;
213 EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0);
214 mReactor.startPeriodTransition(newPeriod);
215
216 bool periodFlushed = true;
217 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
218 EXPECT_FALSE(periodFlushed);
219
220 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(20000, std::nullopt, &periodFlushed));
221 EXPECT_FALSE(periodFlushed);
222
223 Mock::VerifyAndClearExpectations(mMockTracker.get());
224 EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1);
225
226 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(25000, std::nullopt, &periodFlushed));
227 EXPECT_TRUE(periodFlushed);
228 }
229
TEST_F(VSyncReactorTest,changingPeriodBackAbortsConfirmationProcess)230 TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) {
231 nsecs_t sampleTime = 0;
232 nsecs_t const newPeriod = 5000;
233 mReactor.startPeriodTransition(newPeriod);
234 bool periodFlushed = true;
235 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
236 EXPECT_FALSE(periodFlushed);
237
238 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
239 EXPECT_FALSE(periodFlushed);
240
241 mReactor.startPeriodTransition(period);
242 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
243 EXPECT_FALSE(periodFlushed);
244 }
245
TEST_F(VSyncReactorTest,changingToAThirdPeriodWillWaitForLastPeriod)246 TEST_F(VSyncReactorTest, changingToAThirdPeriodWillWaitForLastPeriod) {
247 nsecs_t sampleTime = 0;
248 nsecs_t const secondPeriod = 5000;
249 nsecs_t const thirdPeriod = 2000;
250
251 mReactor.startPeriodTransition(secondPeriod);
252 bool periodFlushed = true;
253 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
254 EXPECT_FALSE(periodFlushed);
255 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
256 EXPECT_FALSE(periodFlushed);
257 mReactor.startPeriodTransition(thirdPeriod);
258 EXPECT_TRUE(
259 mReactor.addHwVsyncTimestamp(sampleTime += secondPeriod, std::nullopt, &periodFlushed));
260 EXPECT_FALSE(periodFlushed);
261 EXPECT_FALSE(
262 mReactor.addHwVsyncTimestamp(sampleTime += thirdPeriod, std::nullopt, &periodFlushed));
263 EXPECT_TRUE(periodFlushed);
264 }
265
TEST_F(VSyncReactorTest,reportedBadTimestampFromPredictorWillReactivateHwVSync)266 TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSync) {
267 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_))
268 .WillOnce(Return(false))
269 .WillOnce(Return(true))
270 .WillOnce(Return(true));
271 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
272 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
273
274 nsecs_t skewyPeriod = period >> 1;
275 bool periodFlushed = false;
276 nsecs_t sampleTime = 0;
277 EXPECT_TRUE(
278 mReactor.addHwVsyncTimestamp(sampleTime += skewyPeriod, std::nullopt, &periodFlushed));
279 EXPECT_FALSE(periodFlushed);
280 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
281 EXPECT_FALSE(periodFlushed);
282 }
283
TEST_F(VSyncReactorTest,reportedBadTimestampFromPredictorWillReactivateHwVSyncPendingFence)284 TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSyncPendingFence) {
285 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_))
286 .Times(2)
287 .WillOnce(Return(false))
288 .WillOnce(Return(true));
289
290 auto fence = generatePendingFence();
291 EXPECT_FALSE(mReactor.addPresentFence(fence));
292 signalFenceWithTime(fence, period >> 1);
293 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
294 }
295
TEST_F(VSyncReactorTest,presentFenceAdditionDoesNotInterruptConfirmationProcess)296 TEST_F(VSyncReactorTest, presentFenceAdditionDoesNotInterruptConfirmationProcess) {
297 nsecs_t const newPeriod = 5000;
298 mReactor.startPeriodTransition(newPeriod);
299 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
300 }
301
TEST_F(VSyncReactorTest,setPeriodCalledFirstTwoEventsNewPeriod)302 TEST_F(VSyncReactorTest, setPeriodCalledFirstTwoEventsNewPeriod) {
303 nsecs_t const newPeriod = 5000;
304 EXPECT_CALL(*mMockTracker, setPeriod(_)).Times(0);
305 mReactor.startPeriodTransition(newPeriod);
306
307 bool periodFlushed = true;
308 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(5000, std::nullopt, &periodFlushed));
309 EXPECT_FALSE(periodFlushed);
310 Mock::VerifyAndClearExpectations(mMockTracker.get());
311
312 EXPECT_CALL(*mMockTracker, setPeriod(newPeriod)).Times(1);
313 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
314 EXPECT_TRUE(periodFlushed);
315 }
316
TEST_F(VSyncReactorTest,addResyncSampleTypical)317 TEST_F(VSyncReactorTest, addResyncSampleTypical) {
318 nsecs_t const fakeTimestamp = 3032;
319 bool periodFlushed = false;
320
321 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(fakeTimestamp));
322 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(fakeTimestamp, std::nullopt, &periodFlushed));
323 EXPECT_FALSE(periodFlushed);
324 }
325
TEST_F(VSyncReactorTest,addResyncSamplePeriodChanges)326 TEST_F(VSyncReactorTest, addResyncSamplePeriodChanges) {
327 bool periodFlushed = false;
328 nsecs_t const newPeriod = 4000;
329
330 mReactor.startPeriodTransition(newPeriod);
331
332 auto time = 0;
333 auto constexpr numTimestampSubmissions = 10;
334 for (auto i = 0; i < numTimestampSubmissions; i++) {
335 time += period;
336 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
337 EXPECT_FALSE(periodFlushed);
338 }
339
340 time += newPeriod;
341 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
342 EXPECT_TRUE(periodFlushed);
343
344 for (auto i = 0; i < numTimestampSubmissions; i++) {
345 time += newPeriod;
346 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
347 EXPECT_FALSE(periodFlushed);
348 }
349 }
350
TEST_F(VSyncReactorTest,addPresentFenceWhileAwaitingPeriodConfirmationRequestsHwVsync)351 TEST_F(VSyncReactorTest, addPresentFenceWhileAwaitingPeriodConfirmationRequestsHwVsync) {
352 auto time = 0;
353 bool periodFlushed = false;
354 nsecs_t const newPeriod = 4000;
355 mReactor.startPeriodTransition(newPeriod);
356
357 time += period;
358 mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed);
359 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
360
361 time += newPeriod;
362 mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed);
363
364 EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
365 }
366
TEST_F(VSyncReactorTest,hwVsyncIsRequestedForTracker)367 TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTracker) {
368 auto time = 0;
369 bool periodFlushed = false;
370 nsecs_t const newPeriod = 4000;
371 mReactor.startPeriodTransition(newPeriod);
372
373 static auto constexpr numSamplesWithNewPeriod = 4;
374 Sequence seq;
375 EXPECT_CALL(*mMockTracker, needsMoreSamples())
376 .Times(numSamplesWithNewPeriod - 2)
377 .InSequence(seq)
378 .WillRepeatedly(Return(true));
379 EXPECT_CALL(*mMockTracker, needsMoreSamples())
380 .Times(1)
381 .InSequence(seq)
382 .WillRepeatedly(Return(false));
383 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(numSamplesWithNewPeriod);
384
385 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
386
387 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
388 // confirmed period, but predictor wants numRequest samples. This one and prior are valid.
389 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
390 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
391 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
392 }
393
TEST_F(VSyncReactorTest,hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest)394 TEST_F(VSyncReactorTest, hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest) {
395 auto time = 0;
396 bool periodFlushed = false;
397 nsecs_t const newPeriod = 4000;
398 mReactor.startPeriodTransition(newPeriod);
399
400 Sequence seq;
401 EXPECT_CALL(*mMockTracker, needsMoreSamples())
402 .Times(1)
403 .InSequence(seq)
404 .WillRepeatedly(Return(false));
405 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2);
406
407 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
408 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
409 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
410 }
411
TEST_F(VSyncReactorTest,hwVsyncIsRequestedForTrackerMultiplePeriodChanges)412 TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTrackerMultiplePeriodChanges) {
413 auto time = 0;
414 bool periodFlushed = false;
415 nsecs_t const newPeriod1 = 4000;
416 nsecs_t const newPeriod2 = 7000;
417
418 mReactor.startPeriodTransition(newPeriod1);
419
420 Sequence seq;
421 EXPECT_CALL(*mMockTracker, needsMoreSamples())
422 .Times(4)
423 .InSequence(seq)
424 .WillRepeatedly(Return(true));
425 EXPECT_CALL(*mMockTracker, needsMoreSamples())
426 .Times(1)
427 .InSequence(seq)
428 .WillRepeatedly(Return(false));
429 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(7);
430
431 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
432 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
433 // confirmed period, but predictor wants numRequest samples. This one and prior are valid.
434 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
435 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
436
437 mReactor.startPeriodTransition(newPeriod2);
438 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
439 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
440 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
441 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
442 }
443
TEST_F(VSyncReactorTest,periodChangeWithGivenVsyncPeriod)444 TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) {
445 bool periodFlushed = true;
446 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2);
447 mReactor.setIgnorePresentFences(true);
448
449 nsecs_t const newPeriod = 5000;
450 mReactor.startPeriodTransition(newPeriod);
451
452 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
453 EXPECT_FALSE(periodFlushed);
454 EXPECT_TRUE(mReactor.addHwVsyncTimestamp(newPeriod, 0, &periodFlushed));
455 EXPECT_FALSE(periodFlushed);
456 EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, newPeriod, &periodFlushed));
457 EXPECT_TRUE(periodFlushed);
458
459 EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
460 }
461
TEST_F(VSyncReactorTest,periodIsMeasuredIfIgnoringComposer)462 TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) {
463 // Create a reactor which supports the kernel idle timer
464 auto idleReactor = VSyncReactor(std::make_unique<ClockWrapper>(mMockClock), *mMockTracker,
465 kPendingLimit, true /* supportKernelIdleTimer */);
466
467 bool periodFlushed = true;
468 EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(4);
469 idleReactor.setIgnorePresentFences(true);
470
471 // First, set the same period, which should only be confirmed when we receive two
472 // matching callbacks
473 idleReactor.startPeriodTransition(10000);
474 EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
475 EXPECT_FALSE(periodFlushed);
476 // Correct period but incorrect timestamp delta
477 EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 10000, &periodFlushed));
478 EXPECT_FALSE(periodFlushed);
479 // Correct period and correct timestamp delta
480 EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(10000, 10000, &periodFlushed));
481 EXPECT_TRUE(periodFlushed);
482
483 // Then, set a new period, which should be confirmed as soon as we receive a callback
484 // reporting the new period
485 nsecs_t const newPeriod = 5000;
486 idleReactor.startPeriodTransition(newPeriod);
487 // Incorrect timestamp delta and period
488 EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(20000, 10000, &periodFlushed));
489 EXPECT_FALSE(periodFlushed);
490 // Incorrect timestamp delta but correct period
491 EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(20000, 5000, &periodFlushed));
492 EXPECT_TRUE(periodFlushed);
493
494 EXPECT_TRUE(idleReactor.addPresentFence(generateSignalledFenceWithTime(0)));
495 }
496
497 } // namespace android::scheduler
498
499 // TODO(b/129481165): remove the #pragma below and fix conversion issues
500 #pragma clang diagnostic pop // ignored "-Wextra"