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