blob: 9b70d92eac334ff97ea533f0910f96507c7b3bff [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());
ramindani32a88b12024-01-31 18:45:30 -0800250 EXPECT_EQ(900, result->callbackTime.ns());
251 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700252 }
253}
254
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800255TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700256 auto intended = mPeriod - 230;
Ady Abrahamb491c902020-08-15 15:47:56 -0700257 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700258
259 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800260 const auto result =
261 mDispatch->schedule(cb,
262 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700263 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800264 EXPECT_EQ(900, result->callbackTime.ns());
265 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700266
Kevin DuBois305bef12019-10-09 13:23:27 -0700267 advanceToNextCallback();
268
269 ASSERT_THAT(cb.mCalls.size(), Eq(1));
270 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
271}
272
Ady Abraham011f8ba2022-11-22 15:09:07 -0800273TEST_F(VSyncDispatchTimerQueueTest, updateAlarmSettingFuture) {
274 auto intended = mPeriod - 230;
275 Sequence seq;
276 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
277 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
278
279 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800280 auto result =
281 mDispatch->schedule(cb,
282 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800283 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800284 EXPECT_EQ(900, result->callbackTime.ns());
285 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham011f8ba2022-11-22 15:09:07 -0800286
Leon Scroggins III67388622023-02-06 20:36:20 -0500287 result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800288 mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800289 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800290 EXPECT_EQ(700, result->callbackTime.ns());
291 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham011f8ba2022-11-22 15:09:07 -0800292
293 advanceToNextCallback();
294
295 ASSERT_THAT(cb.mCalls.size(), Eq(1));
296 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
297 EXPECT_THAT(cb.mWakeupTime[0], Eq(700));
298}
299
300TEST_F(VSyncDispatchTimerQueueTest, updateDoesntSchedule) {
301 auto intended = mPeriod - 230;
302 EXPECT_CALL(mMockClock, alarmAt(_, _)).Times(0);
303
304 CountingCallback cb(mDispatch);
305 const auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800306 mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
Ady Abraham011f8ba2022-11-22 15:09:07 -0800307 EXPECT_FALSE(result.has_value());
308}
309
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800310TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800311 EXPECT_CALL(*mStubTracker.get(),
312 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(mPeriod)))
313 .WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700314 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700315
316 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800317 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700318 advanceToNextCallback();
319
320 ASSERT_THAT(cb.mCalls.size(), Eq(1));
321 EXPECT_THAT(cb.mCalls[0], Eq(1150));
322}
323
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800324TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700325 auto const now = 234;
326 mMockClock.advanceBy(234);
327 auto const workDuration = 10 * mPeriod;
Ady Abraham4335afd2023-12-18 19:10:47 -0800328 EXPECT_CALL(*mStubTracker.get(),
329 nextAnticipatedVSyncTimeFrom(now + workDuration, std::optional<nsecs_t>(mPeriod)))
Kevin DuBois305bef12019-10-09 13:23:27 -0700330 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700331 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700332
333 CountingCallback cb(mDispatch);
Leon Scroggins III67388622023-02-06 20:36:20 -0500334 const auto result = mDispatch->schedule(cb,
335 {.workDuration = workDuration,
336 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800337 .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700338 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800339 EXPECT_EQ(mPeriod, result->callbackTime.ns());
340 EXPECT_EQ(workDuration + mPeriod, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700341}
342
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800343TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700344 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700345 EXPECT_CALL(mMockClock, alarmCancel());
346
347 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800348 const auto result =
349 mDispatch->schedule(cb,
350 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700351 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800352 EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
353 EXPECT_EQ(mPeriod, result->vsyncTime.ns());
Leon Scroggins III67388622023-02-06 20:36:20 -0500354 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700355}
356
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800357TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700358 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700359 EXPECT_CALL(mMockClock, alarmCancel());
360
361 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800362 const auto result =
363 mDispatch->schedule(cb,
364 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700365 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800366 EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
367 EXPECT_EQ(mPeriod, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700368 mMockClock.advanceBy(950);
Leon Scroggins III67388622023-02-06 20:36:20 -0500369 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700370}
371
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800372TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700373 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700374 EXPECT_CALL(mMockClock, alarmCancel());
375
376 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abraham4335afd2023-12-18 19:10:47 -0800377 const auto result =
378 mDispatch->schedule(cb,
379 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700380 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800381 EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
382 EXPECT_EQ(mPeriod, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700383
384 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
385 EXPECT_TRUE(cb.waitForPause());
Leon Scroggins III67388622023-02-06 20:36:20 -0500386 EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
Kevin DuBois305bef12019-10-09 13:23:27 -0700387 cb.unpause();
388 pausingThread.join();
389}
390
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800391TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700392 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700393 EXPECT_CALL(mMockClock, alarmCancel());
394
395 auto resource = std::make_shared<int>(110);
396
397 PausingCallback cb(mDispatch, 50ms);
398 cb.stashResource(resource);
Ady Abraham4335afd2023-12-18 19:10:47 -0800399 const auto result =
400 mDispatch->schedule(cb,
401 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700402 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800403 EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
404 EXPECT_EQ(mPeriod, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700405
406 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
407 EXPECT_TRUE(cb.waitForPause());
408
409 cb.unregister();
410 resource.reset();
411
412 cb.unpause();
413 pausingThread.join();
414
415 EXPECT_TRUE(cb.resourcePresent());
416}
417
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800418TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800419 EXPECT_CALL(*mStubTracker.get(),
420 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBois305bef12019-10-09 13:23:27 -0700421 .Times(4)
422 .WillOnce(Return(1055))
423 .WillOnce(Return(1063))
424 .WillOnce(Return(1063))
425 .WillOnce(Return(1075));
426
427 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700428 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
429 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
430 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700431
432 CountingCallback cb0(mDispatch);
433 CountingCallback cb1(mDispatch);
434
Ady Abraham4335afd2023-12-18 19:10:47 -0800435 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
436 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700437
438 advanceToNextCallback();
439 advanceToNextCallback();
440
441 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
442 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
443 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
444 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
445}
446
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700447TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800448 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700449 .Times(4)
450 .WillOnce(Return(1000))
451 .WillOnce(Return(2000))
452 .WillOnce(Return(2500))
453 .WillOnce(Return(4000));
454
455 Sequence seq;
456 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
457 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
458 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
459
460 CountingCallback cb(mDispatch);
461
Ady Abraham4335afd2023-12-18 19:10:47 -0800462 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 0});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700463
464 advanceToNextCallback();
465
466 ASSERT_THAT(cb.mCalls.size(), Eq(1));
467 EXPECT_THAT(cb.mCalls[0], Eq(1000));
468
Ady Abraham4335afd2023-12-18 19:10:47 -0800469 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700470
471 advanceToNextCallback();
472
473 ASSERT_THAT(cb.mCalls.size(), Eq(2));
474 EXPECT_THAT(cb.mCalls[1], Eq(2000));
475
Ady Abraham4335afd2023-12-18 19:10:47 -0800476 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700477
478 advanceToNextCallback();
479
480 ASSERT_THAT(cb.mCalls.size(), Eq(3));
481 EXPECT_THAT(cb.mCalls[2], Eq(4000));
482}
483
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800484TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800485 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -0700486 .Times(4)
487 .WillOnce(Return(10000))
488 .WillOnce(Return(1000))
489 .WillOnce(Return(10000))
490 .WillOnce(Return(10000));
491
492 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700493 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
494 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
495 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700496
497 CountingCallback cb0(mDispatch);
498 CountingCallback cb1(mDispatch);
499
Ady Abraham4335afd2023-12-18 19:10:47 -0800500 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod * 10});
501 mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
Leon Scroggins III67388622023-02-06 20:36:20 -0500502 mDispatch->cancel(cb1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700503}
504
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800505TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700506 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700507 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
508 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700509
510 CountingCallback cb0(mDispatch);
511 CountingCallback cb1(mDispatch);
512
Ady Abraham4335afd2023-12-18 19:10:47 -0800513 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
514 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
515 mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700516 advanceToNextCallback();
517}
518
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800519TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700520 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700521 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
522 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
523 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700524
525 CountingCallback cb0(mDispatch);
526 CountingCallback cb1(mDispatch);
527
Ady Abraham4335afd2023-12-18 19:10:47 -0800528 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
529 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
530 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700531 advanceToNextCallback();
532}
533
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800534TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700535 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700536 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
537 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
538 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
539 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700540
541 auto offset = 400;
542 auto closeOffset = offset + mDispatchGroupThreshold - 1;
543 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
544
545 CountingCallback cb0(mDispatch);
546 CountingCallback cb1(mDispatch);
547
Ady Abraham4335afd2023-12-18 19:10:47 -0800548 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
549 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
550 mDispatch->schedule(cb1, {.workDuration = closeOffset, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700551
552 advanceToNextCallback();
553 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
554 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
555 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
556 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
557
Ady Abraham4335afd2023-12-18 19:10:47 -0800558 mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 2000});
Leon Scroggins III67388622023-02-06 20:36:20 -0500559 mDispatch->schedule(cb1,
Ady Abraham4335afd2023-12-18 19:10:47 -0800560 {.workDuration = notCloseOffset, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700561 advanceToNextCallback();
562 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
563 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
564
565 advanceToNextCallback();
566 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
567 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
568}
569
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800570TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700571 Sequence seq;
572 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
573 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
574 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700575 EXPECT_CALL(mMockClock, alarmCancel());
576
577 CountingCallback cb0(mDispatch);
578 CountingCallback cb1(mDispatch);
579
Ady Abraham4335afd2023-12-18 19:10:47 -0800580 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
581 mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700582 advanceToNextCallback();
Leon Scroggins III67388622023-02-06 20:36:20 -0500583 EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
Kevin DuBois305bef12019-10-09 13:23:27 -0700584}
585
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800586TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800587 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -0700588 .Times(3)
589 .WillOnce(Return(950))
590 .WillOnce(Return(1975))
591 .WillOnce(Return(2950));
592
593 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800594 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700595
596 mMockClock.advanceBy(850);
597 EXPECT_THAT(cb.mCalls.size(), Eq(1));
598
Ady Abraham4335afd2023-12-18 19:10:47 -0800599 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700600 mMockClock.advanceBy(900);
601 EXPECT_THAT(cb.mCalls.size(), Eq(1));
602 mMockClock.advanceBy(125);
603 EXPECT_THAT(cb.mCalls.size(), Eq(2));
604
Ady Abraham4335afd2023-12-18 19:10:47 -0800605 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700606 mMockClock.advanceBy(975);
607 EXPECT_THAT(cb.mCalls.size(), Eq(3));
608}
609
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800610TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700611 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700612 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
613 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700614
615 VSyncDispatch::CallbackToken tmp;
Leon Scroggins III67388622023-02-06 20:36:20 -0500616 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700617 [&](auto, auto, auto) {
Leon Scroggins III67388622023-02-06 20:36:20 -0500618 mDispatch->schedule(tmp,
Ady Abraham4335afd2023-12-18 19:10:47 -0800619 {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abraham9c53ee72020-07-22 21:16:18 -0700620 },
621 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700622
Ady Abraham4335afd2023-12-18 19:10:47 -0800623 mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700624 advanceToNextCallback();
625}
626
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800627TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700628 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800629 std::optional<nsecs_t> lastTarget;
Leon Scroggins III67388622023-02-06 20:36:20 -0500630 tmp = mDispatch->registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700631 [&](auto timestamp, auto, auto) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800632 auto result = mDispatch->schedule(tmp,
633 {.workDuration = 400,
634 .readyDuration = 0,
635 .lastVsync = timestamp - mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700636 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800637 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
638 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
Leon Scroggins III67388622023-02-06 20:36:20 -0500639 result = mDispatch->schedule(tmp,
640 {.workDuration = 400,
641 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800642 .lastVsync = timestamp});
Leon Scroggins III67388622023-02-06 20:36:20 -0500643 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800644 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
645 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
Leon Scroggins III67388622023-02-06 20:36:20 -0500646 result = mDispatch->schedule(tmp,
647 {.workDuration = 400,
648 .readyDuration = 0,
Ady Abraham4335afd2023-12-18 19:10:47 -0800649 .lastVsync = timestamp + mVsyncMoveThreshold});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700650 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800651 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
652 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800653 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700654 },
655 "oo");
656
Ady Abraham4335afd2023-12-18 19:10:47 -0800657 mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700658 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800659 EXPECT_THAT(lastTarget, Eq(1000));
660
661 advanceToNextCallback();
662 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700663}
664
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800665TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700666 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700667 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
668 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
669 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
670 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700671
672 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800673 mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700674
675 mMockClock.advanceBy(750);
Ady Abraham4335afd2023-12-18 19:10:47 -0800676 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700677
678 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800679 mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700680
681 mMockClock.advanceBy(800);
Ady Abraham4335afd2023-12-18 19:10:47 -0800682 mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700683}
684
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800685TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700686 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700687 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
688 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
689 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
690 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700691
692 CountingCallback cb0(mDispatch);
693 CountingCallback cb1(mDispatch);
694
Ady Abraham4335afd2023-12-18 19:10:47 -0800695 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
696 mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700697
698 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800699 mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .lastVsync = 2000});
700 mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700701
702 advanceToNextCallback();
703 advanceToNextCallback();
704}
705
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800706TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700707 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700708 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700709
710 CountingCallback cb0(mDispatch);
711 CountingCallback cb1(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800712 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
713 mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700714}
715
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800716TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700717 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700718 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700719 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700720 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700721
722 CountingCallback cb0(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -0800723 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Leon Scroggins III67388622023-02-06 20:36:20 -0500724 mDispatch->cancel(cb0);
Ady Abraham4335afd2023-12-18 19:10:47 -0800725 mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700726}
727
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800728TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700729 VSyncDispatch::CallbackToken token(100);
Leon Scroggins III67388622023-02-06 20:36:20 -0500730 EXPECT_FALSE(
Ady Abraham4335afd2023-12-18 19:10:47 -0800731 mDispatch->schedule(token, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000})
Leon Scroggins III67388622023-02-06 20:36:20 -0500732 .has_value());
733 EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
Kevin DuBois305bef12019-10-09 13:23:27 -0700734}
735
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800736TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700737 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700738 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800739 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700740 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800741 EXPECT_EQ(500, result->callbackTime.ns());
742 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham4335afd2023-12-18 19:10:47 -0800743 result = mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700744 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800745 EXPECT_EQ(900, result->callbackTime.ns());
746 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800747}
748
749// b/1450138150
750TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahambf554892024-02-14 18:18:21 +0000751 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -0700752
Ady Abrahamb491c902020-08-15 15:47:56 -0700753 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800754 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700755 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800756 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700757 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800758 EXPECT_EQ(500, result->callbackTime.ns());
759 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800760 mMockClock.advanceBy(400);
761
Ady Abraham4335afd2023-12-18 19:10:47 -0800762 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700763 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800764 EXPECT_EQ(1200, result->callbackTime.ns());
765 EXPECT_EQ(2000, result->vsyncTime.ns());
Ady Abraham3e019972023-10-20 13:23:48 -0700766
767 advanceToNextCallback();
768 ASSERT_THAT(cb.mCalls.size(), Eq(1));
769}
770
771// b/1450138150
772TEST_F(VSyncDispatchTimerQueueTest, movesCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahambf554892024-02-14 18:18:21 +0000773 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -0700774
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700775 Sequence seq;
776 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
777 EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700778 CountingCallback cb(mDispatch);
779 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800780 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700781 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800782 EXPECT_EQ(500, result->callbackTime.ns());
783 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham3e019972023-10-20 13:23:48 -0700784 mMockClock.advanceBy(400);
785
Ady Abraham4335afd2023-12-18 19:10:47 -0800786 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700787 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800788 EXPECT_EQ(400, result->callbackTime.ns());
789 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham3e019972023-10-20 13:23:48 -0700790
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800791 advanceToNextCallback();
792 ASSERT_THAT(cb.mCalls.size(), Eq(1));
793}
794
795TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
Ady Abraham4335afd2023-12-18 19:10:47 -0800796 EXPECT_CALL(*mStubTracker.get(),
797 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800798 .Times(2)
799 .WillOnce(Return(1000))
800 .WillOnce(Return(1002));
801 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700802 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800803 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700804 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800805 EXPECT_EQ(500, result->callbackTime.ns());
806 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800807 mMockClock.advanceBy(400);
Ady Abraham4335afd2023-12-18 19:10:47 -0800808 result = mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700809 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800810 EXPECT_EQ(602, result->callbackTime.ns());
811 EXPECT_EQ(1002, result->vsyncTime.ns());
Kevin DuBois305bef12019-10-09 13:23:27 -0700812}
813
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800814TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
815 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700816 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800817 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700818 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800819 EXPECT_EQ(500, result->callbackTime.ns());
820 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800821 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800822 result =
823 mDispatch->schedule(cb0, {.workDuration = 1100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700824 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800825 EXPECT_EQ(900, result->callbackTime.ns());
826 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800827}
828
829TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
830 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700831 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
832 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800833 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700834 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800835 mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700836 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800837 EXPECT_EQ(500, result->callbackTime.ns());
838 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800839 advanceToNextCallback();
Ady Abraham4335afd2023-12-18 19:10:47 -0800840 result =
841 mDispatch->schedule(cb0, {.workDuration = 1900, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700842 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800843 EXPECT_EQ(1100, result->callbackTime.ns());
844 EXPECT_EQ(3000, result->vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800845}
846
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800847TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahambf554892024-02-14 18:18:21 +0000848 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -0700849
Ady Abrahamb491c902020-08-15 15:47:56 -0700850 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800851
852 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700853 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800854 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700855 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800856 EXPECT_EQ(600, result->callbackTime.ns());
857 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800858
Ady Abraham4335afd2023-12-18 19:10:47 -0800859 result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700860 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800861 EXPECT_EQ(600, result->callbackTime.ns());
862 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800863
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800864 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800865}
866
Ady Abraham3e019972023-10-20 13:23:48 -0700867TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
Ady Abrahambf554892024-02-14 18:18:21 +0000868 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -0700869
Ady Abrahamb0d3d982023-10-30 11:29:51 -0700870 Sequence seq;
871 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
872 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -0700873
874 CountingCallback cb(mDispatch);
875 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800876 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700877 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800878 EXPECT_EQ(600, result->callbackTime.ns());
879 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham3e019972023-10-20 13:23:48 -0700880
Ady Abraham4335afd2023-12-18 19:10:47 -0800881 result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -0700882 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800883 EXPECT_EQ(0, result->callbackTime.ns());
884 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham3e019972023-10-20 13:23:48 -0700885
886 advanceToNextCallback();
887}
888
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800889TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700890 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700891 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
892
893 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700894 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700895 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham4335afd2023-12-18 19:10:47 -0800896 cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700897 cb.cancel();
898
Ady Abraham4335afd2023-12-18 19:10:47 -0800899 cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700900 cb1.cancel();
901}
902
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800903TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700904 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700905 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
906
907 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700908 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700909 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700910 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700911 cb1 = std::move(cb);
Ady Abraham4335afd2023-12-18 19:10:47 -0800912 cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700913 cb.cancel();
914
Ady Abraham4335afd2023-12-18 19:10:47 -0800915 cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700916 cb1.cancel();
917}
918
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700919// b/154303580
920TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
921 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700922 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
923 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700924 CountingCallback cb1(mDispatch);
925 CountingCallback cb2(mDispatch);
926
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700927 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800928 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700929 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800930 EXPECT_EQ(600, result->callbackTime.ns());
931 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700932
933 mMockClock.setLag(100);
934 mMockClock.advanceBy(620);
935
Ady Abraham4335afd2023-12-18 19:10:47 -0800936 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700937 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800938 EXPECT_EQ(1900, result->callbackTime.ns());
939 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700940 mMockClock.advanceBy(80);
941
942 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
943 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
944}
945
946// b/154303580.
947// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
948// update later, as opposed to blocking the calling thread.
949TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000950 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
951
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700952 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700953 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
954 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700955 CountingCallback cb(mDispatch);
956
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700957 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -0800958 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700959 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800960 EXPECT_EQ(600, result->callbackTime.ns());
961 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700962
963 mMockClock.setLag(100);
964 mMockClock.advanceBy(620);
965
Ady Abraham4335afd2023-12-18 19:10:47 -0800966 result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700967 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800968 EXPECT_EQ(1630, result->callbackTime.ns());
969 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700970 mMockClock.advanceBy(80);
971
972 EXPECT_THAT(cb.mCalls.size(), Eq(1));
973}
974
Kevin DuBoisb340b732020-06-16 09:07:35 -0700975// b/154303580.
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000976// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
977// update later, as opposed to blocking the calling thread.
978TEST_F(VSyncDispatchTimerQueueTest, doesntSkipSchedulingIfTimerReschedulingIsImminentSameCallback) {
979 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
980
981 Sequence seq;
982 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
983 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
984 CountingCallback cb(mDispatch);
985
986 auto result =
987 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
988 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800989 EXPECT_EQ(600, result->callbackTime.ns());
990 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000991
992 mMockClock.setLag(100);
993 mMockClock.advanceBy(620);
994
995 result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
996 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -0800997 EXPECT_EQ(600, result->callbackTime.ns());
998 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abrahamda8af4c2024-02-14 00:24:34 +0000999 mMockClock.advanceBy(80);
1000
1001 ASSERT_EQ(1, cb.mCalls.size());
1002 EXPECT_EQ(1000, cb.mCalls[0]);
1003
1004 ASSERT_EQ(1, cb.mWakeupTime.size());
1005 EXPECT_EQ(600, cb.mWakeupTime[0]);
1006}
1007
1008// b/154303580.
Kevin DuBoisb340b732020-06-16 09:07:35 -07001009TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
1010 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -07001011 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001012 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1013 CountingCallback cb1(mDispatch);
1014 CountingCallback cb2(mDispatch);
1015
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001016 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001017 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001018 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001019 EXPECT_EQ(600, result->callbackTime.ns());
1020 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham4335afd2023-12-18 19:10:47 -08001021 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001022 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001023 EXPECT_EQ(1900, result->callbackTime.ns());
1024 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBoisb340b732020-06-16 09:07:35 -07001025
1026 mMockClock.setLag(100);
1027 mMockClock.advanceBy(620);
1028
Leon Scroggins III67388622023-02-06 20:36:20 -05001029 EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001030
1031 mMockClock.advanceBy(80);
1032
1033 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
1034 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1035}
1036
1037TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
1038 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -07001039 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1040 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001041 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1042 CountingCallback cb1(mDispatch);
1043 CountingCallback cb2(mDispatch);
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());
ramindani32a88b12024-01-31 18:45:30 -08001048 EXPECT_EQ(600, result->callbackTime.ns());
1049 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham4335afd2023-12-18 19:10:47 -08001050 result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001051 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001052 EXPECT_EQ(1900, result->callbackTime.ns());
1053 EXPECT_EQ(2000, result->vsyncTime.ns());
Kevin DuBoisb340b732020-06-16 09:07:35 -07001054
1055 mMockClock.setLag(100);
1056 mMockClock.advanceBy(620);
1057
Leon Scroggins III67388622023-02-06 20:36:20 -05001058 EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
Kevin DuBoisb340b732020-06-16 09:07:35 -07001059
1060 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1061 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1062 mMockClock.advanceToNextCallback();
1063
1064 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1065 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1066}
1067
Kevin DuBoisf9477832020-07-16 10:21:36 -07001068TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1069 CountingCallback cb1(mDispatch);
1070 CountingCallback cb2(mDispatch);
1071
1072 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001073 EXPECT_CALL(*mStubTracker.get(),
1074 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001075 .InSequence(seq)
1076 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -07001077 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abraham4335afd2023-12-18 19:10:47 -08001078 EXPECT_CALL(*mStubTracker.get(),
1079 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
Kevin DuBoisf9477832020-07-16 10:21:36 -07001080 .InSequence(seq)
1081 .WillOnce(Return(1000));
1082
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001083 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001084 mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001085 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001086 EXPECT_EQ(600, result->callbackTime.ns());
1087 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham4335afd2023-12-18 19:10:47 -08001088 result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001089 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001090 EXPECT_EQ(610, result->callbackTime.ns());
1091 EXPECT_EQ(1000, result->vsyncTime.ns());
Kevin DuBoisf9477832020-07-16 10:21:36 -07001092
1093 mMockClock.setLag(100);
1094 mMockClock.advanceBy(700);
1095
1096 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1097 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001098 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1099 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -07001100 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1101 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001102 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1103 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1104}
1105
1106TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1107 auto intended = mPeriod - 230;
1108 EXPECT_CALL(mMockClock, alarmAt(_, 900));
1109
1110 CountingCallback cb(mDispatch);
Ady Abraham4335afd2023-12-18 19:10:47 -08001111 const auto result =
1112 mDispatch->schedule(cb,
1113 {.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001114 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001115 EXPECT_EQ(900, result->callbackTime.ns());
1116 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001117 advanceToNextCallback();
1118
1119 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1120 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1121 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1122 EXPECT_THAT(cb.mWakeupTime[0], 900);
1123 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1124 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -07001125}
1126
Ady Abraham69b9e622021-07-19 12:24:31 -07001127TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
Ady Abrahambf554892024-02-14 18:18:21 +00001128 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham3e019972023-10-20 13:23:48 -07001129
Ady Abraham69b9e622021-07-19 12:24:31 -07001130 Sequence seq;
1131 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1132
1133 CountingCallback cb(mDispatch);
1134
Ady Abraham4335afd2023-12-18 19:10:47 -08001135 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1136 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham69b9e622021-07-19 12:24:31 -07001137
1138 advanceToNextCallback();
1139
1140 advanceToNextCallback();
1141
1142 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1143 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1144 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1145 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1146 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1147 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1148}
1149
Ady Abraham3e019972023-10-20 13:23:48 -07001150TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
Ady Abrahambf554892024-02-14 18:18:21 +00001151 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham3e019972023-10-20 13:23:48 -07001152
1153 Sequence seq;
1154 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001155 EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
Ady Abraham3e019972023-10-20 13:23:48 -07001156
1157 CountingCallback cb(mDispatch);
1158
Ady Abraham4335afd2023-12-18 19:10:47 -08001159 mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1160 mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham3e019972023-10-20 13:23:48 -07001161
1162 advanceToNextCallback();
1163
1164 advanceToNextCallback();
1165
1166 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1167 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1168 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001169 EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
Ady Abraham3e019972023-10-20 13:23:48 -07001170 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1171 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1172}
1173
Ady Abraham529bd9f2023-10-05 14:55:30 -07001174TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
Ady Abrahambf554892024-02-14 18:18:21 +00001175 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001176
1177 EXPECT_CALL(mMockClock, alarmAt(_, 500));
1178 CountingCallback cb(mDispatch);
1179 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001180 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001181 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001182 EXPECT_EQ(500, result->callbackTime.ns());
1183 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham529bd9f2023-10-05 14:55:30 -07001184 mMockClock.advanceBy(300);
1185
Ady Abraham4335afd2023-12-18 19:10:47 -08001186 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001187 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001188 EXPECT_EQ(1200, result->callbackTime.ns());
1189 EXPECT_EQ(2000, result->vsyncTime.ns());
Ady Abraham529bd9f2023-10-05 14:55:30 -07001190
1191 advanceToNextCallback();
1192 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1193}
1194
Ady Abraham529bd9f2023-10-05 14:55:30 -07001195TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
Ady Abrahambf554892024-02-14 18:18:21 +00001196 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001197
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001198 Sequence seq;
1199 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1200 EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
Ady Abraham529bd9f2023-10-05 14:55:30 -07001201 CountingCallback cb(mDispatch);
1202 auto result =
Ady Abraham4335afd2023-12-18 19:10:47 -08001203 mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001204 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001205 EXPECT_EQ(500, result->callbackTime.ns());
1206 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham529bd9f2023-10-05 14:55:30 -07001207 mMockClock.advanceBy(300);
1208
Ady Abraham4335afd2023-12-18 19:10:47 -08001209 result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
Ady Abraham529bd9f2023-10-05 14:55:30 -07001210 EXPECT_TRUE(result.has_value());
ramindani32a88b12024-01-31 18:45:30 -08001211 EXPECT_EQ(300, result->callbackTime.ns());
1212 EXPECT_EQ(1000, result->vsyncTime.ns());
Ady Abraham529bd9f2023-10-05 14:55:30 -07001213
1214 advanceToNextCallback();
1215 ASSERT_THAT(cb.mCalls.size(), Eq(1));
Ady Abrahamb0d3d982023-10-30 11:29:51 -07001216 EXPECT_THAT(cb.mCalls[0], Eq(1000));
1217 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1218 EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1219 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1220 EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
Ady Abraham529bd9f2023-10-05 14:55:30 -07001221}
1222
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001223class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001224protected:
1225 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001226 nsecs_t const mVsyncMoveThreshold = 200;
Leon Scroggins III67388622023-02-06 20:36:20 -05001227 std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1228 std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
Kevin DuBois305bef12019-10-09 13:23:27 -07001229};
1230
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001231TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001232 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001233 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001234 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001235 EXPECT_THAT(entry.name(), Eq(name));
1236 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1237 EXPECT_FALSE(entry.wakeupTime());
1238}
1239
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001240TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
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());
ramindani558f4a92024-02-16 15:49:23 -08001245 const auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001246 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1247 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001248 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1249 EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001250 auto const wakeup = entry.wakeupTime();
1251 ASSERT_TRUE(wakeup);
1252 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001253
1254 entry.disarm();
1255 EXPECT_FALSE(entry.wakeupTime());
1256}
1257
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001258TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001259 auto const duration = 500;
1260 auto const now = 8750;
1261
Ady Abraham4335afd2023-12-18 19:10:47 -08001262 EXPECT_CALL(*mStubTracker.get(),
1263 nextAnticipatedVSyncTimeFrom(now + duration, std::optional<nsecs_t>(994)))
Kevin DuBois305bef12019-10-09 13:23:27 -07001264 .Times(1)
1265 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001266 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001267 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001268
1269 EXPECT_FALSE(entry.wakeupTime());
ramindani558f4a92024-02-16 15:49:23 -08001270 const auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001271 entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
1272 *mStubTracker, now);
ramindani558f4a92024-02-16 15:49:23 -08001273 EXPECT_EQ(9500, scheduleResult.callbackTime.ns());
1274 EXPECT_EQ(10000, scheduleResult.vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001275 auto const wakeup = entry.wakeupTime();
1276 ASSERT_TRUE(wakeup);
1277 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001278}
1279
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001280TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001281 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001282 auto vsyncCalledTime = 0;
1283 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001284 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001285 VSyncDispatchTimerQueueEntry entry(
1286 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001287 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001288 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001289 vsyncCalledTime = vsyncTime;
1290 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001291 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001292 },
1293 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001294
ramindani558f4a92024-02-16 15:49:23 -08001295 const auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001296 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1297 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001298 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1299 EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001300 auto const wakeup = entry.wakeupTime();
1301 ASSERT_TRUE(wakeup);
1302 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001303
Ady Abraham9c53ee72020-07-22 21:16:18 -07001304 auto const ready = entry.readyTime();
1305 ASSERT_TRUE(ready);
1306 EXPECT_THAT(*ready, Eq(1000));
1307
1308 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001309
1310 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001311 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1312 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001313 EXPECT_FALSE(entry.wakeupTime());
1314 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1315 ASSERT_TRUE(lastCalledTarget);
1316 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1317}
1318
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001319TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Ady Abraham4335afd2023-12-18 19:10:47 -08001320 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
Kevin DuBois305bef12019-10-09 13:23:27 -07001321 .Times(2)
1322 .WillOnce(Return(1000))
1323 .WillOnce(Return(1020));
1324
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001325 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001326 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001327
1328 EXPECT_FALSE(entry.wakeupTime());
ramindani32a88b12024-01-31 18:45:30 -08001329 entry.update(*mStubTracker, 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001330 EXPECT_FALSE(entry.wakeupTime());
1331
ramindani558f4a92024-02-16 15:49:23 -08001332 const auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001333 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1334 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001335 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1336 EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001337 auto wakeup = entry.wakeupTime();
1338 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001339 EXPECT_THAT(wakeup, Eq(900));
1340
ramindani32a88b12024-01-31 18:45:30 -08001341 entry.update(*mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001342 wakeup = entry.wakeupTime();
1343 ASSERT_TRUE(wakeup);
1344 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001345}
1346
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001347TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001348 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001349 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
ramindani558f4a92024-02-16 15:49:23 -08001350 EXPECT_EQ(900,
1351 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1352 *mStubTracker.get(), 0)
1353 .callbackTime.ns());
Leon Scroggins III67388622023-02-06 20:36:20 -05001354 entry.update(*mStubTracker.get(), 0);
Kevin DuBois305bef12019-10-09 13:23:27 -07001355
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001356 auto const wakeup = entry.wakeupTime();
1357 ASSERT_TRUE(wakeup);
1358 EXPECT_THAT(*wakeup, Eq(wakeup));
1359}
1360
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001361TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1362 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001363 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
ramindani558f4a92024-02-16 15:49:23 -08001364 auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001365 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1366 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001367
1368 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1369 EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001370 entry.executing(); // 1000 is executing
1371 // had 1000 not been executing, this could have been scheduled for time 800.
ramindani558f4a92024-02-16 15:49:23 -08001372 scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1373 *mStubTracker, 0);
1374 EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1375 EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001376 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001377 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001378
ramindani558f4a92024-02-16 15:49:23 -08001379 scheduleResult = entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
1380 *mStubTracker, 0);
1381 EXPECT_EQ(1950, scheduleResult.callbackTime.ns());
1382 EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001383 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001384 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001385
ramindani558f4a92024-02-16 15:49:23 -08001386 scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
1387 *mStubTracker, 0);
1388 EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1389 EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001390 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001391 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001392}
1393
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001394TEST_F(VSyncDispatchTimerQueueEntryTest,
1395 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1396 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001397 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001398
1399 Sequence seq;
Ady Abraham4335afd2023-12-18 19:10:47 -08001400 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001401 .InSequence(seq)
1402 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001403 EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001404 .InSequence(seq)
1405 .WillOnce(Return(1000));
Ady Abraham4335afd2023-12-18 19:10:47 -08001406 EXPECT_CALL(*mStubTracker.get(),
1407 nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold,
1408 std::optional<nsecs_t>(1000)))
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001409 .InSequence(seq)
1410 .WillOnce(Return(2000));
1411
ramindani558f4a92024-02-16 15:49:23 -08001412 auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001413 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1414 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001415 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1416 EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001417
1418 entry.executing(); // 1000 is executing
1419
ramindani558f4a92024-02-16 15:49:23 -08001420 scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1421 *mStubTracker, 0);
1422 EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1423 EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001424}
1425
1426TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
ramindani558f4a92024-02-16 15:49:23 -08001427 VSyncDispatchTimerQueueEntry entry("test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1428 EXPECT_EQ(900,
1429 entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1430 *mStubTracker, 0)
1431 .callbackTime.ns());
1432 EXPECT_EQ(800,
1433 entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1434 *mStubTracker, 0)
1435 .callbackTime.ns());
1436 EXPECT_EQ(950,
1437 entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
1438 *mStubTracker, 0)
1439 .callbackTime.ns());
1440 {
1441 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
1442 EXPECT_EQ(0,
1443 entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
1444 *mStubTracker, 0)
1445 .callbackTime.ns());
1446 }
1447 {
1448 SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
1449 EXPECT_EQ(800,
1450 entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
1451 *mStubTracker, 0)
1452 .callbackTime.ns());
1453 }
Kevin DuBois305bef12019-10-09 13:23:27 -07001454}
1455
Ady Abrahamda8af4c2024-02-14 00:24:34 +00001456TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdateAndDontSkip) {
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001457 static constexpr auto effectualOffset = 200;
1458 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001459 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001460 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abrahamda8af4c2024-02-14 00:24:34 +00001461 entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1462 {.workDuration = 100, .readyDuration = 0, .lastVsync = 400});
1463 entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1464 {.workDuration = effectualOffset,
1465 .readyDuration = 0,
1466 .lastVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001467 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
ramindani32a88b12024-01-31 18:45:30 -08001468 entry.update(*mStubTracker, 0);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001469 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1470 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1471}
1472
Ady Abraham9c53ee72020-07-22 21:16:18 -07001473TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1474 auto callCount = 0;
1475 auto vsyncCalledTime = 0;
1476 auto wakeupCalledTime = 0;
1477 auto readyCalledTime = 0;
1478 VSyncDispatchTimerQueueEntry entry(
1479 "test",
1480 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1481 callCount++;
1482 vsyncCalledTime = vsyncTime;
1483 wakeupCalledTime = wakeupTime;
1484 readyCalledTime = readyTime;
1485 },
1486 mVsyncMoveThreshold);
1487
ramindani558f4a92024-02-16 15:49:23 -08001488 const auto scheduleResult =
ramindani32a88b12024-01-31 18:45:30 -08001489 entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
1490 *mStubTracker, 0);
ramindani558f4a92024-02-16 15:49:23 -08001491 EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1492 EXPECT_EQ(mPeriod, scheduleResult.vsyncTime.ns());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001493 auto const wakeup = entry.wakeupTime();
1494 ASSERT_TRUE(wakeup);
1495 EXPECT_THAT(*wakeup, Eq(900));
1496
1497 auto const ready = entry.readyTime();
1498 ASSERT_TRUE(ready);
1499 EXPECT_THAT(*ready, Eq(970));
1500
1501 entry.callback(entry.executing(), *wakeup, *ready);
1502
1503 EXPECT_THAT(callCount, Eq(1));
1504 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1505 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1506 EXPECT_FALSE(entry.wakeupTime());
1507 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1508 ASSERT_TRUE(lastCalledTarget);
1509 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1510}
1511
Kevin DuBois305bef12019-10-09 13:23:27 -07001512} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001513
1514// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001515#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"