summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ady Abraham <adyabr@google.com> 2021-05-07 11:22:23 -0700
committer Ady Abraham <adyabr@google.com> 2021-05-13 23:09:58 +0000
commitb5d3afa06ccf11f9f78026d946468818a65cec76 (patch)
tree91730f191a8cdc7843f9c1fd841200b5e9eec090
parentccf4b47e9eb5f1284a0e2070a8ef239d807d6d44 (diff)
SF: return the expected wakeup time from VSyncDispatch
Return the expected wakeup of a callback scheduled with VSyncDispatch. This would help the client to better plan it's work. In particular this would be used for SF to know when to schedule the region sample thread to capture the screen. Bug: 181983990 Test: SF unit tests Change-Id: I38b538c1f6fac7cadcf456c55e78f67cf637480d
-rw-r--r--services/surfaceflinger/Scheduler/DispSyncSource.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/VSyncDispatch.h12
-rw-r--r--services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp26
-rw-r--r--services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/MessageQueueTest.cpp12
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp389
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));