blob: 2b86e942446bdbb1d9bde7ea4536033c7ea90782 [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
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080026#include <thread>
Kevin DuBois305bef12019-10-09 13:23:27 -070027
28#include <gmock/gmock.h>
29#include <gtest/gtest.h>
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080030
31#include <scheduler/TimeKeeper.h>
32
33#include "Scheduler/VSyncDispatchTimerQueue.h"
34#include "Scheduler/VSyncTracker.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070035
36using namespace testing;
37using namespace std::literals;
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080038
Kevin DuBois305bef12019-10-09 13:23:27 -070039namespace android::scheduler {
40
41class MockVSyncTracker : public VSyncTracker {
42public:
43 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
44 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
45 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080046 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070047 ON_CALL(*this, currentPeriod())
48 .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -070049 }
50
Kevin DuBois02d5ed92020-01-27 11:05:46 -080051 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070052 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080053 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080054 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080055 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070056 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5cc2e262021-03-25 13:09:17 -070057 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
Ady Abrahamace3d052022-11-17 16:25:05 -080058 MOCK_METHOD(void, setDivisor, (unsigned), (override));
Ady Abraham5e7371c2020-03-24 14:47:24 -070059 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070060
61 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
62 if (timePoint % mPeriod == 0) {
63 return timePoint;
64 }
65 return (timePoint - (timePoint % mPeriod) + mPeriod);
66 }
67
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070068 nsecs_t getCurrentPeriod() const { return mPeriod; }
69
Kevin DuBois305bef12019-10-09 13:23:27 -070070protected:
71 nsecs_t const mPeriod;
72};
73
74class ControllableClock : public TimeKeeper {
75public:
76 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070077 ON_CALL(*this, alarmAt(_, _))
78 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070079 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
80 }
81
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080082 MOCK_METHOD(nsecs_t, now, (), (const));
83 MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
84 MOCK_METHOD(void, alarmCancel, (), (override));
85 MOCK_METHOD(void, dump, (std::string&), (const, override));
Kevin DuBois305bef12019-10-09 13:23:27 -070086
Ady Abrahamb491c902020-08-15 15:47:56 -070087 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070088 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070089 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070090 }
91
92 nsecs_t fakeTime() const { return mCurrentTime; }
93
94 void advanceToNextCallback() {
95 mCurrentTime = mNextCallbackTime;
96 if (mCallback) {
97 mCallback();
98 }
99 }
100
101 void advanceBy(nsecs_t advancement) {
102 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700103 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700104 mCallback();
105 }
106 };
107
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700108 void setLag(nsecs_t lag) { mLag = lag; }
109
Kevin DuBois305bef12019-10-09 13:23:27 -0700110private:
111 std::function<void()> mCallback;
112 nsecs_t mNextCallbackTime = 0;
113 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700114 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700115};
116
117class CountingCallback {
118public:
119 CountingCallback(VSyncDispatch& dispatch)
120 : mDispatch(dispatch),
121 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700122 std::placeholders::_1, std::placeholders::_2,
123 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700124 "test")) {}
125 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
126
127 operator VSyncDispatch::CallbackToken() const { return mToken; }
128
Ady Abraham9c53ee72020-07-22 21:16:18 -0700129 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700130 mCalls.push_back(time);
131 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700132 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700133 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700134
135 VSyncDispatch& mDispatch;
136 VSyncDispatch::CallbackToken mToken;
137 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700138 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700139 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700140};
141
142class PausingCallback {
143public:
144 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
145 : mDispatch(dispatch),
146 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800147 std::placeholders::_1,
148 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700149 "test")),
150 mRegistered(true),
151 mPauseAmount(pauseAmount) {}
152 ~PausingCallback() { unregister(); }
153
154 operator VSyncDispatch::CallbackToken() const { return mToken; }
155
Kevin DuBois2968afc2020-01-14 09:48:50 -0800156 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700157 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700158 mPause = true;
159 mCv.notify_all();
160
Ady Abraham8cb21882020-08-26 18:22:05 -0700161 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700162
163 mResourcePresent = (mResource.lock() != nullptr);
164 }
165
166 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700167 std::unique_lock lock(mMutex);
168 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700169 return waiting;
170 }
171
172 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
173
174 bool resourcePresent() { return mResourcePresent; }
175
176 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700177 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700178 mPause = false;
179 mCv.notify_all();
180 }
181
182 void unregister() {
183 if (mRegistered) {
184 mDispatch.unregisterCallback(mToken);
185 mRegistered = false;
186 }
187 }
188
189 VSyncDispatch& mDispatch;
190 VSyncDispatch::CallbackToken mToken;
191 bool mRegistered = true;
192
193 std::mutex mMutex;
194 std::condition_variable mCv;
195 bool mPause = false;
196 std::weak_ptr<void> mResource;
197 bool mResourcePresent = false;
198 std::chrono::milliseconds const mPauseAmount;
199};
200
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800201class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700202protected:
203 std::unique_ptr<TimeKeeper> createTimeKeeper() {
204 class TimeKeeperWrapper : public TimeKeeper {
205 public:
206 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800207
Kevin DuBois305bef12019-10-09 13:23:27 -0700208 nsecs_t now() const final { return mControllableClock.now(); }
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800209
210 void alarmAt(std::function<void()> callback, nsecs_t time) final {
211 mControllableClock.alarmAt(std::move(callback), time);
212 }
213
214 void alarmCancel() final { mControllableClock.alarmCancel(); }
Ady Abraham75398722020-04-07 14:08:45 -0700215 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700216
217 private:
218 TimeKeeper& mControllableClock;
219 };
220 return std::make_unique<TimeKeeperWrapper>(mMockClock);
221 }
222
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800223 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700224 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
225 Mock::VerifyAndClearExpectations(&mMockClock);
226 }
227
228 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
229
230 NiceMock<ControllableClock> mMockClock;
231 static nsecs_t constexpr mDispatchGroupThreshold = 5;
232 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800233 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700234 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800235 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
236 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700237};
238
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800239TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700240 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700241 EXPECT_CALL(mMockClock, alarmCancel());
242 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800243 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
244 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700245 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700246 const auto result = mDispatch.schedule(cb,
247 {.workDuration = 100,
248 .readyDuration = 0,
249 .earliestVsync = 1000});
250 EXPECT_TRUE(result.has_value());
251 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700252 }
253}
254
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800255TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700256 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700257 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700258
259 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700260 const auto result = mDispatch.schedule(cb,
261 {.workDuration = 100,
262 .readyDuration = 0,
263 .earliestVsync = intended});
264 EXPECT_TRUE(result.has_value());
265 EXPECT_EQ(900, *result);
266
Kevin DuBois305bef12019-10-09 13:23:27 -0700267 advanceToNextCallback();
268
269 ASSERT_THAT(cb.mCalls.size(), Eq(1));
270 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
271}
272
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800273TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700274 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700275 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700276
277 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700278 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700279 advanceToNextCallback();
280
281 ASSERT_THAT(cb.mCalls.size(), Eq(1));
282 EXPECT_THAT(cb.mCalls[0], Eq(1150));
283}
284
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800285TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700286 auto const now = 234;
287 mMockClock.advanceBy(234);
288 auto const workDuration = 10 * mPeriod;
289 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
290 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700291 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700292
293 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700294 const auto result = mDispatch.schedule(cb,
295 {.workDuration = workDuration,
296 .readyDuration = 0,
297 .earliestVsync = mPeriod});
298 EXPECT_TRUE(result.has_value());
299 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700300}
301
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800302TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700303 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700304 EXPECT_CALL(mMockClock, alarmCancel());
305
306 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700307 const auto result =
308 mDispatch.schedule(cb,
309 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
310 EXPECT_TRUE(result.has_value());
311 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700312 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
313}
314
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800315TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700316 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700317 EXPECT_CALL(mMockClock, alarmCancel());
318
319 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700320 const auto result =
321 mDispatch.schedule(cb,
322 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
323 EXPECT_TRUE(result.has_value());
324 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700325 mMockClock.advanceBy(950);
326 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
327}
328
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800329TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700330 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700331 EXPECT_CALL(mMockClock, alarmCancel());
332
333 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700334 const auto result =
335 mDispatch.schedule(cb,
336 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
337 EXPECT_TRUE(result.has_value());
338 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700339
340 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
341 EXPECT_TRUE(cb.waitForPause());
342 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
343 cb.unpause();
344 pausingThread.join();
345}
346
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800347TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700348 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700349 EXPECT_CALL(mMockClock, alarmCancel());
350
351 auto resource = std::make_shared<int>(110);
352
353 PausingCallback cb(mDispatch, 50ms);
354 cb.stashResource(resource);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700355 const auto result =
356 mDispatch.schedule(cb,
357 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
358 EXPECT_TRUE(result.has_value());
359 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700360
361 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
362 EXPECT_TRUE(cb.waitForPause());
363
364 cb.unregister();
365 resource.reset();
366
367 cb.unpause();
368 pausingThread.join();
369
370 EXPECT_TRUE(cb.resourcePresent());
371}
372
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800373TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700374 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
375 .Times(4)
376 .WillOnce(Return(1055))
377 .WillOnce(Return(1063))
378 .WillOnce(Return(1063))
379 .WillOnce(Return(1075));
380
381 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700382 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
383 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
384 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700385
386 CountingCallback cb0(mDispatch);
387 CountingCallback cb1(mDispatch);
388
Ady Abraham9c53ee72020-07-22 21:16:18 -0700389 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
390 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700391
392 advanceToNextCallback();
393 advanceToNextCallback();
394
395 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
396 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
397 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
398 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
399}
400
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700401TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
402 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
403 .Times(4)
404 .WillOnce(Return(1000))
405 .WillOnce(Return(2000))
406 .WillOnce(Return(2500))
407 .WillOnce(Return(4000));
408
409 Sequence seq;
410 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
411 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
412 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
413
414 CountingCallback cb(mDispatch);
415
416 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
417
418 advanceToNextCallback();
419
420 ASSERT_THAT(cb.mCalls.size(), Eq(1));
421 EXPECT_THAT(cb.mCalls[0], Eq(1000));
422
423 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
424
425 advanceToNextCallback();
426
427 ASSERT_THAT(cb.mCalls.size(), Eq(2));
428 EXPECT_THAT(cb.mCalls[1], Eq(2000));
429
430 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
431
432 advanceToNextCallback();
433
434 ASSERT_THAT(cb.mCalls.size(), Eq(3));
435 EXPECT_THAT(cb.mCalls[2], Eq(4000));
436}
437
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800438TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700439 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
440 .Times(4)
441 .WillOnce(Return(10000))
442 .WillOnce(Return(1000))
443 .WillOnce(Return(10000))
444 .WillOnce(Return(10000));
445
446 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700447 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
448 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
449 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700450
451 CountingCallback cb0(mDispatch);
452 CountingCallback cb1(mDispatch);
453
Ady Abraham9c53ee72020-07-22 21:16:18 -0700454 mDispatch.schedule(cb0,
455 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
456 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700457 mDispatch.cancel(cb1);
458}
459
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800460TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700461 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700462 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
463 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700464
465 CountingCallback cb0(mDispatch);
466 CountingCallback cb1(mDispatch);
467
Ady Abraham9c53ee72020-07-22 21:16:18 -0700468 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
469 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
470 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700471 advanceToNextCallback();
472}
473
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800474TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700475 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700476 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
477 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
478 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700479
480 CountingCallback cb0(mDispatch);
481 CountingCallback cb1(mDispatch);
482
Ady Abraham9c53ee72020-07-22 21:16:18 -0700483 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
484 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
485 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700486 advanceToNextCallback();
487}
488
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800489TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700490 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700491 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
492 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
493 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
494 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700495
496 auto offset = 400;
497 auto closeOffset = offset + mDispatchGroupThreshold - 1;
498 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
499
500 CountingCallback cb0(mDispatch);
501 CountingCallback cb1(mDispatch);
502
Ady Abraham9c53ee72020-07-22 21:16:18 -0700503 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
504 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
505 mDispatch.schedule(cb1,
506 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700507
508 advanceToNextCallback();
509 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
510 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
511 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
512 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
513
Ady Abraham9c53ee72020-07-22 21:16:18 -0700514 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
515 mDispatch.schedule(cb1,
516 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700517 advanceToNextCallback();
518 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
519 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
520
521 advanceToNextCallback();
522 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
523 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
524}
525
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800526TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700527 Sequence seq;
528 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
529 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
530 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700531 EXPECT_CALL(mMockClock, alarmCancel());
532
533 CountingCallback cb0(mDispatch);
534 CountingCallback cb1(mDispatch);
535
Ady Abraham9c53ee72020-07-22 21:16:18 -0700536 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
537 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700538 advanceToNextCallback();
539 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
540}
541
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800542TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700543 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
544 .Times(3)
545 .WillOnce(Return(950))
546 .WillOnce(Return(1975))
547 .WillOnce(Return(2950));
548
549 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700550 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700551
552 mMockClock.advanceBy(850);
553 EXPECT_THAT(cb.mCalls.size(), Eq(1));
554
Ady Abraham9c53ee72020-07-22 21:16:18 -0700555 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700556 mMockClock.advanceBy(900);
557 EXPECT_THAT(cb.mCalls.size(), Eq(1));
558 mMockClock.advanceBy(125);
559 EXPECT_THAT(cb.mCalls.size(), Eq(2));
560
Ady Abraham9c53ee72020-07-22 21:16:18 -0700561 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700562 mMockClock.advanceBy(975);
563 EXPECT_THAT(cb.mCalls.size(), Eq(3));
564}
565
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800566TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700567 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700568 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
569 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700570
571 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700572 tmp = mDispatch.registerCallback(
573 [&](auto, auto, auto) {
574 mDispatch.schedule(tmp,
575 {.workDuration = 100,
576 .readyDuration = 0,
577 .earliestVsync = 2000});
578 },
579 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700580
Ady Abraham9c53ee72020-07-22 21:16:18 -0700581 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700582 advanceToNextCallback();
583}
584
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800585TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700586 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800587 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700588 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700589 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700590 auto result =
591 mDispatch.schedule(tmp,
592 {.workDuration = 400,
593 .readyDuration = 0,
594 .earliestVsync = timestamp - mVsyncMoveThreshold});
595 EXPECT_TRUE(result.has_value());
596 EXPECT_EQ(mPeriod + timestamp - 400, *result);
597 result = mDispatch.schedule(tmp,
598 {.workDuration = 400,
599 .readyDuration = 0,
600 .earliestVsync = timestamp});
601 EXPECT_TRUE(result.has_value());
602 EXPECT_EQ(mPeriod + timestamp - 400, *result);
603 result = mDispatch.schedule(tmp,
604 {.workDuration = 400,
605 .readyDuration = 0,
606 .earliestVsync = timestamp + mVsyncMoveThreshold});
607 EXPECT_TRUE(result.has_value());
608 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800609 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700610 },
611 "oo");
612
Ady Abraham9c53ee72020-07-22 21:16:18 -0700613 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700614 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800615 EXPECT_THAT(lastTarget, Eq(1000));
616
617 advanceToNextCallback();
618 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700619}
620
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800621TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700622 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700623 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
624 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
625 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
626 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700627
628 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700629 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700630
631 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700632 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700633
634 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700635 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700636
637 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700638 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700639}
640
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800641TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700642 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700643 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
644 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
645 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
646 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700647
648 CountingCallback cb0(mDispatch);
649 CountingCallback cb1(mDispatch);
650
Ady Abraham9c53ee72020-07-22 21:16:18 -0700651 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
652 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700653
654 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700655 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
656 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700657
658 advanceToNextCallback();
659 advanceToNextCallback();
660}
661
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800662TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700663 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700664 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700665
666 CountingCallback cb0(mDispatch);
667 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700668 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
669 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700670}
671
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800672TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700673 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700674 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700675 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700676 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700677
678 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700679 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700680 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700681 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700682}
683
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800684TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700685 VSyncDispatch::CallbackToken token(100);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700686 EXPECT_FALSE(mDispatch
687 .schedule(token,
688 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
689 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -0700690 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
691}
692
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800693TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700694 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700695 auto result =
696 mDispatch.schedule(cb0,
697 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
698 EXPECT_TRUE(result.has_value());
699 EXPECT_EQ(500, *result);
700 result = mDispatch.schedule(cb0,
701 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
702 EXPECT_TRUE(result.has_value());
703 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800704}
705
706// b/1450138150
707TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700708 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800709 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700710 auto result =
711 mDispatch.schedule(cb,
712 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
713 EXPECT_TRUE(result.has_value());
714 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800715 mMockClock.advanceBy(400);
716
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700717 result = mDispatch.schedule(cb,
718 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
719 EXPECT_TRUE(result.has_value());
720 EXPECT_EQ(1200, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800721 advanceToNextCallback();
722 ASSERT_THAT(cb.mCalls.size(), Eq(1));
723}
724
725TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
726 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
727 .Times(2)
728 .WillOnce(Return(1000))
729 .WillOnce(Return(1002));
730 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700731 auto result =
732 mDispatch.schedule(cb,
733 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
734 EXPECT_TRUE(result.has_value());
735 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800736 mMockClock.advanceBy(400);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700737 result = mDispatch.schedule(cb,
738 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
739 EXPECT_TRUE(result.has_value());
740 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700741}
742
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800743TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
744 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700745 auto result =
746 mDispatch.schedule(cb0,
747 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
748 EXPECT_TRUE(result.has_value());
749 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800750 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700751 result = mDispatch.schedule(cb0,
752 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
753 EXPECT_TRUE(result.has_value());
754 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800755}
756
757TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
758 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700759 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
760 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800761 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700762 auto result =
763 mDispatch.schedule(cb0,
764 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
765 EXPECT_TRUE(result.has_value());
766 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800767 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700768 result = mDispatch.schedule(cb0,
769 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
770 EXPECT_TRUE(result.has_value());
771 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800772}
773
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800774TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700775 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800776
777 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700778 auto result =
779 mDispatch.schedule(cb,
780 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
781 EXPECT_TRUE(result.has_value());
782 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800783
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700784 result = mDispatch.schedule(cb,
785 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
786 EXPECT_TRUE(result.has_value());
787 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800788
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800789 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800790}
791
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800792TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700793 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700794 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
795
796 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700797 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700798 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700799 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700800 cb.cancel();
801
Ady Abraham9c53ee72020-07-22 21:16:18 -0700802 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700803 cb1.cancel();
804}
805
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800806TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700807 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700808 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
809
810 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700811 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700812 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700813 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700814 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700815 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700816 cb.cancel();
817
Ady Abraham9c53ee72020-07-22 21:16:18 -0700818 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700819 cb1.cancel();
820}
821
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700822// b/154303580
823TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
824 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700825 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
826 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700827 CountingCallback cb1(mDispatch);
828 CountingCallback cb2(mDispatch);
829
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700830 auto result =
831 mDispatch.schedule(cb1,
832 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
833 EXPECT_TRUE(result.has_value());
834 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700835
836 mMockClock.setLag(100);
837 mMockClock.advanceBy(620);
838
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700839 result = mDispatch.schedule(cb2,
840 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
841 EXPECT_TRUE(result.has_value());
842 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700843 mMockClock.advanceBy(80);
844
845 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
846 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
847}
848
849// b/154303580.
850// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
851// update later, as opposed to blocking the calling thread.
852TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
853 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700854 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
855 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700856 CountingCallback cb(mDispatch);
857
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700858 auto result =
859 mDispatch.schedule(cb,
860 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
861 EXPECT_TRUE(result.has_value());
862 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700863
864 mMockClock.setLag(100);
865 mMockClock.advanceBy(620);
866
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700867 result = mDispatch.schedule(cb,
868 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
869 EXPECT_TRUE(result.has_value());
870 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700871 mMockClock.advanceBy(80);
872
873 EXPECT_THAT(cb.mCalls.size(), Eq(1));
874}
875
Kevin DuBoisb340b732020-06-16 09:07:35 -0700876// b/154303580.
877TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
878 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700879 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700880 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
881 CountingCallback cb1(mDispatch);
882 CountingCallback cb2(mDispatch);
883
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700884 auto result =
885 mDispatch.schedule(cb1,
886 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
887 EXPECT_TRUE(result.has_value());
888 EXPECT_EQ(600, *result);
889 result = mDispatch.schedule(cb2,
890 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
891 EXPECT_TRUE(result.has_value());
892 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700893
894 mMockClock.setLag(100);
895 mMockClock.advanceBy(620);
896
897 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
898
899 mMockClock.advanceBy(80);
900
901 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
902 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
903}
904
905TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
906 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700907 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
908 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700909 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
910 CountingCallback cb1(mDispatch);
911 CountingCallback cb2(mDispatch);
912
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700913 auto result =
914 mDispatch.schedule(cb1,
915 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
916 EXPECT_TRUE(result.has_value());
917 EXPECT_EQ(600, *result);
918 result = mDispatch.schedule(cb2,
919 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
920 EXPECT_TRUE(result.has_value());
921 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700922
923 mMockClock.setLag(100);
924 mMockClock.advanceBy(620);
925
926 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
927
928 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
929 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
930 mMockClock.advanceToNextCallback();
931
932 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
933 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
934}
935
Kevin DuBoisf9477832020-07-16 10:21:36 -0700936TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
937 CountingCallback cb1(mDispatch);
938 CountingCallback cb2(mDispatch);
939
940 Sequence seq;
941 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
942 .InSequence(seq)
943 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700944 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700945 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
946 .InSequence(seq)
947 .WillOnce(Return(1000));
948
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700949 auto result =
950 mDispatch.schedule(cb1,
951 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
952 EXPECT_TRUE(result.has_value());
953 EXPECT_EQ(600, *result);
954 result = mDispatch.schedule(cb2,
955 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
956 EXPECT_TRUE(result.has_value());
957 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700958
959 mMockClock.setLag(100);
960 mMockClock.advanceBy(700);
961
962 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
963 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700964 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
965 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700966 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
967 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700968 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
969 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
970}
971
972TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
973 auto intended = mPeriod - 230;
974 EXPECT_CALL(mMockClock, alarmAt(_, 900));
975
976 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700977 const auto result = mDispatch.schedule(cb,
978 {.workDuration = 70,
979 .readyDuration = 30,
980 .earliestVsync = intended});
981 EXPECT_TRUE(result.has_value());
982 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700983 advanceToNextCallback();
984
985 ASSERT_THAT(cb.mCalls.size(), Eq(1));
986 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
987 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
988 EXPECT_THAT(cb.mWakeupTime[0], 900);
989 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
990 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700991}
992
Ady Abraham69b9e622021-07-19 12:24:31 -0700993TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
994 Sequence seq;
995 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
996
997 CountingCallback cb(mDispatch);
998
999 mDispatch.schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1000 mDispatch.schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
1001
1002 advanceToNextCallback();
1003
1004 advanceToNextCallback();
1005
1006 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1007 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1008 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1009 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1010 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1011 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1012}
1013
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001014class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001015protected:
1016 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001017 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -07001018 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
1019};
1020
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001021TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001022 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001023 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001024 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001025 EXPECT_THAT(entry.name(), Eq(name));
1026 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1027 EXPECT_FALSE(entry.wakeupTime());
1028}
1029
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001030TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001031 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001032 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001033
1034 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001035 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1036 mStubTracker, 0)
1037 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001038 auto const wakeup = entry.wakeupTime();
1039 ASSERT_TRUE(wakeup);
1040 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001041
1042 entry.disarm();
1043 EXPECT_FALSE(entry.wakeupTime());
1044}
1045
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001046TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001047 auto const duration = 500;
1048 auto const now = 8750;
1049
1050 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
1051 .Times(1)
1052 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001053 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001054 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001055
1056 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001057 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
1058 mStubTracker, now)
1059 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001060 auto const wakeup = entry.wakeupTime();
1061 ASSERT_TRUE(wakeup);
1062 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001063}
1064
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001065TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001066 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001067 auto vsyncCalledTime = 0;
1068 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001069 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001070 VSyncDispatchTimerQueueEntry entry(
1071 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001072 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001073 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001074 vsyncCalledTime = vsyncTime;
1075 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001076 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001077 },
1078 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001079
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001080 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1081 mStubTracker, 0)
1082 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001083 auto const wakeup = entry.wakeupTime();
1084 ASSERT_TRUE(wakeup);
1085 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001086
Ady Abraham9c53ee72020-07-22 21:16:18 -07001087 auto const ready = entry.readyTime();
1088 ASSERT_TRUE(ready);
1089 EXPECT_THAT(*ready, Eq(1000));
1090
1091 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001092
1093 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001094 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1095 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001096 EXPECT_FALSE(entry.wakeupTime());
1097 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1098 ASSERT_TRUE(lastCalledTarget);
1099 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1100}
1101
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001102TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001103 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
1104 .Times(2)
1105 .WillOnce(Return(1000))
1106 .WillOnce(Return(1020));
1107
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001108 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001109 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001110
1111 EXPECT_FALSE(entry.wakeupTime());
1112 entry.update(mStubTracker, 0);
1113 EXPECT_FALSE(entry.wakeupTime());
1114
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001115 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1116 mStubTracker, 0)
1117 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001118 auto wakeup = entry.wakeupTime();
1119 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001120 EXPECT_THAT(wakeup, Eq(900));
1121
1122 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001123 wakeup = entry.wakeupTime();
1124 ASSERT_TRUE(wakeup);
1125 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001126}
1127
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001128TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001129 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001130 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001131 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1132 mStubTracker, 0)
1133 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001134 entry.update(mStubTracker, 0);
1135
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001136 auto const wakeup = entry.wakeupTime();
1137 ASSERT_TRUE(wakeup);
1138 EXPECT_THAT(*wakeup, Eq(wakeup));
1139}
1140
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001141TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1142 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001143 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001144 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1145 mStubTracker, 0)
1146 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001147 entry.executing(); // 1000 is executing
1148 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001149 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1150 mStubTracker, 0)
1151 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001152 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001153 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001154
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001155 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1156 mStubTracker, 0)
1157 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001158 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001159 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001160
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001161 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1162 mStubTracker, 0)
1163 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001164 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001165 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001166}
1167
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001168TEST_F(VSyncDispatchTimerQueueEntryTest,
1169 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1170 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001171 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001172
1173 Sequence seq;
1174 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1175 .InSequence(seq)
1176 .WillOnce(Return(1000));
1177 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1178 .InSequence(seq)
1179 .WillOnce(Return(1000));
1180 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1181 .InSequence(seq)
1182 .WillOnce(Return(2000));
1183
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001184 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1185 mStubTracker, 0)
1186 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001187
1188 entry.executing(); // 1000 is executing
1189
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001190 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1191 mStubTracker, 0)
1192 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001193}
1194
1195TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1196 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001197 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001198 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1199 mStubTracker, 0)
1200 .has_value());
1201 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1202 mStubTracker, 0)
1203 .has_value());
1204 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1205 mStubTracker, 0)
1206 .has_value());
1207 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1208 mStubTracker, 0)
1209 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001210}
1211
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001212TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1213 static constexpr auto effectualOffset = 200;
1214 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001215 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001216 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001217 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1218 entry.addPendingWorkloadUpdate(
1219 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001220 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1221 entry.update(mStubTracker, 0);
1222 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1223 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1224}
1225
Ady Abraham9c53ee72020-07-22 21:16:18 -07001226TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1227 auto callCount = 0;
1228 auto vsyncCalledTime = 0;
1229 auto wakeupCalledTime = 0;
1230 auto readyCalledTime = 0;
1231 VSyncDispatchTimerQueueEntry entry(
1232 "test",
1233 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1234 callCount++;
1235 vsyncCalledTime = vsyncTime;
1236 wakeupCalledTime = wakeupTime;
1237 readyCalledTime = readyTime;
1238 },
1239 mVsyncMoveThreshold);
1240
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001241 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1242 mStubTracker, 0)
1243 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001244 auto const wakeup = entry.wakeupTime();
1245 ASSERT_TRUE(wakeup);
1246 EXPECT_THAT(*wakeup, Eq(900));
1247
1248 auto const ready = entry.readyTime();
1249 ASSERT_TRUE(ready);
1250 EXPECT_THAT(*ready, Eq(970));
1251
1252 entry.callback(entry.executing(), *wakeup, *ready);
1253
1254 EXPECT_THAT(callCount, Eq(1));
1255 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1256 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1257 EXPECT_FALSE(entry.wakeupTime());
1258 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1259 ASSERT_TRUE(lastCalledTarget);
1260 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1261}
1262
Kevin DuBois305bef12019-10-09 13:23:27 -07001263} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001264
1265// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001266#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"