blob: 4bf58de05c89070c84c0c2a8448a19f288223a7f [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 Abraham3e019972023-10-20 13:23:48 -0700737 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
738
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) {
757 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
758
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 Abraham3e019972023-10-20 13:23:48 -0700824 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
825
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) {
842 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
843
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) {
920 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700921 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
922 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700923 CountingCallback cb(mDispatch);
924
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700925 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800926 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700927 EXPECT_TRUE(result.has_value());
928 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700929
930 mMockClock.setLag(100);
931 mMockClock.advanceBy(620);
932
Ady Abraham4335afd2023-12-18 19:10:47 -0800933 result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700934 EXPECT_TRUE(result.has_value());
935 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700936 mMockClock.advanceBy(80);
937
938 EXPECT_THAT(cb.mCalls.size(), Eq(1));
939}
940
Kevin DuBoisb340b732020-06-16 09:07:35 -0700941// b/154303580.
942TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
943 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700944 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700945 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
946 CountingCallback cb1(mDispatch);
947 CountingCallback cb2(mDispatch);
948
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700949 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800950 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700951 EXPECT_TRUE(result.has_value());
952 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -0800953 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700954 EXPECT_TRUE(result.has_value());
955 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700956
957 mMockClock.setLag(100);
958 mMockClock.advanceBy(620);
959
Leon Scroggins III67388622023-02-06 20:36:20 -0500960 EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700961
962 mMockClock.advanceBy(80);
963
964 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
965 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
966}
967
968TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
969 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700970 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
971 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700972 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
973 CountingCallback cb1(mDispatch);
974 CountingCallback cb2(mDispatch);
975
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700976 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800977 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700978 EXPECT_TRUE(result.has_value());
979 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -0800980 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700981 EXPECT_TRUE(result.has_value());
982 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700983
984 mMockClock.setLag(100);
985 mMockClock.advanceBy(620);
986
Leon Scroggins III67388622023-02-06 20:36:20 -0500987 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700988
989 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
990 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
991 mMockClock.advanceToNextCallback();
992
993 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
994 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
995}
996
Kevin DuBoisf9477832020-07-16 10:21:36 -0700997TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
998 CountingCallback cb1(mDispatch);
999 CountingCallback cb2(mDispatch);
1000
1001 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001002 EXPECT_CALL(*mStubTracker.get(),
1003 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001004 .InSequence(seq)
1005 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -07001006 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abraham4335afd2023-12-18 19:10:47 -08001007 EXPECT_CALL(*mStubTracker.get(),
1008 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001009 .InSequence(seq)
1010 .WillOnce(Return(1000));
1011
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001012 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001013 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001014 EXPECT_TRUE(result.has_value());
1015 EXPECT_EQ(600, *result);
Ady Abraham4335afd2023-12-18 19:10:47 -08001016 result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001017 EXPECT_TRUE(result.has_value());
1018 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001019
1020 mMockClock.setLag(100);
1021 mMockClock.advanceBy(700);
1022
1023 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1024 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001025 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1026 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001027 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1028 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001029 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1030 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1031}
1032
1033TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1034 auto intended = mPeriod - 230;
1035 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1036
1037 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -08001038 const auto result =
1039 mDispatch->schedule(cb,
1040 {.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001041 EXPECT_TRUE(result.has_value());
1042 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -07001043 advanceToNextCallback();
1044
1045 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1046 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1047 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1048 EXPECT_THAT(cb.mWakeupTime[0], 900);
1049 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1050 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001051}
1052
Ady Abraham69b9e622021-07-19 12:24:31 -07001053TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abraham3e019972023-10-20 13:23:48 -07001054 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
1055
Ady Abraham69b9e622021-07-19 12:24:31 -07001056 Sequence seq;
1057 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1058
1059 CountingCallback cb(mDispatch);
1060
Ady Abraham4335afd2023-12-18 19:10:47 -08001061 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1062 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001063
1064 advanceToNextCallback();
1065
1066 advanceToNextCallback();
1067
1068 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1069 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1070 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1071 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1072 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1073 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1074}
1075
Ady Abraham3e019972023-10-20 13:23:48 -07001076TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
1077 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
1078
1079 Sequence seq;
1080 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001081 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -07001082
1083 CountingCallback cb(mDispatch);
1084
Ady Abraham4335afd2023-12-18 19:10:47 -08001085 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1086 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -07001087
1088 advanceToNextCallback();
1089
1090 advanceToNextCallback();
1091
1092 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1093 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1094 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001095 EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
Ady Abraham3e019972023-10-20 13:23:48 -07001096 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1097 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1098}
1099
Ady Abraham529bd9f2023-10-05 14:55:30 -07001100TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001101 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001102
1103 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1104 CountingCallback cb(mDispatch);
1105 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001106 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001107 EXPECT_TRUE(result.has_value());
1108 EXPECT_EQ(500, *result);
1109 mMockClock.advanceBy(300);
1110
Ady Abraham4335afd2023-12-18 19:10:47 -08001111 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001112 EXPECT_TRUE(result.has_value());
1113 EXPECT_EQ(1200, *result);
1114
1115 advanceToNextCallback();
1116 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1117}
1118
Ady Abraham529bd9f2023-10-05 14:55:30 -07001119TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahamf1d517d2023-10-10 15:24:33 -07001120 SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001121
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001122 Sequence seq;
1123 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1124 EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001125 CountingCallback cb(mDispatch);
1126 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001127 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001128 EXPECT_TRUE(result.has_value());
1129 EXPECT_EQ(500, *result);
1130 mMockClock.advanceBy(300);
1131
Ady Abraham4335afd2023-12-18 19:10:47 -08001132 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001133 EXPECT_TRUE(result.has_value());
Ady Abraham3e019972023-10-20 13:23:48 -07001134 EXPECT_EQ(300, *result);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001135
1136 advanceToNextCallback();
1137 ASSERT_THAT(cb.mCalls.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001138 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1139 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1140 EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1141 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1142 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
Ady Abraham529bd9f2023-10-05 14:55:30 -07001143}
1144
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001145class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001146protected:
1147 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001148 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001149 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1150 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001151};
1152
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001153TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001154 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001155 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001156 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001157 EXPECT_THAT(entry.name(), Eq(name));
1158 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1159 EXPECT_FALSE(entry.wakeupTime());
1160}
1161
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001162TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001163 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001164 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001165
1166 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham4335afd2023-12-18 19:10:47 -08001167 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001168 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001169 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001170 auto const wakeup = entry.wakeupTime();
1171 ASSERT_TRUE(wakeup);
1172 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001173
1174 entry.disarm();
1175 EXPECT_FALSE(entry.wakeupTime());
1176}
1177
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001178TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001179 auto const duration = 500;
1180 auto const now = 8750;
1181
Ady Abraham4335afd2023-12-18 19:10:47 -08001182 EXPECT_CALL(*mStubTracker.get(),
1183 nextAnticipatedVSyncTimeFrom(now + duration, std::optional<nsecs_t>(994)))
Kevin DuBois305bef12019-10-09 13:23:27 -07001184 .Times(1)
1185 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001186 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001187 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001188
1189 EXPECT_FALSE(entry.wakeupTime());
Ady Abraham4335afd2023-12-18 19:10:47 -08001190 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
Leon Scroggins III67388622023-02-06 20:36:20 -05001191 *mStubTracker.get(), now)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001192 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001193 auto const wakeup = entry.wakeupTime();
1194 ASSERT_TRUE(wakeup);
1195 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001196}
1197
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001198TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001199 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001200 auto vsyncCalledTime = 0;
1201 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001202 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001203 VSyncDispatchTimerQueueEntry entry(
1204 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001205 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001206 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001207 vsyncCalledTime = vsyncTime;
1208 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001209 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001210 },
1211 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001212
Ady Abraham4335afd2023-12-18 19:10:47 -08001213 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001214 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001215 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001216 auto const wakeup = entry.wakeupTime();
1217 ASSERT_TRUE(wakeup);
1218 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001219
Ady Abraham9c53ee72020-07-22 21:16:18 -07001220 auto const ready = entry.readyTime();
1221 ASSERT_TRUE(ready);
1222 EXPECT_THAT(*ready, Eq(1000));
1223
1224 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001225
1226 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001227 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1228 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001229 EXPECT_FALSE(entry.wakeupTime());
1230 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1231 ASSERT_TRUE(lastCalledTarget);
1232 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1233}
1234
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001235TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Ady Abraham4335afd2023-12-18 19:10:47 -08001236 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -07001237 .Times(2)
1238 .WillOnce(Return(1000))
1239 .WillOnce(Return(1020));
1240
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001241 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001242 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001243
1244 EXPECT_FALSE(entry.wakeupTime());
Leon Scroggins III67388622023-02-06 20:36:20 -05001245 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001246 EXPECT_FALSE(entry.wakeupTime());
1247
Ady Abraham4335afd2023-12-18 19:10:47 -08001248 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001249 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001250 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001251 auto wakeup = entry.wakeupTime();
1252 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001253 EXPECT_THAT(wakeup, Eq(900));
1254
Leon Scroggins III67388622023-02-06 20:36:20 -05001255 entry.update(*mStubTracker.get(), 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001256 wakeup = entry.wakeupTime();
1257 ASSERT_TRUE(wakeup);
1258 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001259}
1260
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001261TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001262 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001263 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001264 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001265 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001266 .has_value());
Leon Scroggins III67388622023-02-06 20:36:20 -05001267 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001268
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001269 auto const wakeup = entry.wakeupTime();
1270 ASSERT_TRUE(wakeup);
1271 EXPECT_THAT(*wakeup, Eq(wakeup));
1272}
1273
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001274TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1275 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001276 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001277 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001278 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001279 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001280 entry.executing(); // 1000 is executing
1281 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abraham4335afd2023-12-18 19:10:47 -08001282 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001283 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001284 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001285 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001286 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001287
Ady Abraham4335afd2023-12-18 19:10:47 -08001288 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001289 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001290 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001291 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001292 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001293
Ady Abraham4335afd2023-12-18 19:10:47 -08001294 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
Leon Scroggins III67388622023-02-06 20:36:20 -05001295 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001296 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001297 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001298 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001299}
1300
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001301TEST_F(VSyncDispatchTimerQueueEntryTest,
1302 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1303 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001304 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001305
1306 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001307 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001308 .InSequence(seq)
1309 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001310 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001311 .InSequence(seq)
1312 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001313 EXPECT_CALL(*mStubTracker.get(),
1314 nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold,
1315 std::optional<nsecs_t>(1000)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001316 .InSequence(seq)
1317 .WillOnce(Return(2000));
1318
Ady Abraham4335afd2023-12-18 19:10:47 -08001319 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001320 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001321 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001322
1323 entry.executing(); // 1000 is executing
1324
Ady Abraham4335afd2023-12-18 19:10:47 -08001325 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001326 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001327 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001328}
1329
1330TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1331 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001332 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abraham4335afd2023-12-18 19:10:47 -08001333 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001334 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001335 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001336 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001337 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001338 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001339 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001340 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001341 .has_value());
Ady Abraham4335afd2023-12-18 19:10:47 -08001342 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001343 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001344 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001345}
1346
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001347TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1348 static constexpr auto effectualOffset = 200;
1349 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001350 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001351 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham4335afd2023-12-18 19:10:47 -08001352 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .lastVsync = 400});
Ady Abraham9c53ee72020-07-22 21:16:18 -07001353 entry.addPendingWorkloadUpdate(
Ady Abraham4335afd2023-12-18 19:10:47 -08001354 {.workDuration = effectualOffset, .readyDuration = 0, .lastVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001355 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
Leon Scroggins III67388622023-02-06 20:36:20 -05001356 entry.update(*mStubTracker.get(), 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001357 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1358 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1359}
1360
Ady Abraham9c53ee72020-07-22 21:16:18 -07001361TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1362 auto callCount = 0;
1363 auto vsyncCalledTime = 0;
1364 auto wakeupCalledTime = 0;
1365 auto readyCalledTime = 0;
1366 VSyncDispatchTimerQueueEntry entry(
1367 "test",
1368 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1369 callCount++;
1370 vsyncCalledTime = vsyncTime;
1371 wakeupCalledTime = wakeupTime;
1372 readyCalledTime = readyTime;
1373 },
1374 mVsyncMoveThreshold);
1375
Ady Abraham4335afd2023-12-18 19:10:47 -08001376 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
Leon Scroggins III67388622023-02-06 20:36:20 -05001377 *mStubTracker.get(), 0)
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001378 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001379 auto const wakeup = entry.wakeupTime();
1380 ASSERT_TRUE(wakeup);
1381 EXPECT_THAT(*wakeup, Eq(900));
1382
1383 auto const ready = entry.readyTime();
1384 ASSERT_TRUE(ready);
1385 EXPECT_THAT(*ready, Eq(970));
1386
1387 entry.callback(entry.executing(), *wakeup, *ready);
1388
1389 EXPECT_THAT(callCount, Eq(1));
1390 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1391 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1392 EXPECT_FALSE(entry.wakeupTime());
1393 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1394 ASSERT_TRUE(lastCalledTarget);
1395 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1396}
1397
Kevin DuBois305bef12019-10-09 13:23:27 -07001398} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001399
1400// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001401#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"