[SurfaceFlinger] Some dispsync fixes for early event firing

* Fix lastEventTime for listeners so that they don't fire early.
* Properly set mHasFired for listeners so that if the dispsync model
is currently being updated that mHasFired is always set to true
if lastEventTime is after the most recent vsync reference.

Bug: 132678707
Bug: 130684082
Test: systrace
Change-Id: I5b860336f12b742cc67665776290939b61e7e3af
Merged-In: I5b860336f12b742cc67665776290939b61e7e3af
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index f7a30af..95ff9d0 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -79,11 +79,7 @@
         Mutex::Autolock lock(mMutex);
 
         mPhase = phase;
-        if (mReferenceTime != referenceTime) {
-            for (auto& eventListener : mEventListeners) {
-                eventListener.mHasFired = false;
-            }
-        }
+        const bool referenceTimeChanged = mReferenceTime != referenceTime;
         mReferenceTime = referenceTime;
         if (mPeriod != 0 && mPeriod != period && mReferenceTime != 0) {
             // Inflate the reference time to be the most recent predicted
@@ -94,6 +90,13 @@
             mReferenceTime = mReferenceTime + (numOldPeriods)*mPeriod;
         }
         mPeriod = period;
+        if (!mModelLocked && referenceTimeChanged) {
+            for (auto& eventListener : mEventListeners) {
+                eventListener.mHasFired = false;
+                eventListener.mLastEventTime =
+                        mReferenceTime - mPeriod + mPhase + eventListener.mPhase;
+            }
+        }
         if (mTraceDetailedInfo) {
             ATRACE_INT64("DispSync:Period", mPeriod);
             ATRACE_INT64("DispSync:Phase", mPhase + mPeriod / 2);
@@ -120,6 +123,13 @@
 
     void unlockModel() {
         Mutex::Autolock lock(mMutex);
+        if (mModelLocked) {
+            for (auto& eventListener : mEventListeners) {
+                if (eventListener.mLastEventTime > mReferenceTime) {
+                    eventListener.mHasFired = true;
+                }
+            }
+        }
         mModelLocked = false;
         ATRACE_INT("DispSync:ModelLocked", mModelLocked);
     }
@@ -249,6 +259,10 @@
             listener.mLastCallbackTime = lastCallbackTime;
         }
 
+        if (!mModelLocked && listener.mLastEventTime > mReferenceTime) {
+            listener.mHasFired = true;
+        }
+
         mEventListeners.push_back(listener);
 
         mCond.signal();