blob: ddc02bfbe672a8fc0126b6636e039f984cc1246e [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"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010020#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080021
Kevin DuBois305bef12019-10-09 13:23:27 -070022#undef LOG_TAG
23#define LOG_TAG "LibSurfaceFlingerUnittests"
24#define LOG_NDEBUG 0
25
26#include "Scheduler/TimeKeeper.h"
Kevin DuBoise4f27a82019-11-12 11:41:41 -080027#include "Scheduler/VSyncDispatchTimerQueue.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070028#include "Scheduler/VSyncTracker.h"
29
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32#include <thread>
33
34using namespace testing;
35using namespace std::literals;
36namespace android::scheduler {
37
38class MockVSyncTracker : public VSyncTracker {
39public:
40 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
41 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
42 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080043 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Kevin DuBois305bef12019-10-09 13:23:27 -070044 }
45
Kevin DuBois02d5ed92020-01-27 11:05:46 -080046 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070047 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080048 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080049 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080050 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070051 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5cc2e262021-03-25 13:09:17 -070052 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
Ady Abraham5e7371c2020-03-24 14:47:24 -070053 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070054
55 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
56 if (timePoint % mPeriod == 0) {
57 return timePoint;
58 }
59 return (timePoint - (timePoint % mPeriod) + mPeriod);
60 }
61
62protected:
63 nsecs_t const mPeriod;
64};
65
66class ControllableClock : public TimeKeeper {
67public:
68 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070069 ON_CALL(*this, alarmAt(_, _))
70 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070071 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
72 }
73
74 MOCK_CONST_METHOD0(now, nsecs_t());
Ady Abrahamb491c902020-08-15 15:47:56 -070075 MOCK_METHOD2(alarmAt, void(std::function<void()> const&, nsecs_t time));
Kevin DuBois305bef12019-10-09 13:23:27 -070076 MOCK_METHOD0(alarmCancel, void());
Ady Abraham75398722020-04-07 14:08:45 -070077 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070078
Ady Abrahamb491c902020-08-15 15:47:56 -070079 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070080 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070081 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070082 }
83
84 nsecs_t fakeTime() const { return mCurrentTime; }
85
86 void advanceToNextCallback() {
87 mCurrentTime = mNextCallbackTime;
88 if (mCallback) {
89 mCallback();
90 }
91 }
92
93 void advanceBy(nsecs_t advancement) {
94 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070095 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070096 mCallback();
97 }
98 };
99
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700100 void setLag(nsecs_t lag) { mLag = lag; }
101
Kevin DuBois305bef12019-10-09 13:23:27 -0700102private:
103 std::function<void()> mCallback;
104 nsecs_t mNextCallbackTime = 0;
105 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700106 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700107};
108
109class CountingCallback {
110public:
111 CountingCallback(VSyncDispatch& dispatch)
112 : mDispatch(dispatch),
113 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700114 std::placeholders::_1, std::placeholders::_2,
115 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700116 "test")) {}
117 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
118
119 operator VSyncDispatch::CallbackToken() const { return mToken; }
120
Ady Abraham9c53ee72020-07-22 21:16:18 -0700121 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700122 mCalls.push_back(time);
123 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700124 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700125 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700126
127 VSyncDispatch& mDispatch;
128 VSyncDispatch::CallbackToken mToken;
129 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700130 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700131 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700132};
133
134class PausingCallback {
135public:
136 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
137 : mDispatch(dispatch),
138 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800139 std::placeholders::_1,
140 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700141 "test")),
142 mRegistered(true),
143 mPauseAmount(pauseAmount) {}
144 ~PausingCallback() { unregister(); }
145
146 operator VSyncDispatch::CallbackToken() const { return mToken; }
147
Kevin DuBois2968afc2020-01-14 09:48:50 -0800148 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700149 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700150 mPause = true;
151 mCv.notify_all();
152
Ady Abraham8cb21882020-08-26 18:22:05 -0700153 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700154
155 mResourcePresent = (mResource.lock() != nullptr);
156 }
157
158 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700159 std::unique_lock lock(mMutex);
160 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700161 return waiting;
162 }
163
164 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
165
166 bool resourcePresent() { return mResourcePresent; }
167
168 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700169 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700170 mPause = false;
171 mCv.notify_all();
172 }
173
174 void unregister() {
175 if (mRegistered) {
176 mDispatch.unregisterCallback(mToken);
177 mRegistered = false;
178 }
179 }
180
181 VSyncDispatch& mDispatch;
182 VSyncDispatch::CallbackToken mToken;
183 bool mRegistered = true;
184
185 std::mutex mMutex;
186 std::condition_variable mCv;
187 bool mPause = false;
188 std::weak_ptr<void> mResource;
189 bool mResourcePresent = false;
190 std::chrono::milliseconds const mPauseAmount;
191};
192
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800193class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700194protected:
195 std::unique_ptr<TimeKeeper> createTimeKeeper() {
196 class TimeKeeperWrapper : public TimeKeeper {
197 public:
198 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Ady Abrahamb491c902020-08-15 15:47:56 -0700199 void alarmAt(std::function<void()> const& callback, nsecs_t time) final {
200 mControllableClock.alarmAt(callback, time);
Kevin DuBois305bef12019-10-09 13:23:27 -0700201 }
202 void alarmCancel() final { mControllableClock.alarmCancel(); }
203 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700204 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700205
206 private:
207 TimeKeeper& mControllableClock;
208 };
209 return std::make_unique<TimeKeeperWrapper>(mMockClock);
210 }
211
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800212 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700213 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
214 Mock::VerifyAndClearExpectations(&mMockClock);
215 }
216
217 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
218
219 NiceMock<ControllableClock> mMockClock;
220 static nsecs_t constexpr mDispatchGroupThreshold = 5;
221 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800222 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700223 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800224 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
225 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700226};
227
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800228TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700229 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700230 EXPECT_CALL(mMockClock, alarmCancel());
231 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800232 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
233 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700234 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700235 const auto result = mDispatch.schedule(cb,
236 {.workDuration = 100,
237 .readyDuration = 0,
238 .earliestVsync = 1000});
239 EXPECT_TRUE(result.has_value());
240 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700241 }
242}
243
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800244TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700245 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700246 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700247
248 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700249 const auto result = mDispatch.schedule(cb,
250 {.workDuration = 100,
251 .readyDuration = 0,
252 .earliestVsync = intended});
253 EXPECT_TRUE(result.has_value());
254 EXPECT_EQ(900, *result);
255
Kevin DuBois305bef12019-10-09 13:23:27 -0700256 advanceToNextCallback();
257
258 ASSERT_THAT(cb.mCalls.size(), Eq(1));
259 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
260}
261
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800262TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700263 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700264 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700265
266 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700267 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700268 advanceToNextCallback();
269
270 ASSERT_THAT(cb.mCalls.size(), Eq(1));
271 EXPECT_THAT(cb.mCalls[0], Eq(1150));
272}
273
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800274TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700275 auto const now = 234;
276 mMockClock.advanceBy(234);
277 auto const workDuration = 10 * mPeriod;
278 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
279 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700280 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700281
282 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700283 const auto result = mDispatch.schedule(cb,
284 {.workDuration = workDuration,
285 .readyDuration = 0,
286 .earliestVsync = mPeriod});
287 EXPECT_TRUE(result.has_value());
288 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700289}
290
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800291TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700292 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700293 EXPECT_CALL(mMockClock, alarmCancel());
294
295 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700296 const auto result =
297 mDispatch.schedule(cb,
298 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
299 EXPECT_TRUE(result.has_value());
300 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700301 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
302}
303
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800304TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
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 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700309 const auto result =
310 mDispatch.schedule(cb,
311 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
312 EXPECT_TRUE(result.has_value());
313 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700314 mMockClock.advanceBy(950);
315 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
316}
317
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800318TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700319 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700320 EXPECT_CALL(mMockClock, alarmCancel());
321
322 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700323 const auto result =
324 mDispatch.schedule(cb,
325 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
326 EXPECT_TRUE(result.has_value());
327 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700328
329 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
330 EXPECT_TRUE(cb.waitForPause());
331 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
332 cb.unpause();
333 pausingThread.join();
334}
335
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800336TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700337 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700338 EXPECT_CALL(mMockClock, alarmCancel());
339
340 auto resource = std::make_shared<int>(110);
341
342 PausingCallback cb(mDispatch, 50ms);
343 cb.stashResource(resource);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700344 const auto result =
345 mDispatch.schedule(cb,
346 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
347 EXPECT_TRUE(result.has_value());
348 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700349
350 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
351 EXPECT_TRUE(cb.waitForPause());
352
353 cb.unregister();
354 resource.reset();
355
356 cb.unpause();
357 pausingThread.join();
358
359 EXPECT_TRUE(cb.resourcePresent());
360}
361
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800362TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700363 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
364 .Times(4)
365 .WillOnce(Return(1055))
366 .WillOnce(Return(1063))
367 .WillOnce(Return(1063))
368 .WillOnce(Return(1075));
369
370 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700371 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
372 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
373 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700374
375 CountingCallback cb0(mDispatch);
376 CountingCallback cb1(mDispatch);
377
Ady Abraham9c53ee72020-07-22 21:16:18 -0700378 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
379 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700380
381 advanceToNextCallback();
382 advanceToNextCallback();
383
384 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
385 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
386 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
387 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
388}
389
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800390TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700391 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
392 .Times(4)
393 .WillOnce(Return(10000))
394 .WillOnce(Return(1000))
395 .WillOnce(Return(10000))
396 .WillOnce(Return(10000));
397
398 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700399 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
400 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
401 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700402
403 CountingCallback cb0(mDispatch);
404 CountingCallback cb1(mDispatch);
405
Ady Abraham9c53ee72020-07-22 21:16:18 -0700406 mDispatch.schedule(cb0,
407 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
408 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700409 mDispatch.cancel(cb1);
410}
411
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800412TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700413 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700414 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
415 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700416
417 CountingCallback cb0(mDispatch);
418 CountingCallback cb1(mDispatch);
419
Ady Abraham9c53ee72020-07-22 21:16:18 -0700420 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
421 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
422 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700423 advanceToNextCallback();
424}
425
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800426TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700427 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700428 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
429 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
430 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700431
432 CountingCallback cb0(mDispatch);
433 CountingCallback cb1(mDispatch);
434
Ady Abraham9c53ee72020-07-22 21:16:18 -0700435 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
436 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
437 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700438 advanceToNextCallback();
439}
440
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800441TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700442 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700443 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
444 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
445 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
446 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700447
448 auto offset = 400;
449 auto closeOffset = offset + mDispatchGroupThreshold - 1;
450 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
451
452 CountingCallback cb0(mDispatch);
453 CountingCallback cb1(mDispatch);
454
Ady Abraham9c53ee72020-07-22 21:16:18 -0700455 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
456 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
457 mDispatch.schedule(cb1,
458 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700459
460 advanceToNextCallback();
461 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
462 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
463 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
464 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
465
Ady Abraham9c53ee72020-07-22 21:16:18 -0700466 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
467 mDispatch.schedule(cb1,
468 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700469 advanceToNextCallback();
470 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
471 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
472
473 advanceToNextCallback();
474 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
475 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
476}
477
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800478TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700479 Sequence seq;
480 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
481 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
482 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700483 EXPECT_CALL(mMockClock, alarmCancel());
484
485 CountingCallback cb0(mDispatch);
486 CountingCallback cb1(mDispatch);
487
Ady Abraham9c53ee72020-07-22 21:16:18 -0700488 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
489 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700490 advanceToNextCallback();
491 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
492}
493
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800494TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700495 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
496 .Times(3)
497 .WillOnce(Return(950))
498 .WillOnce(Return(1975))
499 .WillOnce(Return(2950));
500
501 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700502 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700503
504 mMockClock.advanceBy(850);
505 EXPECT_THAT(cb.mCalls.size(), Eq(1));
506
Ady Abraham9c53ee72020-07-22 21:16:18 -0700507 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700508 mMockClock.advanceBy(900);
509 EXPECT_THAT(cb.mCalls.size(), Eq(1));
510 mMockClock.advanceBy(125);
511 EXPECT_THAT(cb.mCalls.size(), Eq(2));
512
Ady Abraham9c53ee72020-07-22 21:16:18 -0700513 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700514 mMockClock.advanceBy(975);
515 EXPECT_THAT(cb.mCalls.size(), Eq(3));
516}
517
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800518TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700519 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700520 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
521 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700522
523 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700524 tmp = mDispatch.registerCallback(
525 [&](auto, auto, auto) {
526 mDispatch.schedule(tmp,
527 {.workDuration = 100,
528 .readyDuration = 0,
529 .earliestVsync = 2000});
530 },
531 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700532
Ady Abraham9c53ee72020-07-22 21:16:18 -0700533 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700534 advanceToNextCallback();
535}
536
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800537TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700538 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800539 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700540 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700541 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700542 auto result =
543 mDispatch.schedule(tmp,
544 {.workDuration = 400,
545 .readyDuration = 0,
546 .earliestVsync = timestamp - mVsyncMoveThreshold});
547 EXPECT_TRUE(result.has_value());
548 EXPECT_EQ(mPeriod + timestamp - 400, *result);
549 result = mDispatch.schedule(tmp,
550 {.workDuration = 400,
551 .readyDuration = 0,
552 .earliestVsync = timestamp});
553 EXPECT_TRUE(result.has_value());
554 EXPECT_EQ(mPeriod + timestamp - 400, *result);
555 result = mDispatch.schedule(tmp,
556 {.workDuration = 400,
557 .readyDuration = 0,
558 .earliestVsync = timestamp + mVsyncMoveThreshold});
559 EXPECT_TRUE(result.has_value());
560 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800561 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700562 },
563 "oo");
564
Ady Abraham9c53ee72020-07-22 21:16:18 -0700565 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700566 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800567 EXPECT_THAT(lastTarget, Eq(1000));
568
569 advanceToNextCallback();
570 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700571}
572
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800573TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700574 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700575 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
576 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
577 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
578 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700579
580 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700581 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700582
583 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700584 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700585
586 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700587 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700588
589 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700590 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700591}
592
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800593TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700594 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700595 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
596 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
597 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
598 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700599
600 CountingCallback cb0(mDispatch);
601 CountingCallback cb1(mDispatch);
602
Ady Abraham9c53ee72020-07-22 21:16:18 -0700603 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
604 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700605
606 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700607 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
608 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700609
610 advanceToNextCallback();
611 advanceToNextCallback();
612}
613
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800614TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700615 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700616 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700617
618 CountingCallback cb0(mDispatch);
619 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700620 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
621 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700622}
623
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800624TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700625 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700626 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700627 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700628 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700629
630 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700631 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700632 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700633 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700634}
635
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800636TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700637 VSyncDispatch::CallbackToken token(100);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700638 EXPECT_FALSE(mDispatch
639 .schedule(token,
640 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
641 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -0700642 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
643}
644
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800645TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700646 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700647 auto result =
648 mDispatch.schedule(cb0,
649 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
650 EXPECT_TRUE(result.has_value());
651 EXPECT_EQ(500, *result);
652 result = mDispatch.schedule(cb0,
653 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
654 EXPECT_TRUE(result.has_value());
655 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800656}
657
658// b/1450138150
659TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700660 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800661 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700662 auto result =
663 mDispatch.schedule(cb,
664 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
665 EXPECT_TRUE(result.has_value());
666 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800667 mMockClock.advanceBy(400);
668
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700669 result = mDispatch.schedule(cb,
670 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
671 EXPECT_TRUE(result.has_value());
672 EXPECT_EQ(1200, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800673 advanceToNextCallback();
674 ASSERT_THAT(cb.mCalls.size(), Eq(1));
675}
676
677TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
678 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
679 .Times(2)
680 .WillOnce(Return(1000))
681 .WillOnce(Return(1002));
682 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700683 auto result =
684 mDispatch.schedule(cb,
685 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
686 EXPECT_TRUE(result.has_value());
687 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800688 mMockClock.advanceBy(400);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700689 result = mDispatch.schedule(cb,
690 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
691 EXPECT_TRUE(result.has_value());
692 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700693}
694
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800695TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
696 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700697 auto result =
698 mDispatch.schedule(cb0,
699 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
700 EXPECT_TRUE(result.has_value());
701 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800702 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700703 result = mDispatch.schedule(cb0,
704 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
705 EXPECT_TRUE(result.has_value());
706 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800707}
708
709TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
710 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700711 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
712 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800713 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700714 auto result =
715 mDispatch.schedule(cb0,
716 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
717 EXPECT_TRUE(result.has_value());
718 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800719 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700720 result = mDispatch.schedule(cb0,
721 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
722 EXPECT_TRUE(result.has_value());
723 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800724}
725
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800726TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700727 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800728
729 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700730 auto result =
731 mDispatch.schedule(cb,
732 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
733 EXPECT_TRUE(result.has_value());
734 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800735
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700736 result = mDispatch.schedule(cb,
737 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
738 EXPECT_TRUE(result.has_value());
739 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800740
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800741 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800742}
743
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800744TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700745 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700746 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
747
748 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700749 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700750 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700751 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700752 cb.cancel();
753
Ady Abraham9c53ee72020-07-22 21:16:18 -0700754 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700755 cb1.cancel();
756}
757
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800758TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700759 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700760 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
761
762 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700763 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700764 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700765 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700766 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700767 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700768 cb.cancel();
769
Ady Abraham9c53ee72020-07-22 21:16:18 -0700770 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700771 cb1.cancel();
772}
773
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700774// b/154303580
775TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
776 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700777 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
778 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700779 CountingCallback cb1(mDispatch);
780 CountingCallback cb2(mDispatch);
781
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700782 auto result =
783 mDispatch.schedule(cb1,
784 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
785 EXPECT_TRUE(result.has_value());
786 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700787
788 mMockClock.setLag(100);
789 mMockClock.advanceBy(620);
790
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700791 result = mDispatch.schedule(cb2,
792 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
793 EXPECT_TRUE(result.has_value());
794 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700795 mMockClock.advanceBy(80);
796
797 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
798 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
799}
800
801// b/154303580.
802// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
803// update later, as opposed to blocking the calling thread.
804TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
805 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700806 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
807 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700808 CountingCallback cb(mDispatch);
809
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700810 auto result =
811 mDispatch.schedule(cb,
812 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
813 EXPECT_TRUE(result.has_value());
814 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700815
816 mMockClock.setLag(100);
817 mMockClock.advanceBy(620);
818
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700819 result = mDispatch.schedule(cb,
820 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
821 EXPECT_TRUE(result.has_value());
822 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700823 mMockClock.advanceBy(80);
824
825 EXPECT_THAT(cb.mCalls.size(), Eq(1));
826}
827
Kevin DuBoisb340b732020-06-16 09:07:35 -0700828// b/154303580.
829TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
830 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700831 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700832 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
833 CountingCallback cb1(mDispatch);
834 CountingCallback cb2(mDispatch);
835
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700836 auto result =
837 mDispatch.schedule(cb1,
838 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
839 EXPECT_TRUE(result.has_value());
840 EXPECT_EQ(600, *result);
841 result = mDispatch.schedule(cb2,
842 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
843 EXPECT_TRUE(result.has_value());
844 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700845
846 mMockClock.setLag(100);
847 mMockClock.advanceBy(620);
848
849 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
850
851 mMockClock.advanceBy(80);
852
853 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
854 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
855}
856
857TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
858 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700859 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
860 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700861 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
862 CountingCallback cb1(mDispatch);
863 CountingCallback cb2(mDispatch);
864
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700865 auto result =
866 mDispatch.schedule(cb1,
867 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
868 EXPECT_TRUE(result.has_value());
869 EXPECT_EQ(600, *result);
870 result = mDispatch.schedule(cb2,
871 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
872 EXPECT_TRUE(result.has_value());
873 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700874
875 mMockClock.setLag(100);
876 mMockClock.advanceBy(620);
877
878 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
879
880 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
881 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
882 mMockClock.advanceToNextCallback();
883
884 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
885 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
886}
887
Kevin DuBoisf9477832020-07-16 10:21:36 -0700888TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
889 CountingCallback cb1(mDispatch);
890 CountingCallback cb2(mDispatch);
891
892 Sequence seq;
893 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
894 .InSequence(seq)
895 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700896 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700897 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
898 .InSequence(seq)
899 .WillOnce(Return(1000));
900
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700901 auto result =
902 mDispatch.schedule(cb1,
903 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
904 EXPECT_TRUE(result.has_value());
905 EXPECT_EQ(600, *result);
906 result = mDispatch.schedule(cb2,
907 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
908 EXPECT_TRUE(result.has_value());
909 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700910
911 mMockClock.setLag(100);
912 mMockClock.advanceBy(700);
913
914 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
915 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700916 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
917 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700918 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
919 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700920 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
921 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
922}
923
924TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
925 auto intended = mPeriod - 230;
926 EXPECT_CALL(mMockClock, alarmAt(_, 900));
927
928 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700929 const auto result = mDispatch.schedule(cb,
930 {.workDuration = 70,
931 .readyDuration = 30,
932 .earliestVsync = intended});
933 EXPECT_TRUE(result.has_value());
934 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700935 advanceToNextCallback();
936
937 ASSERT_THAT(cb.mCalls.size(), Eq(1));
938 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
939 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
940 EXPECT_THAT(cb.mWakeupTime[0], 900);
941 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
942 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700943}
944
Ady Abraham69b9e622021-07-19 12:24:31 -0700945TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
946 Sequence seq;
947 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
948
949 CountingCallback cb(mDispatch);
950
951 mDispatch.schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
952 mDispatch.schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
953
954 advanceToNextCallback();
955
956 advanceToNextCallback();
957
958 ASSERT_THAT(cb.mCalls.size(), Eq(1));
959 EXPECT_THAT(cb.mCalls[0], Eq(2000));
960 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
961 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
962 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
963 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
964}
965
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800966class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700967protected:
968 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800969 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700970 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
971};
972
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800973TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700974 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800975 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700976 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700977 EXPECT_THAT(entry.name(), Eq(name));
978 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
979 EXPECT_FALSE(entry.wakeupTime());
980}
981
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800982TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800983 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700984 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700985
986 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700987 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
988 mStubTracker, 0)
989 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800990 auto const wakeup = entry.wakeupTime();
991 ASSERT_TRUE(wakeup);
992 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700993
994 entry.disarm();
995 EXPECT_FALSE(entry.wakeupTime());
996}
997
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800998TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700999 auto const duration = 500;
1000 auto const now = 8750;
1001
1002 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
1003 .Times(1)
1004 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001005 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001006 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001007
1008 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001009 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
1010 mStubTracker, now)
1011 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001012 auto const wakeup = entry.wakeupTime();
1013 ASSERT_TRUE(wakeup);
1014 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001015}
1016
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001017TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001018 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001019 auto vsyncCalledTime = 0;
1020 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001021 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001022 VSyncDispatchTimerQueueEntry entry(
1023 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001024 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001025 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001026 vsyncCalledTime = vsyncTime;
1027 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001028 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001029 },
1030 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001031
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001032 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1033 mStubTracker, 0)
1034 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001035 auto const wakeup = entry.wakeupTime();
1036 ASSERT_TRUE(wakeup);
1037 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001038
Ady Abraham9c53ee72020-07-22 21:16:18 -07001039 auto const ready = entry.readyTime();
1040 ASSERT_TRUE(ready);
1041 EXPECT_THAT(*ready, Eq(1000));
1042
1043 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001044
1045 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001046 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1047 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001048 EXPECT_FALSE(entry.wakeupTime());
1049 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1050 ASSERT_TRUE(lastCalledTarget);
1051 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1052}
1053
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001054TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001055 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
1056 .Times(2)
1057 .WillOnce(Return(1000))
1058 .WillOnce(Return(1020));
1059
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001060 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001061 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001062
1063 EXPECT_FALSE(entry.wakeupTime());
1064 entry.update(mStubTracker, 0);
1065 EXPECT_FALSE(entry.wakeupTime());
1066
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001067 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1068 mStubTracker, 0)
1069 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001070 auto wakeup = entry.wakeupTime();
1071 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001072 EXPECT_THAT(wakeup, Eq(900));
1073
1074 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001075 wakeup = entry.wakeupTime();
1076 ASSERT_TRUE(wakeup);
1077 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001078}
1079
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001080TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001081 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001082 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001083 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1084 mStubTracker, 0)
1085 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001086 entry.update(mStubTracker, 0);
1087
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001088 auto const wakeup = entry.wakeupTime();
1089 ASSERT_TRUE(wakeup);
1090 EXPECT_THAT(*wakeup, Eq(wakeup));
1091}
1092
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001093TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1094 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001095 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001096 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1097 mStubTracker, 0)
1098 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001099 entry.executing(); // 1000 is executing
1100 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001101 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1102 mStubTracker, 0)
1103 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001104 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001105 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001106
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001107 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1108 mStubTracker, 0)
1109 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001110 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001111 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001112
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001113 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1114 mStubTracker, 0)
1115 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001116 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001117 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001118}
1119
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001120TEST_F(VSyncDispatchTimerQueueEntryTest,
1121 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1122 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001123 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001124
1125 Sequence seq;
1126 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1127 .InSequence(seq)
1128 .WillOnce(Return(1000));
1129 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1130 .InSequence(seq)
1131 .WillOnce(Return(1000));
1132 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1133 .InSequence(seq)
1134 .WillOnce(Return(2000));
1135
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001136 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1137 mStubTracker, 0)
1138 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001139
1140 entry.executing(); // 1000 is executing
1141
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001142 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1143 mStubTracker, 0)
1144 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001145}
1146
1147TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1148 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001149 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001150 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1151 mStubTracker, 0)
1152 .has_value());
1153 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1154 mStubTracker, 0)
1155 .has_value());
1156 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1157 mStubTracker, 0)
1158 .has_value());
1159 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1160 mStubTracker, 0)
1161 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001162}
1163
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001164TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1165 static constexpr auto effectualOffset = 200;
1166 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001167 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001168 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001169 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1170 entry.addPendingWorkloadUpdate(
1171 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001172 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1173 entry.update(mStubTracker, 0);
1174 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1175 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1176}
1177
Ady Abraham9c53ee72020-07-22 21:16:18 -07001178TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1179 auto callCount = 0;
1180 auto vsyncCalledTime = 0;
1181 auto wakeupCalledTime = 0;
1182 auto readyCalledTime = 0;
1183 VSyncDispatchTimerQueueEntry entry(
1184 "test",
1185 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1186 callCount++;
1187 vsyncCalledTime = vsyncTime;
1188 wakeupCalledTime = wakeupTime;
1189 readyCalledTime = readyTime;
1190 },
1191 mVsyncMoveThreshold);
1192
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001193 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1194 mStubTracker, 0)
1195 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001196 auto const wakeup = entry.wakeupTime();
1197 ASSERT_TRUE(wakeup);
1198 EXPECT_THAT(*wakeup, Eq(900));
1199
1200 auto const ready = entry.readyTime();
1201 ASSERT_TRUE(ready);
1202 EXPECT_THAT(*ready, Eq(970));
1203
1204 entry.callback(entry.executing(), *wakeup, *ready);
1205
1206 EXPECT_THAT(callCount, Eq(1));
1207 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1208 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1209 EXPECT_FALSE(entry.wakeupTime());
1210 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1211 ASSERT_TRUE(lastCalledTarget);
1212 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1213}
1214
Kevin DuBois305bef12019-10-09 13:23:27 -07001215} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001216
1217// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001218#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"