blob: b64cce9e43c4e526aa03dd8628e7514179f87d0e [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 Abraham9c53ee72020-07-22 21:16:18 -0700235 EXPECT_EQ(mDispatch.schedule(cb,
236 {.workDuration = 100,
237 .readyDuration = 0,
238 .earliestVsync = 1000}),
239 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700240 }
241}
242
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800243TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700244 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700245 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700246
247 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700248 EXPECT_EQ(mDispatch.schedule(cb,
249 {.workDuration = 100,
250 .readyDuration = 0,
251 .earliestVsync = intended}),
252 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700253 advanceToNextCallback();
254
255 ASSERT_THAT(cb.mCalls.size(), Eq(1));
256 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
257}
258
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800259TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700260 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700261 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700262
263 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700264 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700265 advanceToNextCallback();
266
267 ASSERT_THAT(cb.mCalls.size(), Eq(1));
268 EXPECT_THAT(cb.mCalls[0], Eq(1150));
269}
270
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800271TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700272 auto const now = 234;
273 mMockClock.advanceBy(234);
274 auto const workDuration = 10 * mPeriod;
275 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
276 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700277 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700278
279 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700280 EXPECT_EQ(mDispatch.schedule(cb,
281 {.workDuration = workDuration,
282 .readyDuration = 0,
283 .earliestVsync = mPeriod}),
284 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700285}
286
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800287TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700288 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700289 EXPECT_CALL(mMockClock, alarmCancel());
290
291 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700292 EXPECT_EQ(mDispatch.schedule(cb,
293 {.workDuration = 100,
294 .readyDuration = 0,
295 .earliestVsync = mPeriod}),
296 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700297 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
298}
299
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800300TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700301 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700302 EXPECT_CALL(mMockClock, alarmCancel());
303
304 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700305 EXPECT_EQ(mDispatch.schedule(cb,
306 {.workDuration = 100,
307 .readyDuration = 0,
308 .earliestVsync = mPeriod}),
309 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700310 mMockClock.advanceBy(950);
311 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
312}
313
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800314TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700315 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700316 EXPECT_CALL(mMockClock, alarmCancel());
317
318 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700319 EXPECT_EQ(mDispatch.schedule(cb,
320 {.workDuration = 100,
321 .readyDuration = 0,
322 .earliestVsync = mPeriod}),
323 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700324
325 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
326 EXPECT_TRUE(cb.waitForPause());
327 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
328 cb.unpause();
329 pausingThread.join();
330}
331
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800332TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700333 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700334 EXPECT_CALL(mMockClock, alarmCancel());
335
336 auto resource = std::make_shared<int>(110);
337
338 PausingCallback cb(mDispatch, 50ms);
339 cb.stashResource(resource);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700340 EXPECT_EQ(mDispatch.schedule(cb,
341 {.workDuration = 100,
342 .readyDuration = 0,
343 .earliestVsync = mPeriod}),
344 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700345
346 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
347 EXPECT_TRUE(cb.waitForPause());
348
349 cb.unregister();
350 resource.reset();
351
352 cb.unpause();
353 pausingThread.join();
354
355 EXPECT_TRUE(cb.resourcePresent());
356}
357
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800358TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700359 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
360 .Times(4)
361 .WillOnce(Return(1055))
362 .WillOnce(Return(1063))
363 .WillOnce(Return(1063))
364 .WillOnce(Return(1075));
365
366 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700367 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
368 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
369 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700370
371 CountingCallback cb0(mDispatch);
372 CountingCallback cb1(mDispatch);
373
Ady Abraham9c53ee72020-07-22 21:16:18 -0700374 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
375 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700376
377 advanceToNextCallback();
378 advanceToNextCallback();
379
380 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
381 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
382 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
383 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
384}
385
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800386TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700387 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
388 .Times(4)
389 .WillOnce(Return(10000))
390 .WillOnce(Return(1000))
391 .WillOnce(Return(10000))
392 .WillOnce(Return(10000));
393
394 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700395 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
396 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
397 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700398
399 CountingCallback cb0(mDispatch);
400 CountingCallback cb1(mDispatch);
401
Ady Abraham9c53ee72020-07-22 21:16:18 -0700402 mDispatch.schedule(cb0,
403 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
404 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700405 mDispatch.cancel(cb1);
406}
407
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800408TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700409 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700410 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
411 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700412
413 CountingCallback cb0(mDispatch);
414 CountingCallback cb1(mDispatch);
415
Ady Abraham9c53ee72020-07-22 21:16:18 -0700416 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
417 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
418 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700419 advanceToNextCallback();
420}
421
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800422TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700423 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700424 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
425 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
426 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700427
428 CountingCallback cb0(mDispatch);
429 CountingCallback cb1(mDispatch);
430
Ady Abraham9c53ee72020-07-22 21:16:18 -0700431 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
432 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
433 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700434 advanceToNextCallback();
435}
436
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800437TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700438 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700439 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
440 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
441 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
442 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700443
444 auto offset = 400;
445 auto closeOffset = offset + mDispatchGroupThreshold - 1;
446 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
447
448 CountingCallback cb0(mDispatch);
449 CountingCallback cb1(mDispatch);
450
Ady Abraham9c53ee72020-07-22 21:16:18 -0700451 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
452 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
453 mDispatch.schedule(cb1,
454 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700455
456 advanceToNextCallback();
457 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
458 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
459 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
460 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
461
Ady Abraham9c53ee72020-07-22 21:16:18 -0700462 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
463 mDispatch.schedule(cb1,
464 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700465 advanceToNextCallback();
466 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
467 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
468
469 advanceToNextCallback();
470 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
471 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
472}
473
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800474TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700475 Sequence seq;
476 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
477 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
478 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700479 EXPECT_CALL(mMockClock, alarmCancel());
480
481 CountingCallback cb0(mDispatch);
482 CountingCallback cb1(mDispatch);
483
Ady Abraham9c53ee72020-07-22 21:16:18 -0700484 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
485 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700486 advanceToNextCallback();
487 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
488}
489
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800490TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700491 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
492 .Times(3)
493 .WillOnce(Return(950))
494 .WillOnce(Return(1975))
495 .WillOnce(Return(2950));
496
497 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700498 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700499
500 mMockClock.advanceBy(850);
501 EXPECT_THAT(cb.mCalls.size(), Eq(1));
502
Ady Abraham9c53ee72020-07-22 21:16:18 -0700503 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700504 mMockClock.advanceBy(900);
505 EXPECT_THAT(cb.mCalls.size(), Eq(1));
506 mMockClock.advanceBy(125);
507 EXPECT_THAT(cb.mCalls.size(), Eq(2));
508
Ady Abraham9c53ee72020-07-22 21:16:18 -0700509 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700510 mMockClock.advanceBy(975);
511 EXPECT_THAT(cb.mCalls.size(), Eq(3));
512}
513
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800514TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700515 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700516 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
517 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700518
519 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700520 tmp = mDispatch.registerCallback(
521 [&](auto, auto, auto) {
522 mDispatch.schedule(tmp,
523 {.workDuration = 100,
524 .readyDuration = 0,
525 .earliestVsync = 2000});
526 },
527 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700528
Ady Abraham9c53ee72020-07-22 21:16:18 -0700529 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700530 advanceToNextCallback();
531}
532
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800533TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700534 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800535 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700536 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700537 [&](auto timestamp, auto, auto) {
538 EXPECT_EQ(mDispatch.schedule(tmp,
539 {.workDuration = 400,
540 .readyDuration = 0,
541 .earliestVsync = timestamp - mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800542 ScheduleResult::Scheduled);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700543 EXPECT_EQ(mDispatch.schedule(tmp,
544 {.workDuration = 400,
545 .readyDuration = 0,
546 .earliestVsync = timestamp}),
547 ScheduleResult::Scheduled);
548 EXPECT_EQ(mDispatch.schedule(tmp,
549 {.workDuration = 400,
550 .readyDuration = 0,
551 .earliestVsync = timestamp + mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800552 ScheduleResult::Scheduled);
553 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700554 },
555 "oo");
556
Ady Abraham9c53ee72020-07-22 21:16:18 -0700557 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700558 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800559 EXPECT_THAT(lastTarget, Eq(1000));
560
561 advanceToNextCallback();
562 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700563}
564
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800565TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700566 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700567 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
568 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
569 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
570 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700571
572 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700573 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700574
575 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700576 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700577
578 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700579 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700580
581 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700582 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700583}
584
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800585TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700586 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700587 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
588 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
589 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
590 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700591
592 CountingCallback cb0(mDispatch);
593 CountingCallback cb1(mDispatch);
594
Ady Abraham9c53ee72020-07-22 21:16:18 -0700595 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
596 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700597
598 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700599 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
600 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700601
602 advanceToNextCallback();
603 advanceToNextCallback();
604}
605
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800606TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700607 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700608 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700609
610 CountingCallback cb0(mDispatch);
611 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700612 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
613 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700614}
615
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800616TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700617 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700618 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700619 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700620 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700621
622 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700623 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700624 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700625 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700626}
627
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800628TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700629 VSyncDispatch::CallbackToken token(100);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700630 EXPECT_THAT(mDispatch.schedule(token,
631 {.workDuration = 100,
632 .readyDuration = 0,
633 .earliestVsync = 1000}),
634 Eq(ScheduleResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700635 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
636}
637
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800638TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700639 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700640 EXPECT_EQ(mDispatch.schedule(cb0,
641 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
642 ScheduleResult::Scheduled);
643 EXPECT_EQ(mDispatch.schedule(cb0,
644 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}),
645 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800646}
647
648// b/1450138150
649TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700650 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800651 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700652 EXPECT_EQ(mDispatch.schedule(cb,
653 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
654 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800655 mMockClock.advanceBy(400);
656
Ady Abraham9c53ee72020-07-22 21:16:18 -0700657 EXPECT_EQ(mDispatch.schedule(cb,
658 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000}),
659 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800660 advanceToNextCallback();
661 ASSERT_THAT(cb.mCalls.size(), Eq(1));
662}
663
664TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
665 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
666 .Times(2)
667 .WillOnce(Return(1000))
668 .WillOnce(Return(1002));
669 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700670 EXPECT_EQ(mDispatch.schedule(cb,
671 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
672 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800673 mMockClock.advanceBy(400);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700674 EXPECT_EQ(mDispatch.schedule(cb,
675 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
676 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700677}
678
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800679TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
680 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700681 EXPECT_EQ(mDispatch.schedule(cb0,
682 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
683 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800684 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700685 EXPECT_EQ(mDispatch.schedule(cb0,
686 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000}),
687 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800688}
689
690TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
691 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700692 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
693 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800694 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700695 EXPECT_EQ(mDispatch.schedule(cb0,
696 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
697 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800698 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700699 EXPECT_EQ(mDispatch.schedule(cb0,
700 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000}),
701 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800702}
703
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800704TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700705 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800706
707 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700708 EXPECT_EQ(mDispatch.schedule(cb,
709 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
710 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800711
Ady Abraham9c53ee72020-07-22 21:16:18 -0700712 EXPECT_EQ(mDispatch.schedule(cb,
713 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}),
714 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800715
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800716 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800717}
718
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800719TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700720 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700721 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
722
723 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700724 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700725 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700726 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700727 cb.cancel();
728
Ady Abraham9c53ee72020-07-22 21:16:18 -0700729 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700730 cb1.cancel();
731}
732
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800733TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700734 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700735 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
736
737 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700738 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700739 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700740 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700741 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700742 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700743 cb.cancel();
744
Ady Abraham9c53ee72020-07-22 21:16:18 -0700745 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700746 cb1.cancel();
747}
748
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700749// b/154303580
750TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
751 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700752 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
753 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700754 CountingCallback cb1(mDispatch);
755 CountingCallback cb2(mDispatch);
756
Ady Abraham9c53ee72020-07-22 21:16:18 -0700757 EXPECT_EQ(mDispatch.schedule(cb1,
758 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
759 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700760
761 mMockClock.setLag(100);
762 mMockClock.advanceBy(620);
763
Ady Abraham9c53ee72020-07-22 21:16:18 -0700764 EXPECT_EQ(mDispatch.schedule(cb2,
765 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
766 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700767 mMockClock.advanceBy(80);
768
769 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
770 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
771}
772
773// b/154303580.
774// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
775// update later, as opposed to blocking the calling thread.
776TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
777 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700778 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
779 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700780 CountingCallback cb(mDispatch);
781
Ady Abraham9c53ee72020-07-22 21:16:18 -0700782 EXPECT_EQ(mDispatch.schedule(cb,
783 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
784 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700785
786 mMockClock.setLag(100);
787 mMockClock.advanceBy(620);
788
Ady Abraham9c53ee72020-07-22 21:16:18 -0700789 EXPECT_EQ(mDispatch.schedule(cb,
790 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000}),
791 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700792 mMockClock.advanceBy(80);
793
794 EXPECT_THAT(cb.mCalls.size(), Eq(1));
795}
796
Kevin DuBoisb340b732020-06-16 09:07:35 -0700797// b/154303580.
798TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
799 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700800 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700801 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
802 CountingCallback cb1(mDispatch);
803 CountingCallback cb2(mDispatch);
804
Ady Abraham9c53ee72020-07-22 21:16:18 -0700805 EXPECT_EQ(mDispatch.schedule(cb1,
806 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
807 ScheduleResult::Scheduled);
808 EXPECT_EQ(mDispatch.schedule(cb2,
809 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
810 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700811
812 mMockClock.setLag(100);
813 mMockClock.advanceBy(620);
814
815 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
816
817 mMockClock.advanceBy(80);
818
819 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
820 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
821}
822
823TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
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 DuBoisb340b732020-06-16 09:07:35 -0700827 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
828 CountingCallback cb1(mDispatch);
829 CountingCallback cb2(mDispatch);
830
Ady Abraham9c53ee72020-07-22 21:16:18 -0700831 EXPECT_EQ(mDispatch.schedule(cb1,
832 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
833 ScheduleResult::Scheduled);
834 EXPECT_EQ(mDispatch.schedule(cb2,
835 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
836 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700837
838 mMockClock.setLag(100);
839 mMockClock.advanceBy(620);
840
841 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
842
843 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
844 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
845 mMockClock.advanceToNextCallback();
846
847 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
848 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
849}
850
Kevin DuBoisf9477832020-07-16 10:21:36 -0700851TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
852 CountingCallback cb1(mDispatch);
853 CountingCallback cb2(mDispatch);
854
855 Sequence seq;
856 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
857 .InSequence(seq)
858 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700859 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700860 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
861 .InSequence(seq)
862 .WillOnce(Return(1000));
863
Ady Abraham9c53ee72020-07-22 21:16:18 -0700864 EXPECT_EQ(mDispatch.schedule(cb1,
865 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
866 ScheduleResult::Scheduled);
867 EXPECT_EQ(mDispatch.schedule(cb2,
868 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000}),
869 ScheduleResult::Scheduled);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700870
871 mMockClock.setLag(100);
872 mMockClock.advanceBy(700);
873
874 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
875 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700876 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
877 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700878 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
879 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700880 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
881 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
882}
883
884TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
885 auto intended = mPeriod - 230;
886 EXPECT_CALL(mMockClock, alarmAt(_, 900));
887
888 CountingCallback cb(mDispatch);
889 EXPECT_EQ(mDispatch.schedule(cb,
890 {.workDuration = 70,
891 .readyDuration = 30,
892 .earliestVsync = intended}),
893 ScheduleResult::Scheduled);
894 advanceToNextCallback();
895
896 ASSERT_THAT(cb.mCalls.size(), Eq(1));
897 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
898 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
899 EXPECT_THAT(cb.mWakeupTime[0], 900);
900 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
901 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700902}
903
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800904class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700905protected:
906 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800907 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700908 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
909};
910
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800911TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700912 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800913 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700914 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700915 EXPECT_THAT(entry.name(), Eq(name));
916 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
917 EXPECT_FALSE(entry.wakeupTime());
918}
919
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800920TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800921 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700922 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700923
924 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700925 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
926 mStubTracker, 0),
927 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800928 auto const wakeup = entry.wakeupTime();
929 ASSERT_TRUE(wakeup);
930 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700931
932 entry.disarm();
933 EXPECT_FALSE(entry.wakeupTime());
934}
935
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800936TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700937 auto const duration = 500;
938 auto const now = 8750;
939
940 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
941 .Times(1)
942 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800943 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700944 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700945
946 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700947 EXPECT_THAT(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
948 mStubTracker, now),
949 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800950 auto const wakeup = entry.wakeupTime();
951 ASSERT_TRUE(wakeup);
952 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700953}
954
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800955TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700956 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800957 auto vsyncCalledTime = 0;
958 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700959 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800960 VSyncDispatchTimerQueueEntry entry(
961 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -0700962 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800963 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800964 vsyncCalledTime = vsyncTime;
965 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700966 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800967 },
968 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700969
Ady Abraham9c53ee72020-07-22 21:16:18 -0700970 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
971 mStubTracker, 0),
972 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800973 auto const wakeup = entry.wakeupTime();
974 ASSERT_TRUE(wakeup);
975 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700976
Ady Abraham9c53ee72020-07-22 21:16:18 -0700977 auto const ready = entry.readyTime();
978 ASSERT_TRUE(ready);
979 EXPECT_THAT(*ready, Eq(1000));
980
981 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -0700982
983 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800984 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
985 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700986 EXPECT_FALSE(entry.wakeupTime());
987 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
988 ASSERT_TRUE(lastCalledTarget);
989 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
990}
991
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800992TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700993 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
994 .Times(2)
995 .WillOnce(Return(1000))
996 .WillOnce(Return(1020));
997
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800998 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700999 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001000
1001 EXPECT_FALSE(entry.wakeupTime());
1002 entry.update(mStubTracker, 0);
1003 EXPECT_FALSE(entry.wakeupTime());
1004
Ady Abraham9c53ee72020-07-22 21:16:18 -07001005 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1006 mStubTracker, 0),
1007 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001008 auto wakeup = entry.wakeupTime();
1009 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001010 EXPECT_THAT(wakeup, Eq(900));
1011
1012 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001013 wakeup = entry.wakeupTime();
1014 ASSERT_TRUE(wakeup);
1015 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001016}
1017
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001018TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001019 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001020 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1021 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1022 mStubTracker, 0),
1023 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001024 entry.update(mStubTracker, 0);
1025
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001026 auto const wakeup = entry.wakeupTime();
1027 ASSERT_TRUE(wakeup);
1028 EXPECT_THAT(*wakeup, Eq(wakeup));
1029}
1030
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001031TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1032 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001033 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1034 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1035 mStubTracker, 0),
1036 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001037 entry.executing(); // 1000 is executing
1038 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abraham9c53ee72020-07-22 21:16:18 -07001039 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1040 mStubTracker, 0),
1041 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001042 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001043 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001044
Ady Abraham9c53ee72020-07-22 21:16:18 -07001045 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1046 mStubTracker, 0),
1047 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001048 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001049 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001050
Ady Abraham9c53ee72020-07-22 21:16:18 -07001051 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1052 mStubTracker, 0),
1053 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001054 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001055 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001056}
1057
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001058TEST_F(VSyncDispatchTimerQueueEntryTest,
1059 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1060 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001061 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001062
1063 Sequence seq;
1064 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1065 .InSequence(seq)
1066 .WillOnce(Return(1000));
1067 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1068 .InSequence(seq)
1069 .WillOnce(Return(1000));
1070 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1071 .InSequence(seq)
1072 .WillOnce(Return(2000));
1073
Ady Abraham9c53ee72020-07-22 21:16:18 -07001074 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1075 mStubTracker, 0),
1076 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001077
1078 entry.executing(); // 1000 is executing
1079
Ady Abraham9c53ee72020-07-22 21:16:18 -07001080 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1081 mStubTracker, 0),
1082 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001083}
1084
1085TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1086 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001087 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1088 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1089 mStubTracker, 0),
1090 Eq(ScheduleResult::Scheduled));
1091 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1092 mStubTracker, 0),
1093 Eq(ScheduleResult::Scheduled));
1094 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1095 mStubTracker, 0),
1096 Eq(ScheduleResult::Scheduled));
1097 EXPECT_THAT(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1098 mStubTracker, 0),
1099 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001100}
1101
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001102TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1103 static constexpr auto effectualOffset = 200;
1104 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001105 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001106 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001107 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1108 entry.addPendingWorkloadUpdate(
1109 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001110 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1111 entry.update(mStubTracker, 0);
1112 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1113 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1114}
1115
Ady Abraham9c53ee72020-07-22 21:16:18 -07001116TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1117 auto callCount = 0;
1118 auto vsyncCalledTime = 0;
1119 auto wakeupCalledTime = 0;
1120 auto readyCalledTime = 0;
1121 VSyncDispatchTimerQueueEntry entry(
1122 "test",
1123 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1124 callCount++;
1125 vsyncCalledTime = vsyncTime;
1126 wakeupCalledTime = wakeupTime;
1127 readyCalledTime = readyTime;
1128 },
1129 mVsyncMoveThreshold);
1130
1131 EXPECT_THAT(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1132 mStubTracker, 0),
1133 Eq(ScheduleResult::Scheduled));
1134 auto const wakeup = entry.wakeupTime();
1135 ASSERT_TRUE(wakeup);
1136 EXPECT_THAT(*wakeup, Eq(900));
1137
1138 auto const ready = entry.readyTime();
1139 ASSERT_TRUE(ready);
1140 EXPECT_THAT(*ready, Eq(970));
1141
1142 entry.callback(entry.executing(), *wakeup, *ready);
1143
1144 EXPECT_THAT(callCount, Eq(1));
1145 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1146 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1147 EXPECT_FALSE(entry.wakeupTime());
1148 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1149 ASSERT_TRUE(lastCalledTarget);
1150 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1151}
1152
Kevin DuBois305bef12019-10-09 13:23:27 -07001153} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001154
1155// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001156#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"