blob: f66075362e8b13afa0e274710eb6786e05e491ea [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
33#include "Scheduler/VSyncDispatchTimerQueue.h"
34#include "Scheduler/VSyncTracker.h"
Kevin DuBois305bef12019-10-09 13:23:27 -070035
36using namespace testing;
37using namespace std::literals;
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080038
Kevin DuBois305bef12019-10-09 13:23:27 -070039namespace android::scheduler {
40
41class MockVSyncTracker : public VSyncTracker {
42public:
43 MockVSyncTracker(nsecs_t period) : mPeriod{period} {
44 ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
45 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
Kevin DuBois02d5ed92020-01-27 11:05:46 -080046 ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070047 ON_CALL(*this, currentPeriod())
48 .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -070049 }
50
Kevin DuBois02d5ed92020-01-27 11:05:46 -080051 MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
Kevin DuBois305bef12019-10-09 13:23:27 -070052 MOCK_CONST_METHOD1(nextAnticipatedVSyncTimeFrom, nsecs_t(nsecs_t));
Kevin DuBois2fd3cea2019-11-14 08:52:45 -080053 MOCK_CONST_METHOD0(currentPeriod, nsecs_t());
Kevin DuBoisee2ad9f2019-11-21 11:10:57 -080054 MOCK_METHOD1(setPeriod, void(nsecs_t));
Kevin DuBoisc3e9e8e2020-01-07 09:06:52 -080055 MOCK_METHOD0(resetModel, void());
Kevin DuBoisb818bfa2020-07-10 14:29:36 -070056 MOCK_CONST_METHOD0(needsMoreSamples, bool());
Ady Abraham5cc2e262021-03-25 13:09:17 -070057 MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
Ady Abraham5e7371c2020-03-24 14:47:24 -070058 MOCK_CONST_METHOD1(dump, void(std::string&));
Kevin DuBois305bef12019-10-09 13:23:27 -070059
60 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
61 if (timePoint % mPeriod == 0) {
62 return timePoint;
63 }
64 return (timePoint - (timePoint % mPeriod) + mPeriod);
65 }
66
Ady Abraham3fcfd8b2022-07-12 12:31:00 -070067 nsecs_t getCurrentPeriod() const { return mPeriod; }
68
Kevin DuBois305bef12019-10-09 13:23:27 -070069protected:
70 nsecs_t const mPeriod;
71};
72
73class ControllableClock : public TimeKeeper {
74public:
75 ControllableClock() {
Ady Abrahamb491c902020-08-15 15:47:56 -070076 ON_CALL(*this, alarmAt(_, _))
77 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
Kevin DuBois305bef12019-10-09 13:23:27 -070078 ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
79 }
80
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -080081 MOCK_METHOD(nsecs_t, now, (), (const));
82 MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
83 MOCK_METHOD(void, alarmCancel, (), (override));
84 MOCK_METHOD(void, dump, (std::string&), (const, override));
Kevin DuBois305bef12019-10-09 13:23:27 -070085
Ady Abrahamb491c902020-08-15 15:47:56 -070086 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
Kevin DuBois305bef12019-10-09 13:23:27 -070087 mCallback = callback;
Ady Abrahamb491c902020-08-15 15:47:56 -070088 mNextCallbackTime = time;
Kevin DuBois305bef12019-10-09 13:23:27 -070089 }
90
91 nsecs_t fakeTime() const { return mCurrentTime; }
92
93 void advanceToNextCallback() {
94 mCurrentTime = mNextCallbackTime;
95 if (mCallback) {
96 mCallback();
97 }
98 }
99
100 void advanceBy(nsecs_t advancement) {
101 mCurrentTime += advancement;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700102 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700103 mCallback();
104 }
105 };
106
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700107 void setLag(nsecs_t lag) { mLag = lag; }
108
Kevin DuBois305bef12019-10-09 13:23:27 -0700109private:
110 std::function<void()> mCallback;
111 nsecs_t mNextCallbackTime = 0;
112 nsecs_t mCurrentTime = 0;
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700113 nsecs_t mLag = 0;
Kevin DuBois305bef12019-10-09 13:23:27 -0700114};
115
116class CountingCallback {
117public:
118 CountingCallback(VSyncDispatch& dispatch)
119 : mDispatch(dispatch),
120 mToken(dispatch.registerCallback(std::bind(&CountingCallback::counter, this,
Ady Abraham9c53ee72020-07-22 21:16:18 -0700121 std::placeholders::_1, std::placeholders::_2,
122 std::placeholders::_3),
Kevin DuBois305bef12019-10-09 13:23:27 -0700123 "test")) {}
124 ~CountingCallback() { mDispatch.unregisterCallback(mToken); }
125
126 operator VSyncDispatch::CallbackToken() const { return mToken; }
127
Ady Abraham9c53ee72020-07-22 21:16:18 -0700128 void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
Kevin DuBoisf9477832020-07-16 10:21:36 -0700129 mCalls.push_back(time);
130 mWakeupTime.push_back(wakeup_time);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700131 mReadyTime.push_back(readyTime);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700132 }
Kevin DuBois305bef12019-10-09 13:23:27 -0700133
134 VSyncDispatch& mDispatch;
135 VSyncDispatch::CallbackToken mToken;
136 std::vector<nsecs_t> mCalls;
Kevin DuBoisf9477832020-07-16 10:21:36 -0700137 std::vector<nsecs_t> mWakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700138 std::vector<nsecs_t> mReadyTime;
Kevin DuBois305bef12019-10-09 13:23:27 -0700139};
140
141class PausingCallback {
142public:
143 PausingCallback(VSyncDispatch& dispatch, std::chrono::milliseconds pauseAmount)
144 : mDispatch(dispatch),
145 mToken(dispatch.registerCallback(std::bind(&PausingCallback::pause, this,
Kevin DuBois2968afc2020-01-14 09:48:50 -0800146 std::placeholders::_1,
147 std::placeholders::_2),
Kevin DuBois305bef12019-10-09 13:23:27 -0700148 "test")),
149 mRegistered(true),
150 mPauseAmount(pauseAmount) {}
151 ~PausingCallback() { unregister(); }
152
153 operator VSyncDispatch::CallbackToken() const { return mToken; }
154
Kevin DuBois2968afc2020-01-14 09:48:50 -0800155 void pause(nsecs_t, nsecs_t) {
Ady Abraham8cb21882020-08-26 18:22:05 -0700156 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700157 mPause = true;
158 mCv.notify_all();
159
Ady Abraham8cb21882020-08-26 18:22:05 -0700160 mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700161
162 mResourcePresent = (mResource.lock() != nullptr);
163 }
164
165 bool waitForPause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700166 std::unique_lock lock(mMutex);
167 auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
Kevin DuBois305bef12019-10-09 13:23:27 -0700168 return waiting;
169 }
170
171 void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
172
173 bool resourcePresent() { return mResourcePresent; }
174
175 void unpause() {
Ady Abraham8cb21882020-08-26 18:22:05 -0700176 std::unique_lock lock(mMutex);
Kevin DuBois305bef12019-10-09 13:23:27 -0700177 mPause = false;
178 mCv.notify_all();
179 }
180
181 void unregister() {
182 if (mRegistered) {
183 mDispatch.unregisterCallback(mToken);
184 mRegistered = false;
185 }
186 }
187
188 VSyncDispatch& mDispatch;
189 VSyncDispatch::CallbackToken mToken;
190 bool mRegistered = true;
191
192 std::mutex mMutex;
193 std::condition_variable mCv;
194 bool mPause = false;
195 std::weak_ptr<void> mResource;
196 bool mResourcePresent = false;
197 std::chrono::milliseconds const mPauseAmount;
198};
199
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800200class VSyncDispatchTimerQueueTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -0700201protected:
202 std::unique_ptr<TimeKeeper> createTimeKeeper() {
203 class TimeKeeperWrapper : public TimeKeeper {
204 public:
205 TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800206
Kevin DuBois305bef12019-10-09 13:23:27 -0700207 nsecs_t now() const final { return mControllableClock.now(); }
Dominik Laskowski4e0d20d2021-12-06 11:31:02 -0800208
209 void alarmAt(std::function<void()> callback, nsecs_t time) final {
210 mControllableClock.alarmAt(std::move(callback), time);
211 }
212
213 void alarmCancel() final { mControllableClock.alarmCancel(); }
Ady Abraham75398722020-04-07 14:08:45 -0700214 void dump(std::string&) const final {}
Kevin DuBois305bef12019-10-09 13:23:27 -0700215
216 private:
217 TimeKeeper& mControllableClock;
218 };
219 return std::make_unique<TimeKeeperWrapper>(mMockClock);
220 }
221
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800222 ~VSyncDispatchTimerQueueTest() {
Kevin DuBois305bef12019-10-09 13:23:27 -0700223 // destructor of dispatch will cancelAlarm(). Ignore final cancel in common test.
224 Mock::VerifyAndClearExpectations(&mMockClock);
225 }
226
227 void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
228
229 NiceMock<ControllableClock> mMockClock;
230 static nsecs_t constexpr mDispatchGroupThreshold = 5;
231 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800232 nsecs_t const mVsyncMoveThreshold = 300;
Kevin DuBois305bef12019-10-09 13:23:27 -0700233 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800234 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
235 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700236};
237
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800238TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700239 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700240 EXPECT_CALL(mMockClock, alarmCancel());
241 {
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800242 VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold,
243 mVsyncMoveThreshold};
Kevin DuBois305bef12019-10-09 13:23:27 -0700244 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700245 const auto result = mDispatch.schedule(cb,
246 {.workDuration = 100,
247 .readyDuration = 0,
248 .earliestVsync = 1000});
249 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 Abrahamb5d3afa2021-05-07 11:22:23 -0700259 const auto result = mDispatch.schedule(cb,
260 {.workDuration = 100,
261 .readyDuration = 0,
262 .earliestVsync = intended});
263 EXPECT_TRUE(result.has_value());
264 EXPECT_EQ(900, *result);
265
Kevin DuBois305bef12019-10-09 13:23:27 -0700266 advanceToNextCallback();
267
268 ASSERT_THAT(cb.mCalls.size(), Eq(1));
269 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
270}
271
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800272TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700273 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
Ady Abrahamb491c902020-08-15 15:47:56 -0700274 EXPECT_CALL(mMockClock, alarmAt(_, 1050));
Kevin DuBois305bef12019-10-09 13:23:27 -0700275
276 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700277 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700278 advanceToNextCallback();
279
280 ASSERT_THAT(cb.mCalls.size(), Eq(1));
281 EXPECT_THAT(cb.mCalls[0], Eq(1150));
282}
283
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800284TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700285 auto const now = 234;
286 mMockClock.advanceBy(234);
287 auto const workDuration = 10 * mPeriod;
288 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + workDuration))
289 .WillOnce(Return(mPeriod * 11));
Ady Abrahamb491c902020-08-15 15:47:56 -0700290 EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
Kevin DuBois305bef12019-10-09 13:23:27 -0700291
292 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700293 const auto result = mDispatch.schedule(cb,
294 {.workDuration = workDuration,
295 .readyDuration = 0,
296 .earliestVsync = mPeriod});
297 EXPECT_TRUE(result.has_value());
298 EXPECT_EQ(mPeriod, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700299}
300
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800301TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700302 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700303 EXPECT_CALL(mMockClock, alarmCancel());
304
305 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700306 const auto result =
307 mDispatch.schedule(cb,
308 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
309 EXPECT_TRUE(result.has_value());
310 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700311 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled);
312}
313
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800314TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700315 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700316 EXPECT_CALL(mMockClock, alarmCancel());
317
318 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700319 const auto result =
320 mDispatch.schedule(cb,
321 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
322 EXPECT_TRUE(result.has_value());
323 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700324 mMockClock.advanceBy(950);
325 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
326}
327
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800328TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700329 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700330 EXPECT_CALL(mMockClock, alarmCancel());
331
332 PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700333 const auto result =
334 mDispatch.schedule(cb,
335 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
336 EXPECT_TRUE(result.has_value());
337 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700338
339 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
340 EXPECT_TRUE(cb.waitForPause());
341 EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate);
342 cb.unpause();
343 pausingThread.join();
344}
345
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800346TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700347 EXPECT_CALL(mMockClock, alarmAt(_, 900));
Kevin DuBois305bef12019-10-09 13:23:27 -0700348 EXPECT_CALL(mMockClock, alarmCancel());
349
350 auto resource = std::make_shared<int>(110);
351
352 PausingCallback cb(mDispatch, 50ms);
353 cb.stashResource(resource);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700354 const auto result =
355 mDispatch.schedule(cb,
356 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
357 EXPECT_TRUE(result.has_value());
358 EXPECT_EQ(mPeriod - 100, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700359
360 std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
361 EXPECT_TRUE(cb.waitForPause());
362
363 cb.unregister();
364 resource.reset();
365
366 cb.unpause();
367 pausingThread.join();
368
369 EXPECT_TRUE(cb.resourcePresent());
370}
371
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800372TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700373 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
374 .Times(4)
375 .WillOnce(Return(1055))
376 .WillOnce(Return(1063))
377 .WillOnce(Return(1063))
378 .WillOnce(Return(1075));
379
380 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700381 EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
382 EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
383 EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700384
385 CountingCallback cb0(mDispatch);
386 CountingCallback cb1(mDispatch);
387
Ady Abraham9c53ee72020-07-22 21:16:18 -0700388 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
389 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700390
391 advanceToNextCallback();
392 advanceToNextCallback();
393
394 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
395 EXPECT_THAT(cb0.mCalls[0], Eq(1075));
396 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
397 EXPECT_THAT(cb1.mCalls[0], Eq(1063));
398}
399
Ady Abraham3fcfd8b2022-07-12 12:31:00 -0700400TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
401 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
402 .Times(4)
403 .WillOnce(Return(1000))
404 .WillOnce(Return(2000))
405 .WillOnce(Return(2500))
406 .WillOnce(Return(4000));
407
408 Sequence seq;
409 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
410 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
411 EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
412
413 CountingCallback cb(mDispatch);
414
415 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
416
417 advanceToNextCallback();
418
419 ASSERT_THAT(cb.mCalls.size(), Eq(1));
420 EXPECT_THAT(cb.mCalls[0], Eq(1000));
421
422 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
423
424 advanceToNextCallback();
425
426 ASSERT_THAT(cb.mCalls.size(), Eq(2));
427 EXPECT_THAT(cb.mCalls[1], Eq(2000));
428
429 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
430
431 advanceToNextCallback();
432
433 ASSERT_THAT(cb.mCalls.size(), Eq(3));
434 EXPECT_THAT(cb.mCalls[2], Eq(4000));
435}
436
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800437TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700438 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
439 .Times(4)
440 .WillOnce(Return(10000))
441 .WillOnce(Return(1000))
442 .WillOnce(Return(10000))
443 .WillOnce(Return(10000));
444
445 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700446 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
447 EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
448 EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700449
450 CountingCallback cb0(mDispatch);
451 CountingCallback cb1(mDispatch);
452
Ady Abraham9c53ee72020-07-22 21:16:18 -0700453 mDispatch.schedule(cb0,
454 {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
455 mDispatch.schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
Kevin DuBois305bef12019-10-09 13:23:27 -0700456 mDispatch.cancel(cb1);
457}
458
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800459TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700460 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700461 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
462 EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700463
464 CountingCallback cb0(mDispatch);
465 CountingCallback cb1(mDispatch);
466
Ady Abraham9c53ee72020-07-22 21:16:18 -0700467 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
468 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
469 mDispatch.schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700470 advanceToNextCallback();
471}
472
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800473TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700474 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700475 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
476 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
477 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700478
479 CountingCallback cb0(mDispatch);
480 CountingCallback cb1(mDispatch);
481
Ady Abraham9c53ee72020-07-22 21:16:18 -0700482 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
483 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
484 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700485 advanceToNextCallback();
486}
487
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800488TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700489 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700490 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
491 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
492 EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
493 EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700494
495 auto offset = 400;
496 auto closeOffset = offset + mDispatchGroupThreshold - 1;
497 auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
498
499 CountingCallback cb0(mDispatch);
500 CountingCallback cb1(mDispatch);
501
Ady Abraham9c53ee72020-07-22 21:16:18 -0700502 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
503 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
504 mDispatch.schedule(cb1,
505 {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700506
507 advanceToNextCallback();
508 ASSERT_THAT(cb0.mCalls.size(), Eq(1));
509 EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
510 ASSERT_THAT(cb1.mCalls.size(), Eq(1));
511 EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
512
Ady Abraham9c53ee72020-07-22 21:16:18 -0700513 mDispatch.schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
514 mDispatch.schedule(cb1,
515 {.workDuration = notCloseOffset, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700516 advanceToNextCallback();
517 ASSERT_THAT(cb1.mCalls.size(), Eq(2));
518 EXPECT_THAT(cb1.mCalls[1], Eq(2000));
519
520 advanceToNextCallback();
521 ASSERT_THAT(cb0.mCalls.size(), Eq(2));
522 EXPECT_THAT(cb0.mCalls[1], Eq(2000));
523}
524
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800525TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700526 Sequence seq;
527 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
528 EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
529 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700530 EXPECT_CALL(mMockClock, alarmCancel());
531
532 CountingCallback cb0(mDispatch);
533 CountingCallback cb1(mDispatch);
534
Ady Abraham9c53ee72020-07-22 21:16:18 -0700535 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
536 mDispatch.schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700537 advanceToNextCallback();
538 EXPECT_EQ(mDispatch.cancel(cb0), CancelResult::Cancelled);
539}
540
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800541TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700542 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
543 .Times(3)
544 .WillOnce(Return(950))
545 .WillOnce(Return(1975))
546 .WillOnce(Return(2950));
547
548 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700549 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
Kevin DuBois305bef12019-10-09 13:23:27 -0700550
551 mMockClock.advanceBy(850);
552 EXPECT_THAT(cb.mCalls.size(), Eq(1));
553
Ady Abraham9c53ee72020-07-22 21:16:18 -0700554 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700555 mMockClock.advanceBy(900);
556 EXPECT_THAT(cb.mCalls.size(), Eq(1));
557 mMockClock.advanceBy(125);
558 EXPECT_THAT(cb.mCalls.size(), Eq(2));
559
Ady Abraham9c53ee72020-07-22 21:16:18 -0700560 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
Kevin DuBois305bef12019-10-09 13:23:27 -0700561 mMockClock.advanceBy(975);
562 EXPECT_THAT(cb.mCalls.size(), Eq(3));
563}
564
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800565TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700566 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700567 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
568 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700569
570 VSyncDispatch::CallbackToken tmp;
Ady Abraham9c53ee72020-07-22 21:16:18 -0700571 tmp = mDispatch.registerCallback(
572 [&](auto, auto, auto) {
573 mDispatch.schedule(tmp,
574 {.workDuration = 100,
575 .readyDuration = 0,
576 .earliestVsync = 2000});
577 },
578 "o.o");
Kevin DuBois305bef12019-10-09 13:23:27 -0700579
Ady Abraham9c53ee72020-07-22 21:16:18 -0700580 mDispatch.schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700581 advanceToNextCallback();
582}
583
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800584TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700585 VSyncDispatch::CallbackToken tmp;
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800586 std::optional<nsecs_t> lastTarget;
Kevin DuBois305bef12019-10-09 13:23:27 -0700587 tmp = mDispatch.registerCallback(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700588 [&](auto timestamp, auto, auto) {
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700589 auto result =
590 mDispatch.schedule(tmp,
591 {.workDuration = 400,
592 .readyDuration = 0,
593 .earliestVsync = timestamp - mVsyncMoveThreshold});
594 EXPECT_TRUE(result.has_value());
595 EXPECT_EQ(mPeriod + timestamp - 400, *result);
596 result = mDispatch.schedule(tmp,
597 {.workDuration = 400,
598 .readyDuration = 0,
599 .earliestVsync = timestamp});
600 EXPECT_TRUE(result.has_value());
601 EXPECT_EQ(mPeriod + timestamp - 400, *result);
602 result = mDispatch.schedule(tmp,
603 {.workDuration = 400,
604 .readyDuration = 0,
605 .earliestVsync = timestamp + mVsyncMoveThreshold});
606 EXPECT_TRUE(result.has_value());
607 EXPECT_EQ(mPeriod + timestamp - 400, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800608 lastTarget = timestamp;
Kevin DuBois305bef12019-10-09 13:23:27 -0700609 },
610 "oo");
611
Ady Abraham9c53ee72020-07-22 21:16:18 -0700612 mDispatch.schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700613 advanceToNextCallback();
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800614 EXPECT_THAT(lastTarget, Eq(1000));
615
616 advanceToNextCallback();
617 EXPECT_THAT(lastTarget, Eq(2000));
Kevin DuBois305bef12019-10-09 13:23:27 -0700618}
619
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800620TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700621 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700622 EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
623 EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
624 EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
625 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700626
627 CountingCallback cb(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700628 mDispatch.schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700629
630 mMockClock.advanceBy(750);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700631 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700632
633 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700634 mDispatch.schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700635
636 mMockClock.advanceBy(800);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700637 mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700638}
639
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800640TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700641 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700642 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
643 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
644 EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
645 EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700646
647 CountingCallback cb0(mDispatch);
648 CountingCallback cb1(mDispatch);
649
Ady Abraham9c53ee72020-07-22 21:16:18 -0700650 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
651 mDispatch.schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700652
653 advanceToNextCallback();
Ady Abraham9c53ee72020-07-22 21:16:18 -0700654 mDispatch.schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
655 mDispatch.schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700656
657 advanceToNextCallback();
658 advanceToNextCallback();
659}
660
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800661TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700662 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700663 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700664
665 CountingCallback cb0(mDispatch);
666 CountingCallback cb1(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700667 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
668 mDispatch.schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700669}
670
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800671TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700672 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700673 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700674 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
Ady Abrahamb491c902020-08-15 15:47:56 -0700675 EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
Kevin DuBois305bef12019-10-09 13:23:27 -0700676
677 CountingCallback cb0(mDispatch);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700678 mDispatch.schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700679 mDispatch.cancel(cb0);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700680 mDispatch.schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700681}
682
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800683TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700684 VSyncDispatch::CallbackToken token(100);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700685 EXPECT_FALSE(mDispatch
686 .schedule(token,
687 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
688 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -0700689 EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error));
690}
691
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800692TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
Kevin DuBois305bef12019-10-09 13:23:27 -0700693 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700694 auto result =
695 mDispatch.schedule(cb0,
696 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
697 EXPECT_TRUE(result.has_value());
698 EXPECT_EQ(500, *result);
699 result = mDispatch.schedule(cb0,
700 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
701 EXPECT_TRUE(result.has_value());
702 EXPECT_EQ(900, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800703}
704
705// b/1450138150
706TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700707 EXPECT_CALL(mMockClock, alarmAt(_, 500));
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800708 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700709 auto result =
710 mDispatch.schedule(cb,
711 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
712 EXPECT_TRUE(result.has_value());
713 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800714 mMockClock.advanceBy(400);
715
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700716 result = mDispatch.schedule(cb,
717 {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
718 EXPECT_TRUE(result.has_value());
719 EXPECT_EQ(1200, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800720 advanceToNextCallback();
721 ASSERT_THAT(cb.mCalls.size(), Eq(1));
722}
723
724TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
725 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
726 .Times(2)
727 .WillOnce(Return(1000))
728 .WillOnce(Return(1002));
729 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700730 auto result =
731 mDispatch.schedule(cb,
732 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
733 EXPECT_TRUE(result.has_value());
734 EXPECT_EQ(500, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800735 mMockClock.advanceBy(400);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700736 result = mDispatch.schedule(cb,
737 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
738 EXPECT_TRUE(result.has_value());
739 EXPECT_EQ(602, *result);
Kevin DuBois305bef12019-10-09 13:23:27 -0700740}
741
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800742TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
743 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700744 auto result =
745 mDispatch.schedule(cb0,
746 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
747 EXPECT_TRUE(result.has_value());
748 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800749 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700750 result = mDispatch.schedule(cb0,
751 {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
752 EXPECT_TRUE(result.has_value());
753 EXPECT_EQ(900, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800754}
755
756TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
757 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700758 EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
759 EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800760 CountingCallback cb0(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700761 auto result =
762 mDispatch.schedule(cb0,
763 {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
764 EXPECT_TRUE(result.has_value());
765 EXPECT_EQ(500, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800766 advanceToNextCallback();
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700767 result = mDispatch.schedule(cb0,
768 {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
769 EXPECT_TRUE(result.has_value());
770 EXPECT_EQ(1100, *result);
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800771}
772
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800773TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700774 EXPECT_CALL(mMockClock, alarmAt(_, 600));
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800775
776 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700777 auto result =
778 mDispatch.schedule(cb,
779 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
780 EXPECT_TRUE(result.has_value());
781 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800782
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700783 result = mDispatch.schedule(cb,
784 {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
785 EXPECT_TRUE(result.has_value());
786 EXPECT_EQ(600, *result);
Kevin DuBoisc94ca832019-11-26 12:56:24 -0800787
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800788 advanceToNextCallback();
Kevin DuBois2311b1a2019-11-18 16:19:08 -0800789}
790
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800791TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700792 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700793 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
794
795 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700796 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700797 VSyncCallbackRegistration cb1(std::move(cb));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700798 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700799 cb.cancel();
800
Ady Abraham9c53ee72020-07-22 21:16:18 -0700801 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700802 cb1.cancel();
803}
804
Kevin DuBoise4f27a82019-11-12 11:41:41 -0800805TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
Ady Abrahamb491c902020-08-15 15:47:56 -0700806 EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
Kevin DuBois305bef12019-10-09 13:23:27 -0700807 EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
808
809 VSyncCallbackRegistration cb(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700810 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700811 VSyncCallbackRegistration cb1(
Ady Abraham9c53ee72020-07-22 21:16:18 -0700812 mDispatch, [](auto, auto, auto) {}, "");
Kevin DuBois305bef12019-10-09 13:23:27 -0700813 cb1 = std::move(cb);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700814 cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700815 cb.cancel();
816
Ady Abraham9c53ee72020-07-22 21:16:18 -0700817 cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
Kevin DuBois305bef12019-10-09 13:23:27 -0700818 cb1.cancel();
819}
820
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700821// b/154303580
822TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
823 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700824 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
825 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700826 CountingCallback cb1(mDispatch);
827 CountingCallback cb2(mDispatch);
828
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700829 auto result =
830 mDispatch.schedule(cb1,
831 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
832 EXPECT_TRUE(result.has_value());
833 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700834
835 mMockClock.setLag(100);
836 mMockClock.advanceBy(620);
837
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700838 result = mDispatch.schedule(cb2,
839 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
840 EXPECT_TRUE(result.has_value());
841 EXPECT_EQ(1900, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700842 mMockClock.advanceBy(80);
843
844 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
845 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
846}
847
848// b/154303580.
849// If the same callback tries to reschedule itself after it's too late, timer opts to apply the
850// update later, as opposed to blocking the calling thread.
851TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
852 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700853 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
854 EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700855 CountingCallback cb(mDispatch);
856
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700857 auto result =
858 mDispatch.schedule(cb,
859 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
860 EXPECT_TRUE(result.has_value());
861 EXPECT_EQ(600, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700862
863 mMockClock.setLag(100);
864 mMockClock.advanceBy(620);
865
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700866 result = mDispatch.schedule(cb,
867 {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
868 EXPECT_TRUE(result.has_value());
869 EXPECT_EQ(1630, *result);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -0700870 mMockClock.advanceBy(80);
871
872 EXPECT_THAT(cb.mCalls.size(), Eq(1));
873}
874
Kevin DuBoisb340b732020-06-16 09:07:35 -0700875// b/154303580.
876TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
877 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700878 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700879 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
880 CountingCallback cb1(mDispatch);
881 CountingCallback cb2(mDispatch);
882
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700883 auto result =
884 mDispatch.schedule(cb1,
885 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
886 EXPECT_TRUE(result.has_value());
887 EXPECT_EQ(600, *result);
888 result = mDispatch.schedule(cb2,
889 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
890 EXPECT_TRUE(result.has_value());
891 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700892
893 mMockClock.setLag(100);
894 mMockClock.advanceBy(620);
895
896 EXPECT_EQ(mDispatch.cancel(cb2), CancelResult::Cancelled);
897
898 mMockClock.advanceBy(80);
899
900 EXPECT_THAT(cb1.mCalls.size(), Eq(1));
901 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
902}
903
904TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
905 Sequence seq;
Ady Abrahamb491c902020-08-15 15:47:56 -0700906 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
907 EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700908 EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
909 CountingCallback cb1(mDispatch);
910 CountingCallback cb2(mDispatch);
911
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700912 auto result =
913 mDispatch.schedule(cb1,
914 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
915 EXPECT_TRUE(result.has_value());
916 EXPECT_EQ(600, *result);
917 result = mDispatch.schedule(cb2,
918 {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
919 EXPECT_TRUE(result.has_value());
920 EXPECT_EQ(1900, *result);
Kevin DuBoisb340b732020-06-16 09:07:35 -0700921
922 mMockClock.setLag(100);
923 mMockClock.advanceBy(620);
924
925 EXPECT_EQ(mDispatch.cancel(cb1), CancelResult::Cancelled);
926
927 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
928 EXPECT_THAT(cb2.mCalls.size(), Eq(0));
929 mMockClock.advanceToNextCallback();
930
931 EXPECT_THAT(cb1.mCalls.size(), Eq(0));
932 EXPECT_THAT(cb2.mCalls.size(), Eq(1));
933}
934
Kevin DuBoisf9477832020-07-16 10:21:36 -0700935TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
936 CountingCallback cb1(mDispatch);
937 CountingCallback cb2(mDispatch);
938
939 Sequence seq;
940 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
941 .InSequence(seq)
942 .WillOnce(Return(1000));
Ady Abrahamb491c902020-08-15 15:47:56 -0700943 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700944 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000))
945 .InSequence(seq)
946 .WillOnce(Return(1000));
947
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700948 auto result =
949 mDispatch.schedule(cb1,
950 {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
951 EXPECT_TRUE(result.has_value());
952 EXPECT_EQ(600, *result);
953 result = mDispatch.schedule(cb2,
954 {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
955 EXPECT_TRUE(result.has_value());
956 EXPECT_EQ(610, *result);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700957
958 mMockClock.setLag(100);
959 mMockClock.advanceBy(700);
960
961 ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
962 EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700963 ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
964 EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
Kevin DuBoisf9477832020-07-16 10:21:36 -0700965 ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
966 EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
Ady Abraham9c53ee72020-07-22 21:16:18 -0700967 ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
968 EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
969}
970
971TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
972 auto intended = mPeriod - 230;
973 EXPECT_CALL(mMockClock, alarmAt(_, 900));
974
975 CountingCallback cb(mDispatch);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -0700976 const auto result = mDispatch.schedule(cb,
977 {.workDuration = 70,
978 .readyDuration = 30,
979 .earliestVsync = intended});
980 EXPECT_TRUE(result.has_value());
981 EXPECT_EQ(900, *result);
Ady Abraham9c53ee72020-07-22 21:16:18 -0700982 advanceToNextCallback();
983
984 ASSERT_THAT(cb.mCalls.size(), Eq(1));
985 EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
986 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
987 EXPECT_THAT(cb.mWakeupTime[0], 900);
988 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
989 EXPECT_THAT(cb.mReadyTime[0], 970);
Kevin DuBoisf9477832020-07-16 10:21:36 -0700990}
991
Ady Abraham69b9e622021-07-19 12:24:31 -0700992TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
993 Sequence seq;
994 EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
995
996 CountingCallback cb(mDispatch);
997
998 mDispatch.schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
999 mDispatch.schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
1000
1001 advanceToNextCallback();
1002
1003 advanceToNextCallback();
1004
1005 ASSERT_THAT(cb.mCalls.size(), Eq(1));
1006 EXPECT_THAT(cb.mCalls[0], Eq(2000));
1007 ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1008 EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1009 ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1010 EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1011}
1012
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001013class VSyncDispatchTimerQueueEntryTest : public testing::Test {
Kevin DuBois305bef12019-10-09 13:23:27 -07001014protected:
1015 nsecs_t const mPeriod = 1000;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001016 nsecs_t const mVsyncMoveThreshold = 200;
Kevin DuBois305bef12019-10-09 13:23:27 -07001017 NiceMock<MockVSyncTracker> mStubTracker{mPeriod};
1018};
1019
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001020TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001021 std::string name("basicname");
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001022 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001023 name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001024 EXPECT_THAT(entry.name(), Eq(name));
1025 EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1026 EXPECT_FALSE(entry.wakeupTime());
1027}
1028
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001029TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001030 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001031 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001032
1033 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001034 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1035 mStubTracker, 0)
1036 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001037 auto const wakeup = entry.wakeupTime();
1038 ASSERT_TRUE(wakeup);
1039 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001040
1041 entry.disarm();
1042 EXPECT_FALSE(entry.wakeupTime());
1043}
1044
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001045TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001046 auto const duration = 500;
1047 auto const now = 8750;
1048
1049 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(now + duration))
1050 .Times(1)
1051 .WillOnce(Return(10000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001052 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001053 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001054
1055 EXPECT_FALSE(entry.wakeupTime());
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001056 EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
1057 mStubTracker, now)
1058 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001059 auto const wakeup = entry.wakeupTime();
1060 ASSERT_TRUE(wakeup);
1061 EXPECT_THAT(*wakeup, Eq(9500));
Kevin DuBois305bef12019-10-09 13:23:27 -07001062}
1063
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001064TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001065 auto callCount = 0;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001066 auto vsyncCalledTime = 0;
1067 auto wakeupCalledTime = 0;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001068 auto readyCalledTime = 0;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001069 VSyncDispatchTimerQueueEntry entry(
1070 "test",
Ady Abraham9c53ee72020-07-22 21:16:18 -07001071 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001072 callCount++;
Kevin DuBois2968afc2020-01-14 09:48:50 -08001073 vsyncCalledTime = vsyncTime;
1074 wakeupCalledTime = wakeupTime;
Ady Abraham9c53ee72020-07-22 21:16:18 -07001075 readyCalledTime = readyTime;
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001076 },
1077 mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001078
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001079 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1080 mStubTracker, 0)
1081 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001082 auto const wakeup = entry.wakeupTime();
1083 ASSERT_TRUE(wakeup);
1084 EXPECT_THAT(*wakeup, Eq(900));
Kevin DuBois305bef12019-10-09 13:23:27 -07001085
Ady Abraham9c53ee72020-07-22 21:16:18 -07001086 auto const ready = entry.readyTime();
1087 ASSERT_TRUE(ready);
1088 EXPECT_THAT(*ready, Eq(1000));
1089
1090 entry.callback(entry.executing(), *wakeup, *ready);
Kevin DuBois305bef12019-10-09 13:23:27 -07001091
1092 EXPECT_THAT(callCount, Eq(1));
Kevin DuBois2968afc2020-01-14 09:48:50 -08001093 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1094 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
Kevin DuBois305bef12019-10-09 13:23:27 -07001095 EXPECT_FALSE(entry.wakeupTime());
1096 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1097 ASSERT_TRUE(lastCalledTarget);
1098 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1099}
1100
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001101TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
Kevin DuBois305bef12019-10-09 13:23:27 -07001102 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
1103 .Times(2)
1104 .WillOnce(Return(1000))
1105 .WillOnce(Return(1020));
1106
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001107 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001108 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois305bef12019-10-09 13:23:27 -07001109
1110 EXPECT_FALSE(entry.wakeupTime());
1111 entry.update(mStubTracker, 0);
1112 EXPECT_FALSE(entry.wakeupTime());
1113
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001114 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1115 mStubTracker, 0)
1116 .has_value());
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001117 auto wakeup = entry.wakeupTime();
1118 ASSERT_TRUE(wakeup);
Kevin DuBois305bef12019-10-09 13:23:27 -07001119 EXPECT_THAT(wakeup, Eq(900));
1120
1121 entry.update(mStubTracker, 0);
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001122 wakeup = entry.wakeupTime();
1123 ASSERT_TRUE(wakeup);
1124 EXPECT_THAT(*wakeup, Eq(920));
Kevin DuBois305bef12019-10-09 13:23:27 -07001125}
1126
Kevin DuBoise4f27a82019-11-12 11:41:41 -08001127TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001128 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001129 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001130 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1131 mStubTracker, 0)
1132 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001133 entry.update(mStubTracker, 0);
1134
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001135 auto const wakeup = entry.wakeupTime();
1136 ASSERT_TRUE(wakeup);
1137 EXPECT_THAT(*wakeup, Eq(wakeup));
1138}
1139
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001140TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1141 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001142 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001143 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1144 mStubTracker, 0)
1145 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001146 entry.executing(); // 1000 is executing
1147 // had 1000 not been executing, this could have been scheduled for time 800.
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001148 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1149 mStubTracker, 0)
1150 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001151 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001152 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001153
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001154 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1155 mStubTracker, 0)
1156 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001157 EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001158 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001159
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001160 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
1161 mStubTracker, 0)
1162 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001163 EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
Ady Abraham9c53ee72020-07-22 21:16:18 -07001164 EXPECT_THAT(*entry.readyTime(), Eq(2000));
Kevin DuBois2311b1a2019-11-18 16:19:08 -08001165}
1166
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001167TEST_F(VSyncDispatchTimerQueueEntryTest,
1168 willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1169 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001170 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001171
1172 Sequence seq;
1173 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1174 .InSequence(seq)
1175 .WillOnce(Return(1000));
1176 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(500))
1177 .InSequence(seq)
1178 .WillOnce(Return(1000));
1179 EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
1180 .InSequence(seq)
1181 .WillOnce(Return(2000));
1182
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001183 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1184 mStubTracker, 0)
1185 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001186
1187 entry.executing(); // 1000 is executing
1188
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001189 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1190 mStubTracker, 0)
1191 .has_value());
Kevin DuBoisc94ca832019-11-26 12:56:24 -08001192}
1193
1194TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1195 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001196 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001197 EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
1198 mStubTracker, 0)
1199 .has_value());
1200 EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
1201 mStubTracker, 0)
1202 .has_value());
1203 EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
1204 mStubTracker, 0)
1205 .has_value());
1206 EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
1207 mStubTracker, 0)
1208 .has_value());
Kevin DuBois305bef12019-10-09 13:23:27 -07001209}
1210
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001211TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) {
1212 static constexpr auto effectualOffset = 200;
1213 VSyncDispatchTimerQueueEntry entry(
Ady Abraham9c53ee72020-07-22 21:16:18 -07001214 "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001215 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001216 entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
1217 entry.addPendingWorkloadUpdate(
1218 {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
Kevin DuBois5c18c1c2020-05-27 15:50:50 -07001219 EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1220 entry.update(mStubTracker, 0);
1221 EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1222 EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1223}
1224
Ady Abraham9c53ee72020-07-22 21:16:18 -07001225TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1226 auto callCount = 0;
1227 auto vsyncCalledTime = 0;
1228 auto wakeupCalledTime = 0;
1229 auto readyCalledTime = 0;
1230 VSyncDispatchTimerQueueEntry entry(
1231 "test",
1232 [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1233 callCount++;
1234 vsyncCalledTime = vsyncTime;
1235 wakeupCalledTime = wakeupTime;
1236 readyCalledTime = readyTime;
1237 },
1238 mVsyncMoveThreshold);
1239
Ady Abrahamb5d3afa2021-05-07 11:22:23 -07001240 EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
1241 mStubTracker, 0)
1242 .has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -07001243 auto const wakeup = entry.wakeupTime();
1244 ASSERT_TRUE(wakeup);
1245 EXPECT_THAT(*wakeup, Eq(900));
1246
1247 auto const ready = entry.readyTime();
1248 ASSERT_TRUE(ready);
1249 EXPECT_THAT(*ready, Eq(970));
1250
1251 entry.callback(entry.executing(), *wakeup, *ready);
1252
1253 EXPECT_THAT(callCount, Eq(1));
1254 EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1255 EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1256 EXPECT_FALSE(entry.wakeupTime());
1257 auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1258 ASSERT_TRUE(lastCalledTarget);
1259 EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1260}
1261
Kevin DuBois305bef12019-10-09 13:23:27 -07001262} // namespace android::scheduler
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001263
1264// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001265#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"