SF: VSyncDispatch: correct vsync prediction drift
Refine VSyncDispatch::schedule implementation so that refining
the prediction by small amounts would not lead to skipped callbacks.
The current implementation did not account for a case where
a valid vsync callback would be skipped. (exposed
in unit testing). Like the rest of VSyncDispatch, this
code is flagged off (ie, latent, not production code yet)
Fixes: 145213786
Bug: 146050690
Test: 6 new unit tests, 3 unit test change
Test: validation via systrace
Change-Id: I400fc5e3c181b49ab237b0dd0da2a62e38522fa0
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
index fc78da3..0c9b4fe 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
@@ -36,7 +36,8 @@
// Valid transition: disarmed -> armed ( when scheduled )
// Valid transition: armed -> running -> disarmed ( when timer is called)
// Valid transition: armed -> disarmed ( when cancelled )
- VSyncDispatchTimerQueueEntry(std::string const& name, std::function<void(nsecs_t)> const& fn);
+ VSyncDispatchTimerQueueEntry(std::string const& name, std::function<void(nsecs_t)> const& fn,
+ nsecs_t minVsyncDistance);
std::string_view name() const;
// Start: functions that are not threadsafe.
@@ -72,6 +73,7 @@
nsecs_t mWorkDuration;
nsecs_t mEarliestVsync;
+ nsecs_t const mMinVsyncDistance;
struct ArmingInfo {
nsecs_t mActualWakeupTime;
@@ -91,8 +93,15 @@
*/
class VSyncDispatchTimerQueue : public VSyncDispatch {
public:
+ // Constructs a VSyncDispatchTimerQueue.
+ // \param[in] tk A timekeeper.
+ // \param[in] tracker A tracker.
+ // \param[in] timerSlack The threshold at which different similarly timed callbacks
+ // should be grouped into one wakeup.
+ // \param[in] minVsyncDistance The minimum distance between two vsync estimates before the
+ // vsyncs are considered the same vsync event.
explicit VSyncDispatchTimerQueue(std::unique_ptr<TimeKeeper> tk, VSyncTracker& tracker,
- nsecs_t timerSlack);
+ nsecs_t timerSlack, nsecs_t minVsyncDistance);
~VSyncDispatchTimerQueue();
CallbackToken registerCallback(std::function<void(nsecs_t)> const& callbackFn,
@@ -119,6 +128,7 @@
std::unique_ptr<TimeKeeper> const mTimeKeeper;
VSyncTracker& mTracker;
nsecs_t const mTimerSlack;
+ nsecs_t const mMinVsyncDistance;
std::mutex mutable mMutex;
size_t mCallbackToken GUARDED_BY(mMutex) = 0;