diff options
6 files changed, 251 insertions, 198 deletions
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp index ce5c31ac19..50b38c9cf6 100644 --- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp +++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp @@ -60,8 +60,7 @@ public: mRegistration.schedule({.workDuration = mWorkDuration.count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastCallTime.count()}); - LOG_ALWAYS_FATAL_IF((scheduleResult != scheduler::ScheduleResult::Scheduled), - "Error scheduling callback: rc %X", scheduleResult); + LOG_ALWAYS_FATAL_IF((!scheduleResult.has_value()), "Error scheduling callback"); } void stop() { @@ -100,8 +99,7 @@ private: mRegistration.schedule({.workDuration = mWorkDuration.count(), .readyDuration = mReadyDuration.count(), .earliestVsync = vsyncTime}); - LOG_ALWAYS_FATAL_IF((scheduleResult != ScheduleResult::Scheduled), - "Error rescheduling callback: rc %X", scheduleResult); + LOG_ALWAYS_FATAL_IF(!scheduleResult.has_value(), "Error rescheduling callback"); } } diff --git a/services/surfaceflinger/Scheduler/VSyncDispatch.h b/services/surfaceflinger/Scheduler/VSyncDispatch.h index 9d7110327b..b52706f727 100644 --- a/services/surfaceflinger/Scheduler/VSyncDispatch.h +++ b/services/surfaceflinger/Scheduler/VSyncDispatch.h @@ -16,8 +16,10 @@ #pragma once +#include <utils/Log.h> #include <utils/Timers.h> #include <functional> +#include <optional> #include <string> #include "StrongTyping.h" @@ -26,7 +28,8 @@ namespace android::scheduler { class TimeKeeper; class VSyncTracker; -enum class ScheduleResult { Scheduled, CannotSchedule, Error }; +using ScheduleResult = std::optional<nsecs_t>; + enum class CancelResult { Cancelled, TooLate, Error }; /* @@ -121,11 +124,8 @@ public: * * \param [in] token The callback to schedule. * \param [in] scheduleTiming The timing information for this schedule call - * \return A ScheduleResult::Scheduled if callback was scheduled. - * A ScheduleResult::CannotSchedule - * if (workDuration + readyDuration - earliestVsync) is in the past, - * or if a callback was dispatched for the predictedVsync already. A ScheduleResult::Error if - * there was another error. + * \return The expected callback time if a callback was scheduled. + * std::nullopt if the callback is not registered. */ virtual ScheduleResult schedule(CallbackToken token, ScheduleTiming scheduleTiming) = 0; diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp index ca6ea27d14..28be962f2c 100644 --- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp @@ -26,6 +26,20 @@ namespace android::scheduler { using base::StringAppendF; +namespace { +nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime, + const VSyncDispatch::ScheduleTiming& timing) { + return nextVsyncTime - timing.readyDuration - timing.workDuration; +} + +nsecs_t getExpectedCallbackTime(VSyncTracker& tracker, nsecs_t now, + const VSyncDispatch::ScheduleTiming& timing) { + const auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom( + std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration)); + return getExpectedCallbackTime(nextVsyncTime, timing); +} +} // namespace + VSyncDispatch::~VSyncDispatch() = default; VSyncTracker::~VSyncTracker() = default; TimeKeeper::~TimeKeeper() = default; @@ -74,7 +88,7 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim bool const wouldSkipAVsyncTarget = mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance)); if (wouldSkipAVsyncTarget) { - return ScheduleResult::Scheduled; + return getExpectedCallbackTime(nextVsyncTime, timing); } bool const alreadyDispatchedForVsync = mLastDispatchTime && @@ -89,7 +103,7 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim auto const nextReadyTime = nextVsyncTime - timing.readyDuration; mScheduleTiming = timing; mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime}; - return ScheduleResult::Scheduled; + return getExpectedCallbackTime(nextVsyncTime, timing); } void VSyncDispatchTimerQueueEntry::addPendingWorkloadUpdate(VSyncDispatch::ScheduleTiming timing) { @@ -317,7 +331,7 @@ void VSyncDispatchTimerQueue::unregisterCallback(CallbackToken token) { ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token, ScheduleTiming scheduleTiming) { - auto result = ScheduleResult::Error; + ScheduleResult result; { std::lock_guard lock(mMutex); @@ -333,11 +347,11 @@ ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token, auto const rearmImminent = now > mIntendedWakeupTime; if (CC_UNLIKELY(rearmImminent)) { callback->addPendingWorkloadUpdate(scheduleTiming); - return ScheduleResult::Scheduled; + return getExpectedCallbackTime(mTracker, now, scheduleTiming); } result = callback->schedule(scheduleTiming, mTracker, now); - if (result == ScheduleResult::CannotSchedule) { + if (!result.has_value()) { return result; } @@ -416,7 +430,7 @@ VSyncCallbackRegistration::~VSyncCallbackRegistration() { ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) { if (!mValidToken) { - return ScheduleResult::Error; + return std::nullopt; } return mDispatch.get().schedule(mToken, scheduleTiming); } diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp index 54f4c7c018..a9ad249383 100644 --- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp +++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp @@ -66,7 +66,7 @@ public: ALOGD("schedule: %zu", token.value()); if (mCallbacks.count(token) == 0) { ALOGD("schedule: callback %zu not registered", token.value()); - return scheduler::ScheduleResult::Error; + return scheduler::ScheduleResult{}; } auto& callback = mCallbacks.at(token); @@ -75,7 +75,7 @@ public: callback.targetWakeupTime = timing.earliestVsync - timing.workDuration - timing.readyDuration; ALOGD("schedule: callback %zu scheduled", token.value()); - return scheduler::ScheduleResult::Scheduled; + return scheduler::ScheduleResult{callback.targetWakeupTime}; }); ON_CALL(*this, cancel).WillByDefault([this](CallbackToken token) { diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp index 8208b3fa73..18ebbab09a 100644 --- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp @@ -104,7 +104,7 @@ TEST_F(MessageQueueTest, invalidate) { const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDuration.count(), .readyDuration = 0, .earliestVsync = 0}; - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); } @@ -114,10 +114,10 @@ TEST_F(MessageQueueTest, invalidateTwice) { .readyDuration = 0, .earliestVsync = 0}; - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); } @@ -127,7 +127,7 @@ TEST_F(MessageQueueTest, invalidateTwiceWithCallback) { .readyDuration = 0, .earliestVsync = 0}; - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); const auto startTime = 100; @@ -146,7 +146,7 @@ TEST_F(MessageQueueTest, invalidateTwiceWithCallback) { .readyDuration = 0, .earliestVsync = presentTime}; - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); } @@ -158,7 +158,7 @@ TEST_F(MessageQueueTest, invalidateWithDurationChange) { .readyDuration = 0, .earliestVsync = 0}; - EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).Times(1); + EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0)); EXPECT_NO_FATAL_FAILURE(mEventQueue.invalidate()); } diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp index b64cce9e43..d59d64bc02 100644 --- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp @@ -232,11 +232,12 @@ TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) { VSyncDispatchTimerQueue mDispatch{createTimeKeeper(), mStubTracker, mDispatchGroupThreshold, mVsyncMoveThreshold}; CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = 1000}), - ScheduleResult::Scheduled); + const auto result = mDispatch.schedule(cb, + {.workDuration = 100, + .readyDuration = 0, + .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(900, *result); } } @@ -245,11 +246,13 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) { EXPECT_CALL(mMockClock, alarmAt(_, 900)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = intended}), - ScheduleResult::Scheduled); + const auto result = mDispatch.schedule(cb, + {.workDuration = 100, + .readyDuration = 0, + .earliestVsync = intended}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(900, *result); + advanceToNextCallback(); ASSERT_THAT(cb.mCalls.size(), Eq(1)); @@ -277,11 +280,12 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) { EXPECT_CALL(mMockClock, alarmAt(_, mPeriod)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = workDuration, - .readyDuration = 0, - .earliestVsync = mPeriod}), - ScheduleResult::Scheduled); + const auto result = mDispatch.schedule(cb, + {.workDuration = workDuration, + .readyDuration = 0, + .earliestVsync = mPeriod}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod, *result); } TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) { @@ -289,11 +293,11 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) { EXPECT_CALL(mMockClock, alarmCancel()); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = mPeriod}), - ScheduleResult::Scheduled); + const auto result = + mDispatch.schedule(cb, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod - 100, *result); EXPECT_EQ(mDispatch.cancel(cb), CancelResult::Cancelled); } @@ -302,11 +306,11 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) { EXPECT_CALL(mMockClock, alarmCancel()); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = mPeriod}), - ScheduleResult::Scheduled); + const auto result = + mDispatch.schedule(cb, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod - 100, *result); mMockClock.advanceBy(950); EXPECT_EQ(mDispatch.cancel(cb), CancelResult::TooLate); } @@ -316,11 +320,11 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) { EXPECT_CALL(mMockClock, alarmCancel()); PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s)); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = mPeriod}), - ScheduleResult::Scheduled); + const auto result = + mDispatch.schedule(cb, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod - 100, *result); std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); }); EXPECT_TRUE(cb.waitForPause()); @@ -337,11 +341,11 @@ TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) { PausingCallback cb(mDispatch, 50ms); cb.stashResource(resource); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = mPeriod}), - ScheduleResult::Scheduled); + const auto result = + mDispatch.schedule(cb, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod - 100, *result); std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); }); EXPECT_TRUE(cb.waitForPause()); @@ -535,21 +539,25 @@ TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) { std::optional<nsecs_t> lastTarget; tmp = mDispatch.registerCallback( [&](auto timestamp, auto, auto) { - EXPECT_EQ(mDispatch.schedule(tmp, - {.workDuration = 400, - .readyDuration = 0, - .earliestVsync = timestamp - mVsyncMoveThreshold}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(tmp, - {.workDuration = 400, - .readyDuration = 0, - .earliestVsync = timestamp}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(tmp, - {.workDuration = 400, - .readyDuration = 0, - .earliestVsync = timestamp + mVsyncMoveThreshold}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(tmp, + {.workDuration = 400, + .readyDuration = 0, + .earliestVsync = timestamp - mVsyncMoveThreshold}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod + timestamp - 400, *result); + result = mDispatch.schedule(tmp, + {.workDuration = 400, + .readyDuration = 0, + .earliestVsync = timestamp}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod + timestamp - 400, *result); + result = mDispatch.schedule(tmp, + {.workDuration = 400, + .readyDuration = 0, + .earliestVsync = timestamp + mVsyncMoveThreshold}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(mPeriod + timestamp - 400, *result); lastTarget = timestamp; }, "oo"); @@ -627,36 +635,41 @@ TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) { TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) { VSyncDispatch::CallbackToken token(100); - EXPECT_THAT(mDispatch.schedule(token, - {.workDuration = 100, - .readyDuration = 0, - .earliestVsync = 1000}), - Eq(ScheduleResult::Error)); + EXPECT_FALSE(mDispatch + .schedule(token, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}) + .has_value()); EXPECT_THAT(mDispatch.cancel(token), Eq(CancelResult::Error)); } TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) { CountingCallback cb0(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb0, + {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(500, *result); + result = mDispatch.schedule(cb0, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(900, *result); } // b/1450138150 TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) { EXPECT_CALL(mMockClock, alarmAt(_, 500)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb, + {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(500, *result); mMockClock.advanceBy(400); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb, + {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1200, *result); advanceToNextCallback(); ASSERT_THAT(cb.mCalls.size(), Eq(1)); } @@ -667,24 +680,30 @@ TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedul .WillOnce(Return(1000)) .WillOnce(Return(1002)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb, + {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(500, *result); mMockClock.advanceBy(400); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(602, *result); } TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) { CountingCallback cb0(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb0, + {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(500, *result); advanceToNextCallback(); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb0, + {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(900, *result); } TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) { @@ -692,26 +711,32 @@ TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) { EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq); EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq); CountingCallback cb0(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb0, + {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(500, *result); advanceToNextCallback(); - EXPECT_EQ(mDispatch.schedule(cb0, - {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb0, + {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1100, *result); } TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) { EXPECT_CALL(mMockClock, alarmAt(_, 600)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb, + {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); advanceToNextCallback(); } @@ -754,16 +779,19 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb1, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb1, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); mMockClock.setLag(100); mMockClock.advanceBy(620); - EXPECT_EQ(mDispatch.schedule(cb2, - {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb2, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1900, *result); mMockClock.advanceBy(80); EXPECT_THAT(cb1.mCalls.size(), Eq(1)); @@ -779,16 +807,19 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); mMockClock.setLag(100); mMockClock.advanceBy(620); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + result = mDispatch.schedule(cb, + {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1630, *result); mMockClock.advanceBy(80); EXPECT_THAT(cb.mCalls.size(), Eq(1)); @@ -802,12 +833,15 @@ TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) { CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb1, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(cb2, - {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb1, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); + result = mDispatch.schedule(cb2, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1900, *result); mMockClock.setLag(100); mMockClock.advanceBy(620); @@ -828,12 +862,15 @@ TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) { CountingCallback cb1(mDispatch); CountingCallback cb2(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb1, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(cb2, - {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb1, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); + result = mDispatch.schedule(cb2, + {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(1900, *result); mMockClock.setLag(100); mMockClock.advanceBy(620); @@ -861,12 +898,15 @@ TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) { .InSequence(seq) .WillOnce(Return(1000)); - EXPECT_EQ(mDispatch.schedule(cb1, - {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); - EXPECT_EQ(mDispatch.schedule(cb2, - {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000}), - ScheduleResult::Scheduled); + auto result = + mDispatch.schedule(cb1, + {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(600, *result); + result = mDispatch.schedule(cb2, + {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(610, *result); mMockClock.setLag(100); mMockClock.advanceBy(700); @@ -886,11 +926,12 @@ TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) { EXPECT_CALL(mMockClock, alarmAt(_, 900)); CountingCallback cb(mDispatch); - EXPECT_EQ(mDispatch.schedule(cb, - {.workDuration = 70, - .readyDuration = 30, - .earliestVsync = intended}), - ScheduleResult::Scheduled); + const auto result = mDispatch.schedule(cb, + {.workDuration = 70, + .readyDuration = 30, + .earliestVsync = intended}); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(900, *result); advanceToNextCallback(); ASSERT_THAT(cb.mCalls.size(), Eq(1)); @@ -922,9 +963,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) { "test", [](auto, auto, auto) {}, mVsyncMoveThreshold); EXPECT_FALSE(entry.wakeupTime()); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); auto const wakeup = entry.wakeupTime(); ASSERT_TRUE(wakeup); EXPECT_THAT(*wakeup, Eq(900)); @@ -944,9 +985,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) "test", [](auto, auto, auto) {}, mVsyncMoveThreshold); EXPECT_FALSE(entry.wakeupTime()); - EXPECT_THAT(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994}, - mStubTracker, now), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994}, + mStubTracker, now) + .has_value()); auto const wakeup = entry.wakeupTime(); ASSERT_TRUE(wakeup); EXPECT_THAT(*wakeup, Eq(9500)); @@ -967,9 +1008,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) { }, mVsyncMoveThreshold); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); auto const wakeup = entry.wakeupTime(); ASSERT_TRUE(wakeup); EXPECT_THAT(*wakeup, Eq(900)); @@ -1002,9 +1043,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) { entry.update(mStubTracker, 0); EXPECT_FALSE(entry.wakeupTime()); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); auto wakeup = entry.wakeupTime(); ASSERT_TRUE(wakeup); EXPECT_THAT(wakeup, Eq(900)); @@ -1018,9 +1059,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) { TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) { VSyncDispatchTimerQueueEntry entry( "test", [](auto, auto, auto) {}, mVsyncMoveThreshold); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); entry.update(mStubTracker, 0); auto const wakeup = entry.wakeupTime(); @@ -1031,26 +1072,26 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) { TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) { VSyncDispatchTimerQueueEntry entry( "test", [](auto, auto, auto) {}, mVsyncMoveThreshold); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); entry.executing(); // 1000 is executing // had 1000 not been executing, this could have been scheduled for time 800. - EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); EXPECT_THAT(*entry.wakeupTime(), Eq(1800)); EXPECT_THAT(*entry.readyTime(), Eq(2000)); - EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); EXPECT_THAT(*entry.wakeupTime(), Eq(1950)); EXPECT_THAT(*entry.readyTime(), Eq(2000)); - EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001}, + mStubTracker, 0) + .has_value()); EXPECT_THAT(*entry.wakeupTime(), Eq(1800)); EXPECT_THAT(*entry.readyTime(), Eq(2000)); } @@ -1071,32 +1112,32 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, .InSequence(seq) .WillOnce(Return(2000)); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); entry.executing(); // 1000 is executing - EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); } TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) { VSyncDispatchTimerQueueEntry entry( "test", [](auto, auto, auto) {}, mVsyncMoveThreshold); - EXPECT_THAT(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); - EXPECT_THAT(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); - EXPECT_THAT(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); - EXPECT_THAT(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); + EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); + EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); + EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); } TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdate) { @@ -1128,9 +1169,9 @@ TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) { }, mVsyncMoveThreshold); - EXPECT_THAT(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500}, - mStubTracker, 0), - Eq(ScheduleResult::Scheduled)); + EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500}, + mStubTracker, 0) + .has_value()); auto const wakeup = entry.wakeupTime(); ASSERT_TRUE(wakeup); EXPECT_THAT(*wakeup, Eq(900)); |