Loading services/surfaceflinger/Scheduler/EventThread.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -320,7 +320,7 @@ void EventThread::setDuration(std::chrono::nanoseconds workDuration, mVsyncRegistration.update({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); } sp<EventThreadConnection> EventThread::createEventConnection( Loading Loading @@ -528,7 +528,7 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { const auto scheduleResult = mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback"); } else { mVsyncRegistration.cancel(); Loading Loading @@ -784,7 +784,7 @@ scheduler::VSyncCallbackRegistration EventThread::onNewVsyncScheduleInternal( if (reschedule) { mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); } return oldRegistration; } Loading services/surfaceflinger/Scheduler/MessageQueue.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncSc mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } return oldRegistration; } Loading @@ -143,7 +143,7 @@ void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) { mVsync.scheduledFrameTime = mVsync.registration->update({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } void MessageQueue::waitMessage() { Loading Loading @@ -196,7 +196,7 @@ void MessageQueue::scheduleFrame() { mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } auto MessageQueue::getScheduledFrameTime() const -> std::optional<Clock::time_point> { Loading services/surfaceflinger/Scheduler/Scheduler.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -611,8 +611,10 @@ Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id, const Display& display = *displayOpt; const nsecs_t threshold = display.selectorPtr->getActiveMode().modePtr->getVsyncRate().getPeriodNsecs() / 2; const nsecs_t nextVsyncTime = display.schedulePtr->getTracker().nextAnticipatedVSyncTimeFrom( currentExpectedPresentTime.ns() + threshold); const nsecs_t nextVsyncTime = display.schedulePtr->getTracker() .nextAnticipatedVSyncTimeFrom(currentExpectedPresentTime.ns() + threshold, currentExpectedPresentTime.ns()); return Fps::fromPeriodNsecs(nextVsyncTime - currentExpectedPresentTime.ns()); } Loading services/surfaceflinger/Scheduler/VSyncDispatch.h +7 −7 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ public: * able to provide the ready-by time (deadline) on the callback. * For internal clients, we don't need to add additional padding, so * readyDuration will typically be 0. * @earliestVsync: The targeted display time. This will be snapped to the closest * predicted vsync time after earliestVsync. * @lastVsync: The targeted display time. This will be snapped to the closest * predicted vsync time after lastVsync. * * callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync * event. Loading @@ -93,11 +93,11 @@ public: struct ScheduleTiming { nsecs_t workDuration = 0; nsecs_t readyDuration = 0; nsecs_t earliestVsync = 0; nsecs_t lastVsync = 0; bool operator==(const ScheduleTiming& other) const { return workDuration == other.workDuration && readyDuration == other.readyDuration && earliestVsync == other.earliestVsync; lastVsync == other.lastVsync; } bool operator!=(const ScheduleTiming& other) const { return !(*this == other); } Loading @@ -109,12 +109,12 @@ public: * The callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync * event. * * The caller designates the earliest vsync event that should be targeted by the earliestVsync * The caller designates the earliest vsync event that should be targeted by the lastVsync * parameter. * The callback will be scheduled at (workDuration + readyDuration - predictedVsync), where * predictedVsync is the first vsync event time where ( predictedVsync >= earliestVsync ). * predictedVsync is the first vsync event time where ( predictedVsync >= lastVsync ). * * If (workDuration + readyDuration - earliestVsync) is in the past, or if a callback has * If (workDuration + readyDuration - lastVsync) is in the past, or if a callback has * already been dispatched for the predictedVsync, an error will be returned. * * It is valid to reschedule a callback to a different time. Loading services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +19 −10 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime, 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)); const auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync, now + timing.workDuration + timing.readyDuration), timing.lastVsync); return getExpectedCallbackTime(nextVsyncTime, timing); } Loading Loading @@ -93,8 +96,11 @@ std::optional<nsecs_t> VSyncDispatchTimerQueueEntry::targetVsync() const { ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing, VSyncTracker& tracker, nsecs_t now) { auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom( std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration)); auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync, now + timing.workDuration + timing.readyDuration), timing.lastVsync); auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration; bool const wouldSkipAVsyncTarget = Loading Loading @@ -139,11 +145,13 @@ nsecs_t VSyncDispatchTimerQueueEntry::adjustVsyncIfNeeded(VSyncTracker& tracker, bool const nextVsyncTooClose = mLastDispatchTime && (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod; if (alreadyDispatchedForVsync) { return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance); return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance, *mLastDispatchTime); } if (nextVsyncTooClose) { return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod); return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod, *mLastDispatchTime + currentPeriod); } return nextVsyncTime; Loading @@ -160,11 +168,12 @@ void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) { } const auto earliestReadyBy = now + mScheduleTiming.workDuration + mScheduleTiming.readyDuration; const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.earliestVsync); const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.lastVsync); const auto nextVsyncTime = adjustVsyncIfNeeded(tracker, /*nextVsyncTime*/ tracker.nextAnticipatedVSyncTimeFrom(earliestVsync)); tracker.nextAnticipatedVSyncTimeFrom(earliestVsync, mScheduleTiming.lastVsync)); const auto nextReadyTime = nextVsyncTime - mScheduleTiming.readyDuration; const auto nextWakeupTime = nextReadyTime - mScheduleTiming.workDuration; Loading Loading @@ -214,10 +223,10 @@ void VSyncDispatchTimerQueueEntry::dump(std::string& result) const { StringAppendF(&result, "\t\t%s: %s %s\n", mName.c_str(), mRunning ? "(in callback function)" : "", armedInfo.c_str()); StringAppendF(&result, "\t\t\tworkDuration: %.2fms readyDuration: %.2fms earliestVsync: %.2fms relative " "\t\t\tworkDuration: %.2fms readyDuration: %.2fms lastVsync: %.2fms relative " "to now\n", mScheduleTiming.workDuration / 1e6f, mScheduleTiming.readyDuration / 1e6f, (mScheduleTiming.earliestVsync - systemTime()) / 1e6f); (mScheduleTiming.lastVsync - systemTime()) / 1e6f); if (mLastDispatchTime) { StringAppendF(&result, "\t\t\tmLastDispatchTime: %.2fms ago\n", Loading Loading
services/surfaceflinger/Scheduler/EventThread.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -320,7 +320,7 @@ void EventThread::setDuration(std::chrono::nanoseconds workDuration, mVsyncRegistration.update({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); } sp<EventThreadConnection> EventThread::createEventConnection( Loading Loading @@ -528,7 +528,7 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { const auto scheduleResult = mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback"); } else { mVsyncRegistration.cancel(); Loading Loading @@ -784,7 +784,7 @@ scheduler::VSyncCallbackRegistration EventThread::onNewVsyncScheduleInternal( if (reschedule) { mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); .lastVsync = mLastVsyncCallbackTime.ns()}); } return oldRegistration; } Loading
services/surfaceflinger/Scheduler/MessageQueue.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncSc mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } return oldRegistration; } Loading @@ -143,7 +143,7 @@ void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) { mVsync.scheduledFrameTime = mVsync.registration->update({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } void MessageQueue::waitMessage() { Loading Loading @@ -196,7 +196,7 @@ void MessageQueue::scheduleFrame() { mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); .lastVsync = mVsync.lastCallbackTime.ns()}); } auto MessageQueue::getScheduledFrameTime() const -> std::optional<Clock::time_point> { Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -611,8 +611,10 @@ Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id, const Display& display = *displayOpt; const nsecs_t threshold = display.selectorPtr->getActiveMode().modePtr->getVsyncRate().getPeriodNsecs() / 2; const nsecs_t nextVsyncTime = display.schedulePtr->getTracker().nextAnticipatedVSyncTimeFrom( currentExpectedPresentTime.ns() + threshold); const nsecs_t nextVsyncTime = display.schedulePtr->getTracker() .nextAnticipatedVSyncTimeFrom(currentExpectedPresentTime.ns() + threshold, currentExpectedPresentTime.ns()); return Fps::fromPeriodNsecs(nextVsyncTime - currentExpectedPresentTime.ns()); } Loading
services/surfaceflinger/Scheduler/VSyncDispatch.h +7 −7 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ public: * able to provide the ready-by time (deadline) on the callback. * For internal clients, we don't need to add additional padding, so * readyDuration will typically be 0. * @earliestVsync: The targeted display time. This will be snapped to the closest * predicted vsync time after earliestVsync. * @lastVsync: The targeted display time. This will be snapped to the closest * predicted vsync time after lastVsync. * * callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync * event. Loading @@ -93,11 +93,11 @@ public: struct ScheduleTiming { nsecs_t workDuration = 0; nsecs_t readyDuration = 0; nsecs_t earliestVsync = 0; nsecs_t lastVsync = 0; bool operator==(const ScheduleTiming& other) const { return workDuration == other.workDuration && readyDuration == other.readyDuration && earliestVsync == other.earliestVsync; lastVsync == other.lastVsync; } bool operator!=(const ScheduleTiming& other) const { return !(*this == other); } Loading @@ -109,12 +109,12 @@ public: * The callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync * event. * * The caller designates the earliest vsync event that should be targeted by the earliestVsync * The caller designates the earliest vsync event that should be targeted by the lastVsync * parameter. * The callback will be scheduled at (workDuration + readyDuration - predictedVsync), where * predictedVsync is the first vsync event time where ( predictedVsync >= earliestVsync ). * predictedVsync is the first vsync event time where ( predictedVsync >= lastVsync ). * * If (workDuration + readyDuration - earliestVsync) is in the past, or if a callback has * If (workDuration + readyDuration - lastVsync) is in the past, or if a callback has * already been dispatched for the predictedVsync, an error will be returned. * * It is valid to reschedule a callback to a different time. Loading
services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp +19 −10 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime, 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)); const auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync, now + timing.workDuration + timing.readyDuration), timing.lastVsync); return getExpectedCallbackTime(nextVsyncTime, timing); } Loading Loading @@ -93,8 +96,11 @@ std::optional<nsecs_t> VSyncDispatchTimerQueueEntry::targetVsync() const { ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing, VSyncTracker& tracker, nsecs_t now) { auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom( std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration)); auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync, now + timing.workDuration + timing.readyDuration), timing.lastVsync); auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration; bool const wouldSkipAVsyncTarget = Loading Loading @@ -139,11 +145,13 @@ nsecs_t VSyncDispatchTimerQueueEntry::adjustVsyncIfNeeded(VSyncTracker& tracker, bool const nextVsyncTooClose = mLastDispatchTime && (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod; if (alreadyDispatchedForVsync) { return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance); return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance, *mLastDispatchTime); } if (nextVsyncTooClose) { return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod); return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod, *mLastDispatchTime + currentPeriod); } return nextVsyncTime; Loading @@ -160,11 +168,12 @@ void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) { } const auto earliestReadyBy = now + mScheduleTiming.workDuration + mScheduleTiming.readyDuration; const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.earliestVsync); const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.lastVsync); const auto nextVsyncTime = adjustVsyncIfNeeded(tracker, /*nextVsyncTime*/ tracker.nextAnticipatedVSyncTimeFrom(earliestVsync)); tracker.nextAnticipatedVSyncTimeFrom(earliestVsync, mScheduleTiming.lastVsync)); const auto nextReadyTime = nextVsyncTime - mScheduleTiming.readyDuration; const auto nextWakeupTime = nextReadyTime - mScheduleTiming.workDuration; Loading Loading @@ -214,10 +223,10 @@ void VSyncDispatchTimerQueueEntry::dump(std::string& result) const { StringAppendF(&result, "\t\t%s: %s %s\n", mName.c_str(), mRunning ? "(in callback function)" : "", armedInfo.c_str()); StringAppendF(&result, "\t\t\tworkDuration: %.2fms readyDuration: %.2fms earliestVsync: %.2fms relative " "\t\t\tworkDuration: %.2fms readyDuration: %.2fms lastVsync: %.2fms relative " "to now\n", mScheduleTiming.workDuration / 1e6f, mScheduleTiming.readyDuration / 1e6f, (mScheduleTiming.earliestVsync - systemTime()) / 1e6f); (mScheduleTiming.lastVsync - systemTime()) / 1e6f); if (mLastDispatchTime) { StringAppendF(&result, "\t\t\tmLastDispatchTime: %.2fms ago\n", Loading