blob: 69731fdbedb1c1eade2960c7e36cbfe70bf593b4 [file] [log] [blame]
Kevin DuBois305bef12019-10-09 13:23:27 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Kevin DuBois305bef12019-10-09 13:23:27 -070021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23#define LOG_NDEBUG 0
24
25#include "Scheduler/TimeKeeper.h"
Kevin DuBoise4f27a82019-11-12 11:41:41 -080026#include "Scheduler/VSyncDispatchTimerQueue.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070027#include "Scheduler/VSyncTracker.h"
28
29#include <gmock/gmock.h>
30#include <gtest/gtest.h>
31#include <thread>
32
33using namespace testing;
34using namespace std::literals;
35namespace android::scheduler {
36
37class MockVSyncTracker : public VSyncTracker {
38public:
39 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
40 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
41 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080042 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Kevin DuBois305bef12019-10-09 13:23:27 -070043 }
44
Kevin DuBois02d5ed92020-01-27 11:05:46 -080045 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070046 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080047 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080048 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080049 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070050 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5e7371c2020-03-24 14:47:24 -070051 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070052
53 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
54 if (timePoint % mPeriod == 0) {
55 return timePoint;
56 }
57 return (timePoint - (timePoint % mPeriod) + mPeriod);
58 }
59
60protected:
61 nsecs_t const mPeriod;
62};
63
64class ControllableClock : public TimeKeeper {
65public:
66 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070067 ON_CALL(*this, alarmAt(_, _))
68 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070069 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
70 }
71
72 MOCK_CONST_METHOD0(now, nsecs_t());
Ady Abrahamb491c902020-08-15 15:47:56 -070073 MOCK_METHOD2(alarmAt, void(std::function<void()> const&, nsecs_t time));
Kevin DuBois305bef12019-10-09 13:23:27 -070074 MOCK_METHOD0(alarmCancel, void());
Ady Abraham75398722020-04-07 14:08:45 -070075 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070076
Ady Abrahamb491c902020-08-15 15:47:56 -070077 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070078 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070079 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070080 }
81
82 nsecs_t fakeTime() const { return mCurrentTime; }
83
84 void advanceToNextCallback() {
85 mCurrentTime = mNextCallbackTime;
86 if (mCallback) {
87 mCallback();
88 }
89 }
90
91 void advanceBy(nsecs_t advancement) {
92 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070093 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070094 mCallback();
95 }
96 };
97
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070098 void setLag(nsecs_t lag) { mLag = lag; }
99
Kevin DuBois305bef12019-10-09 13:23:27 -0700100private:
101 std::function<void()> mCallback;
102 nsecs_t mNextCallbackTime = 0;
103 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700104 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700105};
106
107class CountingCallback {
108public:
109 CountingCallback(VSyncDispatch& dispatch)
110 : mDispatch(dispatch),
111 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700112 std::placeholders::_1, std::placeholders::_2,
113 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700114 "test")) {}
115 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
116
117 operator VSyncDispatch::CallbackToken() const { return mToken; }
118
Ady Abraham9c53ee72020-07-22 21:16:18 -0700119 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700120 mCalls.push_back(time);
121 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700122 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700123 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700124
125 VSyncDispatch& mDispatch;
126 VSyncDispatch::CallbackToken mToken;
127 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700128 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700129 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700130};
131
132class PausingCallback {
133public:
134 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
135 : mDispatch(dispatch),
136 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800137 std::placeholders::_1,
138 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700139 "test")),
140 mRegistered(true),
141 mPauseAmount(pauseAmount) {}
142 ~PausingCallback() { unregister(); }
143
144 operator VSyncDispatch::CallbackToken() const { return mToken; }
145
Kevin DuBois2968afc2020-01-14 09:48:50 -0800146 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700147 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700148 mPause = true;
149 mCv.notify_all();
150
Ady Abraham8cb21882020-08-26 18:22:05 -0700151 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700152
153 mResourcePresent = (mResource.lock() != nullptr);
154 }
155
156 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700157 std::unique_lock lock(mMutex);
158 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700159 return waiting;
160 }
161
162 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
163
164 bool resourcePresent() { return mResourcePresent; }
165
166 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700167 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700168 mPause = false;
169 mCv.notify_all();
170 }
171
172 void unregister() {
173 if (mRegistered) {
174 mDispatch.unregisterCallback(mToken);
175 mRegistered = false;
176 }
177 }
178
179 VSyncDispatch& mDispatch;
180 VSyncDispatch::CallbackToken mToken;
181 bool mRegistered = true;
182
183 std::mutex mMutex;
184 std::condition_variable mCv;
185 bool mPause = false;
186 std::weak_ptr<void> mResource;
187 bool mResourcePresent = false;
188 std::chrono::milliseconds const mPauseAmount;
189};
190
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800191class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700192protected:
193 std::unique_ptr<TimeKeeper> createTimeKeeper() {
194 class TimeKeeperWrapper : public TimeKeeper {
195 public:
196 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Ady Abrahamb491c902020-08-15 15:47:56 -0700197 void alarmAt(std::function<void()> const& callback, nsecs_t time) final {
198 mControllableClock.alarmAt(callback, time);
Kevin DuBois305bef12019-10-09 13:23:27 -0700199 }
200 void alarmCancel() final { mControllableClock.alarmCancel(); }
201 nsecs_t now() const final { return mControllableClock.now(); }
Ady Abraham75398722020-04-07 14:08:45 -0700202 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700203
204 private:
205 TimeKeeper& mControllableClock;
206 };
207 return std::make_unique<TimeKeeperWrapper>(mMockClock);
208 }
209
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800210 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700211 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
212 Mock::VerifyAndClearExpectations(&mMockClock);
213 }
214
215 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
216
217 NiceMock<ControllableClock> mMockClock;
218 static nsecs_t constexpr mDispatchGroupThreshold = 5;
219 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800220 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700221 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800222 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
223 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700224};
225
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800226TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700227 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700228 EXPECT_CALL(mMockClock, alarmCancel());
229 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800230 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
231 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700232 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700233 EXPECT_EQ(mDispatch.schedule(cb,
234 {.workDuration = 100,
235 .readyDuration = 0,
236 .earliestVsync = 1000}),
237 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700238 }
239}
240
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800241TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700242 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700243 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700244
245 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700246 EXPECT_EQ(mDispatch.schedule(cb,
247 {.workDuration = 100,
248 .readyDuration = 0,
249 .earliestVsync = intended}),
250 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700251 advanceToNextCallback();
252
253 ASSERT_THAT(cb.mCalls.size(), Eq(1));
254 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
255}
256
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800257TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700258 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700259 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700260
261 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700262 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700263 advanceToNextCallback();
264
265 ASSERT_THAT(cb.mCalls.size(), Eq(1));
266 EXPECT_THAT(cb.mCalls[0], Eq(1150));
267}
268
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800269TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700270 auto const now = 234;
271 mMockClock.advanceBy(234);
272 auto const workDuration = 10 * mPeriod;
273 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
274 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700275 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700276
277 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700278 EXPECT_EQ(mDispatch.schedule(cb,
279 {.workDuration = workDuration,
280 .readyDuration = 0,
281 .earliestVsync = mPeriod}),
282 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700283}
284
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800285TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700286 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700287 EXPECT_CALL(mMockClock, alarmCancel());
288
289 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700290 EXPECT_EQ(mDispatch.schedule(cb,
291 {.workDuration = 100,
292 .readyDuration = 0,
293 .earliestVsync = mPeriod}),
294 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700295 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
296}
297
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800298TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700299 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700300 EXPECT_CALL(mMockClock, alarmCancel());
301
302 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700303 EXPECT_EQ(mDispatch.schedule(cb,
304 {.workDuration = 100,
305 .readyDuration = 0,
306 .earliestVsync = mPeriod}),
307 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700308 mMockClock.advanceBy(950);
309 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
310}
311
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800312TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700313 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700314 EXPECT_CALL(mMockClock, alarmCancel());
315
316 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700317 EXPECT_EQ(mDispatch.schedule(cb,
318 {.workDuration = 100,
319 .readyDuration = 0,
320 .earliestVsync = mPeriod}),
321 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700322
323 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
324 EXPECT_TRUE(cb.waitForPause());
325 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
326 cb.unpause();
327 pausingThread.join();
328}
329
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800330TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700331 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700332 EXPECT_CALL(mMockClock, alarmCancel());
333
334 auto resource = std::make_shared<int>(110);
335
336 PausingCallback cb(mDispatch, 50ms);
337 cb.stashResource(resource);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700338 EXPECT_EQ(mDispatch.schedule(cb,
339 {.workDuration = 100,
340 .readyDuration = 0,
341 .earliestVsync = mPeriod}),
342 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700343
344 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
345 EXPECT_TRUE(cb.waitForPause());
346
347 cb.unregister();
348 resource.reset();
349
350 cb.unpause();
351 pausingThread.join();
352
353 EXPECT_TRUE(cb.resourcePresent());
354}
355
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800356TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700357 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
358 .Times(4)
359 .WillOnce(Return(1055))
360 .WillOnce(Return(1063))
361 .WillOnce(Return(1063))
362 .WillOnce(Return(1075));
363
364 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700365 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
366 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
367 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700368
369 CountingCallback cb0(mDispatch);
370 CountingCallback cb1(mDispatch);
371
Ady Abraham9c53ee72020-07-22 21:16:18 -0700372 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
373 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700374
375 advanceToNextCallback();
376 advanceToNextCallback();
377
378 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
379 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
380 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
381 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
382}
383
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800384TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700385 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
386 .Times(4)
387 .WillOnce(Return(10000))
388 .WillOnce(Return(1000))
389 .WillOnce(Return(10000))
390 .WillOnce(Return(10000));
391
392 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700393 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
394 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
395 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700396
397 CountingCallback cb0(mDispatch);
398 CountingCallback cb1(mDispatch);
399
Ady Abraham9c53ee72020-07-22 21:16:18 -0700400 mDispatch.schedule(cb0,
401 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
402 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700403 mDispatch.cancel(cb1);
404}
405
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800406TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700407 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700408 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
409 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700410
411 CountingCallback cb0(mDispatch);
412 CountingCallback cb1(mDispatch);
413
Ady Abraham9c53ee72020-07-22 21:16:18 -0700414 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
415 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
416 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700417 advanceToNextCallback();
418}
419
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800420TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700421 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700422 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
423 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
424 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700425
426 CountingCallback cb0(mDispatch);
427 CountingCallback cb1(mDispatch);
428
Ady Abraham9c53ee72020-07-22 21:16:18 -0700429 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
430 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
431 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700432 advanceToNextCallback();
433}
434
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800435TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700436 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700437 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
438 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
439 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
440 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700441
442 auto offset = 400;
443 auto closeOffset = offset + mDispatchGroupThreshold - 1;
444 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
445
446 CountingCallback cb0(mDispatch);
447 CountingCallback cb1(mDispatch);
448
Ady Abraham9c53ee72020-07-22 21:16:18 -0700449 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
450 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
451 mDispatch.schedule(cb1,
452 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700453
454 advanceToNextCallback();
455 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
456 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
457 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
458 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
459
Ady Abraham9c53ee72020-07-22 21:16:18 -0700460 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
461 mDispatch.schedule(cb1,
462 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700463 advanceToNextCallback();
464 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
465 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
466
467 advanceToNextCallback();
468 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
469 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
470}
471
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800472TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700473 Sequence seq;
474 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
475 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
476 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700477 EXPECT_CALL(mMockClock, alarmCancel());
478
479 CountingCallback cb0(mDispatch);
480 CountingCallback cb1(mDispatch);
481
Ady Abraham9c53ee72020-07-22 21:16:18 -0700482 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
483 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700484 advanceToNextCallback();
485 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
486}
487
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800488TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700489 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
490 .Times(3)
491 .WillOnce(Return(950))
492 .WillOnce(Return(1975))
493 .WillOnce(Return(2950));
494
495 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700496 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700497
498 mMockClock.advanceBy(850);
499 EXPECT_THAT(cb.mCalls.size(), Eq(1));
500
Ady Abraham9c53ee72020-07-22 21:16:18 -0700501 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700502 mMockClock.advanceBy(900);
503 EXPECT_THAT(cb.mCalls.size(), Eq(1));
504 mMockClock.advanceBy(125);
505 EXPECT_THAT(cb.mCalls.size(), Eq(2));
506
Ady Abraham9c53ee72020-07-22 21:16:18 -0700507 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700508 mMockClock.advanceBy(975);
509 EXPECT_THAT(cb.mCalls.size(), Eq(3));
510}
511
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800512TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700513 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700514 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
515 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700516
517 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700518 tmp = mDispatch.registerCallback(
519 [&](auto, auto, auto) {
520 mDispatch.schedule(tmp,
521 {.workDuration = 100,
522 .readyDuration = 0,
523 .earliestVsync = 2000});
524 },
525 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700526
Ady Abraham9c53ee72020-07-22 21:16:18 -0700527 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700528 advanceToNextCallback();
529}
530
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800531TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700532 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800533 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700534 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700535 [&](auto timestamp, auto, auto) {
536 EXPECT_EQ(mDispatch.schedule(tmp,
537 {.workDuration = 400,
538 .readyDuration = 0,
539 .earliestVsync = timestamp - mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800540 ScheduleResult::Scheduled);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700541 EXPECT_EQ(mDispatch.schedule(tmp,
542 {.workDuration = 400,
543 .readyDuration = 0,
544 .earliestVsync = timestamp}),
545 ScheduleResult::Scheduled);
546 EXPECT_EQ(mDispatch.schedule(tmp,
547 {.workDuration = 400,
548 .readyDuration = 0,
549 .earliestVsync = timestamp + mVsyncMoveThreshold}),
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800550 ScheduleResult::Scheduled);
551 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700552 },
553 "oo");
554
Ady Abraham9c53ee72020-07-22 21:16:18 -0700555 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700556 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800557 EXPECT_THAT(lastTarget, Eq(1000));
558
559 advanceToNextCallback();
560 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700561}
562
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800563TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700564 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700565 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
566 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
567 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
568 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700569
570 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700571 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700572
573 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700574 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700575
576 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700577 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700578
579 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700580 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700581}
582
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800583TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700584 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700585 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
586 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
587 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
588 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700589
590 CountingCallback cb0(mDispatch);
591 CountingCallback cb1(mDispatch);
592
Ady Abraham9c53ee72020-07-22 21:16:18 -0700593 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
594 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700595
596 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700597 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
598 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700599
600 advanceToNextCallback();
601 advanceToNextCallback();
602}
603
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800604TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700605 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700606 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700607
608 CountingCallback cb0(mDispatch);
609 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700610 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
611 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700612}
613
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800614TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700615 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700616 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700617 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700618 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700619
620 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700621 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700622 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700623 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700624}
625
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800626TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700627 VSyncDispatch::CallbackToken token(100);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700628 EXPECT_THAT(mDispatch.schedule(token,
629 {.workDuration = 100,
630 .readyDuration = 0,
631 .earliestVsync = 1000}),
632 Eq(ScheduleResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700633 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
634}
635
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800636TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700637 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700638 EXPECT_EQ(mDispatch.schedule(cb0,
639 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
640 ScheduleResult::Scheduled);
641 EXPECT_EQ(mDispatch.schedule(cb0,
642 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}),
643 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800644}
645
646// b/1450138150
647TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700648 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800649 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700650 EXPECT_EQ(mDispatch.schedule(cb,
651 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
652 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800653 mMockClock.advanceBy(400);
654
Ady Abraham9c53ee72020-07-22 21:16:18 -0700655 EXPECT_EQ(mDispatch.schedule(cb,
656 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000}),
657 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800658 advanceToNextCallback();
659 ASSERT_THAT(cb.mCalls.size(), Eq(1));
660}
661
662TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
663 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
664 .Times(2)
665 .WillOnce(Return(1000))
666 .WillOnce(Return(1002));
667 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700668 EXPECT_EQ(mDispatch.schedule(cb,
669 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
670 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800671 mMockClock.advanceBy(400);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700672 EXPECT_EQ(mDispatch.schedule(cb,
673 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
674 ScheduleResult::Scheduled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700675}
676
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800677TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
678 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700679 EXPECT_EQ(mDispatch.schedule(cb0,
680 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
681 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800682 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700683 EXPECT_EQ(mDispatch.schedule(cb0,
684 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000}),
685 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800686}
687
688TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
689 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700690 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
691 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800692 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700693 EXPECT_EQ(mDispatch.schedule(cb0,
694 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}),
695 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800696 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700697 EXPECT_EQ(mDispatch.schedule(cb0,
698 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000}),
699 ScheduleResult::Scheduled);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800700}
701
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800702TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700703 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800704
705 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700706 EXPECT_EQ(mDispatch.schedule(cb,
707 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
708 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800709
Ady Abraham9c53ee72020-07-22 21:16:18 -0700710 EXPECT_EQ(mDispatch.schedule(cb,
711 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}),
712 ScheduleResult::Scheduled);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800713
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800714 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800715}
716
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800717TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700718 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700719 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
720
721 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700722 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700723 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700724 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700725 cb.cancel();
726
Ady Abraham9c53ee72020-07-22 21:16:18 -0700727 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700728 cb1.cancel();
729}
730
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800731TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700732 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700733 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
734
735 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700736 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700737 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700738 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700739 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700740 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700741 cb.cancel();
742
Ady Abraham9c53ee72020-07-22 21:16:18 -0700743 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700744 cb1.cancel();
745}
746
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700747// b/154303580
748TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
749 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700750 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
751 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700752 CountingCallback cb1(mDispatch);
753 CountingCallback cb2(mDispatch);
754
Ady Abraham9c53ee72020-07-22 21:16:18 -0700755 EXPECT_EQ(mDispatch.schedule(cb1,
756 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
757 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700758
759 mMockClock.setLag(100);
760 mMockClock.advanceBy(620);
761
Ady Abraham9c53ee72020-07-22 21:16:18 -0700762 EXPECT_EQ(mDispatch.schedule(cb2,
763 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
764 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700765 mMockClock.advanceBy(80);
766
767 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
768 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
769}
770
771// b/154303580.
772// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
773// update later, as opposed to blocking the calling thread.
774TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
775 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700776 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
777 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700778 CountingCallback cb(mDispatch);
779
Ady Abraham9c53ee72020-07-22 21:16:18 -0700780 EXPECT_EQ(mDispatch.schedule(cb,
781 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
782 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700783
784 mMockClock.setLag(100);
785 mMockClock.advanceBy(620);
786
Ady Abraham9c53ee72020-07-22 21:16:18 -0700787 EXPECT_EQ(mDispatch.schedule(cb,
788 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000}),
789 ScheduleResult::Scheduled);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700790 mMockClock.advanceBy(80);
791
792 EXPECT_THAT(cb.mCalls.size(), Eq(1));
793}
794
Kevin DuBoisb340b732020-06-16 09:07:35 -0700795// b/154303580.
796TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
797 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700798 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700799 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
800 CountingCallback cb1(mDispatch);
801 CountingCallback cb2(mDispatch);
802
Ady Abraham9c53ee72020-07-22 21:16:18 -0700803 EXPECT_EQ(mDispatch.schedule(cb1,
804 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
805 ScheduleResult::Scheduled);
806 EXPECT_EQ(mDispatch.schedule(cb2,
807 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
808 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700809
810 mMockClock.setLag(100);
811 mMockClock.advanceBy(620);
812
813 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
814
815 mMockClock.advanceBy(80);
816
817 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
818 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
819}
820
821TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
822 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700823 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
824 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700825 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
826 CountingCallback cb1(mDispatch);
827 CountingCallback cb2(mDispatch);
828
Ady Abraham9c53ee72020-07-22 21:16:18 -0700829 EXPECT_EQ(mDispatch.schedule(cb1,
830 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
831 ScheduleResult::Scheduled);
832 EXPECT_EQ(mDispatch.schedule(cb2,
833 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}),
834 ScheduleResult::Scheduled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700835
836 mMockClock.setLag(100);
837 mMockClock.advanceBy(620);
838
839 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
840
841 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
842 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
843 mMockClock.advanceToNextCallback();
844
845 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
846 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
847}
848
Kevin DuBoisf9477832020-07-16 10:21:36 -0700849TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
850 CountingCallback cb1(mDispatch);
851 CountingCallback cb2(mDispatch);
852
853 Sequence seq;
854 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
855 .InSequence(seq)
856 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700857 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700858 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
859 .InSequence(seq)
860 .WillOnce(Return(1000));
861
Ady Abraham9c53ee72020-07-22 21:16:18 -0700862 EXPECT_EQ(mDispatch.schedule(cb1,
863 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}),
864 ScheduleResult::Scheduled);
865 EXPECT_EQ(mDispatch.schedule(cb2,
866 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000}),
867 ScheduleResult::Scheduled);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700868
869 mMockClock.setLag(100);
870 mMockClock.advanceBy(700);
871
872 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
873 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700874 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
875 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700876 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
877 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700878 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
879 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
880}
881
882TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
883 auto intended = mPeriod - 230;
884 EXPECT_CALL(mMockClock, alarmAt(_, 900));
885
886 CountingCallback cb(mDispatch);
887 EXPECT_EQ(mDispatch.schedule(cb,
888 {.workDuration = 70,
889 .readyDuration = 30,
890 .earliestVsync = intended}),
891 ScheduleResult::Scheduled);
892 advanceToNextCallback();
893
894 ASSERT_THAT(cb.mCalls.size(), Eq(1));
895 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
896 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
897 EXPECT_THAT(cb.mWakeupTime[0], 900);
898 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
899 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700900}
901
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800902class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700903protected:
904 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800905 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700906 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
907};
908
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800909TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700910 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800911 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700912 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700913 EXPECT_THAT(entry.name(), Eq(name));
914 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
915 EXPECT_FALSE(entry.wakeupTime());
916}
917
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800918TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800919 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700920 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700921
922 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700923 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
924 mStubTracker, 0),
925 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800926 auto const wakeup = entry.wakeupTime();
927 ASSERT_TRUE(wakeup);
928 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700929
930 entry.disarm();
931 EXPECT_FALSE(entry.wakeupTime());
932}
933
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800934TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700935 auto const duration = 500;
936 auto const now = 8750;
937
938 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
939 .Times(1)
940 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800941 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700942 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700943
944 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700945 EXPECT_THAT(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
946 mStubTracker, now),
947 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800948 auto const wakeup = entry.wakeupTime();
949 ASSERT_TRUE(wakeup);
950 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -0700951}
952
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800953TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700954 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800955 auto vsyncCalledTime = 0;
956 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700957 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800958 VSyncDispatchTimerQueueEntry entry(
959 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -0700960 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800961 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -0800962 vsyncCalledTime = vsyncTime;
963 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700964 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800965 },
966 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700967
Ady Abraham9c53ee72020-07-22 21:16:18 -0700968 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
969 mStubTracker, 0),
970 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800971 auto const wakeup = entry.wakeupTime();
972 ASSERT_TRUE(wakeup);
973 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700974
Ady Abraham9c53ee72020-07-22 21:16:18 -0700975 auto const ready = entry.readyTime();
976 ASSERT_TRUE(ready);
977 EXPECT_THAT(*ready, Eq(1000));
978
979 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -0700980
981 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -0800982 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
983 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -0700984 EXPECT_FALSE(entry.wakeupTime());
985 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
986 ASSERT_TRUE(lastCalledTarget);
987 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
988}
989
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800990TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700991 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
992 .Times(2)
993 .WillOnce(Return(1000))
994 .WillOnce(Return(1020));
995
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800996 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700997 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700998
999 EXPECT_FALSE(entry.wakeupTime());
1000 entry.update(mStubTracker, 0);
1001 EXPECT_FALSE(entry.wakeupTime());
1002
Ady Abraham9c53ee72020-07-22 21:16:18 -07001003 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1004 mStubTracker, 0),
1005 Eq(ScheduleResult::Scheduled));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001006 auto wakeup = entry.wakeupTime();
1007 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001008 EXPECT_THAT(wakeup, Eq(900));
1009
1010 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001011 wakeup = entry.wakeupTime();
1012 ASSERT_TRUE(wakeup);
1013 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001014}
1015
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001016TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001017 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001018 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1019 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1020 mStubTracker, 0),
1021 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001022 entry.update(mStubTracker, 0);
1023
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001024 auto const wakeup = entry.wakeupTime();
1025 ASSERT_TRUE(wakeup);
1026 EXPECT_THAT(*wakeup, Eq(wakeup));
1027}
1028
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001029TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1030 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001031 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1032 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1033 mStubTracker, 0),
1034 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001035 entry.executing(); // 1000 is executing
1036 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abraham9c53ee72020-07-22 21:16:18 -07001037 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1038 mStubTracker, 0),
1039 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001040 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001041 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001042
Ady Abraham9c53ee72020-07-22 21:16:18 -07001043 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1044 mStubTracker, 0),
1045 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001046 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001047 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001048
Ady Abraham9c53ee72020-07-22 21:16:18 -07001049 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1050 mStubTracker, 0),
1051 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001052 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001053 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001054}
1055
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001056TEST_F(VSyncDispatchTimerQueueEntryTest,
1057 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1058 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001059 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001060
1061 Sequence seq;
1062 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1063 .InSequence(seq)
1064 .WillOnce(Return(1000));
1065 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1066 .InSequence(seq)
1067 .WillOnce(Return(1000));
1068 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1069 .InSequence(seq)
1070 .WillOnce(Return(2000));
1071
Ady Abraham9c53ee72020-07-22 21:16:18 -07001072 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1073 mStubTracker, 0),
1074 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001075
1076 entry.executing(); // 1000 is executing
1077
Ady Abraham9c53ee72020-07-22 21:16:18 -07001078 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1079 mStubTracker, 0),
1080 Eq(ScheduleResult::Scheduled));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001081}
1082
1083TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1084 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001085 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1086 EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1087 mStubTracker, 0),
1088 Eq(ScheduleResult::Scheduled));
1089 EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1090 mStubTracker, 0),
1091 Eq(ScheduleResult::Scheduled));
1092 EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1093 mStubTracker, 0),
1094 Eq(ScheduleResult::Scheduled));
1095 EXPECT_THAT(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1096 mStubTracker, 0),
1097 Eq(ScheduleResult::Scheduled));
Kevin DuBois305bef12019-10-09 13:23:27 -07001098}
1099
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001100TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1101 static constexpr auto effectualOffset = 200;
1102 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001103 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001104 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001105 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1106 entry.addPendingWorkloadUpdate(
1107 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001108 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1109 entry.update(mStubTracker, 0);
1110 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1111 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1112}
1113
Ady Abraham9c53ee72020-07-22 21:16:18 -07001114TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1115 auto callCount = 0;
1116 auto vsyncCalledTime = 0;
1117 auto wakeupCalledTime = 0;
1118 auto readyCalledTime = 0;
1119 VSyncDispatchTimerQueueEntry entry(
1120 "test",
1121 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1122 callCount++;
1123 vsyncCalledTime = vsyncTime;
1124 wakeupCalledTime = wakeupTime;
1125 readyCalledTime = readyTime;
1126 },
1127 mVsyncMoveThreshold);
1128
1129 EXPECT_THAT(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1130 mStubTracker, 0),
1131 Eq(ScheduleResult::Scheduled));
1132 auto const wakeup = entry.wakeupTime();
1133 ASSERT_TRUE(wakeup);
1134 EXPECT_THAT(*wakeup, Eq(900));
1135
1136 auto const ready = entry.readyTime();
1137 ASSERT_TRUE(ready);
1138 EXPECT_THAT(*ready, Eq(970));
1139
1140 entry.callback(entry.executing(), *wakeup, *ready);
1141
1142 EXPECT_THAT(callCount, Eq(1));
1143 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1144 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1145 EXPECT_FALSE(entry.wakeupTime());
1146 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1147 ASSERT_TRUE(lastCalledTarget);
1148 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1149}
1150
Kevin DuBois305bef12019-10-09 13:23:27 -07001151} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001152
1153// TODO(b/129481165): remove the #pragma below and fix conversion issues
1154#pragma clang diagnostic pop // ignored "-Wconversion"