blob: eb4e84ef4fe4f59a112e145792b5a43ac468f513 [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 Abraham3db8a3c2023-11-20 17:53:47 -080033#include <common/test/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} {
Ady Abraham4335afd2023-12-18 19:10:47 -080049 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -070050 .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
Ady Abraham4335afd2023-12-18 19:10:47 -080056 nsecs_t nextVSyncTime(nsecs_t timePoint, std::optional<nsecs_t>) const {
Kevin DuBois305bef12019-10-09 13:23:27 -070057 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);
Ady Abraham4335afd2023-12-18 19:10:47 -0800246 const auto result =
247 mDispatch->schedule(cb,
248 {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700249 EXPECT_TRUE(result.has_value());
250 EXPECT_EQ(900, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700251 }
252}
253
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800254TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700255 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700256 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700257
258 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800259 const auto result =
260 mDispatch->schedule(cb,
261 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700262 EXPECT_TRUE(result.has_value());
263 EXPECT_EQ(900, *result);
264
Kevin DuBois305bef12019-10-09 13:23:27 -0700265 advanceToNextCallback();
266
267 ASSERT_THAT(cb.mCalls.size(), Eq(1));
268 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
269}
270
Ady Abraham011f8ba2022-11-22 15:09:07 -0800271TEST_F(VSyncDispatchTimerQueueTest, updateAlarmSettingFuture) {
272 auto intended = mPeriod - 230;
273 Sequence seq;
274 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
275 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
276
277 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800278 auto result =
279 mDispatch->schedule(cb,
280 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800281 EXPECT_TRUE(result.has_value());
282 EXPECT_EQ(900, *result);
283
Leon Scroggins III67388622023-02-06 20:36:20 -0500284 result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800285 mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800286 EXPECT_TRUE(result.has_value());
287 EXPECT_EQ(700, *result);
288
289 advanceToNextCallback();
290
291 ASSERT_THAT(cb.mCalls.size(), Eq(1));
292 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
293 EXPECT_THAT(cb.mWakeupTime[0], Eq(700));
294}
295
296TEST_F(VSyncDispatchTimerQueueTest, updateDoesntSchedule) {
297 auto intended = mPeriod - 230;
298 EXPECT_CALL(mMockClock, alarmAt(_, _)).Times(0);
299
300 CountingCallback cb(mDispatch);
301 const auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800302 mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800303 EXPECT_FALSE(result.has_value());
304}
305
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800306TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800307 EXPECT_CALL(*mStubTracker.get(),
308 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(mPeriod)))
309 .WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700310 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700311
312 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800313 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700314 advanceToNextCallback();
315
316 ASSERT_THAT(cb.mCalls.size(), Eq(1));
317 EXPECT_THAT(cb.mCalls[0], Eq(1150));
318}
319
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800320TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700321 auto const now = 234;
322 mMockClock.advanceBy(234);
323 auto const workDuration = 10 * mPeriod;
Ady Abraham4335afd2023-12-18 19:10:47 -0800324 EXPECT_CALL(*mStubTracker.get(),
325 nextAnticipatedVSyncTimeFrom(now + workDuration, std::optional<nsecs_t>(mPeriod)))
Kevin DuBois305bef12019-10-09 13:23:27 -0700326 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700327 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700328
329 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500330 const auto result = mDispatch->schedule(cb,
331 {.workDuration = workDuration,
332 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800333 .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700334 EXPECT_TRUE(result.has_value());
335 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700336}
337
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800338TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700339 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700340 EXPECT_CALL(mMockClock, alarmCancel());
341
342 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800343 const auto result =
344 mDispatch->schedule(cb,
345 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700346 EXPECT_TRUE(result.has_value());
347 EXPECT_EQ(mPeriod - 100, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500348 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700349}
350
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800351TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700352 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700353 EXPECT_CALL(mMockClock, alarmCancel());
354
355 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800356 const auto result =
357 mDispatch->schedule(cb,
358 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700359 EXPECT_TRUE(result.has_value());
360 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700361 mMockClock.advanceBy(950);
Leon Scroggins III67388622023-02-06 20:36:20 -0500362 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700363}
364
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800365TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700366 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700367 EXPECT_CALL(mMockClock, alarmCancel());
368
369 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abraham4335afd2023-12-18 19:10:47 -0800370 const auto result =
371 mDispatch->schedule(cb,
372 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700373 EXPECT_TRUE(result.has_value());
374 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700375
376 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
377 EXPECT_TRUE(cb.waitForPause());
Leon Scroggins III67388622023-02-06 20:36:20 -0500378 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700379 cb.unpause();
380 pausingThread.join();
381}
382
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800383TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700384 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700385 EXPECT_CALL(mMockClock, alarmCancel());
386
387 auto resource = std::make_shared<int>(110);
388
389 PausingCallback cb(mDispatch, 50ms);
390 cb.stashResource(resource);
Ady Abraham4335afd2023-12-18 19:10:47 -0800391 const auto result =
392 mDispatch->schedule(cb,
393 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700394 EXPECT_TRUE(result.has_value());
395 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700396
397 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
398 EXPECT_TRUE(cb.waitForPause());
399
400 cb.unregister();
401 resource.reset();
402
403 cb.unpause();
404 pausingThread.join();
405
406 EXPECT_TRUE(cb.resourcePresent());
407}
408
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800409TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800410 EXPECT_CALL(*mStubTracker.get(),
411 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBois305bef12019-10-09 13:23:27 -0700412 .Times(4)
413 .WillOnce(Return(1055))
414 .WillOnce(Return(1063))
415 .WillOnce(Return(1063))
416 .WillOnce(Return(1075));
417
418 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700419 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
420 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
421 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700422
423 CountingCallback cb0(mDispatch);
424 CountingCallback cb1(mDispatch);
425
Ady Abraham4335afd2023-12-18 19:10:47 -0800426 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
427 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700428
429 advanceToNextCallback();
430 advanceToNextCallback();
431
432 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
433 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
434 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
435 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
436}
437
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700438TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800439 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700440 .Times(4)
441 .WillOnce(Return(1000))
442 .WillOnce(Return(2000))
443 .WillOnce(Return(2500))
444 .WillOnce(Return(4000));
445
446 Sequence seq;
447 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
448 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
449 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
450
451 CountingCallback cb(mDispatch);
452
Ady Abraham4335afd2023-12-18 19:10:47 -0800453 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 0});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700454
455 advanceToNextCallback();
456
457 ASSERT_THAT(cb.mCalls.size(), Eq(1));
458 EXPECT_THAT(cb.mCalls[0], Eq(1000));
459
Ady Abraham4335afd2023-12-18 19:10:47 -0800460 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700461
462 advanceToNextCallback();
463
464 ASSERT_THAT(cb.mCalls.size(), Eq(2));
465 EXPECT_THAT(cb.mCalls[1], Eq(2000));
466
Ady Abraham4335afd2023-12-18 19:10:47 -0800467 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700468
469 advanceToNextCallback();
470
471 ASSERT_THAT(cb.mCalls.size(), Eq(3));
472 EXPECT_THAT(cb.mCalls[2], Eq(4000));
473}
474
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800475TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800476 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -0700477 .Times(4)
478 .WillOnce(Return(10000))
479 .WillOnce(Return(1000))
480 .WillOnce(Return(10000))
481 .WillOnce(Return(10000));
482
483 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700484 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
485 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
486 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700487
488 CountingCallback cb0(mDispatch);
489 CountingCallback cb1(mDispatch);
490
Ady Abraham4335afd2023-12-18 19:10:47 -0800491 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod * 10});
492 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
Leon Scroggins III67388622023-02-06 20:36:20 -0500493 mDispatch->cancel(cb1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700494}
495
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800496TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700497 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700498 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
499 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700500
501 CountingCallback cb0(mDispatch);
502 CountingCallback cb1(mDispatch);
503
Ady Abraham4335afd2023-12-18 19:10:47 -0800504 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
505 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
506 mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700507 advanceToNextCallback();
508}
509
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800510TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700511 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700512 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
513 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
514 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700515
516 CountingCallback cb0(mDispatch);
517 CountingCallback cb1(mDispatch);
518
Ady Abraham4335afd2023-12-18 19:10:47 -0800519 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
520 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
521 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700522 advanceToNextCallback();
523}
524
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800525TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
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(_, 1600)).InSequence(seq);
529 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
530 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700531
532 auto offset = 400;
533 auto closeOffset = offset + mDispatchGroupThreshold - 1;
534 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
535
536 CountingCallback cb0(mDispatch);
537 CountingCallback cb1(mDispatch);
538
Ady Abraham4335afd2023-12-18 19:10:47 -0800539 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
540 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
541 mDispatch->schedule(cb1, {.workDuration = closeOffset, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700542
543 advanceToNextCallback();
544 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
545 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
546 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
547 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
548
Ady Abraham4335afd2023-12-18 19:10:47 -0800549 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 2000});
Leon Scroggins III67388622023-02-06 20:36:20 -0500550 mDispatch->schedule(cb1,
Ady Abraham4335afd2023-12-18 19:10:47 -0800551 {.workDuration = notCloseOffset, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700552 advanceToNextCallback();
553 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
554 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
555
556 advanceToNextCallback();
557 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
558 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
559}
560
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800561TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700562 Sequence seq;
563 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
564 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
565 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700566 EXPECT_CALL(mMockClock, alarmCancel());
567
568 CountingCallback cb0(mDispatch);
569 CountingCallback cb1(mDispatch);
570
Ady Abraham4335afd2023-12-18 19:10:47 -0800571 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
572 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700573 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500574 EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700575}
576
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800577TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800578 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -0700579 .Times(3)
580 .WillOnce(Return(950))
581 .WillOnce(Return(1975))
582 .WillOnce(Return(2950));
583
584 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800585 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700586
587 mMockClock.advanceBy(850);
588 EXPECT_THAT(cb.mCalls.size(), Eq(1));
589
Ady Abraham4335afd2023-12-18 19:10:47 -0800590 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700591 mMockClock.advanceBy(900);
592 EXPECT_THAT(cb.mCalls.size(), Eq(1));
593 mMockClock.advanceBy(125);
594 EXPECT_THAT(cb.mCalls.size(), Eq(2));
595
Ady Abraham4335afd2023-12-18 19:10:47 -0800596 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700597 mMockClock.advanceBy(975);
598 EXPECT_THAT(cb.mCalls.size(), Eq(3));
599}
600
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800601TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700602 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700603 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
604 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700605
606 VSyncDispatch::CallbackToken tmp;
Leon Scroggins III67388622023-02-06 20:36:20 -0500607 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700608 [&](auto, auto, auto) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500609 mDispatch->schedule(tmp,
Ady Abraham4335afd2023-12-18 19:10:47 -0800610 {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abraham9c53ee72020-07-22 21:16:18 -0700611 },
612 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700613
Ady Abraham4335afd2023-12-18 19:10:47 -0800614 mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700615 advanceToNextCallback();
616}
617
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800618TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700619 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800620 std::optional<nsecs_t> lastTarget;
Leon Scroggins III67388622023-02-06 20:36:20 -0500621 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700622 [&](auto timestamp, auto, auto) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800623 auto result = mDispatch->schedule(tmp,
624 {.workDuration = 400,
625 .readyDuration = 0,
626 .lastVsync = timestamp - mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700627 EXPECT_TRUE(result.has_value());
628 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Leon Scroggins III67388622023-02-06 20:36:20 -0500629 result = mDispatch->schedule(tmp,
630 {.workDuration = 400,
631 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800632 .lastVsync = timestamp});
Leon Scroggins III67388622023-02-06 20:36:20 -0500633 EXPECT_TRUE(result.has_value());
634 EXPECT_EQ(mPeriod + timestamp - 400, *result);
635 result = mDispatch->schedule(tmp,
636 {.workDuration = 400,
637 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800638 .lastVsync = timestamp + mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700639 EXPECT_TRUE(result.has_value());
640 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800641 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700642 },
643 "oo");
644
Ady Abraham4335afd2023-12-18 19:10:47 -0800645 mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700646 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800647 EXPECT_THAT(lastTarget, Eq(1000));
648
649 advanceToNextCallback();
650 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700651}
652
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800653TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700654 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700655 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
656 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
657 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
658 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700659
660 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800661 mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700662
663 mMockClock.advanceBy(750);
Ady Abraham4335afd2023-12-18 19:10:47 -0800664 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700665
666 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800667 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700668
669 mMockClock.advanceBy(800);
Ady Abraham4335afd2023-12-18 19:10:47 -0800670 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700671}
672
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800673TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700674 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700675 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
676 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
677 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
678 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700679
680 CountingCallback cb0(mDispatch);
681 CountingCallback cb1(mDispatch);
682
Ady Abraham4335afd2023-12-18 19:10:47 -0800683 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
684 mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700685
686 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800687 mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .lastVsync = 2000});
688 mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700689
690 advanceToNextCallback();
691 advanceToNextCallback();
692}
693
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800694TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
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);
Kevin DuBois305bef12019-10-09 13:23:27 -0700697
698 CountingCallback cb0(mDispatch);
699 CountingCallback cb1(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800700 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
701 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700702}
703
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800704TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700705 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700706 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700707 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700708 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700709
710 CountingCallback cb0(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800711 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Leon Scroggins III67388622023-02-06 20:36:20 -0500712 mDispatch->cancel(cb0);
Ady Abraham4335afd2023-12-18 19:10:47 -0800713 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700714}
715
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800716TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700717 VSyncDispatch::CallbackToken token(100);
Leon Scroggins III67388622023-02-06 20:36:20 -0500718 EXPECT_FALSE(
Ady Abraham4335afd2023-12-18 19:10:47 -0800719 mDispatch->schedule(token, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000})
Leon Scroggins III67388622023-02-06 20:36:20 -0500720 .has_value());
721 EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700722}
723
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800724TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700725 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700726 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800727 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700728 EXPECT_TRUE(result.has_value());
729 EXPECT_EQ(500, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -0800730 result = mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700731 EXPECT_TRUE(result.has_value());
732 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800733}
734
735// b/1450138150
736TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahambf554892024-02-14 18:18:21 +0000737 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -0700738
Ady Abrahamb491c902020-08-15 15:47:56 -0700739 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800740 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700741 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800742 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700743 EXPECT_TRUE(result.has_value());
744 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800745 mMockClock.advanceBy(400);
746
Ady Abraham4335afd2023-12-18 19:10:47 -0800747 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700748 EXPECT_TRUE(result.has_value());
749 EXPECT_EQ(1200, *result);
Ady Abraham3e019972023-10-20 13:23:48 -0700750
751 advanceToNextCallback();
752 ASSERT_THAT(cb.mCalls.size(), Eq(1));
753}
754
755// b/1450138150
756TEST_F(VSyncDispatchTimerQueueTest, movesCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahambf554892024-02-14 18:18:21 +0000757 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -0700758
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700759 Sequence seq;
760 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
761 EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700762 CountingCallback cb(mDispatch);
763 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800764 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700765 EXPECT_TRUE(result.has_value());
766 EXPECT_EQ(500, *result);
767 mMockClock.advanceBy(400);
768
Ady Abraham4335afd2023-12-18 19:10:47 -0800769 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700770 EXPECT_TRUE(result.has_value());
771 EXPECT_EQ(400, *result);
772
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800773 advanceToNextCallback();
774 ASSERT_THAT(cb.mCalls.size(), Eq(1));
775}
776
777TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800778 EXPECT_CALL(*mStubTracker.get(),
779 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800780 .Times(2)
781 .WillOnce(Return(1000))
782 .WillOnce(Return(1002));
783 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700784 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800785 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700786 EXPECT_TRUE(result.has_value());
787 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800788 mMockClock.advanceBy(400);
Ady Abraham4335afd2023-12-18 19:10:47 -0800789 result = mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700790 EXPECT_TRUE(result.has_value());
791 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700792}
793
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800794TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
795 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700796 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800797 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700798 EXPECT_TRUE(result.has_value());
799 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800800 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800801 result =
802 mDispatch->schedule(cb0, {.workDuration = 1100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700803 EXPECT_TRUE(result.has_value());
804 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800805}
806
807TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
808 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700809 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
810 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800811 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700812 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800813 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700814 EXPECT_TRUE(result.has_value());
815 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800816 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800817 result =
818 mDispatch->schedule(cb0, {.workDuration = 1900, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700819 EXPECT_TRUE(result.has_value());
820 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800821}
822
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800823TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahambf554892024-02-14 18:18:21 +0000824 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -0700825
Ady Abrahamb491c902020-08-15 15:47:56 -0700826 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800827
828 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700829 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800830 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700831 EXPECT_TRUE(result.has_value());
832 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800833
Ady Abraham4335afd2023-12-18 19:10:47 -0800834 result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700835 EXPECT_TRUE(result.has_value());
836 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800837
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800838 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800839}
840
Ady Abraham3e019972023-10-20 13:23:48 -0700841TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
Ady Abrahambf554892024-02-14 18:18:21 +0000842 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -0700843
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700844 Sequence seq;
845 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
846 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700847
848 CountingCallback cb(mDispatch);
849 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800850 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700851 EXPECT_TRUE(result.has_value());
852 EXPECT_EQ(600, *result);
853
Ady Abraham4335afd2023-12-18 19:10:47 -0800854 result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700855 EXPECT_TRUE(result.has_value());
856 EXPECT_EQ(0, *result);
857
858 advanceToNextCallback();
859}
860
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800861TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700862 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700863 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
864
865 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700866 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700867 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham4335afd2023-12-18 19:10:47 -0800868 cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700869 cb.cancel();
870
Ady Abraham4335afd2023-12-18 19:10:47 -0800871 cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700872 cb1.cancel();
873}
874
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800875TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700876 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700877 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
878
879 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700880 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700881 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700882 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700883 cb1 = std::move(cb);
Ady Abraham4335afd2023-12-18 19:10:47 -0800884 cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700885 cb.cancel();
886
Ady Abraham4335afd2023-12-18 19:10:47 -0800887 cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700888 cb1.cancel();
889}
890
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700891// b/154303580
892TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
893 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700894 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
895 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700896 CountingCallback cb1(mDispatch);
897 CountingCallback cb2(mDispatch);
898
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700899 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800900 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700901 EXPECT_TRUE(result.has_value());
902 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700903
904 mMockClock.setLag(100);
905 mMockClock.advanceBy(620);
906
Ady Abraham4335afd2023-12-18 19:10:47 -0800907 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700908 EXPECT_TRUE(result.has_value());
909 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700910 mMockClock.advanceBy(80);
911
912 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
913 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
914}
915
916// b/154303580.
917// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
918// update later, as opposed to blocking the calling thread.
919TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000920 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
921
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700922 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700923 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
924 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700925 CountingCallback cb(mDispatch);
926
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700927 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800928 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 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
Ady Abraham4335afd2023-12-18 19:10:47 -0800935 result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700936 EXPECT_TRUE(result.has_value());
937 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700938 mMockClock.advanceBy(80);
939
940 EXPECT_THAT(cb.mCalls.size(), Eq(1));
941}
942
Kevin DuBoisb340b732020-06-16 09:07:35 -0700943// b/154303580.
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000944// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
945// update later, as opposed to blocking the calling thread.
946TEST_F(VSyncDispatchTimerQueueTest, doesntSkipSchedulingIfTimerReschedulingIsImminentSameCallback) {
947 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
948
949 Sequence seq;
950 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
951 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
952 CountingCallback cb(mDispatch);
953
954 auto result =
955 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
956 EXPECT_TRUE(result.has_value());
957 EXPECT_EQ(600, *result);
958
959 mMockClock.setLag(100);
960 mMockClock.advanceBy(620);
961
962 result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
963 EXPECT_TRUE(result.has_value());
964 EXPECT_EQ(600, *result);
965 mMockClock.advanceBy(80);
966
967 ASSERT_EQ(1, cb.mCalls.size());
968 EXPECT_EQ(1000, cb.mCalls[0]);
969
970 ASSERT_EQ(1, cb.mWakeupTime.size());
971 EXPECT_EQ(600, cb.mWakeupTime[0]);
972}
973
974// b/154303580.
Kevin DuBoisb340b732020-06-16 09:07:35 -0700975TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
976 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700977 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700978 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
979 CountingCallback cb1(mDispatch);
980 CountingCallback cb2(mDispatch);
981
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700982 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800983 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700984 EXPECT_TRUE(result.has_value());
985 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -0800986 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 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 =
Ady Abraham4335afd2023-12-18 19:10:47 -08001010 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001011 EXPECT_TRUE(result.has_value());
1012 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -08001013 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001014 EXPECT_TRUE(result.has_value());
1015 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001016
1017 mMockClock.setLag(100);
1018 mMockClock.advanceBy(620);
1019
Leon Scroggins III67388622023-02-06 20:36:20 -05001020 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001021
1022 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1023 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1024 mMockClock.advanceToNextCallback();
1025
1026 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1027 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1028}
1029
Kevin DuBoisf9477832020-07-16 10:21:36 -07001030TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1031 CountingCallback cb1(mDispatch);
1032 CountingCallback cb2(mDispatch);
1033
1034 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001035 EXPECT_CALL(*mStubTracker.get(),
1036 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001037 .InSequence(seq)
1038 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -07001039 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abraham4335afd2023-12-18 19:10:47 -08001040 EXPECT_CALL(*mStubTracker.get(),
1041 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(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 =
Ady Abraham4335afd2023-12-18 19:10:47 -08001046 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001047 EXPECT_TRUE(result.has_value());
1048 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -08001049 result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001050 EXPECT_TRUE(result.has_value());
1051 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001052
1053 mMockClock.setLag(100);
1054 mMockClock.advanceBy(700);
1055
1056 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1057 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001058 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1059 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001060 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1061 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001062 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1063 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1064}
1065
1066TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1067 auto intended = mPeriod - 230;
1068 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1069
1070 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -08001071 const auto result =
1072 mDispatch->schedule(cb,
1073 {.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001074 EXPECT_TRUE(result.has_value());
1075 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -07001076 advanceToNextCallback();
1077
1078 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1079 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1080 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1081 EXPECT_THAT(cb.mWakeupTime[0], 900);
1082 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1083 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001084}
1085
Ady Abraham69b9e622021-07-19 12:24:31 -07001086TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abrahambf554892024-02-14 18:18:21 +00001087 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -07001088
Ady Abraham69b9e622021-07-19 12:24:31 -07001089 Sequence seq;
1090 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1091
1092 CountingCallback cb(mDispatch);
1093
Ady Abraham4335afd2023-12-18 19:10:47 -08001094 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1095 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001096
1097 advanceToNextCallback();
1098
1099 advanceToNextCallback();
1100
1101 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1102 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1103 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1104 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1105 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1106 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1107}
1108
Ady Abraham3e019972023-10-20 13:23:48 -07001109TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
Ady Abrahambf554892024-02-14 18:18:21 +00001110 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -07001111
1112 Sequence seq;
1113 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001114 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -07001115
1116 CountingCallback cb(mDispatch);
1117
Ady Abraham4335afd2023-12-18 19:10:47 -08001118 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1119 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -07001120
1121 advanceToNextCallback();
1122
1123 advanceToNextCallback();
1124
1125 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1126 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1127 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001128 EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
Ady Abraham3e019972023-10-20 13:23:48 -07001129 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1130 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1131}
1132
Ady Abraham529bd9f2023-10-05 14:55:30 -07001133TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahambf554892024-02-14 18:18:21 +00001134 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001135
1136 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1137 CountingCallback cb(mDispatch);
1138 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001139 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001140 EXPECT_TRUE(result.has_value());
1141 EXPECT_EQ(500, *result);
1142 mMockClock.advanceBy(300);
1143
Ady Abraham4335afd2023-12-18 19:10:47 -08001144 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001145 EXPECT_TRUE(result.has_value());
1146 EXPECT_EQ(1200, *result);
1147
1148 advanceToNextCallback();
1149 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1150}
1151
Ady Abraham529bd9f2023-10-05 14:55:30 -07001152TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahambf554892024-02-14 18:18:21 +00001153 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001154
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001155 Sequence seq;
1156 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1157 EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001158 CountingCallback cb(mDispatch);
1159 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001160 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001161 EXPECT_TRUE(result.has_value());
1162 EXPECT_EQ(500, *result);
1163 mMockClock.advanceBy(300);
1164
Ady Abraham4335afd2023-12-18 19:10:47 -08001165 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001166 EXPECT_TRUE(result.has_value());
Ady Abraham3e019972023-10-20 13:23:48 -07001167 EXPECT_EQ(300, *result);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001168
1169 advanceToNextCallback();
1170 ASSERT_THAT(cb.mCalls.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001171 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1172 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1173 EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1174 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1175 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
Ady Abraham529bd9f2023-10-05 14:55:30 -07001176}
1177
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001178class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001179protected:
1180 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001181 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001182 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1183 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001184};
1185
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001186TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001187 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001188 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001189 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001190 EXPECT_THAT(entry.name(), Eq(name));
1191 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1192 EXPECT_FALSE(entry.wakeupTime());
1193}
1194
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001195TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001196 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001197 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001198
1199 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham4335afd2023-12-18 19:10:47 -08001200 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001201 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001202 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001203 auto const wakeup = entry.wakeupTime();
1204 ASSERT_TRUE(wakeup);
1205 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001206
1207 entry.disarm();
1208 EXPECT_FALSE(entry.wakeupTime());
1209}
1210
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001211TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001212 auto const duration = 500;
1213 auto const now = 8750;
1214
Ady Abraham4335afd2023-12-18 19:10:47 -08001215 EXPECT_CALL(*mStubTracker.get(),
1216 nextAnticipatedVSyncTimeFrom(now + duration, std::optional<nsecs_t>(994)))
Kevin DuBois305bef12019-10-09 13:23:27 -07001217 .Times(1)
1218 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001219 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001220 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001221
1222 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham4335afd2023-12-18 19:10:47 -08001223 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
Leon Scroggins III67388622023-02-06 20:36:20 -05001224 *mStubTracker.get(), now)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001225 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001226 auto const wakeup = entry.wakeupTime();
1227 ASSERT_TRUE(wakeup);
1228 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001229}
1230
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001231TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001232 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001233 auto vsyncCalledTime = 0;
1234 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001235 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001236 VSyncDispatchTimerQueueEntry entry(
1237 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001238 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001239 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001240 vsyncCalledTime = vsyncTime;
1241 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001242 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001243 },
1244 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001245
Ady Abraham4335afd2023-12-18 19:10:47 -08001246 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001247 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001248 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001249 auto const wakeup = entry.wakeupTime();
1250 ASSERT_TRUE(wakeup);
1251 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001252
Ady Abraham9c53ee72020-07-22 21:16:18 -07001253 auto const ready = entry.readyTime();
1254 ASSERT_TRUE(ready);
1255 EXPECT_THAT(*ready, Eq(1000));
1256
1257 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001258
1259 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001260 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1261 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001262 EXPECT_FALSE(entry.wakeupTime());
1263 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1264 ASSERT_TRUE(lastCalledTarget);
1265 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1266}
1267
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001268TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Ady Abraham4335afd2023-12-18 19:10:47 -08001269 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -07001270 .Times(2)
1271 .WillOnce(Return(1000))
1272 .WillOnce(Return(1020));
1273
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001274 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001275 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001276
1277 EXPECT_FALSE(entry.wakeupTime());
Leon Scroggins III67388622023-02-06 20:36:20 -05001278 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001279 EXPECT_FALSE(entry.wakeupTime());
1280
Ady Abraham4335afd2023-12-18 19:10:47 -08001281 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001282 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001283 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001284 auto wakeup = entry.wakeupTime();
1285 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001286 EXPECT_THAT(wakeup, Eq(900));
1287
Leon Scroggins III67388622023-02-06 20:36:20 -05001288 entry.update(*mStubTracker.get(), 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001289 wakeup = entry.wakeupTime();
1290 ASSERT_TRUE(wakeup);
1291 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001292}
1293
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001294TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001295 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001296 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001297 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001298 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001299 .has_value());
Leon Scroggins III67388622023-02-06 20:36:20 -05001300 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001301
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001302 auto const wakeup = entry.wakeupTime();
1303 ASSERT_TRUE(wakeup);
1304 EXPECT_THAT(*wakeup, Eq(wakeup));
1305}
1306
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001307TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1308 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001309 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001310 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001311 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001312 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001313 entry.executing(); // 1000 is executing
1314 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abraham4335afd2023-12-18 19:10:47 -08001315 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001316 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001317 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001318 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001319 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001320
Ady Abraham4335afd2023-12-18 19:10:47 -08001321 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 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(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001325 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001326
Ady Abraham4335afd2023-12-18 19:10:47 -08001327 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
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(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001331 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001332}
1333
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001334TEST_F(VSyncDispatchTimerQueueEntryTest,
1335 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1336 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001337 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001338
1339 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001340 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001341 .InSequence(seq)
1342 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001343 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001344 .InSequence(seq)
1345 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001346 EXPECT_CALL(*mStubTracker.get(),
1347 nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold,
1348 std::optional<nsecs_t>(1000)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001349 .InSequence(seq)
1350 .WillOnce(Return(2000));
1351
Ady Abraham4335afd2023-12-18 19:10:47 -08001352 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001353 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001354 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001355
1356 entry.executing(); // 1000 is executing
1357
Ady Abraham4335afd2023-12-18 19:10:47 -08001358 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001359 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001360 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001361}
1362
1363TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1364 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001365 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001366 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001367 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001368 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001369 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001370 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001371 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001372 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001373 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001374 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001375 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001376 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001377 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001378}
1379
Ady Abrahamda8af4c2024-02-14 00:24:34 +00001380TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdateAndDontSkip) {
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001381 static constexpr auto effectualOffset = 200;
1382 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001383 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001384 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abrahamda8af4c2024-02-14 00:24:34 +00001385 entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1386 {.workDuration = 100, .readyDuration = 0, .lastVsync = 400});
1387 entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1388 {.workDuration = effectualOffset,
1389 .readyDuration = 0,
1390 .lastVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001391 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
Leon Scroggins III67388622023-02-06 20:36:20 -05001392 entry.update(*mStubTracker.get(), 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001393 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1394 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1395}
1396
Ady Abraham9c53ee72020-07-22 21:16:18 -07001397TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1398 auto callCount = 0;
1399 auto vsyncCalledTime = 0;
1400 auto wakeupCalledTime = 0;
1401 auto readyCalledTime = 0;
1402 VSyncDispatchTimerQueueEntry entry(
1403 "test",
1404 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1405 callCount++;
1406 vsyncCalledTime = vsyncTime;
1407 wakeupCalledTime = wakeupTime;
1408 readyCalledTime = readyTime;
1409 },
1410 mVsyncMoveThreshold);
1411
Ady Abraham4335afd2023-12-18 19:10:47 -08001412 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001413 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001414 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001415 auto const wakeup = entry.wakeupTime();
1416 ASSERT_TRUE(wakeup);
1417 EXPECT_THAT(*wakeup, Eq(900));
1418
1419 auto const ready = entry.readyTime();
1420 ASSERT_TRUE(ready);
1421 EXPECT_THAT(*ready, Eq(970));
1422
1423 entry.callback(entry.executing(), *wakeup, *ready);
1424
1425 EXPECT_THAT(callCount, Eq(1));
1426 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1427 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1428 EXPECT_FALSE(entry.wakeupTime());
1429 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1430 ASSERT_TRUE(lastCalledTarget);
1431 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1432}
1433
Kevin DuBois305bef12019-10-09 13:23:27 -07001434} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001435
1436// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001437#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"