blob: db5d6af6116dffbf5b45306aff17372c858be7fb [file] [log] [blame]
Kevin DuBois305bef12019-10-09 13:23:27 -07001/*
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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Kevin DuBois305bef12019-10-09 13:23:27 -070021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23#define LOG_NDEBUG 0
24
25#include "Scheduler/TimeKeeper.h"
Kevin DuBoise4f27a82019-11-12 11:41:41 -080026#include "Scheduler/VSyncDispatchTimerQueue.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070027#include "Scheduler/VSyncTracker.h"
28
29#include <gmock/gmock.h>
30#include <gtest/gtest.h>
31#include <thread>
32
33using namespace testing;
34using namespace std::literals;
35namespace android::scheduler {
36
37class MockVSyncTracker : public VSyncTracker {
38public:
39 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
40 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
41 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080042 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Kevin DuBois305bef12019-10-09 13:23:27 -070043 }
44
Kevin DuBois02d5ed92020-01-27 11:05:46 -080045 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070046 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080047 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080048 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080049 MOCK_METHOD0(resetModel, void());
Ady Abraham5e7371c2020-03-24 14:47:24 -070050 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070051
52 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
53 if (timePoint % mPeriod == 0) {
54 return timePoint;
55 }
56 return (timePoint - (timePoint % mPeriod) + mPeriod);
57 }
58
59protected:
60 nsecs_t const mPeriod;
61};
62
63class ControllableClock : public TimeKeeper {
64public:
65 ControllableClock() {
66 ON_CALL(*this, alarmIn(_, _))
67 .WillByDefault(Invoke(this, &ControllableClock::alarmInDefaultBehavior));
68 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
69 }
70
71 MOCK_CONST_METHOD0(now, nsecs_t());
72 MOCK_METHOD2(alarmIn, void(std::function<void()> const&, nsecs_t time));
73 MOCK_METHOD0(alarmCancel, void());
Ady Abraham75398722020-04-07 14:08:45 -070074 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070075
76 void alarmInDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
77 mCallback = callback;
78 mNextCallbackTime = time + mCurrentTime;
79 }
80
81 nsecs_t fakeTime() const { return mCurrentTime; }
82
83 void advanceToNextCallback() {
84 mCurrentTime = mNextCallbackTime;
85 if (mCallback) {
86 mCallback();
87 }
88 }
89
90 void advanceBy(nsecs_t advancement) {
91 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070092 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070093 mCallback();
94 }
95 };
96
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070097 void setLag(nsecs_t lag) { mLag = lag; }
98
Kevin DuBois305bef12019-10-09 13:23:27 -070099private:
100 std::function<void()> mCallback;
101 nsecs_t mNextCallbackTime = 0;
102 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700103 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700104};
105
106class CountingCallback {
107public:
108 CountingCallback(VSyncDispatch& dispatch)
109 : mDispatch(dispatch),
110 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800111 std::placeholders::_1,
112 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700113 "test")) {}
114 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
115
116 operator VSyncDispatch::CallbackToken() const { return mToken; }
117
Kevin DuBoisacfe5542020-07-16 10:21:36 -0700118 void counter(nsecs_t time, nsecs_t wakeup_time) {
119 mCalls.push_back(time);
120 mWakeupTime.push_back(wakeup_time);
121 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700122
123 VSyncDispatch& mDispatch;
124 VSyncDispatch::CallbackToken mToken;
125 std::vector<nsecs_t> mCalls;
Kevin DuBoisacfe5542020-07-16 10:21:36 -0700126 std::vector<nsecs_t> mWakeupTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700127};
128
129class PausingCallback {
130public:
131 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
132 : mDispatch(dispatch),
133 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800134 std::placeholders::_1,
135 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700136 "test")),
137 mRegistered(true),
138 mPauseAmount(pauseAmount) {}
139 ~PausingCallback() { unregister(); }
140
141 operator VSyncDispatch::CallbackToken() const { return mToken; }
142
Kevin DuBois2968afc2020-01-14 09:48:50 -0800143 void pause(nsecs_t, nsecs_t) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700144 std::unique_lock<std::mutex> lk(mMutex);
145 mPause = true;
146 mCv.notify_all();
147
148 mCv.wait_for(lk, mPauseAmount, [this] { return !mPause; });
149
150 mResourcePresent = (mResource.lock() != nullptr);
151 }
152
153 bool waitForPause() {
154 std::unique_lock<std::mutex> lk(mMutex);
155 auto waiting = mCv.wait_for(lk, 10s, [this] { return mPause; });
156 return waiting;
157 }
158
159 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
160
161 bool resourcePresent() { return mResourcePresent; }
162
163 void unpause() {
164 std::unique_lock<std::mutex> lk(mMutex);
165 mPause = false;
166 mCv.notify_all();
167 }
168
169 void unregister() {
170 if (mRegistered) {
171 mDispatch.unregisterCallback(mToken);
172 mRegistered = false;
173 }
174 }
175
176 VSyncDispatch& mDispatch;
177 VSyncDispatch::CallbackToken mToken;
178 bool mRegistered = true;
179
180 std::mutex mMutex;
181 std::condition_variable mCv;
182 bool mPause = false;
183 std::weak_ptr<void> mResource;
184 bool mResourcePresent = false;
185 std::chrono::milliseconds const mPauseAmount;
186};
187
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800188class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700189protected:
190 std::unique_ptr<TimeKeeper> createTimeKeeper() {
191 class TimeKeeperWrapper : public TimeKeeper {
192 public:
193 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
194 void alarmIn(std::function<void()> const& callback, nsecs_t time) final {
195 mControllableClock.alarmIn(callback, time);
196 }
197 void alarmCancel() final { mControllableClock.alarmCancel(); }
198 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700199 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700200
201 private:
202 TimeKeeper& mControllableClock;
203 };
204 return std::make_unique<TimeKeeperWrapper>(mMockClock);
205 }
206
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800207 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700208 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
209 Mock::VerifyAndClearExpectations(&mMockClock);
210 }
211
212 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
213
214 NiceMock<ControllableClock> mMockClock;
215 static nsecs_t constexpr mDispatchGroupThreshold = 5;
216 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800217 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700218 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800219 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
220 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700221};
222
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800223TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700224 EXPECT_CALL(mMockClock, alarmIn(_, 900));
225 EXPECT_CALL(mMockClock, alarmCancel());
226 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800227 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
228 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700229 CountingCallback cb(mDispatch);
230 EXPECT_EQ(mDispatch.schedule(cb, 100, 1000), ScheduleResult::Scheduled);
231 }
232}
233
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800234TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700235 auto intended = mPeriod - 230;
236 EXPECT_CALL(mMockClock, alarmIn(_, 900));
237
238 CountingCallback cb(mDispatch);
239 EXPECT_EQ(mDispatch.schedule(cb, 100, intended), ScheduleResult::Scheduled);
240 advanceToNextCallback();
241
242 ASSERT_THAT(cb.mCalls.size(), Eq(1));
243 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
244}
245
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800246TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700247 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
248 EXPECT_CALL(mMockClock, alarmIn(_, 1050));
249
250 CountingCallback cb(mDispatch);
251 mDispatch.schedule(cb, 100, mPeriod);
252 advanceToNextCallback();
253
254 ASSERT_THAT(cb.mCalls.size(), Eq(1));
255 EXPECT_THAT(cb.mCalls[0], Eq(1150));
256}
257
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800258TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700259 auto const now = 234;
260 mMockClock.advanceBy(234);
261 auto const workDuration = 10 * mPeriod;
262 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
263 .WillOnce(Return(mPeriod * 11));
264 EXPECT_CALL(mMockClock, alarmIn(_, mPeriod - now));
265
266 CountingCallback cb(mDispatch);
267 EXPECT_EQ(mDispatch.schedule(cb, workDuration, mPeriod), ScheduleResult::Scheduled);
268}
269
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800270TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700271 EXPECT_CALL(mMockClock, alarmIn(_, 900));
272 EXPECT_CALL(mMockClock, alarmCancel());
273
274 CountingCallback cb(mDispatch);
275 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
276 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
277}
278
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800279TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700280 EXPECT_CALL(mMockClock, alarmIn(_, 900));
281 EXPECT_CALL(mMockClock, alarmCancel());
282
283 CountingCallback cb(mDispatch);
284 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
285 mMockClock.advanceBy(950);
286 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
287}
288
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800289TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700290 EXPECT_CALL(mMockClock, alarmIn(_, 900));
291 EXPECT_CALL(mMockClock, alarmCancel());
292
293 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
294 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
295
296 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
297 EXPECT_TRUE(cb.waitForPause());
298 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
299 cb.unpause();
300 pausingThread.join();
301}
302
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800303TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700304 EXPECT_CALL(mMockClock, alarmIn(_, 900));
305 EXPECT_CALL(mMockClock, alarmCancel());
306
307 auto resource = std::make_shared<int>(110);
308
309 PausingCallback cb(mDispatch, 50ms);
310 cb.stashResource(resource);
311 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
312
313 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
314 EXPECT_TRUE(cb.waitForPause());
315
316 cb.unregister();
317 resource.reset();
318
319 cb.unpause();
320 pausingThread.join();
321
322 EXPECT_TRUE(cb.resourcePresent());
323}
324
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800325TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700326 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
327 .Times(4)
328 .WillOnce(Return(1055))
329 .WillOnce(Return(1063))
330 .WillOnce(Return(1063))
331 .WillOnce(Return(1075));
332
333 Sequence seq;
334 EXPECT_CALL(mMockClock, alarmIn(_, 955)).InSequence(seq);
335 EXPECT_CALL(mMockClock, alarmIn(_, 813)).InSequence(seq);
336 EXPECT_CALL(mMockClock, alarmIn(_, 162)).InSequence(seq);
337
338 CountingCallback cb0(mDispatch);
339 CountingCallback cb1(mDispatch);
340
341 mDispatch.schedule(cb0, 100, mPeriod);
342 mDispatch.schedule(cb1, 250, mPeriod);
343
344 advanceToNextCallback();
345 advanceToNextCallback();
346
347 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
348 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
349 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
350 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
351}
352
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800353TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700354 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
355 .Times(4)
356 .WillOnce(Return(10000))
357 .WillOnce(Return(1000))
358 .WillOnce(Return(10000))
359 .WillOnce(Return(10000));
360
361 Sequence seq;
362 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
363 EXPECT_CALL(mMockClock, alarmIn(_, 750)).InSequence(seq);
364 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
365
366 CountingCallback cb0(mDispatch);
367 CountingCallback cb1(mDispatch);
368
369 mDispatch.schedule(cb0, 100, mPeriod * 10);
370 mDispatch.schedule(cb1, 250, mPeriod);
371 mDispatch.cancel(cb1);
372}
373
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800374TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700375 Sequence seq;
376 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
377 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
378
379 CountingCallback cb0(mDispatch);
380 CountingCallback cb1(mDispatch);
381
382 mDispatch.schedule(cb0, 400, 1000);
383 mDispatch.schedule(cb1, 200, 1000);
384 mDispatch.schedule(cb1, 300, 1000);
385 advanceToNextCallback();
386}
387
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800388TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700389 Sequence seq;
390 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
391 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
392 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
393
394 CountingCallback cb0(mDispatch);
395 CountingCallback cb1(mDispatch);
396
397 mDispatch.schedule(cb0, 400, 1000);
398 mDispatch.schedule(cb1, 200, 1000);
399 mDispatch.schedule(cb1, 500, 1000);
400 advanceToNextCallback();
401}
402
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800403TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700404 Sequence seq;
405 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
406 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
407 EXPECT_CALL(mMockClock, alarmIn(_, 990)).InSequence(seq);
408 EXPECT_CALL(mMockClock, alarmIn(_, 10)).InSequence(seq);
409
410 auto offset = 400;
411 auto closeOffset = offset + mDispatchGroupThreshold - 1;
412 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
413
414 CountingCallback cb0(mDispatch);
415 CountingCallback cb1(mDispatch);
416
417 mDispatch.schedule(cb0, 400, 1000);
418 mDispatch.schedule(cb1, 200, 1000);
419 mDispatch.schedule(cb1, closeOffset, 1000);
420
421 advanceToNextCallback();
422 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
423 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
424 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
425 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
426
427 mDispatch.schedule(cb0, 400, 2000);
428 mDispatch.schedule(cb1, notCloseOffset, 2000);
429 advanceToNextCallback();
430 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
431 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
432
433 advanceToNextCallback();
434 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
435 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
436}
437
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800438TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700439 EXPECT_CALL(mMockClock, alarmIn(_, 900));
440 EXPECT_CALL(mMockClock, alarmIn(_, 800));
441 EXPECT_CALL(mMockClock, alarmIn(_, 100));
442 EXPECT_CALL(mMockClock, alarmCancel());
443
444 CountingCallback cb0(mDispatch);
445 CountingCallback cb1(mDispatch);
446
447 mDispatch.schedule(cb0, 100, 1000);
448 mDispatch.schedule(cb1, 200, 1000);
449 advanceToNextCallback();
450 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
451}
452
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800453TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700454 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
455 .Times(3)
456 .WillOnce(Return(950))
457 .WillOnce(Return(1975))
458 .WillOnce(Return(2950));
459
460 CountingCallback cb(mDispatch);
461 mDispatch.schedule(cb, 100, 920);
462
463 mMockClock.advanceBy(850);
464 EXPECT_THAT(cb.mCalls.size(), Eq(1));
465
466 mDispatch.schedule(cb, 100, 1900);
467 mMockClock.advanceBy(900);
468 EXPECT_THAT(cb.mCalls.size(), Eq(1));
469 mMockClock.advanceBy(125);
470 EXPECT_THAT(cb.mCalls.size(), Eq(2));
471
472 mDispatch.schedule(cb, 100, 2900);
473 mMockClock.advanceBy(975);
474 EXPECT_THAT(cb.mCalls.size(), Eq(3));
475}
476
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800477TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700478 Sequence seq;
479 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
480 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
481
482 VSyncDispatch::CallbackToken tmp;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800483 tmp = mDispatch.registerCallback([&](auto, auto) { mDispatch.schedule(tmp, 100, 2000); },
484 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700485
486 mDispatch.schedule(tmp, 100, 1000);
487 advanceToNextCallback();
488}
489
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800490TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700491 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800492 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700493 tmp = mDispatch.registerCallback(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800494 [&](auto timestamp, auto) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800495 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp - mVsyncMoveThreshold),
496 ScheduleResult::Scheduled);
497 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp), ScheduleResult::Scheduled);
498 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp + mVsyncMoveThreshold),
499 ScheduleResult::Scheduled);
500 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700501 },
502 "oo");
503
504 mDispatch.schedule(tmp, 999, 1000);
505 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800506 EXPECT_THAT(lastTarget, Eq(1000));
507
508 advanceToNextCallback();
509 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700510}
511
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800512TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700513 Sequence seq;
514 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
515 EXPECT_CALL(mMockClock, alarmIn(_, 200)).InSequence(seq);
516 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
517 EXPECT_CALL(mMockClock, alarmIn(_, 150)).InSequence(seq);
518
519 CountingCallback cb(mDispatch);
520 mDispatch.schedule(cb, 0, 1000);
521
522 mMockClock.advanceBy(750);
523 mDispatch.schedule(cb, 50, 1000);
524
525 advanceToNextCallback();
526 mDispatch.schedule(cb, 50, 2000);
527
528 mMockClock.advanceBy(800);
529 mDispatch.schedule(cb, 100, 2000);
530}
531
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800532TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700533 Sequence seq;
534 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
535 EXPECT_CALL(mMockClock, alarmIn(_, 400)).InSequence(seq);
536 EXPECT_CALL(mMockClock, alarmIn(_, 350)).InSequence(seq);
537 EXPECT_CALL(mMockClock, alarmIn(_, 950)).InSequence(seq);
538
539 CountingCallback cb0(mDispatch);
540 CountingCallback cb1(mDispatch);
541
542 mDispatch.schedule(cb0, 500, 1000);
543 mDispatch.schedule(cb1, 100, 1000);
544
545 advanceToNextCallback();
546 mDispatch.schedule(cb0, 200, 2000);
547 mDispatch.schedule(cb1, 150, 1000);
548
549 advanceToNextCallback();
550 advanceToNextCallback();
551}
552
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800553TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700554 Sequence seq;
555 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
556
557 CountingCallback cb0(mDispatch);
558 CountingCallback cb1(mDispatch);
559 mDispatch.schedule(cb0, 500, 1000);
560 mDispatch.schedule(cb1, 500, 20000);
561}
562
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800563TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700564 Sequence seq;
565 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
566 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
567 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
568
569 CountingCallback cb0(mDispatch);
570 mDispatch.schedule(cb0, 500, 1000);
571 mDispatch.cancel(cb0);
572 mDispatch.schedule(cb0, 100, 1000);
573}
574
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800575TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700576 VSyncDispatch::CallbackToken token(100);
577 EXPECT_THAT(mDispatch.schedule(token, 100, 1000), Eq(ScheduleResult::Error));
578 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
579}
580
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800581TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700582 CountingCallback cb0(mDispatch);
583 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800584 EXPECT_EQ(mDispatch.schedule(cb0, 100, 1000), ScheduleResult::Scheduled);
585}
586
587// b/1450138150
588TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
589 EXPECT_CALL(mMockClock, alarmIn(_, 500));
590 CountingCallback cb(mDispatch);
591 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
592 mMockClock.advanceBy(400);
593
594 EXPECT_EQ(mDispatch.schedule(cb, 800, 1000), ScheduleResult::Scheduled);
595 advanceToNextCallback();
596 ASSERT_THAT(cb.mCalls.size(), Eq(1));
597}
598
599TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
600 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
601 .Times(2)
602 .WillOnce(Return(1000))
603 .WillOnce(Return(1002));
604 CountingCallback cb(mDispatch);
605 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
606 mMockClock.advanceBy(400);
607 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700608}
609
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800610TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
611 CountingCallback cb0(mDispatch);
612 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
613 advanceToNextCallback();
614 EXPECT_EQ(mDispatch.schedule(cb0, 1100, 2000), ScheduleResult::Scheduled);
615}
616
617TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
618 Sequence seq;
619 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
620 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
621 CountingCallback cb0(mDispatch);
622 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
623 advanceToNextCallback();
624 EXPECT_EQ(mDispatch.schedule(cb0, 1900, 2000), ScheduleResult::Scheduled);
625}
626
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800627TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800628 EXPECT_CALL(mMockClock, alarmIn(_, 600));
629
630 CountingCallback cb(mDispatch);
631 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800632
633 EXPECT_EQ(mDispatch.schedule(cb, 1400, 1000), ScheduleResult::Scheduled);
634
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800635 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800636}
637
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800638TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700639 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
640 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
641
642 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800643 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700644 VSyncCallbackRegistration cb1(std::move(cb));
645 cb.schedule(100, 1000);
646 cb.cancel();
647
648 cb1.schedule(500, 1000);
649 cb1.cancel();
650}
651
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800652TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700653 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
654 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
655
656 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800657 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700658 VSyncCallbackRegistration cb1(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800659 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700660 cb1 = std::move(cb);
661 cb.schedule(100, 1000);
662 cb.cancel();
663
664 cb1.schedule(500, 1000);
665 cb1.cancel();
666}
667
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700668// b/154303580
669TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
670 Sequence seq;
671 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
672 EXPECT_CALL(mMockClock, alarmIn(_, 1200)).InSequence(seq);
673 CountingCallback cb1(mDispatch);
674 CountingCallback cb2(mDispatch);
675
676 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
677
678 mMockClock.setLag(100);
679 mMockClock.advanceBy(620);
680
681 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
682 mMockClock.advanceBy(80);
683
684 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
685 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
686}
687
688// b/154303580.
689// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
690// update later, as opposed to blocking the calling thread.
691TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
692 Sequence seq;
693 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
694 EXPECT_CALL(mMockClock, alarmIn(_, 930)).InSequence(seq);
695 CountingCallback cb(mDispatch);
696
697 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
698
699 mMockClock.setLag(100);
700 mMockClock.advanceBy(620);
701
702 EXPECT_EQ(mDispatch.schedule(cb, 370, 2000), ScheduleResult::Scheduled);
703 mMockClock.advanceBy(80);
704
705 EXPECT_THAT(cb.mCalls.size(), Eq(1));
706}
707
Kevin DuBoisb340b732020-06-16 09:07:35 -0700708// b/154303580.
709TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
710 Sequence seq;
711 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
712 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
713 CountingCallback cb1(mDispatch);
714 CountingCallback cb2(mDispatch);
715
716 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
717 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
718
719 mMockClock.setLag(100);
720 mMockClock.advanceBy(620);
721
722 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
723
724 mMockClock.advanceBy(80);
725
726 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
727 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
728}
729
730TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
731 Sequence seq;
732 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
733 EXPECT_CALL(mMockClock, alarmIn(_, 1280)).InSequence(seq);
734 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
735 CountingCallback cb1(mDispatch);
736 CountingCallback cb2(mDispatch);
737
738 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
739 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
740
741 mMockClock.setLag(100);
742 mMockClock.advanceBy(620);
743
744 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
745
746 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
747 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
748 mMockClock.advanceToNextCallback();
749
750 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
751 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
752}
753
Kevin DuBoisacfe5542020-07-16 10:21:36 -0700754TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
755 CountingCallback cb1(mDispatch);
756 CountingCallback cb2(mDispatch);
757
758 Sequence seq;
759 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
760 .InSequence(seq)
761 .WillOnce(Return(1000));
762 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
763 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
764 .InSequence(seq)
765 .WillOnce(Return(1000));
766
767 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
768 EXPECT_EQ(mDispatch.schedule(cb2, 390, 1000), ScheduleResult::Scheduled);
769
770 mMockClock.setLag(100);
771 mMockClock.advanceBy(700);
772
773 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
774 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
775 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
776 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
777}
778
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800779class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700780protected:
781 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800782 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700783 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
784};
785
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800786TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700787 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800788 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800789 name, [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700790 EXPECT_THAT(entry.name(), Eq(name));
791 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
792 EXPECT_FALSE(entry.wakeupTime());
793}
794
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800795TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800796 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800797 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700798
799 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800800 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
801 auto const wakeup = entry.wakeupTime();
802 ASSERT_TRUE(wakeup);
803 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700804
805 entry.disarm();
806 EXPECT_FALSE(entry.wakeupTime());
807}
808
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800809TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700810 auto const duration = 500;
811 auto const now = 8750;
812
813 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
814 .Times(1)
815 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800816 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800817 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700818
819 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800820 EXPECT_THAT(entry.schedule(500, 994, mStubTracker, now), Eq(ScheduleResult::Scheduled));
821 auto const wakeup = entry.wakeupTime();
822 ASSERT_TRUE(wakeup);
823 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700824}
825
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800826TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700827 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800828 auto vsyncCalledTime = 0;
829 auto wakeupCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800830 VSyncDispatchTimerQueueEntry entry(
831 "test",
Kevin DuBois2968afc2020-01-14 09:48:50 -0800832 [&](auto vsyncTime, auto wakeupTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800833 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800834 vsyncCalledTime = vsyncTime;
835 wakeupCalledTime = wakeupTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800836 },
837 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700838
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800839 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
840 auto const wakeup = entry.wakeupTime();
841 ASSERT_TRUE(wakeup);
842 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700843
Kevin DuBois2968afc2020-01-14 09:48:50 -0800844 entry.callback(entry.executing(), *wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700845
846 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800847 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
848 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700849 EXPECT_FALSE(entry.wakeupTime());
850 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
851 ASSERT_TRUE(lastCalledTarget);
852 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
853}
854
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800855TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700856 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
857 .Times(2)
858 .WillOnce(Return(1000))
859 .WillOnce(Return(1020));
860
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800861 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800862 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700863
864 EXPECT_FALSE(entry.wakeupTime());
865 entry.update(mStubTracker, 0);
866 EXPECT_FALSE(entry.wakeupTime());
867
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800868 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
869 auto wakeup = entry.wakeupTime();
870 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700871 EXPECT_THAT(wakeup, Eq(900));
872
873 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800874 wakeup = entry.wakeupTime();
875 ASSERT_TRUE(wakeup);
876 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -0700877}
878
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800879TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800880 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800881 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800882 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700883 entry.update(mStubTracker, 0);
884
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800885 auto const wakeup = entry.wakeupTime();
886 ASSERT_TRUE(wakeup);
887 EXPECT_THAT(*wakeup, Eq(wakeup));
888}
889
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800890TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
891 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800892 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800893 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800894 entry.executing(); // 1000 is executing
895 // had 1000 not been executing, this could have been scheduled for time 800.
896 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
897 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
898
899 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
900 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
901
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800902 EXPECT_THAT(entry.schedule(200, 1001, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800903 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800904}
905
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800906TEST_F(VSyncDispatchTimerQueueEntryTest,
907 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
908 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800909 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800910
911 Sequence seq;
912 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
913 .InSequence(seq)
914 .WillOnce(Return(1000));
915 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
916 .InSequence(seq)
917 .WillOnce(Return(1000));
918 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
919 .InSequence(seq)
920 .WillOnce(Return(2000));
921
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800922 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800923
924 entry.executing(); // 1000 is executing
925
926 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
927}
928
929TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
930 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800931 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800932 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
933 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
934 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
935 EXPECT_THAT(entry.schedule(1200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700936}
937
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700938TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
939 static constexpr auto effectualOffset = 200;
940 VSyncDispatchTimerQueueEntry entry(
941 "test", [](auto, auto) {}, mVsyncMoveThreshold);
942 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
943 entry.addPendingWorkloadUpdate(100, 400);
944 entry.addPendingWorkloadUpdate(effectualOffset, 700);
945 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
946 entry.update(mStubTracker, 0);
947 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
948 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
949}
950
Kevin DuBois305bef12019-10-09 13:23:27 -0700951} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800952
953// TODO(b/129481165): remove the #pragma below and fix conversion issues
954#pragma clang diagnostic pop // ignored "-Wconversion"