blob: 7161fa16d9fa4deaa567069b26e6955148f9bb63 [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
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700786 Sequence seq;
787 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
788 EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700789 CountingCallback cb(mDispatch);
790 auto result =
791 mDispatch->schedule(cb,
792 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
793 EXPECT_TRUE(result.has_value());
794 EXPECT_EQ(500, *result);
795 mMockClock.advanceBy(400);
796
797 result = mDispatch->schedule(cb,
798 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
799 EXPECT_TRUE(result.has_value());
800 EXPECT_EQ(400, *result);
801
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800802 advanceToNextCallback();
803 ASSERT_THAT(cb.mCalls.size(), Eq(1));
804}
805
806TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500807 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800808 .Times(2)
809 .WillOnce(Return(1000))
810 .WillOnce(Return(1002));
811 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700812 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500813 mDispatch->schedule(cb,
814 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700815 EXPECT_TRUE(result.has_value());
816 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800817 mMockClock.advanceBy(400);
Leon Scroggins III67388622023-02-06 20:36:20 -0500818 result = mDispatch->schedule(cb,
819 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700820 EXPECT_TRUE(result.has_value());
821 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700822}
823
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800824TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
825 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700826 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500827 mDispatch->schedule(cb0,
828 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700829 EXPECT_TRUE(result.has_value());
830 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800831 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500832 result = mDispatch->schedule(cb0,
833 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700834 EXPECT_TRUE(result.has_value());
835 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800836}
837
838TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
839 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700840 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
841 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800842 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700843 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500844 mDispatch->schedule(cb0,
845 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700846 EXPECT_TRUE(result.has_value());
847 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800848 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500849 result = mDispatch->schedule(cb0,
850 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700851 EXPECT_TRUE(result.has_value());
852 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800853}
854
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800855TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abraham3e019972023-10-20 13:23:48 -0700856 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
857
Ady Abrahamb491c902020-08-15 15:47:56 -0700858 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800859
860 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700861 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500862 mDispatch->schedule(cb,
863 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700864 EXPECT_TRUE(result.has_value());
865 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800866
Leon Scroggins III67388622023-02-06 20:36:20 -0500867 result = mDispatch->schedule(cb,
868 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700869 EXPECT_TRUE(result.has_value());
870 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800871
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800872 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800873}
874
Ady Abraham3e019972023-10-20 13:23:48 -0700875TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
876 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
877
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700878 Sequence seq;
879 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
880 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700881
882 CountingCallback cb(mDispatch);
883 auto result =
884 mDispatch->schedule(cb,
885 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
886 EXPECT_TRUE(result.has_value());
887 EXPECT_EQ(600, *result);
888
889 result = mDispatch->schedule(cb,
890 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
891 EXPECT_TRUE(result.has_value());
892 EXPECT_EQ(0, *result);
893
894 advanceToNextCallback();
895}
896
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800897TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700898 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700899 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
900
901 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700902 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700903 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700904 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700905 cb.cancel();
906
Ady Abraham9c53ee72020-07-22 21:16:18 -0700907 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700908 cb1.cancel();
909}
910
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800911TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700912 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700913 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
914
915 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700916 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700917 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700918 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700919 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700920 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700921 cb.cancel();
922
Ady Abraham9c53ee72020-07-22 21:16:18 -0700923 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700924 cb1.cancel();
925}
926
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700927// b/154303580
928TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
929 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700930 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
931 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700932 CountingCallback cb1(mDispatch);
933 CountingCallback cb2(mDispatch);
934
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700935 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500936 mDispatch->schedule(cb1,
937 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700938 EXPECT_TRUE(result.has_value());
939 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700940
941 mMockClock.setLag(100);
942 mMockClock.advanceBy(620);
943
Leon Scroggins III67388622023-02-06 20:36:20 -0500944 result = mDispatch->schedule(cb2,
945 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700946 EXPECT_TRUE(result.has_value());
947 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700948 mMockClock.advanceBy(80);
949
950 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
951 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
952}
953
954// b/154303580.
955// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
956// update later, as opposed to blocking the calling thread.
957TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
958 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700959 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
960 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700961 CountingCallback cb(mDispatch);
962
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700963 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500964 mDispatch->schedule(cb,
965 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700966 EXPECT_TRUE(result.has_value());
967 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700968
969 mMockClock.setLag(100);
970 mMockClock.advanceBy(620);
971
Leon Scroggins III67388622023-02-06 20:36:20 -0500972 result = mDispatch->schedule(cb,
973 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700974 EXPECT_TRUE(result.has_value());
975 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700976 mMockClock.advanceBy(80);
977
978 EXPECT_THAT(cb.mCalls.size(), Eq(1));
979}
980
Kevin DuBoisb340b732020-06-16 09:07:35 -0700981// b/154303580.
982TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
983 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700984 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700985 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
986 CountingCallback cb1(mDispatch);
987 CountingCallback cb2(mDispatch);
988
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700989 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500990 mDispatch->schedule(cb1,
991 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700992 EXPECT_TRUE(result.has_value());
993 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500994 result = mDispatch->schedule(cb2,
995 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700996 EXPECT_TRUE(result.has_value());
997 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700998
999 mMockClock.setLag(100);
1000 mMockClock.advanceBy(620);
1001
Leon Scroggins III67388622023-02-06 20:36:20 -05001002 EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001003
1004 mMockClock.advanceBy(80);
1005
1006 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
1007 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1008}
1009
1010TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
1011 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -07001012 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1013 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001014 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1015 CountingCallback cb1(mDispatch);
1016 CountingCallback cb2(mDispatch);
1017
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001018 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001019 mDispatch->schedule(cb1,
1020 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001021 EXPECT_TRUE(result.has_value());
1022 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001023 result = mDispatch->schedule(cb2,
1024 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001025 EXPECT_TRUE(result.has_value());
1026 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001027
1028 mMockClock.setLag(100);
1029 mMockClock.advanceBy(620);
1030
Leon Scroggins III67388622023-02-06 20:36:20 -05001031 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001032
1033 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1034 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1035 mMockClock.advanceToNextCallback();
1036
1037 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1038 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1039}
1040
Kevin DuBoisf9477832020-07-16 10:21:36 -07001041TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1042 CountingCallback cb1(mDispatch);
1043 CountingCallback cb2(mDispatch);
1044
1045 Sequence 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));
Ady Abrahamb491c902020-08-15 15:47:56 -07001049 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Leon Scroggins III67388622023-02-06 20:36:20 -05001050 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001051 .InSequence(seq)
1052 .WillOnce(Return(1000));
1053
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001054 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001055 mDispatch->schedule(cb1,
1056 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001057 EXPECT_TRUE(result.has_value());
1058 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001059 result = mDispatch->schedule(cb2,
1060 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001061 EXPECT_TRUE(result.has_value());
1062 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001063
1064 mMockClock.setLag(100);
1065 mMockClock.advanceBy(700);
1066
1067 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1068 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001069 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1070 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001071 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1072 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001073 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1074 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1075}
1076
1077TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1078 auto intended = mPeriod - 230;
1079 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1080
1081 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -05001082 const auto result = mDispatch->schedule(cb,
1083 {.workDuration = 70,
1084 .readyDuration = 30,
1085 .earliestVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001086 EXPECT_TRUE(result.has_value());
1087 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -07001088 advanceToNextCallback();
1089
1090 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1091 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1092 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1093 EXPECT_THAT(cb.mWakeupTime[0], 900);
1094 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1095 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001096}
1097
Ady Abraham69b9e622021-07-19 12:24:31 -07001098TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abraham3e019972023-10-20 13:23:48 -07001099 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
1100
Ady Abraham69b9e622021-07-19 12:24:31 -07001101 Sequence seq;
1102 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1103
1104 CountingCallback cb(mDispatch);
1105
Leon Scroggins III67388622023-02-06 20:36:20 -05001106 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1107 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001108
1109 advanceToNextCallback();
1110
1111 advanceToNextCallback();
1112
1113 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1114 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1115 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1116 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1117 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1118 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1119}
1120
Ady Abraham3e019972023-10-20 13:23:48 -07001121TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
1122 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
1123
1124 Sequence seq;
1125 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001126 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -07001127
1128 CountingCallback cb(mDispatch);
1129
1130 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1131 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
1132
1133 advanceToNextCallback();
1134
1135 advanceToNextCallback();
1136
1137 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1138 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1139 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001140 EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
Ady Abraham3e019972023-10-20 13:23:48 -07001141 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1142 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1143}
1144
Ady Abraham529bd9f2023-10-05 14:55:30 -07001145TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001146 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001147
1148 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1149 CountingCallback cb(mDispatch);
1150 auto result =
1151 mDispatch->schedule(cb,
1152 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1153 EXPECT_TRUE(result.has_value());
1154 EXPECT_EQ(500, *result);
1155 mMockClock.advanceBy(300);
1156
1157 result = mDispatch->schedule(cb,
1158 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1159 EXPECT_TRUE(result.has_value());
1160 EXPECT_EQ(1200, *result);
1161
1162 advanceToNextCallback();
1163 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1164}
1165
Ady Abraham529bd9f2023-10-05 14:55:30 -07001166TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001167 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001168
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001169 Sequence seq;
1170 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1171 EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001172 CountingCallback cb(mDispatch);
1173 auto result =
1174 mDispatch->schedule(cb,
1175 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1176 EXPECT_TRUE(result.has_value());
1177 EXPECT_EQ(500, *result);
1178 mMockClock.advanceBy(300);
1179
1180 result = mDispatch->schedule(cb,
1181 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1182 EXPECT_TRUE(result.has_value());
Ady Abraham3e019972023-10-20 13:23:48 -07001183 EXPECT_EQ(300, *result);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001184
1185 advanceToNextCallback();
1186 ASSERT_THAT(cb.mCalls.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001187 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1188 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1189 EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1190 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1191 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
Ady Abraham529bd9f2023-10-05 14:55:30 -07001192}
1193
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001194class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001195protected:
1196 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001197 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001198 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1199 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001200};
1201
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001202TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001203 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001204 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001205 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001206 EXPECT_THAT(entry.name(), Eq(name));
1207 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1208 EXPECT_FALSE(entry.wakeupTime());
1209}
1210
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001211TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001212 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001213 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001214
1215 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001216 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001217 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001218 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001219 auto const wakeup = entry.wakeupTime();
1220 ASSERT_TRUE(wakeup);
1221 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001222
1223 entry.disarm();
1224 EXPECT_FALSE(entry.wakeupTime());
1225}
1226
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001227TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001228 auto const duration = 500;
1229 auto const now = 8750;
1230
Leon Scroggins III67388622023-02-06 20:36:20 -05001231 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + duration))
Kevin DuBois305bef12019-10-09 13:23:27 -07001232 .Times(1)
1233 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001234 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001235 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001236
1237 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001238 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
Leon Scroggins III67388622023-02-06 20:36:20 -05001239 *mStubTracker.get(), now)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001240 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001241 auto const wakeup = entry.wakeupTime();
1242 ASSERT_TRUE(wakeup);
1243 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001244}
1245
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001246TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001247 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001248 auto vsyncCalledTime = 0;
1249 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001250 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001251 VSyncDispatchTimerQueueEntry entry(
1252 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001253 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001254 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001255 vsyncCalledTime = vsyncTime;
1256 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001257 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001258 },
1259 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001260
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001261 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001262 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001263 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001264 auto const wakeup = entry.wakeupTime();
1265 ASSERT_TRUE(wakeup);
1266 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001267
Ady Abraham9c53ee72020-07-22 21:16:18 -07001268 auto const ready = entry.readyTime();
1269 ASSERT_TRUE(ready);
1270 EXPECT_THAT(*ready, Eq(1000));
1271
1272 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001273
1274 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001275 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1276 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001277 EXPECT_FALSE(entry.wakeupTime());
1278 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1279 ASSERT_TRUE(lastCalledTarget);
1280 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1281}
1282
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001283TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Leon Scroggins III67388622023-02-06 20:36:20 -05001284 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -07001285 .Times(2)
1286 .WillOnce(Return(1000))
1287 .WillOnce(Return(1020));
1288
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001289 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001290 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001291
1292 EXPECT_FALSE(entry.wakeupTime());
Leon Scroggins III67388622023-02-06 20:36:20 -05001293 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001294 EXPECT_FALSE(entry.wakeupTime());
1295
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001296 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001297 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001298 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001299 auto wakeup = entry.wakeupTime();
1300 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001301 EXPECT_THAT(wakeup, Eq(900));
1302
Leon Scroggins III67388622023-02-06 20:36:20 -05001303 entry.update(*mStubTracker.get(), 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001304 wakeup = entry.wakeupTime();
1305 ASSERT_TRUE(wakeup);
1306 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001307}
1308
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001309TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001310 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001311 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001312 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001313 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001314 .has_value());
Leon Scroggins III67388622023-02-06 20:36:20 -05001315 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001316
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001317 auto const wakeup = entry.wakeupTime();
1318 ASSERT_TRUE(wakeup);
1319 EXPECT_THAT(*wakeup, Eq(wakeup));
1320}
1321
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001322TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1323 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001324 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001325 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001326 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001327 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001328 entry.executing(); // 1000 is executing
1329 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001330 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
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 DuBoisc94ca832019-11-26 12:56:24 -08001335
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001336 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001337 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001338 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001339 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001340 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001341
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001342 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
Leon Scroggins III67388622023-02-06 20:36:20 -05001343 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001344 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001345 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001346 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001347}
1348
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001349TEST_F(VSyncDispatchTimerQueueEntryTest,
1350 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1351 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001352 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001353
1354 Sequence seq;
Leon Scroggins III67388622023-02-06 20:36:20 -05001355 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001356 .InSequence(seq)
1357 .WillOnce(Return(1000));
Leon Scroggins III67388622023-02-06 20:36:20 -05001358 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001359 .InSequence(seq)
1360 .WillOnce(Return(1000));
Leon Scroggins III67388622023-02-06 20:36:20 -05001361 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001362 .InSequence(seq)
1363 .WillOnce(Return(2000));
1364
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001365 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001366 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001367 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001368
1369 entry.executing(); // 1000 is executing
1370
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001371 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001372 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001373 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001374}
1375
1376TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1377 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001378 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001379 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001380 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001381 .has_value());
1382 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001383 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001384 .has_value());
1385 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001386 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001387 .has_value());
1388 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001389 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001390 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001391}
1392
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001393TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1394 static constexpr auto effectualOffset = 200;
1395 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001396 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001397 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001398 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1399 entry.addPendingWorkloadUpdate(
1400 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001401 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
Leon Scroggins III67388622023-02-06 20:36:20 -05001402 entry.update(*mStubTracker.get(), 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001403 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1404 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1405}
1406
Ady Abraham9c53ee72020-07-22 21:16:18 -07001407TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1408 auto callCount = 0;
1409 auto vsyncCalledTime = 0;
1410 auto wakeupCalledTime = 0;
1411 auto readyCalledTime = 0;
1412 VSyncDispatchTimerQueueEntry entry(
1413 "test",
1414 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1415 callCount++;
1416 vsyncCalledTime = vsyncTime;
1417 wakeupCalledTime = wakeupTime;
1418 readyCalledTime = readyTime;
1419 },
1420 mVsyncMoveThreshold);
1421
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001422 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001423 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001424 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001425 auto const wakeup = entry.wakeupTime();
1426 ASSERT_TRUE(wakeup);
1427 EXPECT_THAT(*wakeup, Eq(900));
1428
1429 auto const ready = entry.readyTime();
1430 ASSERT_TRUE(ready);
1431 EXPECT_THAT(*ready, Eq(970));
1432
1433 entry.callback(entry.executing(), *wakeup, *ready);
1434
1435 EXPECT_THAT(callCount, Eq(1));
1436 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1437 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1438 EXPECT_FALSE(entry.wakeupTime());
1439 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1440 ASSERT_TRUE(lastCalledTarget);
1441 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1442}
1443
Kevin DuBois305bef12019-10-09 13:23:27 -07001444} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001445
1446// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001447#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"