Add the notion of a last callback time into DispSync.

If we do not track real callback times we run into two issues:

* We can potentially fall into double-rate vsyncs due to error in thread
wakeup latency. For instance, we only correct up to 1.5 ms when wakeup
latency can be up to 5 ms in duration. To correct for this error, we
need a sanity check that callback timings won't fall into double-rate
vsyncs.
* Registering and unregistering event listeners can occur rapidly within
the same vsyncs, so that without any correction we can initially
double-fire events. If we only rely on inferring the last event time,
then we may end up skipping a frame, so we'll require the calling
thread registering and unregistering listeners to best-effort cache the
lastest callback time.

Bug: 124383894
Test: systrace
Change-Id: I7bc8f00502a3b798073a77c5ba4794c12cd14341
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 4f0b3bb..718e996 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -101,7 +101,7 @@
 
         mPhaseIntervalSetting = Phase::ZERO;
         mScheduler.withPrimaryDispSync([this](android::DispSync& sync) {
-            sync.addEventListener("SamplingThreadDispSyncListener", 0, this);
+            sync.addEventListener("SamplingThreadDispSyncListener", 0, this, mLastCallbackTime);
         });
         mVsyncListening = true;
     }
@@ -115,8 +115,9 @@
     void stopVsyncListenerLocked() /*REQUIRES(mMutex)*/ {
         if (!mVsyncListening) return;
 
-        mScheduler.withPrimaryDispSync(
-                [this](android::DispSync& sync) { sync.removeEventListener(this); });
+        mScheduler.withPrimaryDispSync([this](android::DispSync& sync) {
+            sync.removeEventListener(this, &mLastCallbackTime);
+        });
         mVsyncListening = false;
     }
 
@@ -147,6 +148,7 @@
     Scheduler& mScheduler;
     const std::chrono::nanoseconds mTargetSamplingOffset;
     mutable std::mutex mMutex;
+    nsecs_t mLastCallbackTime = 0;
     enum class Phase {
         ZERO,
         SAMPLING