blob: 72b53960473c71c7b699225d23153ff6209aab09 [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 Abraham0bb6a472020-10-12 10:22:13 -070051 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, int));
Ady Abraham5e7371c2020-03-24 14:47:24 -070052 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070053
54 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
55 if (timePoint % mPeriod == 0) {
56 return timePoint;
57 }
58 return (timePoint - (timePoint % mPeriod) + mPeriod);
59 }
60
61protected:
62 nsecs_t const mPeriod;
63};
64
65class ControllableClock : public TimeKeeper {
66public:
67 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070068 ON_CALL(*this, alarmAt(_, _))
69 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070070 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
71 }
72
73 MOCK_CONST_METHOD0(now, nsecs_t());
Ady Abrahamb491c902020-08-15 15:47:56 -070074 MOCK_METHOD2(alarmAt, void(std::function<void()> const&, nsecs_t time));
Kevin DuBois305bef12019-10-09 13:23:27 -070075 MOCK_METHOD0(alarmCancel, void());
Ady Abraham75398722020-04-07 14:08:45 -070076 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070077
Ady Abrahamb491c902020-08-15 15:47:56 -070078 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070079 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070080 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070081 }
82
83 nsecs_t fakeTime() const { return mCurrentTime; }
84
85 void advanceToNextCallback() {
86 mCurrentTime = mNextCallbackTime;
87 if (mCallback) {
88 mCallback();
89 }
90 }
91
92 void advanceBy(nsecs_t advancement) {
93 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070094 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070095 mCallback();
96 }
97 };
98
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070099 void setLag(nsecs_t lag) { mLag = lag; }
100
Kevin DuBois305bef12019-10-09 13:23:27 -0700101private:
102 std::function<void()> mCallback;
103 nsecs_t mNextCallbackTime = 0;
104 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700105 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700106};
107
108class CountingCallback {
109public:
110 CountingCallback(VSyncDispatch& dispatch)
111 : mDispatch(dispatch),
112 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700113 std::placeholders::_1, std::placeholders::_2,
114 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700115 "test")) {}
116 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
117
118 operator VSyncDispatch::CallbackToken() const { return mToken; }
119
Ady Abraham9c53ee72020-07-22 21:16:18 -0700120 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700121 mCalls.push_back(time);
122 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700123 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700124 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700125
126 VSyncDispatch& mDispatch;
127 VSyncDispatch::CallbackToken mToken;
128 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700129 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700130 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700131};
132
133class PausingCallback {
134public:
135 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
136 : mDispatch(dispatch),
137 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800138 std::placeholders::_1,
139 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700140 "test")),
141 mRegistered(true),
142 mPauseAmount(pauseAmount) {}
143 ~PausingCallback() { unregister(); }
144
145 operator VSyncDispatch::CallbackToken() const { return mToken; }
146
Kevin DuBois2968afc2020-01-14 09:48:50 -0800147 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700148 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700149 mPause = true;
150 mCv.notify_all();
151
Ady Abraham8cb21882020-08-26 18:22:05 -0700152 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700153
154 mResourcePresent = (mResource.lock() != nullptr);
155 }
156
157 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700158 std::unique_lock lock(mMutex);
159 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700160 return waiting;
161 }
162
163 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
164
165 bool resourcePresent() { return mResourcePresent; }
166
167 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700168 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700169 mPause = false;
170 mCv.notify_all();
171 }
172
173 void unregister() {
174 if (mRegistered) {
175 mDispatch.unregisterCallback(mToken);
176 mRegistered = false;
177 }
178 }
179
180 VSyncDispatch& mDispatch;
181 VSyncDispatch::CallbackToken mToken;
182 bool mRegistered = true;
183
184 std::mutex mMutex;
185 std::condition_variable mCv;
186 bool mPause = false;
187 std::weak_ptr<void> mResource;
188 bool mResourcePresent = false;
189 std::chrono::milliseconds const mPauseAmount;
190};
191
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800192class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700193protected:
194 std::unique_ptr<TimeKeeper> createTimeKeeper() {
195 class TimeKeeperWrapper : public TimeKeeper {
196 public:
197 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Ady Abrahamb491c902020-08-15 15:47:56 -0700198 void alarmAt(std::function<void()> const& callback, nsecs_t time) final {
199 mControllableClock.alarmAt(callback, time);
Kevin DuBois305bef12019-10-09 13:23:27 -0700200 }
201 void alarmCancel() final { mControllableClock.alarmCancel(); }
202 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700203 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700204
205 private:
206 TimeKeeper& mControllableClock;
207 };
208 return std::make_unique<TimeKeeperWrapper>(mMockClock);
209 }
210
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800211 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700212 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
213 Mock::VerifyAndClearExpectations(&mMockClock);
214 }
215
216 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
217
218 NiceMock<ControllableClock> mMockClock;
219 static nsecs_t constexpr mDispatchGroupThreshold = 5;
220 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800221 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700222 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800223 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
224 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700225};
226
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800227TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700228 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700229 EXPECT_CALL(mMockClock, alarmCancel());
230 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800231 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
232 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700233 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700234 EXPECT_EQ(mDispatch.schedule(cb,
235 {.workDuration = 100,
236 .readyDuration = 0,
237 .earliestVsync = 1000}),
238 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700239 }
240}
241
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800242TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700243 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700244 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700245
246 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700247 EXPECT_EQ(mDispatch.schedule(cb,
248 {.workDuration = 100,
249 .readyDuration = 0,
250 .earliestVsync = intended}),
251 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700252 advanceToNextCallback();
253
254 ASSERT_THAT(cb.mCalls.size(), Eq(1));
255 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
256}
257
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800258TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700259 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700260 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700261
262 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700263 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700264 advanceToNextCallback();
265
266 ASSERT_THAT(cb.mCalls.size(), Eq(1));
267 EXPECT_THAT(cb.mCalls[0], Eq(1150));
268}
269
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800270TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700271 auto const now = 234;
272 mMockClock.advanceBy(234);
273 auto const workDuration = 10 * mPeriod;
274 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
275 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700276 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700277
278 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700279 EXPECT_EQ(mDispatch.schedule(cb,
280 {.workDuration = workDuration,
281 .readyDuration = 0,
282 .earliestVsync = mPeriod}),
283 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700284}
285
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800286TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700287 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700288 EXPECT_CALL(mMockClock, alarmCancel());
289
290 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700291 EXPECT_EQ(mDispatch.schedule(cb,
292 {.workDuration = 100,
293 .readyDuration = 0,
294 .earliestVsync = mPeriod}),
295 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700296 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
297}
298
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800299TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700300 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700301 EXPECT_CALL(mMockClock, alarmCancel());
302
303 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700304 EXPECT_EQ(mDispatch.schedule(cb,
305 {.workDuration = 100,
306 .readyDuration = 0,
307 .earliestVsync = mPeriod}),
308 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700309 mMockClock.advanceBy(950);
310 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
311}
312
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800313TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700314 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700315 EXPECT_CALL(mMockClock, alarmCancel());
316
317 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700318 EXPECT_EQ(mDispatch.schedule(cb,
319 {.workDuration = 100,
320 .readyDuration = 0,
321 .earliestVsync = mPeriod}),
322 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700323
324 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
325 EXPECT_TRUE(cb.waitForPause());
326 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
327 cb.unpause();
328 pausingThread.join();
329}
330
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800331TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700332 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700333 EXPECT_CALL(mMockClock, alarmCancel());
334
335 auto resource = std::make_shared<int>(110);
336
337 PausingCallback cb(mDispatch, 50ms);
338 cb.stashResource(resource);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700339 EXPECT_EQ(mDispatch.schedule(cb,
340 {.workDuration = 100,
341 .readyDuration = 0,
342 .earliestVsync = mPeriod}),
343 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700344
345 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
346 EXPECT_TRUE(cb.waitForPause());
347
348 cb.unregister();
349 resource.reset();
350
351 cb.unpause();
352 pausingThread.join();
353
354 EXPECT_TRUE(cb.resourcePresent());
355}
356
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800357TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700358 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
359 .Times(4)
360 .WillOnce(Return(1055))
361 .WillOnce(Return(1063))
362 .WillOnce(Return(1063))
363 .WillOnce(Return(1075));
364
365 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700366 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
367 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
368 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700369
370 CountingCallback cb0(mDispatch);
371 CountingCallback cb1(mDispatch);
372
Ady Abraham9c53ee72020-07-22 21:16:18 -0700373 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
374 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700375
376 advanceToNextCallback();
377 advanceToNextCallback();
378
379 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
380 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
381 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
382 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
383}
384
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800385TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700386 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
387 .Times(4)
388 .WillOnce(Return(10000))
389 .WillOnce(Return(1000))
390 .WillOnce(Return(10000))
391 .WillOnce(Return(10000));
392
393 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700394 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
395 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
396 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700397
398 CountingCallback cb0(mDispatch);
399 CountingCallback cb1(mDispatch);
400
Ady Abraham9c53ee72020-07-22 21:16:18 -0700401 mDispatch.schedule(cb0,
402 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
403 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700404 mDispatch.cancel(cb1);
405}
406
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800407TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700408 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700409 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
410 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700411
412 CountingCallback cb0(mDispatch);
413 CountingCallback cb1(mDispatch);
414
Ady Abraham9c53ee72020-07-22 21:16:18 -0700415 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
416 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
417 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700418 advanceToNextCallback();
419}
420
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800421TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700422 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700423 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
424 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
425 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700426
427 CountingCallback cb0(mDispatch);
428 CountingCallback cb1(mDispatch);
429
Ady Abraham9c53ee72020-07-22 21:16:18 -0700430 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
431 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
432 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700433 advanceToNextCallback();
434}
435
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800436TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700437 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700438 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
439 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
440 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
441 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700442
443 auto offset = 400;
444 auto closeOffset = offset + mDispatchGroupThreshold - 1;
445 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
446
447 CountingCallback cb0(mDispatch);
448 CountingCallback cb1(mDispatch);
449
Ady Abraham9c53ee72020-07-22 21:16:18 -0700450 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
451 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
452 mDispatch.schedule(cb1,
453 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700454
455 advanceToNextCallback();
456 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
457 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
458 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
459 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
460
Ady Abraham9c53ee72020-07-22 21:16:18 -0700461 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
462 mDispatch.schedule(cb1,
463 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700464 advanceToNextCallback();
465 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
466 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
467
468 advanceToNextCallback();
469 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
470 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
471}
472
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800473TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700474 Sequence seq;
475 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
476 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
477 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700478 EXPECT_CALL(mMockClock, alarmCancel());
479
480 CountingCallback cb0(mDispatch);
481 CountingCallback cb1(mDispatch);
482
Ady Abraham9c53ee72020-07-22 21:16:18 -0700483 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
484 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700485 advanceToNextCallback();
486 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
487}
488
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800489TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700490 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
491 .Times(3)
492 .WillOnce(Return(950))
493 .WillOnce(Return(1975))
494 .WillOnce(Return(2950));
495
496 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700497 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700498
499 mMockClock.advanceBy(850);
500 EXPECT_THAT(cb.mCalls.size(), Eq(1));
501
Ady Abraham9c53ee72020-07-22 21:16:18 -0700502 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700503 mMockClock.advanceBy(900);
504 EXPECT_THAT(cb.mCalls.size(), Eq(1));
505 mMockClock.advanceBy(125);
506 EXPECT_THAT(cb.mCalls.size(), Eq(2));
507
Ady Abraham9c53ee72020-07-22 21:16:18 -0700508 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700509 mMockClock.advanceBy(975);
510 EXPECT_THAT(cb.mCalls.size(), Eq(3));
511}
512
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800513TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700514 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700515 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
516 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700517
518 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700519 tmp = mDispatch.registerCallback(
520 [&](auto, auto, auto) {
521 mDispatch.schedule(tmp,
522 {.workDuration = 100,
523 .readyDuration = 0,
524 .earliestVsync = 2000});
525 },
526 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700527
Ady Abraham9c53ee72020-07-22 21:16:18 -0700528 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700529 advanceToNextCallback();
530}
531
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800532TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700533 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800534 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700535 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700536 [&](auto timestamp, auto, auto) {
537 EXPECT_EQ(mDispatch.schedule(tmp,
538 {.workDuration = 400,
539 .readyDuration = 0,
540 .earliestVsync = timestamp - mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800541 ScheduleResult::Scheduled);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700542 EXPECT_EQ(mDispatch.schedule(tmp,
543 {.workDuration = 400,
544 .readyDuration = 0,
545 .earliestVsync = timestamp}),
546 ScheduleResult::Scheduled);
547 EXPECT_EQ(mDispatch.schedule(tmp,
548 {.workDuration = 400,
549 .readyDuration = 0,
550 .earliestVsync = timestamp + mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800551 ScheduleResult::Scheduled);
552 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700553 },
554 "oo");
555
Ady Abraham9c53ee72020-07-22 21:16:18 -0700556 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700557 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800558 EXPECT_THAT(lastTarget, Eq(1000));
559
560 advanceToNextCallback();
561 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700562}
563
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800564TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700565 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700566 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
567 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
568 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
569 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700570
571 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700572 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700573
574 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700575 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700576
577 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700578 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700579
580 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700581 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700582}
583
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800584TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700585 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700586 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
587 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
588 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
589 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700590
591 CountingCallback cb0(mDispatch);
592 CountingCallback cb1(mDispatch);
593
Ady Abraham9c53ee72020-07-22 21:16:18 -0700594 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
595 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700596
597 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700598 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
599 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700600
601 advanceToNextCallback();
602 advanceToNextCallback();
603}
604
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800605TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700606 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700607 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700608
609 CountingCallback cb0(mDispatch);
610 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700611 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
612 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700613}
614
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800615TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700616 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700617 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700618 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700619 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700620
621 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700622 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700623 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700624 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700625}
626
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800627TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700628 VSyncDispatch::CallbackToken token(100);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700629 EXPECT_THAT(mDispatch.schedule(token,
630 {.workDuration = 100,
631 .readyDuration = 0,
632 .earliestVsync = 1000}),
633 Eq(ScheduleResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700634 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
635}
636
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800637TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700638 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700639 EXPECT_EQ(mDispatch.schedule(cb0,
640 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
641 ScheduleResult::Scheduled);
642 EXPECT_EQ(mDispatch.schedule(cb0,
643 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}),
644 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800645}
646
647// b/1450138150
648TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700649 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800650 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700651 EXPECT_EQ(mDispatch.schedule(cb,
652 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
653 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800654 mMockClock.advanceBy(400);
655
Ady Abraham9c53ee72020-07-22 21:16:18 -0700656 EXPECT_EQ(mDispatch.schedule(cb,
657 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000}),
658 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800659 advanceToNextCallback();
660 ASSERT_THAT(cb.mCalls.size(), Eq(1));
661}
662
663TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
664 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
665 .Times(2)
666 .WillOnce(Return(1000))
667 .WillOnce(Return(1002));
668 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700669 EXPECT_EQ(mDispatch.schedule(cb,
670 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
671 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800672 mMockClock.advanceBy(400);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700673 EXPECT_EQ(mDispatch.schedule(cb,
674 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
675 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700676}
677
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800678TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
679 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700680 EXPECT_EQ(mDispatch.schedule(cb0,
681 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
682 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800683 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700684 EXPECT_EQ(mDispatch.schedule(cb0,
685 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000}),
686 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800687}
688
689TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
690 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700691 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
692 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800693 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700694 EXPECT_EQ(mDispatch.schedule(cb0,
695 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
696 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800697 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700698 EXPECT_EQ(mDispatch.schedule(cb0,
699 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000}),
700 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800701}
702
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800703TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700704 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800705
706 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700707 EXPECT_EQ(mDispatch.schedule(cb,
708 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
709 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800710
Ady Abraham9c53ee72020-07-22 21:16:18 -0700711 EXPECT_EQ(mDispatch.schedule(cb,
712 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}),
713 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800714
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800715 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800716}
717
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800718TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700719 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700720 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
721
722 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700723 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700724 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700725 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700726 cb.cancel();
727
Ady Abraham9c53ee72020-07-22 21:16:18 -0700728 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700729 cb1.cancel();
730}
731
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800732TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700733 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700734 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
735
736 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700737 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700738 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700739 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700740 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700741 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700742 cb.cancel();
743
Ady Abraham9c53ee72020-07-22 21:16:18 -0700744 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700745 cb1.cancel();
746}
747
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700748// b/154303580
749TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
750 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700751 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
752 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700753 CountingCallback cb1(mDispatch);
754 CountingCallback cb2(mDispatch);
755
Ady Abraham9c53ee72020-07-22 21:16:18 -0700756 EXPECT_EQ(mDispatch.schedule(cb1,
757 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
758 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700759
760 mMockClock.setLag(100);
761 mMockClock.advanceBy(620);
762
Ady Abraham9c53ee72020-07-22 21:16:18 -0700763 EXPECT_EQ(mDispatch.schedule(cb2,
764 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
765 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700766 mMockClock.advanceBy(80);
767
768 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
769 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
770}
771
772// b/154303580.
773// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
774// update later, as opposed to blocking the calling thread.
775TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
776 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700777 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
778 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700779 CountingCallback cb(mDispatch);
780
Ady Abraham9c53ee72020-07-22 21:16:18 -0700781 EXPECT_EQ(mDispatch.schedule(cb,
782 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
783 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700784
785 mMockClock.setLag(100);
786 mMockClock.advanceBy(620);
787
Ady Abraham9c53ee72020-07-22 21:16:18 -0700788 EXPECT_EQ(mDispatch.schedule(cb,
789 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000}),
790 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700791 mMockClock.advanceBy(80);
792
793 EXPECT_THAT(cb.mCalls.size(), Eq(1));
794}
795
Kevin DuBoisb340b732020-06-16 09:07:35 -0700796// b/154303580.
797TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
798 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700799 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700800 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
801 CountingCallback cb1(mDispatch);
802 CountingCallback cb2(mDispatch);
803
Ady Abraham9c53ee72020-07-22 21:16:18 -0700804 EXPECT_EQ(mDispatch.schedule(cb1,
805 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
806 ScheduleResult::Scheduled);
807 EXPECT_EQ(mDispatch.schedule(cb2,
808 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
809 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700810
811 mMockClock.setLag(100);
812 mMockClock.advanceBy(620);
813
814 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
815
816 mMockClock.advanceBy(80);
817
818 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
819 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
820}
821
822TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
823 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700824 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
825 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700826 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
827 CountingCallback cb1(mDispatch);
828 CountingCallback cb2(mDispatch);
829
Ady Abraham9c53ee72020-07-22 21:16:18 -0700830 EXPECT_EQ(mDispatch.schedule(cb1,
831 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
832 ScheduleResult::Scheduled);
833 EXPECT_EQ(mDispatch.schedule(cb2,
834 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
835 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700836
837 mMockClock.setLag(100);
838 mMockClock.advanceBy(620);
839
840 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
841
842 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
843 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
844 mMockClock.advanceToNextCallback();
845
846 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
847 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
848}
849
Kevin DuBoisf9477832020-07-16 10:21:36 -0700850TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
851 CountingCallback cb1(mDispatch);
852 CountingCallback cb2(mDispatch);
853
854 Sequence seq;
855 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
856 .InSequence(seq)
857 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700858 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700859 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
860 .InSequence(seq)
861 .WillOnce(Return(1000));
862
Ady Abraham9c53ee72020-07-22 21:16:18 -0700863 EXPECT_EQ(mDispatch.schedule(cb1,
864 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
865 ScheduleResult::Scheduled);
866 EXPECT_EQ(mDispatch.schedule(cb2,
867 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000}),
868 ScheduleResult::Scheduled);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700869
870 mMockClock.setLag(100);
871 mMockClock.advanceBy(700);
872
873 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
874 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700875 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
876 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700877 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
878 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700879 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
880 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
881}
882
883TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
884 auto intended = mPeriod - 230;
885 EXPECT_CALL(mMockClock, alarmAt(_, 900));
886
887 CountingCallback cb(mDispatch);
888 EXPECT_EQ(mDispatch.schedule(cb,
889 {.workDuration = 70,
890 .readyDuration = 30,
891 .earliestVsync = intended}),
892 ScheduleResult::Scheduled);
893 advanceToNextCallback();
894
895 ASSERT_THAT(cb.mCalls.size(), Eq(1));
896 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
897 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
898 EXPECT_THAT(cb.mWakeupTime[0], 900);
899 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
900 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700901}
902
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800903class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700904protected:
905 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800906 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700907 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
908};
909
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800910TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700911 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800912 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700913 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700914 EXPECT_THAT(entry.name(), Eq(name));
915 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
916 EXPECT_FALSE(entry.wakeupTime());
917}
918
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800919TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800920 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700921 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700922
923 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700924 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
925 mStubTracker, 0),
926 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800927 auto const wakeup = entry.wakeupTime();
928 ASSERT_TRUE(wakeup);
929 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700930
931 entry.disarm();
932 EXPECT_FALSE(entry.wakeupTime());
933}
934
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800935TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700936 auto const duration = 500;
937 auto const now = 8750;
938
939 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
940 .Times(1)
941 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800942 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700943 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700944
945 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700946 EXPECT_THAT(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
947 mStubTracker, now),
948 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800949 auto const wakeup = entry.wakeupTime();
950 ASSERT_TRUE(wakeup);
951 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700952}
953
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800954TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700955 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800956 auto vsyncCalledTime = 0;
957 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700958 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800959 VSyncDispatchTimerQueueEntry entry(
960 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -0700961 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800962 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800963 vsyncCalledTime = vsyncTime;
964 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700965 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800966 },
967 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700968
Ady Abraham9c53ee72020-07-22 21:16:18 -0700969 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
970 mStubTracker, 0),
971 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800972 auto const wakeup = entry.wakeupTime();
973 ASSERT_TRUE(wakeup);
974 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700975
Ady Abraham9c53ee72020-07-22 21:16:18 -0700976 auto const ready = entry.readyTime();
977 ASSERT_TRUE(ready);
978 EXPECT_THAT(*ready, Eq(1000));
979
980 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -0700981
982 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800983 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
984 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700985 EXPECT_FALSE(entry.wakeupTime());
986 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
987 ASSERT_TRUE(lastCalledTarget);
988 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
989}
990
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800991TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700992 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
993 .Times(2)
994 .WillOnce(Return(1000))
995 .WillOnce(Return(1020));
996
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800997 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700998 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700999
1000 EXPECT_FALSE(entry.wakeupTime());
1001 entry.update(mStubTracker, 0);
1002 EXPECT_FALSE(entry.wakeupTime());
1003
Ady Abraham9c53ee72020-07-22 21:16:18 -07001004 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1005 mStubTracker, 0),
1006 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001007 auto wakeup = entry.wakeupTime();
1008 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001009 EXPECT_THAT(wakeup, Eq(900));
1010
1011 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001012 wakeup = entry.wakeupTime();
1013 ASSERT_TRUE(wakeup);
1014 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001015}
1016
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001017TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001018 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001019 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1020 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1021 mStubTracker, 0),
1022 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001023 entry.update(mStubTracker, 0);
1024
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001025 auto const wakeup = entry.wakeupTime();
1026 ASSERT_TRUE(wakeup);
1027 EXPECT_THAT(*wakeup, Eq(wakeup));
1028}
1029
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001030TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1031 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001032 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1033 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1034 mStubTracker, 0),
1035 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001036 entry.executing(); // 1000 is executing
1037 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abraham9c53ee72020-07-22 21:16:18 -07001038 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1039 mStubTracker, 0),
1040 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001041 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001042 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001043
Ady Abraham9c53ee72020-07-22 21:16:18 -07001044 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1045 mStubTracker, 0),
1046 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001047 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001048 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001049
Ady Abraham9c53ee72020-07-22 21:16:18 -07001050 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1051 mStubTracker, 0),
1052 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001053 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001054 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001055}
1056
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001057TEST_F(VSyncDispatchTimerQueueEntryTest,
1058 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1059 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001060 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001061
1062 Sequence seq;
1063 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1064 .InSequence(seq)
1065 .WillOnce(Return(1000));
1066 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1067 .InSequence(seq)
1068 .WillOnce(Return(1000));
1069 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1070 .InSequence(seq)
1071 .WillOnce(Return(2000));
1072
Ady Abraham9c53ee72020-07-22 21:16:18 -07001073 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1074 mStubTracker, 0),
1075 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001076
1077 entry.executing(); // 1000 is executing
1078
Ady Abraham9c53ee72020-07-22 21:16:18 -07001079 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1080 mStubTracker, 0),
1081 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001082}
1083
1084TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1085 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001086 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1087 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1088 mStubTracker, 0),
1089 Eq(ScheduleResult::Scheduled));
1090 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1091 mStubTracker, 0),
1092 Eq(ScheduleResult::Scheduled));
1093 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1094 mStubTracker, 0),
1095 Eq(ScheduleResult::Scheduled));
1096 EXPECT_THAT(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1097 mStubTracker, 0),
1098 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001099}
1100
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001101TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1102 static constexpr auto effectualOffset = 200;
1103 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001104 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001105 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001106 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1107 entry.addPendingWorkloadUpdate(
1108 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001109 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1110 entry.update(mStubTracker, 0);
1111 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1112 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1113}
1114
Ady Abraham9c53ee72020-07-22 21:16:18 -07001115TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1116 auto callCount = 0;
1117 auto vsyncCalledTime = 0;
1118 auto wakeupCalledTime = 0;
1119 auto readyCalledTime = 0;
1120 VSyncDispatchTimerQueueEntry entry(
1121 "test",
1122 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1123 callCount++;
1124 vsyncCalledTime = vsyncTime;
1125 wakeupCalledTime = wakeupTime;
1126 readyCalledTime = readyTime;
1127 },
1128 mVsyncMoveThreshold);
1129
1130 EXPECT_THAT(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1131 mStubTracker, 0),
1132 Eq(ScheduleResult::Scheduled));
1133 auto const wakeup = entry.wakeupTime();
1134 ASSERT_TRUE(wakeup);
1135 EXPECT_THAT(*wakeup, Eq(900));
1136
1137 auto const ready = entry.readyTime();
1138 ASSERT_TRUE(ready);
1139 EXPECT_THAT(*ready, Eq(970));
1140
1141 entry.callback(entry.executing(), *wakeup, *ready);
1142
1143 EXPECT_THAT(callCount, Eq(1));
1144 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1145 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1146 EXPECT_FALSE(entry.wakeupTime());
1147 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1148 ASSERT_TRUE(lastCalledTarget);
1149 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1150}
1151
Kevin DuBois305bef12019-10-09 13:23:27 -07001152} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001153
1154// TODO(b/129481165): remove the #pragma below and fix conversion issues
1155#pragma clang diagnostic pop // ignored "-Wconversion"