blob: f630e3bb46aa0216beeb6bbe66c7a74e2f28e78f [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() {
Ady Abrahamb491c902020-08-15 15:47:56 -070067 ON_CALL(*this, alarmAt(_, _))
68 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070069 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
70 }
71
72 MOCK_CONST_METHOD0(now, nsecs_t());
Ady Abrahamb491c902020-08-15 15:47:56 -070073 MOCK_METHOD2(alarmAt, void(std::function<void()> const&, nsecs_t time));
Kevin DuBois305bef12019-10-09 13:23:27 -070074 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
Ady Abrahamb491c902020-08-15 15:47:56 -070077 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070078 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070079 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070080 }
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 DuBoisf9477832020-07-16 10:21:36 -0700119 void counter(nsecs_t time, nsecs_t wakeup_time) {
120 mCalls.push_back(time);
121 mWakeupTime.push_back(wakeup_time);
122 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700123
124 VSyncDispatch& mDispatch;
125 VSyncDispatch::CallbackToken mToken;
126 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700127 std::vector<nsecs_t> mWakeupTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700128};
129
130class PausingCallback {
131public:
132 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
133 : mDispatch(dispatch),
134 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800135 std::placeholders::_1,
136 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700137 "test")),
138 mRegistered(true),
139 mPauseAmount(pauseAmount) {}
140 ~PausingCallback() { unregister(); }
141
142 operator VSyncDispatch::CallbackToken() const { return mToken; }
143
Kevin DuBois2968afc2020-01-14 09:48:50 -0800144 void pause(nsecs_t, nsecs_t) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700145 std::unique_lock<std::mutex> lk(mMutex);
146 mPause = true;
147 mCv.notify_all();
148
149 mCv.wait_for(lk, mPauseAmount, [this] { return !mPause; });
150
151 mResourcePresent = (mResource.lock() != nullptr);
152 }
153
154 bool waitForPause() {
155 std::unique_lock<std::mutex> lk(mMutex);
156 auto waiting = mCv.wait_for(lk, 10s, [this] { return mPause; });
157 return waiting;
158 }
159
160 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
161
162 bool resourcePresent() { return mResourcePresent; }
163
164 void unpause() {
165 std::unique_lock<std::mutex> lk(mMutex);
166 mPause = false;
167 mCv.notify_all();
168 }
169
170 void unregister() {
171 if (mRegistered) {
172 mDispatch.unregisterCallback(mToken);
173 mRegistered = false;
174 }
175 }
176
177 VSyncDispatch& mDispatch;
178 VSyncDispatch::CallbackToken mToken;
179 bool mRegistered = true;
180
181 std::mutex mMutex;
182 std::condition_variable mCv;
183 bool mPause = false;
184 std::weak_ptr<void> mResource;
185 bool mResourcePresent = false;
186 std::chrono::milliseconds const mPauseAmount;
187};
188
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800189class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700190protected:
191 std::unique_ptr<TimeKeeper> createTimeKeeper() {
192 class TimeKeeperWrapper : public TimeKeeper {
193 public:
194 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Ady Abrahamb491c902020-08-15 15:47:56 -0700195 void alarmAt(std::function<void()> const& callback, nsecs_t time) final {
196 mControllableClock.alarmAt(callback, time);
Kevin DuBois305bef12019-10-09 13:23:27 -0700197 }
198 void alarmCancel() final { mControllableClock.alarmCancel(); }
199 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700200 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700201
202 private:
203 TimeKeeper& mControllableClock;
204 };
205 return std::make_unique<TimeKeeperWrapper>(mMockClock);
206 }
207
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800208 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700209 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
210 Mock::VerifyAndClearExpectations(&mMockClock);
211 }
212
213 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
214
215 NiceMock<ControllableClock> mMockClock;
216 static nsecs_t constexpr mDispatchGroupThreshold = 5;
217 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800218 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700219 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800220 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
221 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700222};
223
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800224TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700225 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700226 EXPECT_CALL(mMockClock, alarmCancel());
227 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800228 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
229 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700230 CountingCallback cb(mDispatch);
231 EXPECT_EQ(mDispatch.schedule(cb, 100, 1000), ScheduleResult::Scheduled);
232 }
233}
234
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800235TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700236 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700237 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700238
239 CountingCallback cb(mDispatch);
240 EXPECT_EQ(mDispatch.schedule(cb, 100, intended), ScheduleResult::Scheduled);
241 advanceToNextCallback();
242
243 ASSERT_THAT(cb.mCalls.size(), Eq(1));
244 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
245}
246
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800247TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700248 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700249 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700250
251 CountingCallback cb(mDispatch);
252 mDispatch.schedule(cb, 100, mPeriod);
253 advanceToNextCallback();
254
255 ASSERT_THAT(cb.mCalls.size(), Eq(1));
256 EXPECT_THAT(cb.mCalls[0], Eq(1150));
257}
258
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800259TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700260 auto const now = 234;
261 mMockClock.advanceBy(234);
262 auto const workDuration = 10 * mPeriod;
263 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
264 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700265 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700266
267 CountingCallback cb(mDispatch);
268 EXPECT_EQ(mDispatch.schedule(cb, workDuration, mPeriod), ScheduleResult::Scheduled);
269}
270
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800271TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700272 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700273 EXPECT_CALL(mMockClock, alarmCancel());
274
275 CountingCallback cb(mDispatch);
276 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
277 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
278}
279
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800280TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700281 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700282 EXPECT_CALL(mMockClock, alarmCancel());
283
284 CountingCallback cb(mDispatch);
285 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
286 mMockClock.advanceBy(950);
287 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
288}
289
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800290TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700291 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700292 EXPECT_CALL(mMockClock, alarmCancel());
293
294 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
295 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
296
297 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
298 EXPECT_TRUE(cb.waitForPause());
299 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
300 cb.unpause();
301 pausingThread.join();
302}
303
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800304TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700305 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700306 EXPECT_CALL(mMockClock, alarmCancel());
307
308 auto resource = std::make_shared<int>(110);
309
310 PausingCallback cb(mDispatch, 50ms);
311 cb.stashResource(resource);
312 EXPECT_EQ(mDispatch.schedule(cb, 100, mPeriod), ScheduleResult::Scheduled);
313
314 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
315 EXPECT_TRUE(cb.waitForPause());
316
317 cb.unregister();
318 resource.reset();
319
320 cb.unpause();
321 pausingThread.join();
322
323 EXPECT_TRUE(cb.resourcePresent());
324}
325
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800326TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700327 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
328 .Times(4)
329 .WillOnce(Return(1055))
330 .WillOnce(Return(1063))
331 .WillOnce(Return(1063))
332 .WillOnce(Return(1075));
333
334 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700335 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
336 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
337 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700338
339 CountingCallback cb0(mDispatch);
340 CountingCallback cb1(mDispatch);
341
342 mDispatch.schedule(cb0, 100, mPeriod);
343 mDispatch.schedule(cb1, 250, mPeriod);
344
345 advanceToNextCallback();
346 advanceToNextCallback();
347
348 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
349 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
350 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
351 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
352}
353
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800354TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700355 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
356 .Times(4)
357 .WillOnce(Return(10000))
358 .WillOnce(Return(1000))
359 .WillOnce(Return(10000))
360 .WillOnce(Return(10000));
361
362 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700363 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
364 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
365 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700366
367 CountingCallback cb0(mDispatch);
368 CountingCallback cb1(mDispatch);
369
370 mDispatch.schedule(cb0, 100, mPeriod * 10);
371 mDispatch.schedule(cb1, 250, mPeriod);
372 mDispatch.cancel(cb1);
373}
374
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800375TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700376 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700377 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
378 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700379
380 CountingCallback cb0(mDispatch);
381 CountingCallback cb1(mDispatch);
382
383 mDispatch.schedule(cb0, 400, 1000);
384 mDispatch.schedule(cb1, 200, 1000);
385 mDispatch.schedule(cb1, 300, 1000);
386 advanceToNextCallback();
387}
388
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800389TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700390 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700391 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
392 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
393 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700394
395 CountingCallback cb0(mDispatch);
396 CountingCallback cb1(mDispatch);
397
398 mDispatch.schedule(cb0, 400, 1000);
399 mDispatch.schedule(cb1, 200, 1000);
400 mDispatch.schedule(cb1, 500, 1000);
401 advanceToNextCallback();
402}
403
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800404TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700405 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700406 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
407 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
408 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
409 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700410
411 auto offset = 400;
412 auto closeOffset = offset + mDispatchGroupThreshold - 1;
413 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
414
415 CountingCallback cb0(mDispatch);
416 CountingCallback cb1(mDispatch);
417
418 mDispatch.schedule(cb0, 400, 1000);
419 mDispatch.schedule(cb1, 200, 1000);
420 mDispatch.schedule(cb1, closeOffset, 1000);
421
422 advanceToNextCallback();
423 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
424 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
425 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
426 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
427
428 mDispatch.schedule(cb0, 400, 2000);
429 mDispatch.schedule(cb1, notCloseOffset, 2000);
430 advanceToNextCallback();
431 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
432 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
433
434 advanceToNextCallback();
435 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
436 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
437}
438
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800439TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700440 Sequence seq;
441 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
442 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
443 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700444 EXPECT_CALL(mMockClock, alarmCancel());
445
446 CountingCallback cb0(mDispatch);
447 CountingCallback cb1(mDispatch);
448
449 mDispatch.schedule(cb0, 100, 1000);
450 mDispatch.schedule(cb1, 200, 1000);
451 advanceToNextCallback();
452 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
453}
454
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800455TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700456 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
457 .Times(3)
458 .WillOnce(Return(950))
459 .WillOnce(Return(1975))
460 .WillOnce(Return(2950));
461
462 CountingCallback cb(mDispatch);
463 mDispatch.schedule(cb, 100, 920);
464
465 mMockClock.advanceBy(850);
466 EXPECT_THAT(cb.mCalls.size(), Eq(1));
467
468 mDispatch.schedule(cb, 100, 1900);
469 mMockClock.advanceBy(900);
470 EXPECT_THAT(cb.mCalls.size(), Eq(1));
471 mMockClock.advanceBy(125);
472 EXPECT_THAT(cb.mCalls.size(), Eq(2));
473
474 mDispatch.schedule(cb, 100, 2900);
475 mMockClock.advanceBy(975);
476 EXPECT_THAT(cb.mCalls.size(), Eq(3));
477}
478
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800479TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700480 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700481 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
482 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700483
484 VSyncDispatch::CallbackToken tmp;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800485 tmp = mDispatch.registerCallback([&](auto, auto) { mDispatch.schedule(tmp, 100, 2000); },
486 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700487
488 mDispatch.schedule(tmp, 100, 1000);
489 advanceToNextCallback();
490}
491
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800492TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700493 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800494 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700495 tmp = mDispatch.registerCallback(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800496 [&](auto timestamp, auto) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800497 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp - mVsyncMoveThreshold),
498 ScheduleResult::Scheduled);
499 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp), ScheduleResult::Scheduled);
500 EXPECT_EQ(mDispatch.schedule(tmp, 400, timestamp + mVsyncMoveThreshold),
501 ScheduleResult::Scheduled);
502 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700503 },
504 "oo");
505
506 mDispatch.schedule(tmp, 999, 1000);
507 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800508 EXPECT_THAT(lastTarget, Eq(1000));
509
510 advanceToNextCallback();
511 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700512}
513
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800514TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700515 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700516 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
517 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
518 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
519 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700520
521 CountingCallback cb(mDispatch);
522 mDispatch.schedule(cb, 0, 1000);
523
524 mMockClock.advanceBy(750);
525 mDispatch.schedule(cb, 50, 1000);
526
527 advanceToNextCallback();
528 mDispatch.schedule(cb, 50, 2000);
529
530 mMockClock.advanceBy(800);
531 mDispatch.schedule(cb, 100, 2000);
532}
533
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800534TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700535 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700536 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
537 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
538 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
539 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700540
541 CountingCallback cb0(mDispatch);
542 CountingCallback cb1(mDispatch);
543
544 mDispatch.schedule(cb0, 500, 1000);
545 mDispatch.schedule(cb1, 100, 1000);
546
547 advanceToNextCallback();
548 mDispatch.schedule(cb0, 200, 2000);
549 mDispatch.schedule(cb1, 150, 1000);
550
551 advanceToNextCallback();
552 advanceToNextCallback();
553}
554
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800555TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700556 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700557 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700558
559 CountingCallback cb0(mDispatch);
560 CountingCallback cb1(mDispatch);
561 mDispatch.schedule(cb0, 500, 1000);
562 mDispatch.schedule(cb1, 500, 20000);
563}
564
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800565TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700566 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700567 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700568 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700569 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700570
571 CountingCallback cb0(mDispatch);
572 mDispatch.schedule(cb0, 500, 1000);
573 mDispatch.cancel(cb0);
574 mDispatch.schedule(cb0, 100, 1000);
575}
576
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800577TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700578 VSyncDispatch::CallbackToken token(100);
579 EXPECT_THAT(mDispatch.schedule(token, 100, 1000), Eq(ScheduleResult::Error));
580 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
581}
582
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800583TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700584 CountingCallback cb0(mDispatch);
585 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800586 EXPECT_EQ(mDispatch.schedule(cb0, 100, 1000), ScheduleResult::Scheduled);
587}
588
589// b/1450138150
590TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700591 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800592 CountingCallback cb(mDispatch);
593 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
594 mMockClock.advanceBy(400);
595
596 EXPECT_EQ(mDispatch.schedule(cb, 800, 1000), ScheduleResult::Scheduled);
597 advanceToNextCallback();
598 ASSERT_THAT(cb.mCalls.size(), Eq(1));
599}
600
601TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
602 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
603 .Times(2)
604 .WillOnce(Return(1000))
605 .WillOnce(Return(1002));
606 CountingCallback cb(mDispatch);
607 EXPECT_EQ(mDispatch.schedule(cb, 500, 1000), ScheduleResult::Scheduled);
608 mMockClock.advanceBy(400);
609 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700610}
611
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800612TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
613 CountingCallback cb0(mDispatch);
614 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
615 advanceToNextCallback();
616 EXPECT_EQ(mDispatch.schedule(cb0, 1100, 2000), ScheduleResult::Scheduled);
617}
618
619TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
620 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700621 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
622 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800623 CountingCallback cb0(mDispatch);
624 EXPECT_EQ(mDispatch.schedule(cb0, 500, 1000), ScheduleResult::Scheduled);
625 advanceToNextCallback();
626 EXPECT_EQ(mDispatch.schedule(cb0, 1900, 2000), ScheduleResult::Scheduled);
627}
628
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800629TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700630 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800631
632 CountingCallback cb(mDispatch);
633 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800634
635 EXPECT_EQ(mDispatch.schedule(cb, 1400, 1000), ScheduleResult::Scheduled);
636
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800637 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800638}
639
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800640TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700641 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700642 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
643
644 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800645 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700646 VSyncCallbackRegistration cb1(std::move(cb));
647 cb.schedule(100, 1000);
648 cb.cancel();
649
650 cb1.schedule(500, 1000);
651 cb1.cancel();
652}
653
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800654TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700655 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700656 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
657
658 VSyncCallbackRegistration cb(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800659 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700660 VSyncCallbackRegistration cb1(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800661 mDispatch, [](auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700662 cb1 = std::move(cb);
663 cb.schedule(100, 1000);
664 cb.cancel();
665
666 cb1.schedule(500, 1000);
667 cb1.cancel();
668}
669
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700670// b/154303580
671TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
672 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700673 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
674 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700675 CountingCallback cb1(mDispatch);
676 CountingCallback cb2(mDispatch);
677
678 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
679
680 mMockClock.setLag(100);
681 mMockClock.advanceBy(620);
682
683 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
684 mMockClock.advanceBy(80);
685
686 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
687 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
688}
689
690// b/154303580.
691// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
692// update later, as opposed to blocking the calling thread.
693TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
694 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700695 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
696 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700697 CountingCallback cb(mDispatch);
698
699 EXPECT_EQ(mDispatch.schedule(cb, 400, 1000), ScheduleResult::Scheduled);
700
701 mMockClock.setLag(100);
702 mMockClock.advanceBy(620);
703
704 EXPECT_EQ(mDispatch.schedule(cb, 370, 2000), ScheduleResult::Scheduled);
705 mMockClock.advanceBy(80);
706
707 EXPECT_THAT(cb.mCalls.size(), Eq(1));
708}
709
Kevin DuBoisb340b732020-06-16 09:07:35 -0700710// b/154303580.
711TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
712 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700713 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700714 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
715 CountingCallback cb1(mDispatch);
716 CountingCallback cb2(mDispatch);
717
718 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
719 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
720
721 mMockClock.setLag(100);
722 mMockClock.advanceBy(620);
723
724 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
725
726 mMockClock.advanceBy(80);
727
728 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
729 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
730}
731
732TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
733 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700734 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
735 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700736 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
737 CountingCallback cb1(mDispatch);
738 CountingCallback cb2(mDispatch);
739
740 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
741 EXPECT_EQ(mDispatch.schedule(cb2, 100, 2000), ScheduleResult::Scheduled);
742
743 mMockClock.setLag(100);
744 mMockClock.advanceBy(620);
745
746 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
747
748 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
749 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
750 mMockClock.advanceToNextCallback();
751
752 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
753 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
754}
755
Kevin DuBoisf9477832020-07-16 10:21:36 -0700756TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
757 CountingCallback cb1(mDispatch);
758 CountingCallback cb2(mDispatch);
759
760 Sequence seq;
761 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
762 .InSequence(seq)
763 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700764 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700765 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
766 .InSequence(seq)
767 .WillOnce(Return(1000));
768
769 EXPECT_EQ(mDispatch.schedule(cb1, 400, 1000), ScheduleResult::Scheduled);
770 EXPECT_EQ(mDispatch.schedule(cb2, 390, 1000), ScheduleResult::Scheduled);
771
772 mMockClock.setLag(100);
773 mMockClock.advanceBy(700);
774
775 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
776 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
777 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
778 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
779}
780
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800781class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700782protected:
783 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800784 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700785 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
786};
787
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800788TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700789 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800790 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800791 name, [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700792 EXPECT_THAT(entry.name(), Eq(name));
793 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
794 EXPECT_FALSE(entry.wakeupTime());
795}
796
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800797TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800798 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800799 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700800
801 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800802 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
803 auto const wakeup = entry.wakeupTime();
804 ASSERT_TRUE(wakeup);
805 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700806
807 entry.disarm();
808 EXPECT_FALSE(entry.wakeupTime());
809}
810
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800811TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700812 auto const duration = 500;
813 auto const now = 8750;
814
815 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
816 .Times(1)
817 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800818 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800819 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700820
821 EXPECT_FALSE(entry.wakeupTime());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800822 EXPECT_THAT(entry.schedule(500, 994, mStubTracker, now), Eq(ScheduleResult::Scheduled));
823 auto const wakeup = entry.wakeupTime();
824 ASSERT_TRUE(wakeup);
825 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700826}
827
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800828TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700829 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800830 auto vsyncCalledTime = 0;
831 auto wakeupCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800832 VSyncDispatchTimerQueueEntry entry(
833 "test",
Kevin DuBois2968afc2020-01-14 09:48:50 -0800834 [&](auto vsyncTime, auto wakeupTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800835 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800836 vsyncCalledTime = vsyncTime;
837 wakeupCalledTime = wakeupTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800838 },
839 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700840
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800841 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
842 auto const wakeup = entry.wakeupTime();
843 ASSERT_TRUE(wakeup);
844 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700845
Kevin DuBois2968afc2020-01-14 09:48:50 -0800846 entry.callback(entry.executing(), *wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700847
848 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800849 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
850 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700851 EXPECT_FALSE(entry.wakeupTime());
852 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
853 ASSERT_TRUE(lastCalledTarget);
854 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
855}
856
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800857TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700858 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
859 .Times(2)
860 .WillOnce(Return(1000))
861 .WillOnce(Return(1020));
862
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800863 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800864 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700865
866 EXPECT_FALSE(entry.wakeupTime());
867 entry.update(mStubTracker, 0);
868 EXPECT_FALSE(entry.wakeupTime());
869
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800870 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
871 auto wakeup = entry.wakeupTime();
872 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -0700873 EXPECT_THAT(wakeup, Eq(900));
874
875 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800876 wakeup = entry.wakeupTime();
877 ASSERT_TRUE(wakeup);
878 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -0700879}
880
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800881TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800882 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800883 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800884 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700885 entry.update(mStubTracker, 0);
886
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800887 auto const wakeup = entry.wakeupTime();
888 ASSERT_TRUE(wakeup);
889 EXPECT_THAT(*wakeup, Eq(wakeup));
890}
891
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800892TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
893 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800894 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800895 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800896 entry.executing(); // 1000 is executing
897 // had 1000 not been executing, this could have been scheduled for time 800.
898 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
899 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
900
901 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
902 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
903
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800904 EXPECT_THAT(entry.schedule(200, 1001, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800905 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800906}
907
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800908TEST_F(VSyncDispatchTimerQueueEntryTest,
909 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
910 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800911 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800912
913 Sequence seq;
914 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
915 .InSequence(seq)
916 .WillOnce(Return(1000));
917 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
918 .InSequence(seq)
919 .WillOnce(Return(1000));
920 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
921 .InSequence(seq)
922 .WillOnce(Return(2000));
923
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800924 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800925
926 entry.executing(); // 1000 is executing
927
928 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
929}
930
931TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
932 VSyncDispatchTimerQueueEntry entry(
Kevin DuBois2968afc2020-01-14 09:48:50 -0800933 "test", [](auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800934 EXPECT_THAT(entry.schedule(100, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
935 EXPECT_THAT(entry.schedule(200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
936 EXPECT_THAT(entry.schedule(50, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
937 EXPECT_THAT(entry.schedule(1200, 500, mStubTracker, 0), Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -0700938}
939
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700940TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
941 static constexpr auto effectualOffset = 200;
942 VSyncDispatchTimerQueueEntry entry(
943 "test", [](auto, auto) {}, mVsyncMoveThreshold);
944 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
945 entry.addPendingWorkloadUpdate(100, 400);
946 entry.addPendingWorkloadUpdate(effectualOffset, 700);
947 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
948 entry.update(mStubTracker, 0);
949 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
950 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
951}
952
Kevin DuBois305bef12019-10-09 13:23:27 -0700953} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800954
955// TODO(b/129481165): remove the #pragma below and fix conversion issues
956#pragma clang diagnostic pop // ignored "-Wconversion"