blob: d940dc58707e18a75ba1257aa3a218a4724ae60f [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 DuBois2968afc2020-01-14 09:48:50 -0800118 void counter(nsecs_t time, nsecs_t) { mCalls.push_back(time); }
Kevin DuBois305bef12019-10-09 13:23:27 -0700119
120 VSyncDispatch& mDispatch;
121 VSyncDispatch::CallbackToken mToken;
122 std::vector<nsecs_t> mCalls;
123};
124
125class PausingCallback {
126public:
127 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
128 : mDispatch(dispatch),
129 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800130 std::placeholders::_1,
131 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700132 "test")),
133 mRegistered(true),
134 mPauseAmount(pauseAmount) {}
135 ~PausingCallback() { unregister(); }
136
137 operator VSyncDispatch::CallbackToken() const { return mToken; }
138
Kevin DuBois2968afc2020-01-14 09:48:50 -0800139 void pause(nsecs_t, nsecs_t) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700140 std::unique_lock<std::mutex> lk(mMutex);
141 mPause = true;
142 mCv.notify_all();
143
144 mCv.wait_for(lk, mPauseAmount, [this] { return !mPause; });
145
146 mResourcePresent = (mResource.lock() != nullptr);
147 }
148
149 bool waitForPause() {
150 std::unique_lock<std::mutex> lk(mMutex);
151 auto waiting = mCv.wait_for(lk, 10s, [this] { return mPause; });
152 return waiting;
153 }
154
155 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
156
157 bool resourcePresent() { return mResourcePresent; }
158
159 void unpause() {
160 std::unique_lock<std::mutex> lk(mMutex);
161 mPause = false;
162 mCv.notify_all();
163 }
164
165 void unregister() {
166 if (mRegistered) {
167 mDispatch.unregisterCallback(mToken);
168 mRegistered = false;
169 }
170 }
171
172 VSyncDispatch& mDispatch;
173 VSyncDispatch::CallbackToken mToken;
174 bool mRegistered = true;
175
176 std::mutex mMutex;
177 std::condition_variable mCv;
178 bool mPause = false;
179 std::weak_ptr<void> mResource;
180 bool mResourcePresent = false;
181 std::chrono::milliseconds const mPauseAmount;
182};
183
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800184class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700185protected:
186 std::unique_ptr<TimeKeeper> createTimeKeeper() {
187 class TimeKeeperWrapper : public TimeKeeper {
188 public:
189 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
190 void alarmIn(std::function<void()> const& callback, nsecs_t time) final {
191 mControllableClock.alarmIn(callback, time);
192 }
193 void alarmCancel() final { mControllableClock.alarmCancel(); }
194 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700195 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700196
197 private:
198 TimeKeeper& mControllableClock;
199 };
200 return std::make_unique<TimeKeeperWrapper>(mMockClock);
201 }
202
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800203 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700204 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
205 Mock::VerifyAndClearExpectations(&mMockClock);
206 }
207
208 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
209
210 NiceMock<ControllableClock> mMockClock;
211 static nsecs_t constexpr mDispatchGroupThreshold = 5;
212 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800213 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700214 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800215 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
216 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700217};
218
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800219TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700220 EXPECT_CALL(mMockClock, alarmIn(_, 900));
221 EXPECT_CALL(mMockClock, alarmCancel());
222 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800223 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
224 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700225 CountingCallback cb(mDispatch);
226 EXPECT_EQ(mDispatch.schedule(cb, 100, 1000), ScheduleResult::Scheduled);
227 }
228}
229
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800230TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700231 auto intended = mPeriod - 230;
232 EXPECT_CALL(mMockClock, alarmIn(_, 900));
233
234 CountingCallback cb(mDispatch);
235 EXPECT_EQ(mDispatch.schedule(cb, 100, intended), ScheduleResult::Scheduled);
236 advanceToNextCallback();
237
238 ASSERT_THAT(cb.mCalls.size(), Eq(1));
239 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
240}
241
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800242TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700243 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
244 EXPECT_CALL(mMockClock, alarmIn(_, 1050));
245
246 CountingCallback cb(mDispatch);
247 mDispatch.schedule(cb, 100, mPeriod);
248 advanceToNextCallback();
249
250 ASSERT_THAT(cb.mCalls.size(), Eq(1));
251 EXPECT_THAT(cb.mCalls[0], Eq(1150));
252}
253
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800254TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700255 auto const now = 234;
256 mMockClock.advanceBy(234);
257 auto const workDuration = 10 * mPeriod;
258 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
259 .WillOnce(Return(mPeriod * 11));
260 EXPECT_CALL(mMockClock, alarmIn(_, mPeriod - now));
261
262 CountingCallback cb(mDispatch);
263 EXPECT_EQ(mDispatch.schedule(cb, workDuration, mPeriod), ScheduleResult::Scheduled);
264}
265
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800266TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700267 EXPECT_CALL(mMockClock, alarmIn(_, 900));
268 EXPECT_CALL(mMockClock, alarmCancel());
269
270 CountingCallback cb(mDispatch);
271 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
272 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
273}
274
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800275TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700276 EXPECT_CALL(mMockClock, alarmIn(_, 900));
277 EXPECT_CALL(mMockClock, alarmCancel());
278
279 CountingCallback cb(mDispatch);
280 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
281 mMockClock.advanceBy(950);
282 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
283}
284
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800285TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700286 EXPECT_CALL(mMockClock, alarmIn(_, 900));
287 EXPECT_CALL(mMockClock, alarmCancel());
288
289 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
290 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
291
292 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
293 EXPECT_TRUE(cb.waitForPause());
294 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
295 cb.unpause();
296 pausingThread.join();
297}
298
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800299TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700300 EXPECT_CALL(mMockClock, alarmIn(_, 900));
301 EXPECT_CALL(mMockClock, alarmCancel());
302
303 auto resource = std::make_shared<int>(110);
304
305 PausingCallback cb(mDispatch, 50ms);
306 cb.stashResource(resource);
307 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
308
309 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
310 EXPECT_TRUE(cb.waitForPause());
311
312 cb.unregister();
313 resource.reset();
314
315 cb.unpause();
316 pausingThread.join();
317
318 EXPECT_TRUE(cb.resourcePresent());
319}
320
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800321TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700322 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
323 .Times(4)
324 .WillOnce(Return(1055))
325 .WillOnce(Return(1063))
326 .WillOnce(Return(1063))
327 .WillOnce(Return(1075));
328
329 Sequence seq;
330 EXPECT_CALL(mMockClock, alarmIn(_, 955)).InSequence(seq);
331 EXPECT_CALL(mMockClock, alarmIn(_, 813)).InSequence(seq);
332 EXPECT_CALL(mMockClock, alarmIn(_, 162)).InSequence(seq);
333
334 CountingCallback cb0(mDispatch);
335 CountingCallback cb1(mDispatch);
336
337 mDispatch.schedule(cb0, 100, mPeriod);
338 mDispatch.schedule(cb1, 250, mPeriod);
339
340 advanceToNextCallback();
341 advanceToNextCallback();
342
343 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
344 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
345 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
346 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
347}
348
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800349TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700350 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
351 .Times(4)
352 .WillOnce(Return(10000))
353 .WillOnce(Return(1000))
354 .WillOnce(Return(10000))
355 .WillOnce(Return(10000));
356
357 Sequence seq;
358 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
359 EXPECT_CALL(mMockClock, alarmIn(_, 750)).InSequence(seq);
360 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
361
362 CountingCallback cb0(mDispatch);
363 CountingCallback cb1(mDispatch);
364
365 mDispatch.schedule(cb0, 100, mPeriod * 10);
366 mDispatch.schedule(cb1, 250, mPeriod);
367 mDispatch.cancel(cb1);
368}
369
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800370TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700371 Sequence seq;
372 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
373 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
374
375 CountingCallback cb0(mDispatch);
376 CountingCallback cb1(mDispatch);
377
378 mDispatch.schedule(cb0, 400, 1000);
379 mDispatch.schedule(cb1, 200, 1000);
380 mDispatch.schedule(cb1, 300, 1000);
381 advanceToNextCallback();
382}
383
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800384TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700385 Sequence seq;
386 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
387 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
388 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
389
390 CountingCallback cb0(mDispatch);
391 CountingCallback cb1(mDispatch);
392
393 mDispatch.schedule(cb0, 400, 1000);
394 mDispatch.schedule(cb1, 200, 1000);
395 mDispatch.schedule(cb1, 500, 1000);
396 advanceToNextCallback();
397}
398
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800399TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700400 Sequence seq;
401 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
402 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
403 EXPECT_CALL(mMockClock, alarmIn(_, 990)).InSequence(seq);
404 EXPECT_CALL(mMockClock, alarmIn(_, 10)).InSequence(seq);
405
406 auto offset = 400;
407 auto closeOffset = offset + mDispatchGroupThreshold - 1;
408 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
409
410 CountingCallback cb0(mDispatch);
411 CountingCallback cb1(mDispatch);
412
413 mDispatch.schedule(cb0, 400, 1000);
414 mDispatch.schedule(cb1, 200, 1000);
415 mDispatch.schedule(cb1, closeOffset, 1000);
416
417 advanceToNextCallback();
418 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
419 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
420 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
421 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
422
423 mDispatch.schedule(cb0, 400, 2000);
424 mDispatch.schedule(cb1, notCloseOffset, 2000);
425 advanceToNextCallback();
426 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
427 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
428
429 advanceToNextCallback();
430 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
431 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
432}
433
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800434TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700435 EXPECT_CALL(mMockClock, alarmIn(_, 900));
436 EXPECT_CALL(mMockClock, alarmIn(_, 800));
437 EXPECT_CALL(mMockClock, alarmIn(_, 100));
438 EXPECT_CALL(mMockClock, alarmCancel());
439
440 CountingCallback cb0(mDispatch);
441 CountingCallback cb1(mDispatch);
442
443 mDispatch.schedule(cb0, 100, 1000);
444 mDispatch.schedule(cb1, 200, 1000);
445 advanceToNextCallback();
446 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
447}
448
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800449TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700450 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
451 .Times(3)
452 .WillOnce(Return(950))
453 .WillOnce(Return(1975))
454 .WillOnce(Return(2950));
455
456 CountingCallback cb(mDispatch);
457 mDispatch.schedule(cb, 100, 920);
458
459 mMockClock.advanceBy(850);
460 EXPECT_THAT(cb.mCalls.size(), Eq(1));
461
462 mDispatch.schedule(cb, 100, 1900);
463 mMockClock.advanceBy(900);
464 EXPECT_THAT(cb.mCalls.size(), Eq(1));
465 mMockClock.advanceBy(125);
466 EXPECT_THAT(cb.mCalls.size(), Eq(2));
467
468 mDispatch.schedule(cb, 100, 2900);
469 mMockClock.advanceBy(975);
470 EXPECT_THAT(cb.mCalls.size(), Eq(3));
471}
472
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800473TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700474 Sequence seq;
475 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
476 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
477
478 VSyncDispatch::CallbackToken tmp;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800479 tmp = mDispatch.registerCallback([&](auto, auto) { mDispatch.schedule(tmp, 100, 2000); },
480 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700481
482 mDispatch.schedule(tmp, 100, 1000);
483 advanceToNextCallback();
484}
485
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800486TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700487 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800488 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700489 tmp = mDispatch.registerCallback(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800490 [&](auto timestamp, auto) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800491 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp - mVsyncMoveThreshold),
492 ScheduleResult::Scheduled);
493 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp), ScheduleResult::Scheduled);
494 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp + mVsyncMoveThreshold),
495 ScheduleResult::Scheduled);
496 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700497 },
498 "oo");
499
500 mDispatch.schedule(tmp, 999, 1000);
501 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800502 EXPECT_THAT(lastTarget, Eq(1000));
503
504 advanceToNextCallback();
505 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700506}
507
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800508TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700509 Sequence seq;
510 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
511 EXPECT_CALL(mMockClock, alarmIn(_, 200)).InSequence(seq);
512 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
513 EXPECT_CALL(mMockClock, alarmIn(_, 150)).InSequence(seq);
514
515 CountingCallback cb(mDispatch);
516 mDispatch.schedule(cb, 0, 1000);
517
518 mMockClock.advanceBy(750);
519 mDispatch.schedule(cb, 50, 1000);
520
521 advanceToNextCallback();
522 mDispatch.schedule(cb, 50, 2000);
523
524 mMockClock.advanceBy(800);
525 mDispatch.schedule(cb, 100, 2000);
526}
527
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800528TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700529 Sequence seq;
530 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
531 EXPECT_CALL(mMockClock, alarmIn(_, 400)).InSequence(seq);
532 EXPECT_CALL(mMockClock, alarmIn(_, 350)).InSequence(seq);
533 EXPECT_CALL(mMockClock, alarmIn(_, 950)).InSequence(seq);
534
535 CountingCallback cb0(mDispatch);
536 CountingCallback cb1(mDispatch);
537
538 mDispatch.schedule(cb0, 500, 1000);
539 mDispatch.schedule(cb1, 100, 1000);
540
541 advanceToNextCallback();
542 mDispatch.schedule(cb0, 200, 2000);
543 mDispatch.schedule(cb1, 150, 1000);
544
545 advanceToNextCallback();
546 advanceToNextCallback();
547}
548
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800549TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700550 Sequence seq;
551 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
552
553 CountingCallback cb0(mDispatch);
554 CountingCallback cb1(mDispatch);
555 mDispatch.schedule(cb0, 500, 1000);
556 mDispatch.schedule(cb1, 500, 20000);
557}
558
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800559TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700560 Sequence seq;
561 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
562 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
563 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
564
565 CountingCallback cb0(mDispatch);
566 mDispatch.schedule(cb0, 500, 1000);
567 mDispatch.cancel(cb0);
568 mDispatch.schedule(cb0, 100, 1000);
569}
570
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800571TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700572 VSyncDispatch::CallbackToken token(100);
573 EXPECT_THAT(mDispatch.schedule(token, 100, 1000), Eq(ScheduleResult::Error));
574 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
575}
576
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800577TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700578 CountingCallback cb0(mDispatch);
579 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800580 EXPECT_EQ(mDispatch.schedule(cb0, 100, 1000), ScheduleResult::Scheduled);
581}
582
583// b/1450138150
584TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
585 EXPECT_CALL(mMockClock, alarmIn(_, 500));
586 CountingCallback cb(mDispatch);
587 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
588 mMockClock.advanceBy(400);
589
590 EXPECT_EQ(mDispatch.schedule(cb, 800, 1000), ScheduleResult::Scheduled);
591 advanceToNextCallback();
592 ASSERT_THAT(cb.mCalls.size(), Eq(1));
593}
594
595TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
596 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
597 .Times(2)
598 .WillOnce(Return(1000))
599 .WillOnce(Return(1002));
600 CountingCallback cb(mDispatch);
601 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
602 mMockClock.advanceBy(400);
603 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700604}
605
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800606TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
607 CountingCallback cb0(mDispatch);
608 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
609 advanceToNextCallback();
610 EXPECT_EQ(mDispatch.schedule(cb0, 1100, 2000), ScheduleResult::Scheduled);
611}
612
613TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
614 Sequence seq;
615 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
616 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
617 CountingCallback cb0(mDispatch);
618 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
619 advanceToNextCallback();
620 EXPECT_EQ(mDispatch.schedule(cb0, 1900, 2000), ScheduleResult::Scheduled);
621}
622
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800623TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800624 EXPECT_CALL(mMockClock, alarmIn(_, 600));
625
626 CountingCallback cb(mDispatch);
627 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800628
629 EXPECT_EQ(mDispatch.schedule(cb, 1400, 1000), ScheduleResult::Scheduled);
630
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800631 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800632}
633
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800634TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700635 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
636 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
637
638 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800639 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700640 VSyncCallbackRegistration cb1(std::move(cb));
641 cb.schedule(100, 1000);
642 cb.cancel();
643
644 cb1.schedule(500, 1000);
645 cb1.cancel();
646}
647
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800648TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700649 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
650 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
651
652 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800653 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700654 VSyncCallbackRegistration cb1(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800655 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700656 cb1 = std::move(cb);
657 cb.schedule(100, 1000);
658 cb.cancel();
659
660 cb1.schedule(500, 1000);
661 cb1.cancel();
662}
663
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700664// b/154303580
665TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
666 Sequence seq;
667 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
668 EXPECT_CALL(mMockClock, alarmIn(_, 1200)).InSequence(seq);
669 CountingCallback cb1(mDispatch);
670 CountingCallback cb2(mDispatch);
671
672 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
673
674 mMockClock.setLag(100);
675 mMockClock.advanceBy(620);
676
677 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
678 mMockClock.advanceBy(80);
679
680 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
681 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
682}
683
684// b/154303580.
685// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
686// update later, as opposed to blocking the calling thread.
687TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
688 Sequence seq;
689 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
690 EXPECT_CALL(mMockClock, alarmIn(_, 930)).InSequence(seq);
691 CountingCallback cb(mDispatch);
692
693 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
694
695 mMockClock.setLag(100);
696 mMockClock.advanceBy(620);
697
698 EXPECT_EQ(mDispatch.schedule(cb, 370, 2000), ScheduleResult::Scheduled);
699 mMockClock.advanceBy(80);
700
701 EXPECT_THAT(cb.mCalls.size(), Eq(1));
702}
703
Kevin DuBoisb340b732020-06-16 09:07:35 -0700704// b/154303580.
705TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
706 Sequence seq;
707 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
708 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
709 CountingCallback cb1(mDispatch);
710 CountingCallback cb2(mDispatch);
711
712 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
713 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
714
715 mMockClock.setLag(100);
716 mMockClock.advanceBy(620);
717
718 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
719
720 mMockClock.advanceBy(80);
721
722 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
723 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
724}
725
726TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
727 Sequence seq;
728 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
729 EXPECT_CALL(mMockClock, alarmIn(_, 1280)).InSequence(seq);
730 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
731 CountingCallback cb1(mDispatch);
732 CountingCallback cb2(mDispatch);
733
734 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
735 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
736
737 mMockClock.setLag(100);
738 mMockClock.advanceBy(620);
739
740 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
741
742 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
743 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
744 mMockClock.advanceToNextCallback();
745
746 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
747 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
748}
749
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800750class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700751protected:
752 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800753 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700754 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
755};
756
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800757TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700758 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800759 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800760 name, [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700761 EXPECT_THAT(entry.name(), Eq(name));
762 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
763 EXPECT_FALSE(entry.wakeupTime());
764}
765
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800766TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800767 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800768 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700769
770 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800771 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
772 auto const wakeup = entry.wakeupTime();
773 ASSERT_TRUE(wakeup);
774 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700775
776 entry.disarm();
777 EXPECT_FALSE(entry.wakeupTime());
778}
779
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800780TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700781 auto const duration = 500;
782 auto const now = 8750;
783
784 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
785 .Times(1)
786 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800787 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800788 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700789
790 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800791 EXPECT_THAT(entry.schedule(500, 994, mStubTracker, now), Eq(ScheduleResult::Scheduled));
792 auto const wakeup = entry.wakeupTime();
793 ASSERT_TRUE(wakeup);
794 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700795}
796
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800797TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700798 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800799 auto vsyncCalledTime = 0;
800 auto wakeupCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800801 VSyncDispatchTimerQueueEntry entry(
802 "test",
Kevin DuBois2968afc2020-01-14 09:48:50 -0800803 [&](auto vsyncTime, auto wakeupTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800804 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800805 vsyncCalledTime = vsyncTime;
806 wakeupCalledTime = wakeupTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800807 },
808 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700809
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800810 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
811 auto const wakeup = entry.wakeupTime();
812 ASSERT_TRUE(wakeup);
813 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700814
Kevin DuBois2968afc2020-01-14 09:48:50 -0800815 entry.callback(entry.executing(), *wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700816
817 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800818 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
819 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700820 EXPECT_FALSE(entry.wakeupTime());
821 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
822 ASSERT_TRUE(lastCalledTarget);
823 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
824}
825
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800826TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700827 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
828 .Times(2)
829 .WillOnce(Return(1000))
830 .WillOnce(Return(1020));
831
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800832 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800833 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700834
835 EXPECT_FALSE(entry.wakeupTime());
836 entry.update(mStubTracker, 0);
837 EXPECT_FALSE(entry.wakeupTime());
838
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800839 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
840 auto wakeup = entry.wakeupTime();
841 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700842 EXPECT_THAT(wakeup, Eq(900));
843
844 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800845 wakeup = entry.wakeupTime();
846 ASSERT_TRUE(wakeup);
847 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -0700848}
849
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800850TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800851 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800852 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800853 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700854 entry.update(mStubTracker, 0);
855
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800856 auto const wakeup = entry.wakeupTime();
857 ASSERT_TRUE(wakeup);
858 EXPECT_THAT(*wakeup, Eq(wakeup));
859}
860
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800861TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
862 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800863 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800864 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800865 entry.executing(); // 1000 is executing
866 // had 1000 not been executing, this could have been scheduled for time 800.
867 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
868 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
869
870 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
871 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
872
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800873 EXPECT_THAT(entry.schedule(200, 1001, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800874 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800875}
876
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800877TEST_F(VSyncDispatchTimerQueueEntryTest,
878 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
879 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800880 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800881
882 Sequence seq;
883 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
884 .InSequence(seq)
885 .WillOnce(Return(1000));
886 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
887 .InSequence(seq)
888 .WillOnce(Return(1000));
889 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
890 .InSequence(seq)
891 .WillOnce(Return(2000));
892
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
895 entry.executing(); // 1000 is executing
896
897 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
898}
899
900TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
901 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800902 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800903 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
904 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
905 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
906 EXPECT_THAT(entry.schedule(1200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700907}
908
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700909TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
910 static constexpr auto effectualOffset = 200;
911 VSyncDispatchTimerQueueEntry entry(
912 "test", [](auto, auto) {}, mVsyncMoveThreshold);
913 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
914 entry.addPendingWorkloadUpdate(100, 400);
915 entry.addPendingWorkloadUpdate(effectualOffset, 700);
916 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
917 entry.update(mStubTracker, 0);
918 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
919 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
920}
921
Kevin DuBois305bef12019-10-09 13:23:27 -0700922} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800923
924// TODO(b/129481165): remove the #pragma below and fix conversion issues
925#pragma clang diagnostic pop // ignored "-Wconversion"