blob: b7f968dc1785567004af8c5ddf89c4963e4afa69 [file] [log] [blame]
Kevin DuBois305bef12019-10-09 13:23:27 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010020#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080021
Kevin DuBois305bef12019-10-09 13:23:27 -070022#undef LOG_TAG
23#define LOG_TAG "LibSurfaceFlingerUnittests"
24#define LOG_NDEBUG 0
25
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080026#include <thread>
Kevin DuBois305bef12019-10-09 13:23:27 -070027
28#include <gmock/gmock.h>
29#include <gtest/gtest.h>
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080030
31#include <scheduler/TimeKeeper.h>
32
33#include "Scheduler/VSyncDispatchTimerQueue.h"
34#include "Scheduler/VSyncTracker.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070035
36using namespace testing;
37using namespace std::literals;
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080038
Kevin DuBois305bef12019-10-09 13:23:27 -070039namespace android::scheduler {
40
41class MockVSyncTracker : public VSyncTracker {
42public:
43 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
44 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
45 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080046 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Kevin DuBois305bef12019-10-09 13:23:27 -070047 }
48
Kevin DuBois02d5ed92020-01-27 11:05:46 -080049 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070050 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080051 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080052 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080053 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070054 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5cc2e262021-03-25 13:09:17 -070055 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
Ady Abraham5e7371c2020-03-24 14:47:24 -070056 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070057
58 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
59 if (timePoint % mPeriod == 0) {
60 return timePoint;
61 }
62 return (timePoint - (timePoint % mPeriod) + mPeriod);
63 }
64
65protected:
66 nsecs_t const mPeriod;
67};
68
69class ControllableClock : public TimeKeeper {
70public:
71 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070072 ON_CALL(*this, alarmAt(_, _))
73 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070074 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
75 }
76
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080077 MOCK_METHOD(nsecs_t, now, (), (const));
78 MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
79 MOCK_METHOD(void, alarmCancel, (), (override));
80 MOCK_METHOD(void, dump, (std::string&), (const, override));
Kevin DuBois305bef12019-10-09 13:23:27 -070081
Ady Abrahamb491c902020-08-15 15:47:56 -070082 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070083 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070084 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070085 }
86
87 nsecs_t fakeTime() const { return mCurrentTime; }
88
89 void advanceToNextCallback() {
90 mCurrentTime = mNextCallbackTime;
91 if (mCallback) {
92 mCallback();
93 }
94 }
95
96 void advanceBy(nsecs_t advancement) {
97 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070098 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070099 mCallback();
100 }
101 };
102
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700103 void setLag(nsecs_t lag) { mLag = lag; }
104
Kevin DuBois305bef12019-10-09 13:23:27 -0700105private:
106 std::function<void()> mCallback;
107 nsecs_t mNextCallbackTime = 0;
108 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700109 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700110};
111
112class CountingCallback {
113public:
114 CountingCallback(VSyncDispatch& dispatch)
115 : mDispatch(dispatch),
116 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700117 std::placeholders::_1, std::placeholders::_2,
118 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700119 "test")) {}
120 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
121
122 operator VSyncDispatch::CallbackToken() const { return mToken; }
123
Ady Abraham9c53ee72020-07-22 21:16:18 -0700124 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700125 mCalls.push_back(time);
126 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700127 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700128 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700129
130 VSyncDispatch& mDispatch;
131 VSyncDispatch::CallbackToken mToken;
132 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700133 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700134 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700135};
136
137class PausingCallback {
138public:
139 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
140 : mDispatch(dispatch),
141 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800142 std::placeholders::_1,
143 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700144 "test")),
145 mRegistered(true),
146 mPauseAmount(pauseAmount) {}
147 ~PausingCallback() { unregister(); }
148
149 operator VSyncDispatch::CallbackToken() const { return mToken; }
150
Kevin DuBois2968afc2020-01-14 09:48:50 -0800151 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700152 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700153 mPause = true;
154 mCv.notify_all();
155
Ady Abraham8cb21882020-08-26 18:22:05 -0700156 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700157
158 mResourcePresent = (mResource.lock() != nullptr);
159 }
160
161 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700162 std::unique_lock lock(mMutex);
163 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700164 return waiting;
165 }
166
167 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
168
169 bool resourcePresent() { return mResourcePresent; }
170
171 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700172 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700173 mPause = false;
174 mCv.notify_all();
175 }
176
177 void unregister() {
178 if (mRegistered) {
179 mDispatch.unregisterCallback(mToken);
180 mRegistered = false;
181 }
182 }
183
184 VSyncDispatch& mDispatch;
185 VSyncDispatch::CallbackToken mToken;
186 bool mRegistered = true;
187
188 std::mutex mMutex;
189 std::condition_variable mCv;
190 bool mPause = false;
191 std::weak_ptr<void> mResource;
192 bool mResourcePresent = false;
193 std::chrono::milliseconds const mPauseAmount;
194};
195
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800196class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700197protected:
198 std::unique_ptr<TimeKeeper> createTimeKeeper() {
199 class TimeKeeperWrapper : public TimeKeeper {
200 public:
201 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800202
Kevin DuBois305bef12019-10-09 13:23:27 -0700203 nsecs_t now() const final { return mControllableClock.now(); }
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800204
205 void alarmAt(std::function<void()> callback, nsecs_t time) final {
206 mControllableClock.alarmAt(std::move(callback), time);
207 }
208
209 void alarmCancel() final { mControllableClock.alarmCancel(); }
Ady Abraham75398722020-04-07 14:08:45 -0700210 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700211
212 private:
213 TimeKeeper& mControllableClock;
214 };
215 return std::make_unique<TimeKeeperWrapper>(mMockClock);
216 }
217
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800218 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700219 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
220 Mock::VerifyAndClearExpectations(&mMockClock);
221 }
222
223 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
224
225 NiceMock<ControllableClock> mMockClock;
226 static nsecs_t constexpr mDispatchGroupThreshold = 5;
227 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800228 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700229 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800230 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
231 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700232};
233
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800234TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700235 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700236 EXPECT_CALL(mMockClock, alarmCancel());
237 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800238 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
239 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700240 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700241 const auto result = mDispatch.schedule(cb,
242 {.workDuration = 100,
243 .readyDuration = 0,
244 .earliestVsync = 1000});
245 EXPECT_TRUE(result.has_value());
246 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700247 }
248}
249
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800250TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700251 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700252 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700253
254 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700255 const auto result = mDispatch.schedule(cb,
256 {.workDuration = 100,
257 .readyDuration = 0,
258 .earliestVsync = intended});
259 EXPECT_TRUE(result.has_value());
260 EXPECT_EQ(900, *result);
261
Kevin DuBois305bef12019-10-09 13:23:27 -0700262 advanceToNextCallback();
263
264 ASSERT_THAT(cb.mCalls.size(), Eq(1));
265 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
266}
267
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800268TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700269 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700270 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700271
272 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700273 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700274 advanceToNextCallback();
275
276 ASSERT_THAT(cb.mCalls.size(), Eq(1));
277 EXPECT_THAT(cb.mCalls[0], Eq(1150));
278}
279
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800280TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700281 auto const now = 234;
282 mMockClock.advanceBy(234);
283 auto const workDuration = 10 * mPeriod;
284 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
285 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700286 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700287
288 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700289 const auto result = mDispatch.schedule(cb,
290 {.workDuration = workDuration,
291 .readyDuration = 0,
292 .earliestVsync = mPeriod});
293 EXPECT_TRUE(result.has_value());
294 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700295}
296
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800297TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700298 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700299 EXPECT_CALL(mMockClock, alarmCancel());
300
301 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700302 const auto result =
303 mDispatch.schedule(cb,
304 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
305 EXPECT_TRUE(result.has_value());
306 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700307 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
308}
309
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800310TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700311 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700312 EXPECT_CALL(mMockClock, alarmCancel());
313
314 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700315 const auto result =
316 mDispatch.schedule(cb,
317 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
318 EXPECT_TRUE(result.has_value());
319 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700320 mMockClock.advanceBy(950);
321 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
322}
323
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800324TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700325 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700326 EXPECT_CALL(mMockClock, alarmCancel());
327
328 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700329 const auto result =
330 mDispatch.schedule(cb,
331 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
332 EXPECT_TRUE(result.has_value());
333 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700334
335 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
336 EXPECT_TRUE(cb.waitForPause());
337 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
338 cb.unpause();
339 pausingThread.join();
340}
341
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800342TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700343 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700344 EXPECT_CALL(mMockClock, alarmCancel());
345
346 auto resource = std::make_shared<int>(110);
347
348 PausingCallback cb(mDispatch, 50ms);
349 cb.stashResource(resource);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700350 const auto result =
351 mDispatch.schedule(cb,
352 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
353 EXPECT_TRUE(result.has_value());
354 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700355
356 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
357 EXPECT_TRUE(cb.waitForPause());
358
359 cb.unregister();
360 resource.reset();
361
362 cb.unpause();
363 pausingThread.join();
364
365 EXPECT_TRUE(cb.resourcePresent());
366}
367
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800368TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700369 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
370 .Times(4)
371 .WillOnce(Return(1055))
372 .WillOnce(Return(1063))
373 .WillOnce(Return(1063))
374 .WillOnce(Return(1075));
375
376 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700377 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
378 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
379 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700380
381 CountingCallback cb0(mDispatch);
382 CountingCallback cb1(mDispatch);
383
Ady Abraham9c53ee72020-07-22 21:16:18 -0700384 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
385 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700386
387 advanceToNextCallback();
388 advanceToNextCallback();
389
390 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
391 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
392 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
393 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
394}
395
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800396TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700397 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
398 .Times(4)
399 .WillOnce(Return(10000))
400 .WillOnce(Return(1000))
401 .WillOnce(Return(10000))
402 .WillOnce(Return(10000));
403
404 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700405 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
406 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
407 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700408
409 CountingCallback cb0(mDispatch);
410 CountingCallback cb1(mDispatch);
411
Ady Abraham9c53ee72020-07-22 21:16:18 -0700412 mDispatch.schedule(cb0,
413 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
414 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700415 mDispatch.cancel(cb1);
416}
417
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800418TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700419 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700420 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
421 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700422
423 CountingCallback cb0(mDispatch);
424 CountingCallback cb1(mDispatch);
425
Ady Abraham9c53ee72020-07-22 21:16:18 -0700426 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
427 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
428 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700429 advanceToNextCallback();
430}
431
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800432TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700433 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700434 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
435 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
436 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700437
438 CountingCallback cb0(mDispatch);
439 CountingCallback cb1(mDispatch);
440
Ady Abraham9c53ee72020-07-22 21:16:18 -0700441 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
442 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
443 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700444 advanceToNextCallback();
445}
446
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800447TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700448 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700449 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
450 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
451 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
452 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700453
454 auto offset = 400;
455 auto closeOffset = offset + mDispatchGroupThreshold - 1;
456 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
457
458 CountingCallback cb0(mDispatch);
459 CountingCallback cb1(mDispatch);
460
Ady Abraham9c53ee72020-07-22 21:16:18 -0700461 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
462 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
463 mDispatch.schedule(cb1,
464 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700465
466 advanceToNextCallback();
467 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
468 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
469 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
470 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
471
Ady Abraham9c53ee72020-07-22 21:16:18 -0700472 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
473 mDispatch.schedule(cb1,
474 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700475 advanceToNextCallback();
476 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
477 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
478
479 advanceToNextCallback();
480 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
481 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
482}
483
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800484TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700485 Sequence seq;
486 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
487 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
488 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700489 EXPECT_CALL(mMockClock, alarmCancel());
490
491 CountingCallback cb0(mDispatch);
492 CountingCallback cb1(mDispatch);
493
Ady Abraham9c53ee72020-07-22 21:16:18 -0700494 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
495 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700496 advanceToNextCallback();
497 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
498}
499
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800500TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700501 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
502 .Times(3)
503 .WillOnce(Return(950))
504 .WillOnce(Return(1975))
505 .WillOnce(Return(2950));
506
507 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700508 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700509
510 mMockClock.advanceBy(850);
511 EXPECT_THAT(cb.mCalls.size(), Eq(1));
512
Ady Abraham9c53ee72020-07-22 21:16:18 -0700513 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700514 mMockClock.advanceBy(900);
515 EXPECT_THAT(cb.mCalls.size(), Eq(1));
516 mMockClock.advanceBy(125);
517 EXPECT_THAT(cb.mCalls.size(), Eq(2));
518
Ady Abraham9c53ee72020-07-22 21:16:18 -0700519 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700520 mMockClock.advanceBy(975);
521 EXPECT_THAT(cb.mCalls.size(), Eq(3));
522}
523
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800524TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700525 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700526 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
527 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700528
529 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700530 tmp = mDispatch.registerCallback(
531 [&](auto, auto, auto) {
532 mDispatch.schedule(tmp,
533 {.workDuration = 100,
534 .readyDuration = 0,
535 .earliestVsync = 2000});
536 },
537 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700538
Ady Abraham9c53ee72020-07-22 21:16:18 -0700539 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700540 advanceToNextCallback();
541}
542
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800543TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700544 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800545 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700546 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700547 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700548 auto result =
549 mDispatch.schedule(tmp,
550 {.workDuration = 400,
551 .readyDuration = 0,
552 .earliestVsync = timestamp - mVsyncMoveThreshold});
553 EXPECT_TRUE(result.has_value());
554 EXPECT_EQ(mPeriod + timestamp - 400, *result);
555 result = mDispatch.schedule(tmp,
556 {.workDuration = 400,
557 .readyDuration = 0,
558 .earliestVsync = timestamp});
559 EXPECT_TRUE(result.has_value());
560 EXPECT_EQ(mPeriod + timestamp - 400, *result);
561 result = mDispatch.schedule(tmp,
562 {.workDuration = 400,
563 .readyDuration = 0,
564 .earliestVsync = timestamp + mVsyncMoveThreshold});
565 EXPECT_TRUE(result.has_value());
566 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800567 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700568 },
569 "oo");
570
Ady Abraham9c53ee72020-07-22 21:16:18 -0700571 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700572 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800573 EXPECT_THAT(lastTarget, Eq(1000));
574
575 advanceToNextCallback();
576 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700577}
578
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800579TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700580 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700581 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
582 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
583 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
584 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700585
586 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700587 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700588
589 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700590 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700591
592 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700593 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700594
595 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700596 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700597}
598
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800599TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700600 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700601 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
602 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
603 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
604 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700605
606 CountingCallback cb0(mDispatch);
607 CountingCallback cb1(mDispatch);
608
Ady Abraham9c53ee72020-07-22 21:16:18 -0700609 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
610 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700611
612 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700613 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
614 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700615
616 advanceToNextCallback();
617 advanceToNextCallback();
618}
619
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800620TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700621 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700622 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700623
624 CountingCallback cb0(mDispatch);
625 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700626 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
627 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700628}
629
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800630TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700631 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700632 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700633 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700634 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700635
636 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700637 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700638 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700639 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700640}
641
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800642TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700643 VSyncDispatch::CallbackToken token(100);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700644 EXPECT_FALSE(mDispatch
645 .schedule(token,
646 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
647 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -0700648 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
649}
650
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800651TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700652 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700653 auto result =
654 mDispatch.schedule(cb0,
655 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
656 EXPECT_TRUE(result.has_value());
657 EXPECT_EQ(500, *result);
658 result = mDispatch.schedule(cb0,
659 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
660 EXPECT_TRUE(result.has_value());
661 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800662}
663
664// b/1450138150
665TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700666 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800667 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700668 auto result =
669 mDispatch.schedule(cb,
670 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
671 EXPECT_TRUE(result.has_value());
672 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800673 mMockClock.advanceBy(400);
674
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700675 result = mDispatch.schedule(cb,
676 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
677 EXPECT_TRUE(result.has_value());
678 EXPECT_EQ(1200, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800679 advanceToNextCallback();
680 ASSERT_THAT(cb.mCalls.size(), Eq(1));
681}
682
683TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
684 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
685 .Times(2)
686 .WillOnce(Return(1000))
687 .WillOnce(Return(1002));
688 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700689 auto result =
690 mDispatch.schedule(cb,
691 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
692 EXPECT_TRUE(result.has_value());
693 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800694 mMockClock.advanceBy(400);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700695 result = mDispatch.schedule(cb,
696 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
697 EXPECT_TRUE(result.has_value());
698 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700699}
700
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800701TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
702 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700703 auto result =
704 mDispatch.schedule(cb0,
705 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
706 EXPECT_TRUE(result.has_value());
707 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800708 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700709 result = mDispatch.schedule(cb0,
710 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
711 EXPECT_TRUE(result.has_value());
712 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800713}
714
715TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
716 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700717 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
718 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800719 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700720 auto result =
721 mDispatch.schedule(cb0,
722 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
723 EXPECT_TRUE(result.has_value());
724 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800725 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700726 result = mDispatch.schedule(cb0,
727 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
728 EXPECT_TRUE(result.has_value());
729 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800730}
731
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800732TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700733 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800734
735 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700736 auto result =
737 mDispatch.schedule(cb,
738 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
739 EXPECT_TRUE(result.has_value());
740 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800741
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700742 result = mDispatch.schedule(cb,
743 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
744 EXPECT_TRUE(result.has_value());
745 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800746
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800747 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800748}
749
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800750TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700751 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700752 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
753
754 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700755 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700756 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700757 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700758 cb.cancel();
759
Ady Abraham9c53ee72020-07-22 21:16:18 -0700760 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700761 cb1.cancel();
762}
763
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800764TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700765 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700766 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
767
768 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700769 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700770 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700771 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700772 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700773 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700774 cb.cancel();
775
Ady Abraham9c53ee72020-07-22 21:16:18 -0700776 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700777 cb1.cancel();
778}
779
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700780// b/154303580
781TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
782 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700783 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
784 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700785 CountingCallback cb1(mDispatch);
786 CountingCallback cb2(mDispatch);
787
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700788 auto result =
789 mDispatch.schedule(cb1,
790 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
791 EXPECT_TRUE(result.has_value());
792 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700793
794 mMockClock.setLag(100);
795 mMockClock.advanceBy(620);
796
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700797 result = mDispatch.schedule(cb2,
798 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
799 EXPECT_TRUE(result.has_value());
800 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700801 mMockClock.advanceBy(80);
802
803 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
804 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
805}
806
807// b/154303580.
808// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
809// update later, as opposed to blocking the calling thread.
810TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
811 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700812 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
813 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700814 CountingCallback cb(mDispatch);
815
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700816 auto result =
817 mDispatch.schedule(cb,
818 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
819 EXPECT_TRUE(result.has_value());
820 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700821
822 mMockClock.setLag(100);
823 mMockClock.advanceBy(620);
824
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700825 result = mDispatch.schedule(cb,
826 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
827 EXPECT_TRUE(result.has_value());
828 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700829 mMockClock.advanceBy(80);
830
831 EXPECT_THAT(cb.mCalls.size(), Eq(1));
832}
833
Kevin DuBoisb340b732020-06-16 09:07:35 -0700834// b/154303580.
835TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
836 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700837 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700838 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
839 CountingCallback cb1(mDispatch);
840 CountingCallback cb2(mDispatch);
841
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700842 auto result =
843 mDispatch.schedule(cb1,
844 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
845 EXPECT_TRUE(result.has_value());
846 EXPECT_EQ(600, *result);
847 result = mDispatch.schedule(cb2,
848 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
849 EXPECT_TRUE(result.has_value());
850 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700851
852 mMockClock.setLag(100);
853 mMockClock.advanceBy(620);
854
855 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
856
857 mMockClock.advanceBy(80);
858
859 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
860 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
861}
862
863TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
864 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700865 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
866 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700867 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
868 CountingCallback cb1(mDispatch);
869 CountingCallback cb2(mDispatch);
870
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700871 auto result =
872 mDispatch.schedule(cb1,
873 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
874 EXPECT_TRUE(result.has_value());
875 EXPECT_EQ(600, *result);
876 result = mDispatch.schedule(cb2,
877 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
878 EXPECT_TRUE(result.has_value());
879 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700880
881 mMockClock.setLag(100);
882 mMockClock.advanceBy(620);
883
884 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
885
886 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
887 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
888 mMockClock.advanceToNextCallback();
889
890 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
891 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
892}
893
Kevin DuBoisf9477832020-07-16 10:21:36 -0700894TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
895 CountingCallback cb1(mDispatch);
896 CountingCallback cb2(mDispatch);
897
898 Sequence seq;
899 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
900 .InSequence(seq)
901 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700902 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700903 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
904 .InSequence(seq)
905 .WillOnce(Return(1000));
906
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700907 auto result =
908 mDispatch.schedule(cb1,
909 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
910 EXPECT_TRUE(result.has_value());
911 EXPECT_EQ(600, *result);
912 result = mDispatch.schedule(cb2,
913 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
914 EXPECT_TRUE(result.has_value());
915 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700916
917 mMockClock.setLag(100);
918 mMockClock.advanceBy(700);
919
920 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
921 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700922 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
923 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700924 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
925 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700926 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
927 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
928}
929
930TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
931 auto intended = mPeriod - 230;
932 EXPECT_CALL(mMockClock, alarmAt(_, 900));
933
934 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700935 const auto result = mDispatch.schedule(cb,
936 {.workDuration = 70,
937 .readyDuration = 30,
938 .earliestVsync = intended});
939 EXPECT_TRUE(result.has_value());
940 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700941 advanceToNextCallback();
942
943 ASSERT_THAT(cb.mCalls.size(), Eq(1));
944 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
945 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
946 EXPECT_THAT(cb.mWakeupTime[0], 900);
947 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
948 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700949}
950
Ady Abraham69b9e622021-07-19 12:24:31 -0700951TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
952 Sequence seq;
953 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
954
955 CountingCallback cb(mDispatch);
956
957 mDispatch.schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
958 mDispatch.schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
959
960 advanceToNextCallback();
961
962 advanceToNextCallback();
963
964 ASSERT_THAT(cb.mCalls.size(), Eq(1));
965 EXPECT_THAT(cb.mCalls[0], Eq(2000));
966 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
967 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
968 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
969 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
970}
971
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800972class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700973protected:
974 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800975 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -0700976 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
977};
978
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800979TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700980 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800981 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700982 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700983 EXPECT_THAT(entry.name(), Eq(name));
984 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
985 EXPECT_FALSE(entry.wakeupTime());
986}
987
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800988TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800989 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700990 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700991
992 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700993 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
994 mStubTracker, 0)
995 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800996 auto const wakeup = entry.wakeupTime();
997 ASSERT_TRUE(wakeup);
998 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700999
1000 entry.disarm();
1001 EXPECT_FALSE(entry.wakeupTime());
1002}
1003
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001004TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001005 auto const duration = 500;
1006 auto const now = 8750;
1007
1008 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
1009 .Times(1)
1010 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001011 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001012 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001013
1014 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001015 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
1016 mStubTracker, now)
1017 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001018 auto const wakeup = entry.wakeupTime();
1019 ASSERT_TRUE(wakeup);
1020 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001021}
1022
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001023TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001024 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001025 auto vsyncCalledTime = 0;
1026 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001027 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001028 VSyncDispatchTimerQueueEntry entry(
1029 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001030 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001031 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001032 vsyncCalledTime = vsyncTime;
1033 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001034 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001035 },
1036 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001037
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001038 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1039 mStubTracker, 0)
1040 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001041 auto const wakeup = entry.wakeupTime();
1042 ASSERT_TRUE(wakeup);
1043 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001044
Ady Abraham9c53ee72020-07-22 21:16:18 -07001045 auto const ready = entry.readyTime();
1046 ASSERT_TRUE(ready);
1047 EXPECT_THAT(*ready, Eq(1000));
1048
1049 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001050
1051 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001052 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1053 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001054 EXPECT_FALSE(entry.wakeupTime());
1055 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1056 ASSERT_TRUE(lastCalledTarget);
1057 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1058}
1059
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001060TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001061 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
1062 .Times(2)
1063 .WillOnce(Return(1000))
1064 .WillOnce(Return(1020));
1065
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001066 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001067 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001068
1069 EXPECT_FALSE(entry.wakeupTime());
1070 entry.update(mStubTracker, 0);
1071 EXPECT_FALSE(entry.wakeupTime());
1072
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001073 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1074 mStubTracker, 0)
1075 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001076 auto wakeup = entry.wakeupTime();
1077 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001078 EXPECT_THAT(wakeup, Eq(900));
1079
1080 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001081 wakeup = entry.wakeupTime();
1082 ASSERT_TRUE(wakeup);
1083 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001084}
1085
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001086TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001087 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001088 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001089 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1090 mStubTracker, 0)
1091 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001092 entry.update(mStubTracker, 0);
1093
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001094 auto const wakeup = entry.wakeupTime();
1095 ASSERT_TRUE(wakeup);
1096 EXPECT_THAT(*wakeup, Eq(wakeup));
1097}
1098
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001099TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1100 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001101 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001102 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1103 mStubTracker, 0)
1104 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001105 entry.executing(); // 1000 is executing
1106 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001107 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1108 mStubTracker, 0)
1109 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001110 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001111 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001112
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001113 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1114 mStubTracker, 0)
1115 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001116 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001117 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001118
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001119 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1120 mStubTracker, 0)
1121 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001122 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001123 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001124}
1125
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001126TEST_F(VSyncDispatchTimerQueueEntryTest,
1127 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1128 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001129 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001130
1131 Sequence seq;
1132 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1133 .InSequence(seq)
1134 .WillOnce(Return(1000));
1135 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1136 .InSequence(seq)
1137 .WillOnce(Return(1000));
1138 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1139 .InSequence(seq)
1140 .WillOnce(Return(2000));
1141
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001142 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1143 mStubTracker, 0)
1144 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001145
1146 entry.executing(); // 1000 is executing
1147
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001148 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1149 mStubTracker, 0)
1150 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001151}
1152
1153TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1154 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001155 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001156 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1157 mStubTracker, 0)
1158 .has_value());
1159 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1160 mStubTracker, 0)
1161 .has_value());
1162 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1163 mStubTracker, 0)
1164 .has_value());
1165 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1166 mStubTracker, 0)
1167 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001168}
1169
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001170TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1171 static constexpr auto effectualOffset = 200;
1172 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001173 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001174 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001175 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1176 entry.addPendingWorkloadUpdate(
1177 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001178 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1179 entry.update(mStubTracker, 0);
1180 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1181 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1182}
1183
Ady Abraham9c53ee72020-07-22 21:16:18 -07001184TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1185 auto callCount = 0;
1186 auto vsyncCalledTime = 0;
1187 auto wakeupCalledTime = 0;
1188 auto readyCalledTime = 0;
1189 VSyncDispatchTimerQueueEntry entry(
1190 "test",
1191 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1192 callCount++;
1193 vsyncCalledTime = vsyncTime;
1194 wakeupCalledTime = wakeupTime;
1195 readyCalledTime = readyTime;
1196 },
1197 mVsyncMoveThreshold);
1198
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001199 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1200 mStubTracker, 0)
1201 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001202 auto const wakeup = entry.wakeupTime();
1203 ASSERT_TRUE(wakeup);
1204 EXPECT_THAT(*wakeup, Eq(900));
1205
1206 auto const ready = entry.readyTime();
1207 ASSERT_TRUE(ready);
1208 EXPECT_THAT(*ready, Eq(970));
1209
1210 entry.callback(entry.executing(), *wakeup, *ready);
1211
1212 EXPECT_THAT(callCount, Eq(1));
1213 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1214 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1215 EXPECT_FALSE(entry.wakeupTime());
1216 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1217 ASSERT_TRUE(lastCalledTarget);
1218 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1219}
1220
Kevin DuBois305bef12019-10-09 13:23:27 -07001221} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001222
1223// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001224#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"