blob: 1dc54982213aa78cfb85788a1dc66877ca09e357 [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
Ady Abraham529bd9f2023-10-05 14:55:30 -070033#include "FlagUtils.h"
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080034#include "Scheduler/VSyncDispatchTimerQueue.h"
35#include "Scheduler/VSyncTracker.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070036
Ady Abraham529bd9f2023-10-05 14:55:30 -070037#include <com_android_graphics_surfaceflinger_flags.h>
38
Kevin DuBois305bef12019-10-09 13:23:27 -070039using namespace testing;
40using namespace std::literals;
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080041
Kevin DuBois305bef12019-10-09 13:23:27 -070042namespace android::scheduler {
Ady Abraham529bd9f2023-10-05 14:55:30 -070043using namespace com::android::graphics::surfaceflinger;
Kevin DuBois305bef12019-10-09 13:23:27 -070044
45class MockVSyncTracker : public VSyncTracker {
46public:
47 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
48 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
49 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080050 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070051 ON_CALL(*this, currentPeriod())
52 .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -070053 }
54
Kevin DuBois02d5ed92020-01-27 11:05:46 -080055 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070056 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080057 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080058 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080059 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070060 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5cc2e262021-03-25 13:09:17 -070061 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
Ady Abrahamfdc049c2023-02-17 14:52:05 +000062 MOCK_METHOD(void, setRenderRate, (Fps), (override));
Ady Abraham5e7371c2020-03-24 14:47:24 -070063 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070064
65 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
66 if (timePoint % mPeriod == 0) {
67 return timePoint;
68 }
69 return (timePoint - (timePoint % mPeriod) + mPeriod);
70 }
71
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070072 nsecs_t getCurrentPeriod() const { return mPeriod; }
73
Kevin DuBois305bef12019-10-09 13:23:27 -070074protected:
75 nsecs_t const mPeriod;
76};
77
78class ControllableClock : public TimeKeeper {
79public:
80 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070081 ON_CALL(*this, alarmAt(_, _))
82 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070083 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
84 }
85
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080086 MOCK_METHOD(nsecs_t, now, (), (const));
87 MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
88 MOCK_METHOD(void, alarmCancel, (), (override));
89 MOCK_METHOD(void, dump, (std::string&), (const, override));
Kevin DuBois305bef12019-10-09 13:23:27 -070090
Ady Abrahamb491c902020-08-15 15:47:56 -070091 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070092 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070093 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070094 }
95
96 nsecs_t fakeTime() const { return mCurrentTime; }
97
98 void advanceToNextCallback() {
99 mCurrentTime = mNextCallbackTime;
100 if (mCallback) {
101 mCallback();
102 }
103 }
104
105 void advanceBy(nsecs_t advancement) {
106 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700107 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700108 mCallback();
109 }
110 };
111
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700112 void setLag(nsecs_t lag) { mLag = lag; }
113
Kevin DuBois305bef12019-10-09 13:23:27 -0700114private:
115 std::function<void()> mCallback;
116 nsecs_t mNextCallbackTime = 0;
117 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700118 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700119};
120
121class CountingCallback {
122public:
Leon Scroggins III67388622023-02-06 20:36:20 -0500123 CountingCallback(std::shared_ptr<VSyncDispatch> dispatch)
124 : mDispatch(std::move(dispatch)),
125 mToken(mDispatch->registerCallback(std::bind(&CountingCallback::counter, this,
126 std::placeholders::_1,
127 std::placeholders::_2,
128 std::placeholders::_3),
129 "test")) {}
130 ~CountingCallback() { mDispatch->unregisterCallback(mToken); }
Kevin DuBois305bef12019-10-09 13:23:27 -0700131
132 operator VSyncDispatch::CallbackToken() const { return mToken; }
133
Ady Abraham9c53ee72020-07-22 21:16:18 -0700134 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700135 mCalls.push_back(time);
136 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700137 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700138 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700139
Leon Scroggins III67388622023-02-06 20:36:20 -0500140 std::shared_ptr<VSyncDispatch> mDispatch;
Kevin DuBois305bef12019-10-09 13:23:27 -0700141 VSyncDispatch::CallbackToken mToken;
142 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700143 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700144 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700145};
146
147class PausingCallback {
148public:
Leon Scroggins III67388622023-02-06 20:36:20 -0500149 PausingCallback(std::shared_ptr<VSyncDispatch> dispatch, std::chrono::milliseconds pauseAmount)
150 : mDispatch(std::move(dispatch)),
151 mToken(mDispatch->registerCallback(std::bind(&PausingCallback::pause, this,
152 std::placeholders::_1,
153 std::placeholders::_2),
154 "test")),
Kevin DuBois305bef12019-10-09 13:23:27 -0700155 mRegistered(true),
156 mPauseAmount(pauseAmount) {}
157 ~PausingCallback() { unregister(); }
158
159 operator VSyncDispatch::CallbackToken() const { return mToken; }
160
Kevin DuBois2968afc2020-01-14 09:48:50 -0800161 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700162 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700163 mPause = true;
164 mCv.notify_all();
165
Ady Abraham8cb21882020-08-26 18:22:05 -0700166 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700167
168 mResourcePresent = (mResource.lock() != nullptr);
169 }
170
171 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700172 std::unique_lock lock(mMutex);
173 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700174 return waiting;
175 }
176
177 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
178
179 bool resourcePresent() { return mResourcePresent; }
180
181 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700182 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700183 mPause = false;
184 mCv.notify_all();
185 }
186
187 void unregister() {
188 if (mRegistered) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500189 mDispatch->unregisterCallback(mToken);
Kevin DuBois305bef12019-10-09 13:23:27 -0700190 mRegistered = false;
191 }
192 }
193
Leon Scroggins III67388622023-02-06 20:36:20 -0500194 std::shared_ptr<VSyncDispatch> mDispatch;
Kevin DuBois305bef12019-10-09 13:23:27 -0700195 VSyncDispatch::CallbackToken mToken;
196 bool mRegistered = true;
197
198 std::mutex mMutex;
199 std::condition_variable mCv;
200 bool mPause = false;
201 std::weak_ptr<void> mResource;
202 bool mResourcePresent = false;
203 std::chrono::milliseconds const mPauseAmount;
204};
205
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800206class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700207protected:
208 std::unique_ptr<TimeKeeper> createTimeKeeper() {
209 class TimeKeeperWrapper : public TimeKeeper {
210 public:
211 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800212
Kevin DuBois305bef12019-10-09 13:23:27 -0700213 nsecs_t now() const final { return mControllableClock.now(); }
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800214
215 void alarmAt(std::function<void()> callback, nsecs_t time) final {
216 mControllableClock.alarmAt(std::move(callback), time);
217 }
218
219 void alarmCancel() final { mControllableClock.alarmCancel(); }
Ady Abraham75398722020-04-07 14:08:45 -0700220 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700221
222 private:
223 TimeKeeper& mControllableClock;
224 };
225 return std::make_unique<TimeKeeperWrapper>(mMockClock);
226 }
227
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800228 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700229 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
230 Mock::VerifyAndClearExpectations(&mMockClock);
231 }
232
233 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
234
235 NiceMock<ControllableClock> mMockClock;
236 static nsecs_t constexpr mDispatchGroupThreshold = 5;
237 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800238 nsecs_t const mVsyncMoveThreshold = 300;
Leon Scroggins III67388622023-02-06 20:36:20 -0500239 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
240 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
241 std::shared_ptr<VSyncDispatch> mDispatch =
242 std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
243 mDispatchGroupThreshold, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700244};
245
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800246TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700247 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700248 EXPECT_CALL(mMockClock, alarmCancel());
249 {
Leon Scroggins III67388622023-02-06 20:36:20 -0500250 std::shared_ptr<VSyncDispatch> mDispatch =
251 std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
252 mDispatchGroupThreshold,
253 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700254 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500255 const auto result = mDispatch->schedule(cb,
256 {.workDuration = 100,
257 .readyDuration = 0,
258 .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700259 EXPECT_TRUE(result.has_value());
260 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700261 }
262}
263
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800264TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700265 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700266 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700267
268 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500269 const auto result = mDispatch->schedule(cb,
270 {.workDuration = 100,
271 .readyDuration = 0,
272 .earliestVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700273 EXPECT_TRUE(result.has_value());
274 EXPECT_EQ(900, *result);
275
Kevin DuBois305bef12019-10-09 13:23:27 -0700276 advanceToNextCallback();
277
278 ASSERT_THAT(cb.mCalls.size(), Eq(1));
279 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
280}
281
Ady Abraham011f8ba2022-11-22 15:09:07 -0800282TEST_F(VSyncDispatchTimerQueueTest, updateAlarmSettingFuture) {
283 auto intended = mPeriod - 230;
284 Sequence seq;
285 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
286 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
287
288 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500289 auto result = mDispatch->schedule(cb,
290 {.workDuration = 100,
291 .readyDuration = 0,
292 .earliestVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800293 EXPECT_TRUE(result.has_value());
294 EXPECT_EQ(900, *result);
295
Leon Scroggins III67388622023-02-06 20:36:20 -0500296 result =
297 mDispatch->update(cb,
Ady Abraham011f8ba2022-11-22 15:09:07 -0800298 {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
299 EXPECT_TRUE(result.has_value());
300 EXPECT_EQ(700, *result);
301
302 advanceToNextCallback();
303
304 ASSERT_THAT(cb.mCalls.size(), Eq(1));
305 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
306 EXPECT_THAT(cb.mWakeupTime[0], Eq(700));
307}
308
309TEST_F(VSyncDispatchTimerQueueTest, updateDoesntSchedule) {
310 auto intended = mPeriod - 230;
311 EXPECT_CALL(mMockClock, alarmAt(_, _)).Times(0);
312
313 CountingCallback cb(mDispatch);
314 const auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500315 mDispatch->update(cb,
316 {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800317 EXPECT_FALSE(result.has_value());
318}
319
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800320TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500321 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700322 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700323
324 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500325 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700326 advanceToNextCallback();
327
328 ASSERT_THAT(cb.mCalls.size(), Eq(1));
329 EXPECT_THAT(cb.mCalls[0], Eq(1150));
330}
331
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800332TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700333 auto const now = 234;
334 mMockClock.advanceBy(234);
335 auto const workDuration = 10 * mPeriod;
Leon Scroggins III67388622023-02-06 20:36:20 -0500336 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + workDuration))
Kevin DuBois305bef12019-10-09 13:23:27 -0700337 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700338 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700339
340 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500341 const auto result = mDispatch->schedule(cb,
342 {.workDuration = workDuration,
343 .readyDuration = 0,
344 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700345 EXPECT_TRUE(result.has_value());
346 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700347}
348
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800349TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700350 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700351 EXPECT_CALL(mMockClock, alarmCancel());
352
353 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500354 const auto result = mDispatch->schedule(cb,
355 {.workDuration = 100,
356 .readyDuration = 0,
357 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700358 EXPECT_TRUE(result.has_value());
359 EXPECT_EQ(mPeriod - 100, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500360 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700361}
362
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800363TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700364 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700365 EXPECT_CALL(mMockClock, alarmCancel());
366
367 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500368 const auto result = mDispatch->schedule(cb,
369 {.workDuration = 100,
370 .readyDuration = 0,
371 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700372 EXPECT_TRUE(result.has_value());
373 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700374 mMockClock.advanceBy(950);
Leon Scroggins III67388622023-02-06 20:36:20 -0500375 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700376}
377
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800378TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700379 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700380 EXPECT_CALL(mMockClock, alarmCancel());
381
382 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Leon Scroggins III67388622023-02-06 20:36:20 -0500383 const auto result = mDispatch->schedule(cb,
384 {.workDuration = 100,
385 .readyDuration = 0,
386 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700387 EXPECT_TRUE(result.has_value());
388 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700389
390 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
391 EXPECT_TRUE(cb.waitForPause());
Leon Scroggins III67388622023-02-06 20:36:20 -0500392 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700393 cb.unpause();
394 pausingThread.join();
395}
396
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800397TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700398 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700399 EXPECT_CALL(mMockClock, alarmCancel());
400
401 auto resource = std::make_shared<int>(110);
402
403 PausingCallback cb(mDispatch, 50ms);
404 cb.stashResource(resource);
Leon Scroggins III67388622023-02-06 20:36:20 -0500405 const auto result = mDispatch->schedule(cb,
406 {.workDuration = 100,
407 .readyDuration = 0,
408 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700409 EXPECT_TRUE(result.has_value());
410 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700411
412 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
413 EXPECT_TRUE(cb.waitForPause());
414
415 cb.unregister();
416 resource.reset();
417
418 cb.unpause();
419 pausingThread.join();
420
421 EXPECT_TRUE(cb.resourcePresent());
422}
423
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800424TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500425 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBois305bef12019-10-09 13:23:27 -0700426 .Times(4)
427 .WillOnce(Return(1055))
428 .WillOnce(Return(1063))
429 .WillOnce(Return(1063))
430 .WillOnce(Return(1075));
431
432 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700433 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
434 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
435 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700436
437 CountingCallback cb0(mDispatch);
438 CountingCallback cb1(mDispatch);
439
Leon Scroggins III67388622023-02-06 20:36:20 -0500440 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
441 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700442
443 advanceToNextCallback();
444 advanceToNextCallback();
445
446 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
447 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
448 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
449 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
450}
451
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700452TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500453 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700454 .Times(4)
455 .WillOnce(Return(1000))
456 .WillOnce(Return(2000))
457 .WillOnce(Return(2500))
458 .WillOnce(Return(4000));
459
460 Sequence seq;
461 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
462 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
463 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
464
465 CountingCallback cb(mDispatch);
466
Leon Scroggins III67388622023-02-06 20:36:20 -0500467 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700468
469 advanceToNextCallback();
470
471 ASSERT_THAT(cb.mCalls.size(), Eq(1));
472 EXPECT_THAT(cb.mCalls[0], Eq(1000));
473
Leon Scroggins III67388622023-02-06 20:36:20 -0500474 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700475
476 advanceToNextCallback();
477
478 ASSERT_THAT(cb.mCalls.size(), Eq(2));
479 EXPECT_THAT(cb.mCalls[1], Eq(2000));
480
Leon Scroggins III67388622023-02-06 20:36:20 -0500481 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700482
483 advanceToNextCallback();
484
485 ASSERT_THAT(cb.mCalls.size(), Eq(3));
486 EXPECT_THAT(cb.mCalls[2], Eq(4000));
487}
488
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800489TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500490 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -0700491 .Times(4)
492 .WillOnce(Return(10000))
493 .WillOnce(Return(1000))
494 .WillOnce(Return(10000))
495 .WillOnce(Return(10000));
496
497 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700498 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
499 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
500 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700501
502 CountingCallback cb0(mDispatch);
503 CountingCallback cb1(mDispatch);
504
Leon Scroggins III67388622023-02-06 20:36:20 -0500505 mDispatch->schedule(cb0,
506 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
507 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
508 mDispatch->cancel(cb1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700509}
510
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800511TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700512 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700513 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
514 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700515
516 CountingCallback cb0(mDispatch);
517 CountingCallback cb1(mDispatch);
518
Leon Scroggins III67388622023-02-06 20:36:20 -0500519 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
520 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
521 mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700522 advanceToNextCallback();
523}
524
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800525TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700526 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700527 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
528 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
529 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700530
531 CountingCallback cb0(mDispatch);
532 CountingCallback cb1(mDispatch);
533
Leon Scroggins III67388622023-02-06 20:36:20 -0500534 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
535 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
536 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700537 advanceToNextCallback();
538}
539
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800540TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700541 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700542 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
543 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
544 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
545 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700546
547 auto offset = 400;
548 auto closeOffset = offset + mDispatchGroupThreshold - 1;
549 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
550
551 CountingCallback cb0(mDispatch);
552 CountingCallback cb1(mDispatch);
553
Leon Scroggins III67388622023-02-06 20:36:20 -0500554 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
555 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
556 mDispatch->schedule(cb1,
557 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700558
559 advanceToNextCallback();
560 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
561 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
562 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
563 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
564
Leon Scroggins III67388622023-02-06 20:36:20 -0500565 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
566 mDispatch->schedule(cb1,
567 {.workDuration = notCloseOffset,
568 .readyDuration = 0,
569 .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700570 advanceToNextCallback();
571 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
572 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
573
574 advanceToNextCallback();
575 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
576 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
577}
578
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800579TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700580 Sequence seq;
581 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
582 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
583 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700584 EXPECT_CALL(mMockClock, alarmCancel());
585
586 CountingCallback cb0(mDispatch);
587 CountingCallback cb1(mDispatch);
588
Leon Scroggins III67388622023-02-06 20:36:20 -0500589 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
590 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700591 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500592 EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700593}
594
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800595TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500596 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -0700597 .Times(3)
598 .WillOnce(Return(950))
599 .WillOnce(Return(1975))
600 .WillOnce(Return(2950));
601
602 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500603 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700604
605 mMockClock.advanceBy(850);
606 EXPECT_THAT(cb.mCalls.size(), Eq(1));
607
Leon Scroggins III67388622023-02-06 20:36:20 -0500608 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700609 mMockClock.advanceBy(900);
610 EXPECT_THAT(cb.mCalls.size(), Eq(1));
611 mMockClock.advanceBy(125);
612 EXPECT_THAT(cb.mCalls.size(), Eq(2));
613
Leon Scroggins III67388622023-02-06 20:36:20 -0500614 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700615 mMockClock.advanceBy(975);
616 EXPECT_THAT(cb.mCalls.size(), Eq(3));
617}
618
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800619TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700620 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700621 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
622 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700623
624 VSyncDispatch::CallbackToken tmp;
Leon Scroggins III67388622023-02-06 20:36:20 -0500625 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700626 [&](auto, auto, auto) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500627 mDispatch->schedule(tmp,
628 {.workDuration = 100,
629 .readyDuration = 0,
630 .earliestVsync = 2000});
Ady Abraham9c53ee72020-07-22 21:16:18 -0700631 },
632 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700633
Leon Scroggins III67388622023-02-06 20:36:20 -0500634 mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700635 advanceToNextCallback();
636}
637
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800638TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700639 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800640 std::optional<nsecs_t> lastTarget;
Leon Scroggins III67388622023-02-06 20:36:20 -0500641 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700642 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700643 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500644 mDispatch->schedule(tmp,
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700645 {.workDuration = 400,
646 .readyDuration = 0,
Leon Scroggins III67388622023-02-06 20:36:20 -0500647 .earliestVsync = timestamp - mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700648 EXPECT_TRUE(result.has_value());
649 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500650 result = mDispatch->schedule(tmp,
651 {.workDuration = 400,
652 .readyDuration = 0,
653 .earliestVsync = timestamp});
654 EXPECT_TRUE(result.has_value());
655 EXPECT_EQ(mPeriod + timestamp - 400, *result);
656 result = mDispatch->schedule(tmp,
657 {.workDuration = 400,
658 .readyDuration = 0,
659 .earliestVsync = timestamp + mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700660 EXPECT_TRUE(result.has_value());
661 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800662 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700663 },
664 "oo");
665
Leon Scroggins III67388622023-02-06 20:36:20 -0500666 mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700667 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800668 EXPECT_THAT(lastTarget, Eq(1000));
669
670 advanceToNextCallback();
671 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700672}
673
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800674TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700675 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700676 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
677 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
678 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
679 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700680
681 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500682 mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700683
684 mMockClock.advanceBy(750);
Leon Scroggins III67388622023-02-06 20:36:20 -0500685 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700686
687 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500688 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700689
690 mMockClock.advanceBy(800);
Leon Scroggins III67388622023-02-06 20:36:20 -0500691 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700692}
693
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800694TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700695 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700696 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
697 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
698 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
699 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700700
701 CountingCallback cb0(mDispatch);
702 CountingCallback cb1(mDispatch);
703
Leon Scroggins III67388622023-02-06 20:36:20 -0500704 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
705 mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700706
707 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500708 mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
709 mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700710
711 advanceToNextCallback();
712 advanceToNextCallback();
713}
714
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800715TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700716 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700717 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700718
719 CountingCallback cb0(mDispatch);
720 CountingCallback cb1(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500721 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
722 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700723}
724
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800725TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700726 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700727 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700728 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700729 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700730
731 CountingCallback cb0(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500732 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
733 mDispatch->cancel(cb0);
734 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700735}
736
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800737TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700738 VSyncDispatch::CallbackToken token(100);
Leon Scroggins III67388622023-02-06 20:36:20 -0500739 EXPECT_FALSE(
740 mDispatch
741 ->schedule(token,
742 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
743 .has_value());
744 EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700745}
746
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800747TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700748 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700749 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500750 mDispatch->schedule(cb0,
751 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700752 EXPECT_TRUE(result.has_value());
753 EXPECT_EQ(500, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500754 result = mDispatch->schedule(cb0,
755 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700756 EXPECT_TRUE(result.has_value());
757 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800758}
759
760// b/1450138150
761TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abraham3e019972023-10-20 13:23:48 -0700762 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
763
Ady Abrahamb491c902020-08-15 15:47:56 -0700764 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800765 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700766 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500767 mDispatch->schedule(cb,
768 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700769 EXPECT_TRUE(result.has_value());
770 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800771 mMockClock.advanceBy(400);
772
Leon Scroggins III67388622023-02-06 20:36:20 -0500773 result = mDispatch->schedule(cb,
774 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700775 EXPECT_TRUE(result.has_value());
776 EXPECT_EQ(1200, *result);
Ady Abraham3e019972023-10-20 13:23:48 -0700777
778 advanceToNextCallback();
779 ASSERT_THAT(cb.mCalls.size(), Eq(1));
780}
781
782// b/1450138150
783TEST_F(VSyncDispatchTimerQueueTest, movesCallbackBackwardsAndSkipAScheduledTargetVSync) {
784 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
785
786 EXPECT_CALL(mMockClock, alarmAt(_, 500));
787 CountingCallback cb(mDispatch);
788 auto result =
789 mDispatch->schedule(cb,
790 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
791 EXPECT_TRUE(result.has_value());
792 EXPECT_EQ(500, *result);
793 mMockClock.advanceBy(400);
794
795 result = mDispatch->schedule(cb,
796 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
797 EXPECT_TRUE(result.has_value());
798 EXPECT_EQ(400, *result);
799
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800800 advanceToNextCallback();
801 ASSERT_THAT(cb.mCalls.size(), Eq(1));
802}
803
804TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500805 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800806 .Times(2)
807 .WillOnce(Return(1000))
808 .WillOnce(Return(1002));
809 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700810 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500811 mDispatch->schedule(cb,
812 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700813 EXPECT_TRUE(result.has_value());
814 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800815 mMockClock.advanceBy(400);
Leon Scroggins III67388622023-02-06 20:36:20 -0500816 result = mDispatch->schedule(cb,
817 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700818 EXPECT_TRUE(result.has_value());
819 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700820}
821
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800822TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
823 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700824 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500825 mDispatch->schedule(cb0,
826 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700827 EXPECT_TRUE(result.has_value());
828 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800829 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500830 result = mDispatch->schedule(cb0,
831 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700832 EXPECT_TRUE(result.has_value());
833 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800834}
835
836TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
837 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700838 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
839 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800840 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700841 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500842 mDispatch->schedule(cb0,
843 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700844 EXPECT_TRUE(result.has_value());
845 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800846 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500847 result = mDispatch->schedule(cb0,
848 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700849 EXPECT_TRUE(result.has_value());
850 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800851}
852
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800853TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abraham3e019972023-10-20 13:23:48 -0700854 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
855
Ady Abrahamb491c902020-08-15 15:47:56 -0700856 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800857
858 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700859 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500860 mDispatch->schedule(cb,
861 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700862 EXPECT_TRUE(result.has_value());
863 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800864
Leon Scroggins III67388622023-02-06 20:36:20 -0500865 result = mDispatch->schedule(cb,
866 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700867 EXPECT_TRUE(result.has_value());
868 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800869
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800870 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800871}
872
Ady Abraham3e019972023-10-20 13:23:48 -0700873TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
874 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
875
876 EXPECT_CALL(mMockClock, alarmAt(_, 600));
877
878 CountingCallback cb(mDispatch);
879 auto result =
880 mDispatch->schedule(cb,
881 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
882 EXPECT_TRUE(result.has_value());
883 EXPECT_EQ(600, *result);
884
885 result = mDispatch->schedule(cb,
886 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
887 EXPECT_TRUE(result.has_value());
888 EXPECT_EQ(0, *result);
889
890 advanceToNextCallback();
891}
892
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800893TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700894 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700895 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
896
897 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700898 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700899 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700900 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700901 cb.cancel();
902
Ady Abraham9c53ee72020-07-22 21:16:18 -0700903 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700904 cb1.cancel();
905}
906
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800907TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700908 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700909 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
910
911 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700912 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700913 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700914 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700915 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700916 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700917 cb.cancel();
918
Ady Abraham9c53ee72020-07-22 21:16:18 -0700919 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700920 cb1.cancel();
921}
922
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700923// b/154303580
924TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
925 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700926 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
927 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700928 CountingCallback cb1(mDispatch);
929 CountingCallback cb2(mDispatch);
930
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700931 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500932 mDispatch->schedule(cb1,
933 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700934 EXPECT_TRUE(result.has_value());
935 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700936
937 mMockClock.setLag(100);
938 mMockClock.advanceBy(620);
939
Leon Scroggins III67388622023-02-06 20:36:20 -0500940 result = mDispatch->schedule(cb2,
941 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700942 EXPECT_TRUE(result.has_value());
943 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700944 mMockClock.advanceBy(80);
945
946 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
947 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
948}
949
950// b/154303580.
951// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
952// update later, as opposed to blocking the calling thread.
953TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
954 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700955 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
956 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700957 CountingCallback cb(mDispatch);
958
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700959 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500960 mDispatch->schedule(cb,
961 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700962 EXPECT_TRUE(result.has_value());
963 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700964
965 mMockClock.setLag(100);
966 mMockClock.advanceBy(620);
967
Leon Scroggins III67388622023-02-06 20:36:20 -0500968 result = mDispatch->schedule(cb,
969 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700970 EXPECT_TRUE(result.has_value());
971 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700972 mMockClock.advanceBy(80);
973
974 EXPECT_THAT(cb.mCalls.size(), Eq(1));
975}
976
Kevin DuBoisb340b732020-06-16 09:07:35 -0700977// b/154303580.
978TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
979 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700980 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700981 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
982 CountingCallback cb1(mDispatch);
983 CountingCallback cb2(mDispatch);
984
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700985 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500986 mDispatch->schedule(cb1,
987 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700988 EXPECT_TRUE(result.has_value());
989 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500990 result = mDispatch->schedule(cb2,
991 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700992 EXPECT_TRUE(result.has_value());
993 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700994
995 mMockClock.setLag(100);
996 mMockClock.advanceBy(620);
997
Leon Scroggins III67388622023-02-06 20:36:20 -0500998 EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700999
1000 mMockClock.advanceBy(80);
1001
1002 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
1003 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1004}
1005
1006TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
1007 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -07001008 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1009 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001010 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1011 CountingCallback cb1(mDispatch);
1012 CountingCallback cb2(mDispatch);
1013
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001014 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001015 mDispatch->schedule(cb1,
1016 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001017 EXPECT_TRUE(result.has_value());
1018 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001019 result = mDispatch->schedule(cb2,
1020 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001021 EXPECT_TRUE(result.has_value());
1022 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001023
1024 mMockClock.setLag(100);
1025 mMockClock.advanceBy(620);
1026
Leon Scroggins III67388622023-02-06 20:36:20 -05001027 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001028
1029 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1030 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1031 mMockClock.advanceToNextCallback();
1032
1033 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1034 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1035}
1036
Kevin DuBoisf9477832020-07-16 10:21:36 -07001037TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1038 CountingCallback cb1(mDispatch);
1039 CountingCallback cb2(mDispatch);
1040
1041 Sequence seq;
Leon Scroggins III67388622023-02-06 20:36:20 -05001042 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001043 .InSequence(seq)
1044 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -07001045 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Leon Scroggins III67388622023-02-06 20:36:20 -05001046 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001047 .InSequence(seq)
1048 .WillOnce(Return(1000));
1049
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001050 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001051 mDispatch->schedule(cb1,
1052 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001053 EXPECT_TRUE(result.has_value());
1054 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001055 result = mDispatch->schedule(cb2,
1056 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001057 EXPECT_TRUE(result.has_value());
1058 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001059
1060 mMockClock.setLag(100);
1061 mMockClock.advanceBy(700);
1062
1063 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1064 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001065 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1066 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001067 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1068 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001069 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1070 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1071}
1072
1073TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1074 auto intended = mPeriod - 230;
1075 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1076
1077 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -05001078 const auto result = mDispatch->schedule(cb,
1079 {.workDuration = 70,
1080 .readyDuration = 30,
1081 .earliestVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001082 EXPECT_TRUE(result.has_value());
1083 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -07001084 advanceToNextCallback();
1085
1086 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1087 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1088 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1089 EXPECT_THAT(cb.mWakeupTime[0], 900);
1090 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1091 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001092}
1093
Ady Abraham69b9e622021-07-19 12:24:31 -07001094TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abraham3e019972023-10-20 13:23:48 -07001095 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
1096
Ady Abraham69b9e622021-07-19 12:24:31 -07001097 Sequence seq;
1098 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1099
1100 CountingCallback cb(mDispatch);
1101
Leon Scroggins III67388622023-02-06 20:36:20 -05001102 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1103 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001104
1105 advanceToNextCallback();
1106
1107 advanceToNextCallback();
1108
1109 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1110 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1111 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1112 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1113 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1114 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1115}
1116
Ady Abraham3e019972023-10-20 13:23:48 -07001117TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
1118 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
1119
1120 Sequence seq;
1121 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1122
1123 CountingCallback cb(mDispatch);
1124
1125 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1126 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
1127
1128 advanceToNextCallback();
1129
1130 advanceToNextCallback();
1131
1132 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1133 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1134 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1135 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1136 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1137 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1138}
1139
Ady Abraham529bd9f2023-10-05 14:55:30 -07001140TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001141 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001142
1143 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1144 CountingCallback cb(mDispatch);
1145 auto result =
1146 mDispatch->schedule(cb,
1147 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1148 EXPECT_TRUE(result.has_value());
1149 EXPECT_EQ(500, *result);
1150 mMockClock.advanceBy(300);
1151
1152 result = mDispatch->schedule(cb,
1153 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1154 EXPECT_TRUE(result.has_value());
1155 EXPECT_EQ(1200, *result);
1156
1157 advanceToNextCallback();
1158 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1159}
1160
Ady Abraham529bd9f2023-10-05 14:55:30 -07001161TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001162 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001163
1164 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1165 CountingCallback cb(mDispatch);
1166 auto result =
1167 mDispatch->schedule(cb,
1168 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1169 EXPECT_TRUE(result.has_value());
1170 EXPECT_EQ(500, *result);
1171 mMockClock.advanceBy(300);
1172
1173 result = mDispatch->schedule(cb,
1174 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1175 EXPECT_TRUE(result.has_value());
Ady Abraham3e019972023-10-20 13:23:48 -07001176 EXPECT_EQ(300, *result);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001177
1178 advanceToNextCallback();
1179 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1180}
1181
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001182class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001183protected:
1184 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001185 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001186 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1187 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001188};
1189
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001190TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001191 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001192 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001193 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001194 EXPECT_THAT(entry.name(), Eq(name));
1195 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1196 EXPECT_FALSE(entry.wakeupTime());
1197}
1198
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001199TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001200 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001201 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001202
1203 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001204 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001205 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001206 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001207 auto const wakeup = entry.wakeupTime();
1208 ASSERT_TRUE(wakeup);
1209 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001210
1211 entry.disarm();
1212 EXPECT_FALSE(entry.wakeupTime());
1213}
1214
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001215TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001216 auto const duration = 500;
1217 auto const now = 8750;
1218
Leon Scroggins III67388622023-02-06 20:36:20 -05001219 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + duration))
Kevin DuBois305bef12019-10-09 13:23:27 -07001220 .Times(1)
1221 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001222 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001223 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001224
1225 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001226 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
Leon Scroggins III67388622023-02-06 20:36:20 -05001227 *mStubTracker.get(), now)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001228 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001229 auto const wakeup = entry.wakeupTime();
1230 ASSERT_TRUE(wakeup);
1231 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001232}
1233
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001234TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001235 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001236 auto vsyncCalledTime = 0;
1237 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001238 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001239 VSyncDispatchTimerQueueEntry entry(
1240 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001241 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001242 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001243 vsyncCalledTime = vsyncTime;
1244 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001245 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001246 },
1247 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001248
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001249 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001250 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001251 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001252 auto const wakeup = entry.wakeupTime();
1253 ASSERT_TRUE(wakeup);
1254 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001255
Ady Abraham9c53ee72020-07-22 21:16:18 -07001256 auto const ready = entry.readyTime();
1257 ASSERT_TRUE(ready);
1258 EXPECT_THAT(*ready, Eq(1000));
1259
1260 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001261
1262 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001263 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1264 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001265 EXPECT_FALSE(entry.wakeupTime());
1266 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1267 ASSERT_TRUE(lastCalledTarget);
1268 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1269}
1270
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001271TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Leon Scroggins III67388622023-02-06 20:36:20 -05001272 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -07001273 .Times(2)
1274 .WillOnce(Return(1000))
1275 .WillOnce(Return(1020));
1276
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001277 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001278 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001279
1280 EXPECT_FALSE(entry.wakeupTime());
Leon Scroggins III67388622023-02-06 20:36:20 -05001281 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001282 EXPECT_FALSE(entry.wakeupTime());
1283
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001284 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001285 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001286 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001287 auto wakeup = entry.wakeupTime();
1288 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001289 EXPECT_THAT(wakeup, Eq(900));
1290
Leon Scroggins III67388622023-02-06 20:36:20 -05001291 entry.update(*mStubTracker.get(), 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001292 wakeup = entry.wakeupTime();
1293 ASSERT_TRUE(wakeup);
1294 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001295}
1296
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001297TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001298 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001299 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001300 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001301 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001302 .has_value());
Leon Scroggins III67388622023-02-06 20:36:20 -05001303 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001304
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001305 auto const wakeup = entry.wakeupTime();
1306 ASSERT_TRUE(wakeup);
1307 EXPECT_THAT(*wakeup, Eq(wakeup));
1308}
1309
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001310TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1311 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001312 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001313 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001314 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001315 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001316 entry.executing(); // 1000 is executing
1317 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001318 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001319 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001320 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001321 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001322 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001323
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001324 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001325 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001326 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001327 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001328 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001329
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001330 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
Leon Scroggins III67388622023-02-06 20:36:20 -05001331 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001332 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001333 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001334 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001335}
1336
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001337TEST_F(VSyncDispatchTimerQueueEntryTest,
1338 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1339 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001340 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001341
1342 Sequence seq;
Leon Scroggins III67388622023-02-06 20:36:20 -05001343 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001344 .InSequence(seq)
1345 .WillOnce(Return(1000));
Leon Scroggins III67388622023-02-06 20:36:20 -05001346 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001347 .InSequence(seq)
1348 .WillOnce(Return(1000));
Leon Scroggins III67388622023-02-06 20:36:20 -05001349 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001350 .InSequence(seq)
1351 .WillOnce(Return(2000));
1352
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001353 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001354 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001355 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001356
1357 entry.executing(); // 1000 is executing
1358
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001359 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001360 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001361 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001362}
1363
1364TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1365 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001366 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001367 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001368 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001369 .has_value());
1370 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001371 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001372 .has_value());
1373 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001374 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001375 .has_value());
1376 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001377 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001378 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001379}
1380
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001381TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1382 static constexpr auto effectualOffset = 200;
1383 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001384 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001385 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001386 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1387 entry.addPendingWorkloadUpdate(
1388 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001389 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
Leon Scroggins III67388622023-02-06 20:36:20 -05001390 entry.update(*mStubTracker.get(), 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001391 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1392 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1393}
1394
Ady Abraham9c53ee72020-07-22 21:16:18 -07001395TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1396 auto callCount = 0;
1397 auto vsyncCalledTime = 0;
1398 auto wakeupCalledTime = 0;
1399 auto readyCalledTime = 0;
1400 VSyncDispatchTimerQueueEntry entry(
1401 "test",
1402 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1403 callCount++;
1404 vsyncCalledTime = vsyncTime;
1405 wakeupCalledTime = wakeupTime;
1406 readyCalledTime = readyTime;
1407 },
1408 mVsyncMoveThreshold);
1409
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001410 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001411 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001412 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001413 auto const wakeup = entry.wakeupTime();
1414 ASSERT_TRUE(wakeup);
1415 EXPECT_THAT(*wakeup, Eq(900));
1416
1417 auto const ready = entry.readyTime();
1418 ASSERT_TRUE(ready);
1419 EXPECT_THAT(*ready, Eq(970));
1420
1421 entry.callback(entry.executing(), *wakeup, *ready);
1422
1423 EXPECT_THAT(callCount, Eq(1));
1424 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1425 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1426 EXPECT_FALSE(entry.wakeupTime());
1427 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1428 ASSERT_TRUE(lastCalledTarget);
1429 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1430}
1431
Kevin DuBois305bef12019-10-09 13:23:27 -07001432} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001433
1434// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001435#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"