blob: 65c391d4991eb52e64054c3bf7e551c20c548dc9 [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());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070050 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5e7371c2020-03-24 14:47:24 -070051 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070052
53 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
54 if (timePoint % mPeriod == 0) {
55 return timePoint;
56 }
57 return (timePoint - (timePoint % mPeriod) + mPeriod);
58 }
59
60protected:
61 nsecs_t const mPeriod;
62};
63
64class ControllableClock : public TimeKeeper {
65public:
66 ControllableClock() {
67 ON_CALL(*this, alarmIn(_, _))
68 .WillByDefault(Invoke(this, &ControllableClock::alarmInDefaultBehavior));
69 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
70 }
71
72 MOCK_CONST_METHOD0(now, nsecs_t());
73 MOCK_METHOD2(alarmIn, void(std::function<void()> const&, nsecs_t time));
74 MOCK_METHOD0(alarmCancel, void());
Ady Abraham75398722020-04-07 14:08:45 -070075 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070076
77 void alarmInDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
78 mCallback = callback;
79 mNextCallbackTime = time + mCurrentTime;
80 }
81
82 nsecs_t fakeTime() const { return mCurrentTime; }
83
84 void advanceToNextCallback() {
85 mCurrentTime = mNextCallbackTime;
86 if (mCallback) {
87 mCallback();
88 }
89 }
90
91 void advanceBy(nsecs_t advancement) {
92 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070093 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070094 mCallback();
95 }
96 };
97
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070098 void setLag(nsecs_t lag) { mLag = lag; }
99
Kevin DuBois305bef12019-10-09 13:23:27 -0700100private:
101 std::function<void()> mCallback;
102 nsecs_t mNextCallbackTime = 0;
103 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700104 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700105};
106
107class CountingCallback {
108public:
109 CountingCallback(VSyncDispatch& dispatch)
110 : mDispatch(dispatch),
111 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800112 std::placeholders::_1,
113 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700114 "test")) {}
115 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
116
117 operator VSyncDispatch::CallbackToken() const { return mToken; }
118
Kevin DuBois2968afc2020-01-14 09:48:50 -0800119 void counter(nsecs_t time, nsecs_t) { mCalls.push_back(time); }
Kevin DuBois305bef12019-10-09 13:23:27 -0700120
121 VSyncDispatch& mDispatch;
122 VSyncDispatch::CallbackToken mToken;
123 std::vector<nsecs_t> mCalls;
124};
125
126class PausingCallback {
127public:
128 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
129 : mDispatch(dispatch),
130 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800131 std::placeholders::_1,
132 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700133 "test")),
134 mRegistered(true),
135 mPauseAmount(pauseAmount) {}
136 ~PausingCallback() { unregister(); }
137
138 operator VSyncDispatch::CallbackToken() const { return mToken; }
139
Kevin DuBois2968afc2020-01-14 09:48:50 -0800140 void pause(nsecs_t, nsecs_t) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700141 std::unique_lock<std::mutex> lk(mMutex);
142 mPause = true;
143 mCv.notify_all();
144
145 mCv.wait_for(lk, mPauseAmount, [this] { return !mPause; });
146
147 mResourcePresent = (mResource.lock() != nullptr);
148 }
149
150 bool waitForPause() {
151 std::unique_lock<std::mutex> lk(mMutex);
152 auto waiting = mCv.wait_for(lk, 10s, [this] { return mPause; });
153 return waiting;
154 }
155
156 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
157
158 bool resourcePresent() { return mResourcePresent; }
159
160 void unpause() {
161 std::unique_lock<std::mutex> lk(mMutex);
162 mPause = false;
163 mCv.notify_all();
164 }
165
166 void unregister() {
167 if (mRegistered) {
168 mDispatch.unregisterCallback(mToken);
169 mRegistered = false;
170 }
171 }
172
173 VSyncDispatch& mDispatch;
174 VSyncDispatch::CallbackToken mToken;
175 bool mRegistered = true;
176
177 std::mutex mMutex;
178 std::condition_variable mCv;
179 bool mPause = false;
180 std::weak_ptr<void> mResource;
181 bool mResourcePresent = false;
182 std::chrono::milliseconds const mPauseAmount;
183};
184
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800185class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700186protected:
187 std::unique_ptr<TimeKeeper> createTimeKeeper() {
188 class TimeKeeperWrapper : public TimeKeeper {
189 public:
190 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
191 void alarmIn(std::function<void()> const& callback, nsecs_t time) final {
192 mControllableClock.alarmIn(callback, time);
193 }
194 void alarmCancel() final { mControllableClock.alarmCancel(); }
195 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700196 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700197
198 private:
199 TimeKeeper& mControllableClock;
200 };
201 return std::make_unique<TimeKeeperWrapper>(mMockClock);
202 }
203
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800204 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700205 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
206 Mock::VerifyAndClearExpectations(&mMockClock);
207 }
208
209 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
210
211 NiceMock<ControllableClock> mMockClock;
212 static nsecs_t constexpr mDispatchGroupThreshold = 5;
213 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800214 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700215 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800216 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
217 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700218};
219
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800220TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700221 EXPECT_CALL(mMockClock, alarmIn(_, 900));
222 EXPECT_CALL(mMockClock, alarmCancel());
223 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800224 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
225 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700226 CountingCallback cb(mDispatch);
227 EXPECT_EQ(mDispatch.schedule(cb, 100, 1000), ScheduleResult::Scheduled);
228 }
229}
230
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800231TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700232 auto intended = mPeriod - 230;
233 EXPECT_CALL(mMockClock, alarmIn(_, 900));
234
235 CountingCallback cb(mDispatch);
236 EXPECT_EQ(mDispatch.schedule(cb, 100, intended), ScheduleResult::Scheduled);
237 advanceToNextCallback();
238
239 ASSERT_THAT(cb.mCalls.size(), Eq(1));
240 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
241}
242
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800243TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700244 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
245 EXPECT_CALL(mMockClock, alarmIn(_, 1050));
246
247 CountingCallback cb(mDispatch);
248 mDispatch.schedule(cb, 100, mPeriod);
249 advanceToNextCallback();
250
251 ASSERT_THAT(cb.mCalls.size(), Eq(1));
252 EXPECT_THAT(cb.mCalls[0], Eq(1150));
253}
254
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800255TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700256 auto const now = 234;
257 mMockClock.advanceBy(234);
258 auto const workDuration = 10 * mPeriod;
259 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
260 .WillOnce(Return(mPeriod * 11));
261 EXPECT_CALL(mMockClock, alarmIn(_, mPeriod - now));
262
263 CountingCallback cb(mDispatch);
264 EXPECT_EQ(mDispatch.schedule(cb, workDuration, mPeriod), ScheduleResult::Scheduled);
265}
266
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800267TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700268 EXPECT_CALL(mMockClock, alarmIn(_, 900));
269 EXPECT_CALL(mMockClock, alarmCancel());
270
271 CountingCallback cb(mDispatch);
272 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
273 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
274}
275
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800276TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700277 EXPECT_CALL(mMockClock, alarmIn(_, 900));
278 EXPECT_CALL(mMockClock, alarmCancel());
279
280 CountingCallback cb(mDispatch);
281 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
282 mMockClock.advanceBy(950);
283 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
284}
285
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800286TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700287 EXPECT_CALL(mMockClock, alarmIn(_, 900));
288 EXPECT_CALL(mMockClock, alarmCancel());
289
290 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
291 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
292
293 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
294 EXPECT_TRUE(cb.waitForPause());
295 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
296 cb.unpause();
297 pausingThread.join();
298}
299
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800300TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700301 EXPECT_CALL(mMockClock, alarmIn(_, 900));
302 EXPECT_CALL(mMockClock, alarmCancel());
303
304 auto resource = std::make_shared<int>(110);
305
306 PausingCallback cb(mDispatch, 50ms);
307 cb.stashResource(resource);
308 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
309
310 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
311 EXPECT_TRUE(cb.waitForPause());
312
313 cb.unregister();
314 resource.reset();
315
316 cb.unpause();
317 pausingThread.join();
318
319 EXPECT_TRUE(cb.resourcePresent());
320}
321
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800322TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700323 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
324 .Times(4)
325 .WillOnce(Return(1055))
326 .WillOnce(Return(1063))
327 .WillOnce(Return(1063))
328 .WillOnce(Return(1075));
329
330 Sequence seq;
331 EXPECT_CALL(mMockClock, alarmIn(_, 955)).InSequence(seq);
332 EXPECT_CALL(mMockClock, alarmIn(_, 813)).InSequence(seq);
333 EXPECT_CALL(mMockClock, alarmIn(_, 162)).InSequence(seq);
334
335 CountingCallback cb0(mDispatch);
336 CountingCallback cb1(mDispatch);
337
338 mDispatch.schedule(cb0, 100, mPeriod);
339 mDispatch.schedule(cb1, 250, mPeriod);
340
341 advanceToNextCallback();
342 advanceToNextCallback();
343
344 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
345 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
346 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
347 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
348}
349
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800350TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700351 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
352 .Times(4)
353 .WillOnce(Return(10000))
354 .WillOnce(Return(1000))
355 .WillOnce(Return(10000))
356 .WillOnce(Return(10000));
357
358 Sequence seq;
359 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
360 EXPECT_CALL(mMockClock, alarmIn(_, 750)).InSequence(seq);
361 EXPECT_CALL(mMockClock, alarmIn(_, 9900)).InSequence(seq);
362
363 CountingCallback cb0(mDispatch);
364 CountingCallback cb1(mDispatch);
365
366 mDispatch.schedule(cb0, 100, mPeriod * 10);
367 mDispatch.schedule(cb1, 250, mPeriod);
368 mDispatch.cancel(cb1);
369}
370
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800371TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700372 Sequence seq;
373 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
374 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
375
376 CountingCallback cb0(mDispatch);
377 CountingCallback cb1(mDispatch);
378
379 mDispatch.schedule(cb0, 400, 1000);
380 mDispatch.schedule(cb1, 200, 1000);
381 mDispatch.schedule(cb1, 300, 1000);
382 advanceToNextCallback();
383}
384
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800385TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700386 Sequence seq;
387 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
388 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
389 EXPECT_CALL(mMockClock, alarmIn(_, 100)).InSequence(seq);
390
391 CountingCallback cb0(mDispatch);
392 CountingCallback cb1(mDispatch);
393
394 mDispatch.schedule(cb0, 400, 1000);
395 mDispatch.schedule(cb1, 200, 1000);
396 mDispatch.schedule(cb1, 500, 1000);
397 advanceToNextCallback();
398}
399
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800400TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700401 Sequence seq;
402 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
403 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
404 EXPECT_CALL(mMockClock, alarmIn(_, 990)).InSequence(seq);
405 EXPECT_CALL(mMockClock, alarmIn(_, 10)).InSequence(seq);
406
407 auto offset = 400;
408 auto closeOffset = offset + mDispatchGroupThreshold - 1;
409 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
410
411 CountingCallback cb0(mDispatch);
412 CountingCallback cb1(mDispatch);
413
414 mDispatch.schedule(cb0, 400, 1000);
415 mDispatch.schedule(cb1, 200, 1000);
416 mDispatch.schedule(cb1, closeOffset, 1000);
417
418 advanceToNextCallback();
419 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
420 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
421 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
422 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
423
424 mDispatch.schedule(cb0, 400, 2000);
425 mDispatch.schedule(cb1, notCloseOffset, 2000);
426 advanceToNextCallback();
427 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
428 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
429
430 advanceToNextCallback();
431 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
432 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
433}
434
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800435TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700436 EXPECT_CALL(mMockClock, alarmIn(_, 900));
437 EXPECT_CALL(mMockClock, alarmIn(_, 800));
438 EXPECT_CALL(mMockClock, alarmIn(_, 100));
439 EXPECT_CALL(mMockClock, alarmCancel());
440
441 CountingCallback cb0(mDispatch);
442 CountingCallback cb1(mDispatch);
443
444 mDispatch.schedule(cb0, 100, 1000);
445 mDispatch.schedule(cb1, 200, 1000);
446 advanceToNextCallback();
447 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
448}
449
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800450TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700451 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
452 .Times(3)
453 .WillOnce(Return(950))
454 .WillOnce(Return(1975))
455 .WillOnce(Return(2950));
456
457 CountingCallback cb(mDispatch);
458 mDispatch.schedule(cb, 100, 920);
459
460 mMockClock.advanceBy(850);
461 EXPECT_THAT(cb.mCalls.size(), Eq(1));
462
463 mDispatch.schedule(cb, 100, 1900);
464 mMockClock.advanceBy(900);
465 EXPECT_THAT(cb.mCalls.size(), Eq(1));
466 mMockClock.advanceBy(125);
467 EXPECT_THAT(cb.mCalls.size(), Eq(2));
468
469 mDispatch.schedule(cb, 100, 2900);
470 mMockClock.advanceBy(975);
471 EXPECT_THAT(cb.mCalls.size(), Eq(3));
472}
473
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800474TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700475 Sequence seq;
476 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
477 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
478
479 VSyncDispatch::CallbackToken tmp;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800480 tmp = mDispatch.registerCallback([&](auto, auto) { mDispatch.schedule(tmp, 100, 2000); },
481 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700482
483 mDispatch.schedule(tmp, 100, 1000);
484 advanceToNextCallback();
485}
486
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800487TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700488 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800489 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700490 tmp = mDispatch.registerCallback(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800491 [&](auto timestamp, auto) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800492 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp - mVsyncMoveThreshold),
493 ScheduleResult::Scheduled);
494 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp), ScheduleResult::Scheduled);
495 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp + mVsyncMoveThreshold),
496 ScheduleResult::Scheduled);
497 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700498 },
499 "oo");
500
501 mDispatch.schedule(tmp, 999, 1000);
502 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800503 EXPECT_THAT(lastTarget, Eq(1000));
504
505 advanceToNextCallback();
506 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700507}
508
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800509TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700510 Sequence seq;
511 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
512 EXPECT_CALL(mMockClock, alarmIn(_, 200)).InSequence(seq);
513 EXPECT_CALL(mMockClock, alarmIn(_, 1000)).InSequence(seq);
514 EXPECT_CALL(mMockClock, alarmIn(_, 150)).InSequence(seq);
515
516 CountingCallback cb(mDispatch);
517 mDispatch.schedule(cb, 0, 1000);
518
519 mMockClock.advanceBy(750);
520 mDispatch.schedule(cb, 50, 1000);
521
522 advanceToNextCallback();
523 mDispatch.schedule(cb, 50, 2000);
524
525 mMockClock.advanceBy(800);
526 mDispatch.schedule(cb, 100, 2000);
527}
528
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800529TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700530 Sequence seq;
531 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
532 EXPECT_CALL(mMockClock, alarmIn(_, 400)).InSequence(seq);
533 EXPECT_CALL(mMockClock, alarmIn(_, 350)).InSequence(seq);
534 EXPECT_CALL(mMockClock, alarmIn(_, 950)).InSequence(seq);
535
536 CountingCallback cb0(mDispatch);
537 CountingCallback cb1(mDispatch);
538
539 mDispatch.schedule(cb0, 500, 1000);
540 mDispatch.schedule(cb1, 100, 1000);
541
542 advanceToNextCallback();
543 mDispatch.schedule(cb0, 200, 2000);
544 mDispatch.schedule(cb1, 150, 1000);
545
546 advanceToNextCallback();
547 advanceToNextCallback();
548}
549
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800550TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700551 Sequence seq;
552 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
553
554 CountingCallback cb0(mDispatch);
555 CountingCallback cb1(mDispatch);
556 mDispatch.schedule(cb0, 500, 1000);
557 mDispatch.schedule(cb1, 500, 20000);
558}
559
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800560TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700561 Sequence seq;
562 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
563 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
564 EXPECT_CALL(mMockClock, alarmIn(_, 900)).InSequence(seq);
565
566 CountingCallback cb0(mDispatch);
567 mDispatch.schedule(cb0, 500, 1000);
568 mDispatch.cancel(cb0);
569 mDispatch.schedule(cb0, 100, 1000);
570}
571
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800572TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700573 VSyncDispatch::CallbackToken token(100);
574 EXPECT_THAT(mDispatch.schedule(token, 100, 1000), Eq(ScheduleResult::Error));
575 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
576}
577
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800578TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700579 CountingCallback cb0(mDispatch);
580 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800581 EXPECT_EQ(mDispatch.schedule(cb0, 100, 1000), ScheduleResult::Scheduled);
582}
583
584// b/1450138150
585TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
586 EXPECT_CALL(mMockClock, alarmIn(_, 500));
587 CountingCallback cb(mDispatch);
588 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
589 mMockClock.advanceBy(400);
590
591 EXPECT_EQ(mDispatch.schedule(cb, 800, 1000), ScheduleResult::Scheduled);
592 advanceToNextCallback();
593 ASSERT_THAT(cb.mCalls.size(), Eq(1));
594}
595
596TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
597 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
598 .Times(2)
599 .WillOnce(Return(1000))
600 .WillOnce(Return(1002));
601 CountingCallback cb(mDispatch);
602 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
603 mMockClock.advanceBy(400);
604 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700605}
606
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800607TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
608 CountingCallback cb0(mDispatch);
609 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
610 advanceToNextCallback();
611 EXPECT_EQ(mDispatch.schedule(cb0, 1100, 2000), ScheduleResult::Scheduled);
612}
613
614TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
615 Sequence seq;
616 EXPECT_CALL(mMockClock, alarmIn(_, 500)).InSequence(seq);
617 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
618 CountingCallback cb0(mDispatch);
619 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
620 advanceToNextCallback();
621 EXPECT_EQ(mDispatch.schedule(cb0, 1900, 2000), ScheduleResult::Scheduled);
622}
623
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800624TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800625 EXPECT_CALL(mMockClock, alarmIn(_, 600));
626
627 CountingCallback cb(mDispatch);
628 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800629
630 EXPECT_EQ(mDispatch.schedule(cb, 1400, 1000), ScheduleResult::Scheduled);
631
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800632 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800633}
634
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800635TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700636 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
637 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
638
639 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800640 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700641 VSyncCallbackRegistration cb1(std::move(cb));
642 cb.schedule(100, 1000);
643 cb.cancel();
644
645 cb1.schedule(500, 1000);
646 cb1.cancel();
647}
648
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800649TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700650 EXPECT_CALL(mMockClock, alarmIn(_, 500)).Times(1);
651 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
652
653 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800654 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700655 VSyncCallbackRegistration cb1(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800656 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700657 cb1 = std::move(cb);
658 cb.schedule(100, 1000);
659 cb.cancel();
660
661 cb1.schedule(500, 1000);
662 cb1.cancel();
663}
664
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700665// b/154303580
666TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
667 Sequence seq;
668 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
669 EXPECT_CALL(mMockClock, alarmIn(_, 1200)).InSequence(seq);
670 CountingCallback cb1(mDispatch);
671 CountingCallback cb2(mDispatch);
672
673 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
674
675 mMockClock.setLag(100);
676 mMockClock.advanceBy(620);
677
678 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
679 mMockClock.advanceBy(80);
680
681 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
682 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
683}
684
685// b/154303580.
686// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
687// update later, as opposed to blocking the calling thread.
688TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
689 Sequence seq;
690 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
691 EXPECT_CALL(mMockClock, alarmIn(_, 930)).InSequence(seq);
692 CountingCallback cb(mDispatch);
693
694 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
695
696 mMockClock.setLag(100);
697 mMockClock.advanceBy(620);
698
699 EXPECT_EQ(mDispatch.schedule(cb, 370, 2000), ScheduleResult::Scheduled);
700 mMockClock.advanceBy(80);
701
702 EXPECT_THAT(cb.mCalls.size(), Eq(1));
703}
704
Kevin DuBoisb340b732020-06-16 09:07:35 -0700705// b/154303580.
706TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
707 Sequence seq;
708 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
709 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
710 CountingCallback cb1(mDispatch);
711 CountingCallback cb2(mDispatch);
712
713 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
714 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
715
716 mMockClock.setLag(100);
717 mMockClock.advanceBy(620);
718
719 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
720
721 mMockClock.advanceBy(80);
722
723 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
724 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
725}
726
727TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
728 Sequence seq;
729 EXPECT_CALL(mMockClock, alarmIn(_, 600)).InSequence(seq);
730 EXPECT_CALL(mMockClock, alarmIn(_, 1280)).InSequence(seq);
731 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
732 CountingCallback cb1(mDispatch);
733 CountingCallback cb2(mDispatch);
734
735 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
736 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
737
738 mMockClock.setLag(100);
739 mMockClock.advanceBy(620);
740
741 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
742
743 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
744 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
745 mMockClock.advanceToNextCallback();
746
747 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
748 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
749}
750
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800751class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700752protected:
753 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800754 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700755 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
756};
757
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800758TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700759 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800760 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800761 name, [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700762 EXPECT_THAT(entry.name(), Eq(name));
763 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
764 EXPECT_FALSE(entry.wakeupTime());
765}
766
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800767TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800768 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800769 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700770
771 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800772 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
773 auto const wakeup = entry.wakeupTime();
774 ASSERT_TRUE(wakeup);
775 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700776
777 entry.disarm();
778 EXPECT_FALSE(entry.wakeupTime());
779}
780
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800781TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700782 auto const duration = 500;
783 auto const now = 8750;
784
785 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
786 .Times(1)
787 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800788 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800789 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700790
791 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800792 EXPECT_THAT(entry.schedule(500, 994, mStubTracker, now), Eq(ScheduleResult::Scheduled));
793 auto const wakeup = entry.wakeupTime();
794 ASSERT_TRUE(wakeup);
795 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700796}
797
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800798TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700799 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800800 auto vsyncCalledTime = 0;
801 auto wakeupCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800802 VSyncDispatchTimerQueueEntry entry(
803 "test",
Kevin DuBois2968afc2020-01-14 09:48:50 -0800804 [&](auto vsyncTime, auto wakeupTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800805 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800806 vsyncCalledTime = vsyncTime;
807 wakeupCalledTime = wakeupTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800808 },
809 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700810
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800811 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
812 auto const wakeup = entry.wakeupTime();
813 ASSERT_TRUE(wakeup);
814 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700815
Kevin DuBois2968afc2020-01-14 09:48:50 -0800816 entry.callback(entry.executing(), *wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700817
818 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800819 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
820 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700821 EXPECT_FALSE(entry.wakeupTime());
822 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
823 ASSERT_TRUE(lastCalledTarget);
824 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
825}
826
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800827TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700828 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
829 .Times(2)
830 .WillOnce(Return(1000))
831 .WillOnce(Return(1020));
832
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800833 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800834 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700835
836 EXPECT_FALSE(entry.wakeupTime());
837 entry.update(mStubTracker, 0);
838 EXPECT_FALSE(entry.wakeupTime());
839
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800840 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
841 auto wakeup = entry.wakeupTime();
842 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700843 EXPECT_THAT(wakeup, Eq(900));
844
845 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800846 wakeup = entry.wakeupTime();
847 ASSERT_TRUE(wakeup);
848 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -0700849}
850
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800851TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800852 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800853 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800854 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700855 entry.update(mStubTracker, 0);
856
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800857 auto const wakeup = entry.wakeupTime();
858 ASSERT_TRUE(wakeup);
859 EXPECT_THAT(*wakeup, Eq(wakeup));
860}
861
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800862TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
863 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800864 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800865 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800866 entry.executing(); // 1000 is executing
867 // had 1000 not been executing, this could have been scheduled for time 800.
868 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
869 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
870
871 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
872 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
873
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800874 EXPECT_THAT(entry.schedule(200, 1001, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800875 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800876}
877
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800878TEST_F(VSyncDispatchTimerQueueEntryTest,
879 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
880 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800881 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800882
883 Sequence seq;
884 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
885 .InSequence(seq)
886 .WillOnce(Return(1000));
887 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
888 .InSequence(seq)
889 .WillOnce(Return(1000));
890 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
891 .InSequence(seq)
892 .WillOnce(Return(2000));
893
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800894 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800895
896 entry.executing(); // 1000 is executing
897
898 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
899}
900
901TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
902 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800903 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800904 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
905 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
906 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
907 EXPECT_THAT(entry.schedule(1200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700908}
909
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700910TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
911 static constexpr auto effectualOffset = 200;
912 VSyncDispatchTimerQueueEntry entry(
913 "test", [](auto, auto) {}, mVsyncMoveThreshold);
914 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
915 entry.addPendingWorkloadUpdate(100, 400);
916 entry.addPendingWorkloadUpdate(effectualOffset, 700);
917 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
918 entry.update(mStubTracker, 0);
919 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
920 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
921}
922
Kevin DuBois305bef12019-10-09 13:23:27 -0700923} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800924
925// TODO(b/129481165): remove the #pragma below and fix conversion issues
926#pragma clang diagnostic pop // ignored "-Wconversion"