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
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index ca6ea27..28be962 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 @@
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 @@
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 @@
ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token,
ScheduleTiming scheduleTiming) {
- auto result = ScheduleResult::Error;
+ ScheduleResult result;
{
std::lock_guard lock(mMutex);
@@ -333,11 +347,11 @@
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 @@
ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
if (!mValidToken) {
- return ScheduleResult::Error;
+ return std::nullopt;
}
return mDispatch.get().schedule(mToken, scheduleTiming);
}