blob: b97ebba48ee626611daf212787f785e11f0527ae [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"
Ady Abrahamc585dba2023-11-15 18:41:35 -080036#include "mock/MockVSyncTracker.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070037
Ady Abraham529bd9f2023-10-05 14:55:30 -070038#include <com_android_graphics_surfaceflinger_flags.h>
39
Kevin DuBois305bef12019-10-09 13:23:27 -070040using namespace testing;
41using namespace std::literals;
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080042
Kevin DuBois305bef12019-10-09 13:23:27 -070043namespace android::scheduler {
Ady Abraham529bd9f2023-10-05 14:55:30 -070044using namespace com::android::graphics::surfaceflinger;
Kevin DuBois305bef12019-10-09 13:23:27 -070045
Ady Abrahamc585dba2023-11-15 18:41:35 -080046class MockVSyncTracker : public mock::VSyncTracker {
Kevin DuBois305bef12019-10-09 13:23:27 -070047public:
48 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
49 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
50 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080051 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070052 ON_CALL(*this, currentPeriod())
53 .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -070054 }
55
Kevin DuBois305bef12019-10-09 13:23:27 -070056 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
57 if (timePoint % mPeriod == 0) {
58 return timePoint;
59 }
60 return (timePoint - (timePoint % mPeriod) + mPeriod);
61 }
62
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070063 nsecs_t getCurrentPeriod() const { return mPeriod; }
64
Kevin DuBois305bef12019-10-09 13:23:27 -070065protected:
66 nsecs_t const mPeriod;
67};
68
69class ControllableClock : public TimeKeeper {
70public:
71 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070072 ON_CALL(*this, alarmAt(_, _))
73 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070074 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
75 }
76
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080077 MOCK_METHOD(nsecs_t, now, (), (const));
78 MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
79 MOCK_METHOD(void, alarmCancel, (), (override));
80 MOCK_METHOD(void, dump, (std::string&), (const, override));
Kevin DuBois305bef12019-10-09 13:23:27 -070081
Ady Abrahamb491c902020-08-15 15:47:56 -070082 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070083 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070084 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070085 }
86
87 nsecs_t fakeTime() const { return mCurrentTime; }
88
89 void advanceToNextCallback() {
90 mCurrentTime = mNextCallbackTime;
91 if (mCallback) {
92 mCallback();
93 }
94 }
95
96 void advanceBy(nsecs_t advancement) {
97 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -070098 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -070099 mCallback();
100 }
101 };
102
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700103 void setLag(nsecs_t lag) { mLag = lag; }
104
Kevin DuBois305bef12019-10-09 13:23:27 -0700105private:
106 std::function<void()> mCallback;
107 nsecs_t mNextCallbackTime = 0;
108 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700109 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700110};
111
112class CountingCallback {
113public:
Leon Scroggins III67388622023-02-06 20:36:20 -0500114 CountingCallback(std::shared_ptr<VSyncDispatch> dispatch)
115 : mDispatch(std::move(dispatch)),
116 mToken(mDispatch->registerCallback(std::bind(&CountingCallback::counter, this,
117 std::placeholders::_1,
118 std::placeholders::_2,
119 std::placeholders::_3),
120 "test")) {}
121 ~CountingCallback() { mDispatch->unregisterCallback(mToken); }
Kevin DuBois305bef12019-10-09 13:23:27 -0700122
123 operator VSyncDispatch::CallbackToken() const { return mToken; }
124
Ady Abraham9c53ee72020-07-22 21:16:18 -0700125 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700126 mCalls.push_back(time);
127 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700128 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700129 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700130
Leon Scroggins III67388622023-02-06 20:36:20 -0500131 std::shared_ptr<VSyncDispatch> mDispatch;
Kevin DuBois305bef12019-10-09 13:23:27 -0700132 VSyncDispatch::CallbackToken mToken;
133 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700134 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700135 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700136};
137
138class PausingCallback {
139public:
Leon Scroggins III67388622023-02-06 20:36:20 -0500140 PausingCallback(std::shared_ptr<VSyncDispatch> dispatch, std::chrono::milliseconds pauseAmount)
141 : mDispatch(std::move(dispatch)),
142 mToken(mDispatch->registerCallback(std::bind(&PausingCallback::pause, this,
143 std::placeholders::_1,
144 std::placeholders::_2),
145 "test")),
Kevin DuBois305bef12019-10-09 13:23:27 -0700146 mRegistered(true),
147 mPauseAmount(pauseAmount) {}
148 ~PausingCallback() { unregister(); }
149
150 operator VSyncDispatch::CallbackToken() const { return mToken; }
151
Kevin DuBois2968afc2020-01-14 09:48:50 -0800152 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700153 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700154 mPause = true;
155 mCv.notify_all();
156
Ady Abraham8cb21882020-08-26 18:22:05 -0700157 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700158
159 mResourcePresent = (mResource.lock() != nullptr);
160 }
161
162 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700163 std::unique_lock lock(mMutex);
164 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700165 return waiting;
166 }
167
168 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
169
170 bool resourcePresent() { return mResourcePresent; }
171
172 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700173 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700174 mPause = false;
175 mCv.notify_all();
176 }
177
178 void unregister() {
179 if (mRegistered) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500180 mDispatch->unregisterCallback(mToken);
Kevin DuBois305bef12019-10-09 13:23:27 -0700181 mRegistered = false;
182 }
183 }
184
Leon Scroggins III67388622023-02-06 20:36:20 -0500185 std::shared_ptr<VSyncDispatch> mDispatch;
Kevin DuBois305bef12019-10-09 13:23:27 -0700186 VSyncDispatch::CallbackToken mToken;
187 bool mRegistered = true;
188
189 std::mutex mMutex;
190 std::condition_variable mCv;
191 bool mPause = false;
192 std::weak_ptr<void> mResource;
193 bool mResourcePresent = false;
194 std::chrono::milliseconds const mPauseAmount;
195};
196
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800197class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700198protected:
199 std::unique_ptr<TimeKeeper> createTimeKeeper() {
200 class TimeKeeperWrapper : public TimeKeeper {
201 public:
202 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800203
Kevin DuBois305bef12019-10-09 13:23:27 -0700204 nsecs_t now() const final { return mControllableClock.now(); }
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800205
206 void alarmAt(std::function<void()> callback, nsecs_t time) final {
207 mControllableClock.alarmAt(std::move(callback), time);
208 }
209
210 void alarmCancel() final { mControllableClock.alarmCancel(); }
Ady Abraham75398722020-04-07 14:08:45 -0700211 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700212
213 private:
214 TimeKeeper& mControllableClock;
215 };
216 return std::make_unique<TimeKeeperWrapper>(mMockClock);
217 }
218
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800219 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700220 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
221 Mock::VerifyAndClearExpectations(&mMockClock);
222 }
223
224 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
225
226 NiceMock<ControllableClock> mMockClock;
227 static nsecs_t constexpr mDispatchGroupThreshold = 5;
228 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800229 nsecs_t const mVsyncMoveThreshold = 300;
Leon Scroggins III67388622023-02-06 20:36:20 -0500230 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
231 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
232 std::shared_ptr<VSyncDispatch> mDispatch =
233 std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
234 mDispatchGroupThreshold, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700235};
236
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800237TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700238 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700239 EXPECT_CALL(mMockClock, alarmCancel());
240 {
Leon Scroggins III67388622023-02-06 20:36:20 -0500241 std::shared_ptr<VSyncDispatch> mDispatch =
242 std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
243 mDispatchGroupThreshold,
244 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -0700245 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500246 const auto result = mDispatch->schedule(cb,
247 {.workDuration = 100,
248 .readyDuration = 0,
249 .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700250 EXPECT_TRUE(result.has_value());
251 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700252 }
253}
254
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800255TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700256 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700257 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700258
259 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500260 const auto result = mDispatch->schedule(cb,
261 {.workDuration = 100,
262 .readyDuration = 0,
263 .earliestVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700264 EXPECT_TRUE(result.has_value());
265 EXPECT_EQ(900, *result);
266
Kevin DuBois305bef12019-10-09 13:23:27 -0700267 advanceToNextCallback();
268
269 ASSERT_THAT(cb.mCalls.size(), Eq(1));
270 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
271}
272
Ady Abraham011f8ba2022-11-22 15:09:07 -0800273TEST_F(VSyncDispatchTimerQueueTest, updateAlarmSettingFuture) {
274 auto intended = mPeriod - 230;
275 Sequence seq;
276 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
277 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
278
279 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500280 auto result = mDispatch->schedule(cb,
281 {.workDuration = 100,
282 .readyDuration = 0,
283 .earliestVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800284 EXPECT_TRUE(result.has_value());
285 EXPECT_EQ(900, *result);
286
Leon Scroggins III67388622023-02-06 20:36:20 -0500287 result =
288 mDispatch->update(cb,
Ady Abraham011f8ba2022-11-22 15:09:07 -0800289 {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
290 EXPECT_TRUE(result.has_value());
291 EXPECT_EQ(700, *result);
292
293 advanceToNextCallback();
294
295 ASSERT_THAT(cb.mCalls.size(), Eq(1));
296 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
297 EXPECT_THAT(cb.mWakeupTime[0], Eq(700));
298}
299
300TEST_F(VSyncDispatchTimerQueueTest, updateDoesntSchedule) {
301 auto intended = mPeriod - 230;
302 EXPECT_CALL(mMockClock, alarmAt(_, _)).Times(0);
303
304 CountingCallback cb(mDispatch);
305 const auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500306 mDispatch->update(cb,
307 {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800308 EXPECT_FALSE(result.has_value());
309}
310
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800311TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500312 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700313 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700314
315 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500316 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700317 advanceToNextCallback();
318
319 ASSERT_THAT(cb.mCalls.size(), Eq(1));
320 EXPECT_THAT(cb.mCalls[0], Eq(1150));
321}
322
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800323TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700324 auto const now = 234;
325 mMockClock.advanceBy(234);
326 auto const workDuration = 10 * mPeriod;
Leon Scroggins III67388622023-02-06 20:36:20 -0500327 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + workDuration))
Kevin DuBois305bef12019-10-09 13:23:27 -0700328 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700329 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700330
331 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500332 const auto result = mDispatch->schedule(cb,
333 {.workDuration = workDuration,
334 .readyDuration = 0,
335 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700336 EXPECT_TRUE(result.has_value());
337 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700338}
339
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800340TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700341 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700342 EXPECT_CALL(mMockClock, alarmCancel());
343
344 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500345 const auto result = mDispatch->schedule(cb,
346 {.workDuration = 100,
347 .readyDuration = 0,
348 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700349 EXPECT_TRUE(result.has_value());
350 EXPECT_EQ(mPeriod - 100, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500351 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700352}
353
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800354TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700355 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700356 EXPECT_CALL(mMockClock, alarmCancel());
357
358 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500359 const auto result = mDispatch->schedule(cb,
360 {.workDuration = 100,
361 .readyDuration = 0,
362 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700363 EXPECT_TRUE(result.has_value());
364 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700365 mMockClock.advanceBy(950);
Leon Scroggins III67388622023-02-06 20:36:20 -0500366 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700367}
368
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800369TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700370 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700371 EXPECT_CALL(mMockClock, alarmCancel());
372
373 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Leon Scroggins III67388622023-02-06 20:36:20 -0500374 const auto result = mDispatch->schedule(cb,
375 {.workDuration = 100,
376 .readyDuration = 0,
377 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700378 EXPECT_TRUE(result.has_value());
379 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700380
381 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
382 EXPECT_TRUE(cb.waitForPause());
Leon Scroggins III67388622023-02-06 20:36:20 -0500383 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700384 cb.unpause();
385 pausingThread.join();
386}
387
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800388TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700389 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700390 EXPECT_CALL(mMockClock, alarmCancel());
391
392 auto resource = std::make_shared<int>(110);
393
394 PausingCallback cb(mDispatch, 50ms);
395 cb.stashResource(resource);
Leon Scroggins III67388622023-02-06 20:36:20 -0500396 const auto result = mDispatch->schedule(cb,
397 {.workDuration = 100,
398 .readyDuration = 0,
399 .earliestVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700400 EXPECT_TRUE(result.has_value());
401 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700402
403 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
404 EXPECT_TRUE(cb.waitForPause());
405
406 cb.unregister();
407 resource.reset();
408
409 cb.unpause();
410 pausingThread.join();
411
412 EXPECT_TRUE(cb.resourcePresent());
413}
414
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800415TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500416 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBois305bef12019-10-09 13:23:27 -0700417 .Times(4)
418 .WillOnce(Return(1055))
419 .WillOnce(Return(1063))
420 .WillOnce(Return(1063))
421 .WillOnce(Return(1075));
422
423 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700424 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
425 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
426 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700427
428 CountingCallback cb0(mDispatch);
429 CountingCallback cb1(mDispatch);
430
Leon Scroggins III67388622023-02-06 20:36:20 -0500431 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
432 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700433
434 advanceToNextCallback();
435 advanceToNextCallback();
436
437 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
438 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
439 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
440 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
441}
442
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700443TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500444 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700445 .Times(4)
446 .WillOnce(Return(1000))
447 .WillOnce(Return(2000))
448 .WillOnce(Return(2500))
449 .WillOnce(Return(4000));
450
451 Sequence seq;
452 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
453 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
454 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
455
456 CountingCallback cb(mDispatch);
457
Leon Scroggins III67388622023-02-06 20:36:20 -0500458 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700459
460 advanceToNextCallback();
461
462 ASSERT_THAT(cb.mCalls.size(), Eq(1));
463 EXPECT_THAT(cb.mCalls[0], Eq(1000));
464
Leon Scroggins III67388622023-02-06 20:36:20 -0500465 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700466
467 advanceToNextCallback();
468
469 ASSERT_THAT(cb.mCalls.size(), Eq(2));
470 EXPECT_THAT(cb.mCalls[1], Eq(2000));
471
Leon Scroggins III67388622023-02-06 20:36:20 -0500472 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700473
474 advanceToNextCallback();
475
476 ASSERT_THAT(cb.mCalls.size(), Eq(3));
477 EXPECT_THAT(cb.mCalls[2], Eq(4000));
478}
479
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800480TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500481 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -0700482 .Times(4)
483 .WillOnce(Return(10000))
484 .WillOnce(Return(1000))
485 .WillOnce(Return(10000))
486 .WillOnce(Return(10000));
487
488 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700489 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
490 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
491 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700492
493 CountingCallback cb0(mDispatch);
494 CountingCallback cb1(mDispatch);
495
Leon Scroggins III67388622023-02-06 20:36:20 -0500496 mDispatch->schedule(cb0,
497 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
498 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
499 mDispatch->cancel(cb1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700500}
501
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800502TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700503 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700504 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
505 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700506
507 CountingCallback cb0(mDispatch);
508 CountingCallback cb1(mDispatch);
509
Leon Scroggins III67388622023-02-06 20:36:20 -0500510 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
511 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
512 mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700513 advanceToNextCallback();
514}
515
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800516TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700517 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700518 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
519 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
520 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700521
522 CountingCallback cb0(mDispatch);
523 CountingCallback cb1(mDispatch);
524
Leon Scroggins III67388622023-02-06 20:36:20 -0500525 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
526 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
527 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700528 advanceToNextCallback();
529}
530
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800531TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700532 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700533 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
534 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
535 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
536 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700537
538 auto offset = 400;
539 auto closeOffset = offset + mDispatchGroupThreshold - 1;
540 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
541
542 CountingCallback cb0(mDispatch);
543 CountingCallback cb1(mDispatch);
544
Leon Scroggins III67388622023-02-06 20:36:20 -0500545 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
546 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
547 mDispatch->schedule(cb1,
548 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700549
550 advanceToNextCallback();
551 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
552 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
553 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
554 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
555
Leon Scroggins III67388622023-02-06 20:36:20 -0500556 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
557 mDispatch->schedule(cb1,
558 {.workDuration = notCloseOffset,
559 .readyDuration = 0,
560 .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700561 advanceToNextCallback();
562 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
563 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
564
565 advanceToNextCallback();
566 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
567 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
568}
569
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800570TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700571 Sequence seq;
572 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
573 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
574 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700575 EXPECT_CALL(mMockClock, alarmCancel());
576
577 CountingCallback cb0(mDispatch);
578 CountingCallback cb1(mDispatch);
579
Leon Scroggins III67388622023-02-06 20:36:20 -0500580 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
581 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700582 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500583 EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700584}
585
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800586TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500587 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -0700588 .Times(3)
589 .WillOnce(Return(950))
590 .WillOnce(Return(1975))
591 .WillOnce(Return(2950));
592
593 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500594 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700595
596 mMockClock.advanceBy(850);
597 EXPECT_THAT(cb.mCalls.size(), Eq(1));
598
Leon Scroggins III67388622023-02-06 20:36:20 -0500599 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700600 mMockClock.advanceBy(900);
601 EXPECT_THAT(cb.mCalls.size(), Eq(1));
602 mMockClock.advanceBy(125);
603 EXPECT_THAT(cb.mCalls.size(), Eq(2));
604
Leon Scroggins III67388622023-02-06 20:36:20 -0500605 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700606 mMockClock.advanceBy(975);
607 EXPECT_THAT(cb.mCalls.size(), Eq(3));
608}
609
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800610TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700611 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700612 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
613 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700614
615 VSyncDispatch::CallbackToken tmp;
Leon Scroggins III67388622023-02-06 20:36:20 -0500616 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700617 [&](auto, auto, auto) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500618 mDispatch->schedule(tmp,
619 {.workDuration = 100,
620 .readyDuration = 0,
621 .earliestVsync = 2000});
Ady Abraham9c53ee72020-07-22 21:16:18 -0700622 },
623 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700624
Leon Scroggins III67388622023-02-06 20:36:20 -0500625 mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700626 advanceToNextCallback();
627}
628
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800629TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700630 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800631 std::optional<nsecs_t> lastTarget;
Leon Scroggins III67388622023-02-06 20:36:20 -0500632 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700633 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700634 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500635 mDispatch->schedule(tmp,
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700636 {.workDuration = 400,
637 .readyDuration = 0,
Leon Scroggins III67388622023-02-06 20:36:20 -0500638 .earliestVsync = timestamp - mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700639 EXPECT_TRUE(result.has_value());
640 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500641 result = mDispatch->schedule(tmp,
642 {.workDuration = 400,
643 .readyDuration = 0,
644 .earliestVsync = timestamp});
645 EXPECT_TRUE(result.has_value());
646 EXPECT_EQ(mPeriod + timestamp - 400, *result);
647 result = mDispatch->schedule(tmp,
648 {.workDuration = 400,
649 .readyDuration = 0,
650 .earliestVsync = timestamp + mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700651 EXPECT_TRUE(result.has_value());
652 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800653 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700654 },
655 "oo");
656
Leon Scroggins III67388622023-02-06 20:36:20 -0500657 mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700658 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800659 EXPECT_THAT(lastTarget, Eq(1000));
660
661 advanceToNextCallback();
662 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700663}
664
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800665TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700666 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700667 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
668 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
669 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
670 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700671
672 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500673 mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700674
675 mMockClock.advanceBy(750);
Leon Scroggins III67388622023-02-06 20:36:20 -0500676 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700677
678 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500679 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700680
681 mMockClock.advanceBy(800);
Leon Scroggins III67388622023-02-06 20:36:20 -0500682 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700683}
684
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800685TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700686 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700687 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
688 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
689 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
690 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700691
692 CountingCallback cb0(mDispatch);
693 CountingCallback cb1(mDispatch);
694
Leon Scroggins III67388622023-02-06 20:36:20 -0500695 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
696 mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700697
698 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500699 mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
700 mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700701
702 advanceToNextCallback();
703 advanceToNextCallback();
704}
705
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800706TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700707 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700708 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700709
710 CountingCallback cb0(mDispatch);
711 CountingCallback cb1(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500712 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
713 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700714}
715
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800716TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700717 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700718 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700719 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700720 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700721
722 CountingCallback cb0(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500723 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
724 mDispatch->cancel(cb0);
725 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700726}
727
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800728TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700729 VSyncDispatch::CallbackToken token(100);
Leon Scroggins III67388622023-02-06 20:36:20 -0500730 EXPECT_FALSE(
731 mDispatch
732 ->schedule(token,
733 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
734 .has_value());
735 EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700736}
737
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800738TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700739 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700740 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500741 mDispatch->schedule(cb0,
742 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700743 EXPECT_TRUE(result.has_value());
744 EXPECT_EQ(500, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500745 result = mDispatch->schedule(cb0,
746 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700747 EXPECT_TRUE(result.has_value());
748 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800749}
750
751// b/1450138150
752TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abraham3e019972023-10-20 13:23:48 -0700753 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
754
Ady Abrahamb491c902020-08-15 15:47:56 -0700755 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800756 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700757 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500758 mDispatch->schedule(cb,
759 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700760 EXPECT_TRUE(result.has_value());
761 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800762 mMockClock.advanceBy(400);
763
Leon Scroggins III67388622023-02-06 20:36:20 -0500764 result = mDispatch->schedule(cb,
765 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700766 EXPECT_TRUE(result.has_value());
767 EXPECT_EQ(1200, *result);
Ady Abraham3e019972023-10-20 13:23:48 -0700768
769 advanceToNextCallback();
770 ASSERT_THAT(cb.mCalls.size(), Eq(1));
771}
772
773// b/1450138150
774TEST_F(VSyncDispatchTimerQueueTest, movesCallbackBackwardsAndSkipAScheduledTargetVSync) {
775 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
776
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700777 Sequence seq;
778 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
779 EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700780 CountingCallback cb(mDispatch);
781 auto result =
782 mDispatch->schedule(cb,
783 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
784 EXPECT_TRUE(result.has_value());
785 EXPECT_EQ(500, *result);
786 mMockClock.advanceBy(400);
787
788 result = mDispatch->schedule(cb,
789 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
790 EXPECT_TRUE(result.has_value());
791 EXPECT_EQ(400, *result);
792
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800793 advanceToNextCallback();
794 ASSERT_THAT(cb.mCalls.size(), Eq(1));
795}
796
797TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500798 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800799 .Times(2)
800 .WillOnce(Return(1000))
801 .WillOnce(Return(1002));
802 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700803 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500804 mDispatch->schedule(cb,
805 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700806 EXPECT_TRUE(result.has_value());
807 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800808 mMockClock.advanceBy(400);
Leon Scroggins III67388622023-02-06 20:36:20 -0500809 result = mDispatch->schedule(cb,
810 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700811 EXPECT_TRUE(result.has_value());
812 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700813}
814
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800815TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
816 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700817 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500818 mDispatch->schedule(cb0,
819 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700820 EXPECT_TRUE(result.has_value());
821 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800822 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500823 result = mDispatch->schedule(cb0,
824 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700825 EXPECT_TRUE(result.has_value());
826 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800827}
828
829TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
830 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700831 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
832 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800833 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700834 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500835 mDispatch->schedule(cb0,
836 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700837 EXPECT_TRUE(result.has_value());
838 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800839 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500840 result = mDispatch->schedule(cb0,
841 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700842 EXPECT_TRUE(result.has_value());
843 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800844}
845
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800846TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abraham3e019972023-10-20 13:23:48 -0700847 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
848
Ady Abrahamb491c902020-08-15 15:47:56 -0700849 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800850
851 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700852 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500853 mDispatch->schedule(cb,
854 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700855 EXPECT_TRUE(result.has_value());
856 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800857
Leon Scroggins III67388622023-02-06 20:36:20 -0500858 result = mDispatch->schedule(cb,
859 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700860 EXPECT_TRUE(result.has_value());
861 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800862
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800863 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800864}
865
Ady Abraham3e019972023-10-20 13:23:48 -0700866TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
867 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
868
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700869 Sequence seq;
870 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
871 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700872
873 CountingCallback cb(mDispatch);
874 auto result =
875 mDispatch->schedule(cb,
876 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
877 EXPECT_TRUE(result.has_value());
878 EXPECT_EQ(600, *result);
879
880 result = mDispatch->schedule(cb,
881 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
882 EXPECT_TRUE(result.has_value());
883 EXPECT_EQ(0, *result);
884
885 advanceToNextCallback();
886}
887
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800888TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700889 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700890 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
891
892 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700893 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700894 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700895 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700896 cb.cancel();
897
Ady Abraham9c53ee72020-07-22 21:16:18 -0700898 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700899 cb1.cancel();
900}
901
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800902TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700903 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700904 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
905
906 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700907 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700908 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700909 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700910 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700911 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700912 cb.cancel();
913
Ady Abraham9c53ee72020-07-22 21:16:18 -0700914 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700915 cb1.cancel();
916}
917
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700918// b/154303580
919TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
920 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700921 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
922 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700923 CountingCallback cb1(mDispatch);
924 CountingCallback cb2(mDispatch);
925
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700926 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500927 mDispatch->schedule(cb1,
928 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700929 EXPECT_TRUE(result.has_value());
930 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700931
932 mMockClock.setLag(100);
933 mMockClock.advanceBy(620);
934
Leon Scroggins III67388622023-02-06 20:36:20 -0500935 result = mDispatch->schedule(cb2,
936 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700937 EXPECT_TRUE(result.has_value());
938 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700939 mMockClock.advanceBy(80);
940
941 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
942 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
943}
944
945// b/154303580.
946// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
947// update later, as opposed to blocking the calling thread.
948TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
949 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700950 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
951 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700952 CountingCallback cb(mDispatch);
953
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700954 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500955 mDispatch->schedule(cb,
956 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700957 EXPECT_TRUE(result.has_value());
958 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700959
960 mMockClock.setLag(100);
961 mMockClock.advanceBy(620);
962
Leon Scroggins III67388622023-02-06 20:36:20 -0500963 result = mDispatch->schedule(cb,
964 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700965 EXPECT_TRUE(result.has_value());
966 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700967 mMockClock.advanceBy(80);
968
969 EXPECT_THAT(cb.mCalls.size(), Eq(1));
970}
971
Kevin DuBoisb340b732020-06-16 09:07:35 -0700972// b/154303580.
973TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
974 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700975 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700976 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
977 CountingCallback cb1(mDispatch);
978 CountingCallback cb2(mDispatch);
979
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700980 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -0500981 mDispatch->schedule(cb1,
982 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700983 EXPECT_TRUE(result.has_value());
984 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500985 result = mDispatch->schedule(cb2,
986 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700987 EXPECT_TRUE(result.has_value());
988 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700989
990 mMockClock.setLag(100);
991 mMockClock.advanceBy(620);
992
Leon Scroggins III67388622023-02-06 20:36:20 -0500993 EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700994
995 mMockClock.advanceBy(80);
996
997 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
998 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
999}
1000
1001TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
1002 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -07001003 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1004 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001005 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1006 CountingCallback cb1(mDispatch);
1007 CountingCallback cb2(mDispatch);
1008
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001009 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001010 mDispatch->schedule(cb1,
1011 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001012 EXPECT_TRUE(result.has_value());
1013 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001014 result = mDispatch->schedule(cb2,
1015 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001016 EXPECT_TRUE(result.has_value());
1017 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001018
1019 mMockClock.setLag(100);
1020 mMockClock.advanceBy(620);
1021
Leon Scroggins III67388622023-02-06 20:36:20 -05001022 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001023
1024 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1025 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1026 mMockClock.advanceToNextCallback();
1027
1028 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1029 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1030}
1031
Kevin DuBoisf9477832020-07-16 10:21:36 -07001032TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1033 CountingCallback cb1(mDispatch);
1034 CountingCallback cb2(mDispatch);
1035
1036 Sequence seq;
Leon Scroggins III67388622023-02-06 20:36:20 -05001037 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001038 .InSequence(seq)
1039 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -07001040 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Leon Scroggins III67388622023-02-06 20:36:20 -05001041 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001042 .InSequence(seq)
1043 .WillOnce(Return(1000));
1044
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001045 auto result =
Leon Scroggins III67388622023-02-06 20:36:20 -05001046 mDispatch->schedule(cb1,
1047 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001048 EXPECT_TRUE(result.has_value());
1049 EXPECT_EQ(600, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -05001050 result = mDispatch->schedule(cb2,
1051 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001052 EXPECT_TRUE(result.has_value());
1053 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001054
1055 mMockClock.setLag(100);
1056 mMockClock.advanceBy(700);
1057
1058 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1059 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001060 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1061 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001062 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1063 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001064 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1065 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1066}
1067
1068TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1069 auto intended = mPeriod - 230;
1070 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1071
1072 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -05001073 const auto result = mDispatch->schedule(cb,
1074 {.workDuration = 70,
1075 .readyDuration = 30,
1076 .earliestVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001077 EXPECT_TRUE(result.has_value());
1078 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -07001079 advanceToNextCallback();
1080
1081 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1082 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1083 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1084 EXPECT_THAT(cb.mWakeupTime[0], 900);
1085 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1086 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001087}
1088
Ady Abraham69b9e622021-07-19 12:24:31 -07001089TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abraham3e019972023-10-20 13:23:48 -07001090 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
1091
Ady Abraham69b9e622021-07-19 12:24:31 -07001092 Sequence seq;
1093 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1094
1095 CountingCallback cb(mDispatch);
1096
Leon Scroggins III67388622023-02-06 20:36:20 -05001097 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1098 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001099
1100 advanceToNextCallback();
1101
1102 advanceToNextCallback();
1103
1104 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1105 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1106 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1107 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1108 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1109 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1110}
1111
Ady Abraham3e019972023-10-20 13:23:48 -07001112TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
1113 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
1114
1115 Sequence seq;
1116 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001117 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -07001118
1119 CountingCallback cb(mDispatch);
1120
1121 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
1122 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
1123
1124 advanceToNextCallback();
1125
1126 advanceToNextCallback();
1127
1128 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1129 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1130 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001131 EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
Ady Abraham3e019972023-10-20 13:23:48 -07001132 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1133 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1134}
1135
Ady Abraham529bd9f2023-10-05 14:55:30 -07001136TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001137 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001138
1139 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1140 CountingCallback cb(mDispatch);
1141 auto result =
1142 mDispatch->schedule(cb,
1143 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1144 EXPECT_TRUE(result.has_value());
1145 EXPECT_EQ(500, *result);
1146 mMockClock.advanceBy(300);
1147
1148 result = mDispatch->schedule(cb,
1149 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1150 EXPECT_TRUE(result.has_value());
1151 EXPECT_EQ(1200, *result);
1152
1153 advanceToNextCallback();
1154 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1155}
1156
Ady Abraham529bd9f2023-10-05 14:55:30 -07001157TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001158 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001159
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001160 Sequence seq;
1161 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1162 EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001163 CountingCallback cb(mDispatch);
1164 auto result =
1165 mDispatch->schedule(cb,
1166 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
1167 EXPECT_TRUE(result.has_value());
1168 EXPECT_EQ(500, *result);
1169 mMockClock.advanceBy(300);
1170
1171 result = mDispatch->schedule(cb,
1172 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
1173 EXPECT_TRUE(result.has_value());
Ady Abraham3e019972023-10-20 13:23:48 -07001174 EXPECT_EQ(300, *result);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001175
1176 advanceToNextCallback();
1177 ASSERT_THAT(cb.mCalls.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001178 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1179 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1180 EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1181 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1182 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
Ady Abraham529bd9f2023-10-05 14:55:30 -07001183}
1184
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001185class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001186protected:
1187 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001188 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001189 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1190 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001191};
1192
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001193TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001194 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001195 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001196 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001197 EXPECT_THAT(entry.name(), Eq(name));
1198 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1199 EXPECT_FALSE(entry.wakeupTime());
1200}
1201
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001202TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001203 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001204 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001205
1206 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001207 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001208 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001209 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001210 auto const wakeup = entry.wakeupTime();
1211 ASSERT_TRUE(wakeup);
1212 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001213
1214 entry.disarm();
1215 EXPECT_FALSE(entry.wakeupTime());
1216}
1217
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001218TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001219 auto const duration = 500;
1220 auto const now = 8750;
1221
Leon Scroggins III67388622023-02-06 20:36:20 -05001222 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + duration))
Kevin DuBois305bef12019-10-09 13:23:27 -07001223 .Times(1)
1224 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001225 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001226 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001227
1228 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001229 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
Leon Scroggins III67388622023-02-06 20:36:20 -05001230 *mStubTracker.get(), now)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001231 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001232 auto const wakeup = entry.wakeupTime();
1233 ASSERT_TRUE(wakeup);
1234 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001235}
1236
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001237TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001238 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001239 auto vsyncCalledTime = 0;
1240 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001241 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001242 VSyncDispatchTimerQueueEntry entry(
1243 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001244 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001245 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001246 vsyncCalledTime = vsyncTime;
1247 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001248 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001249 },
1250 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001251
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001252 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001253 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001254 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001255 auto const wakeup = entry.wakeupTime();
1256 ASSERT_TRUE(wakeup);
1257 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001258
Ady Abraham9c53ee72020-07-22 21:16:18 -07001259 auto const ready = entry.readyTime();
1260 ASSERT_TRUE(ready);
1261 EXPECT_THAT(*ready, Eq(1000));
1262
1263 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001264
1265 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001266 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1267 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001268 EXPECT_FALSE(entry.wakeupTime());
1269 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1270 ASSERT_TRUE(lastCalledTarget);
1271 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1272}
1273
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001274TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Leon Scroggins III67388622023-02-06 20:36:20 -05001275 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
Kevin DuBois305bef12019-10-09 13:23:27 -07001276 .Times(2)
1277 .WillOnce(Return(1000))
1278 .WillOnce(Return(1020));
1279
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001280 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001281 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001282
1283 EXPECT_FALSE(entry.wakeupTime());
Leon Scroggins III67388622023-02-06 20:36:20 -05001284 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001285 EXPECT_FALSE(entry.wakeupTime());
1286
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001287 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001288 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001289 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001290 auto wakeup = entry.wakeupTime();
1291 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001292 EXPECT_THAT(wakeup, Eq(900));
1293
Leon Scroggins III67388622023-02-06 20:36:20 -05001294 entry.update(*mStubTracker.get(), 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001295 wakeup = entry.wakeupTime();
1296 ASSERT_TRUE(wakeup);
1297 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001298}
1299
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001300TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001301 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001302 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001303 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001304 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001305 .has_value());
Leon Scroggins III67388622023-02-06 20:36:20 -05001306 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001307
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001308 auto const wakeup = entry.wakeupTime();
1309 ASSERT_TRUE(wakeup);
1310 EXPECT_THAT(*wakeup, Eq(wakeup));
1311}
1312
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001313TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1314 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001315 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001316 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001317 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001318 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001319 entry.executing(); // 1000 is executing
1320 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001321 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001322 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001323 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001324 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001325 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001326
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001327 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001328 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001329 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001330 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001331 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001332
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001333 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
Leon Scroggins III67388622023-02-06 20:36:20 -05001334 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001335 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001336 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001337 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001338}
1339
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001340TEST_F(VSyncDispatchTimerQueueEntryTest,
1341 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1342 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001343 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001344
1345 Sequence seq;
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(500))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001350 .InSequence(seq)
1351 .WillOnce(Return(1000));
Leon Scroggins III67388622023-02-06 20:36:20 -05001352 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001353 .InSequence(seq)
1354 .WillOnce(Return(2000));
1355
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001356 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001357 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001358 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001359
1360 entry.executing(); // 1000 is executing
1361
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001362 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001363 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001364 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001365}
1366
1367TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1368 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001369 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001370 EXPECT_TRUE(entry.schedule({.workDuration = 100, .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 = 200, .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 = 50, .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());
1379 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .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());
Kevin DuBois305bef12019-10-09 13:23:27 -07001382}
1383
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001384TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1385 static constexpr auto effectualOffset = 200;
1386 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001387 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001388 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001389 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1390 entry.addPendingWorkloadUpdate(
1391 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001392 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
Leon Scroggins III67388622023-02-06 20:36:20 -05001393 entry.update(*mStubTracker.get(), 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001394 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1395 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1396}
1397
Ady Abraham9c53ee72020-07-22 21:16:18 -07001398TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1399 auto callCount = 0;
1400 auto vsyncCalledTime = 0;
1401 auto wakeupCalledTime = 0;
1402 auto readyCalledTime = 0;
1403 VSyncDispatchTimerQueueEntry entry(
1404 "test",
1405 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1406 callCount++;
1407 vsyncCalledTime = vsyncTime;
1408 wakeupCalledTime = wakeupTime;
1409 readyCalledTime = readyTime;
1410 },
1411 mVsyncMoveThreshold);
1412
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001413 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001414 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001415 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001416 auto const wakeup = entry.wakeupTime();
1417 ASSERT_TRUE(wakeup);
1418 EXPECT_THAT(*wakeup, Eq(900));
1419
1420 auto const ready = entry.readyTime();
1421 ASSERT_TRUE(ready);
1422 EXPECT_THAT(*ready, Eq(970));
1423
1424 entry.callback(entry.executing(), *wakeup, *ready);
1425
1426 EXPECT_THAT(callCount, Eq(1));
1427 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1428 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1429 EXPECT_FALSE(entry.wakeupTime());
1430 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1431 ASSERT_TRUE(lastCalledTarget);
1432 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1433}
1434
Kevin DuBois305bef12019-10-09 13:23:27 -07001435} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001436
1437// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001438#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"