[SurfaceFlinger] fix permanently enabling early offsets.

* Add notion of intended period in DispSync, and use that to detect
whether the simulated period will be changed.
* Propagate that signal to setDesiredActiveConfig, so that we don't fall
into early offsets unnecessarily, which can cause early offsets to
always be enabled.

Bug: 132678707
Test: systrace
Test: swappy test app
Test: scrolling through google news
Change-Id: I18df1b9d949cd534ecbf1c8891b6f88eab8be399
(cherry picked from commit f8e689cfd25f27c4af36a27e145d4cac1d0bb9cb)
Merged-In: I18df1b9d949cd534ecbf1c8891b6f88eab8be399
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0cf84a9..6d73104 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -940,9 +940,14 @@
         // Start receiving vsync samples now, so that we can detect a period
         // switch.
         mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
+        // We should only move to early offsets when we know that the refresh
+        // rate will change. Otherwise, we may be stuck in early offsets
+        // forever, as onRefreshRateChangeDetected will not be called.
+        if (mDesiredActiveConfig.event == Scheduler::ConfigEvent::Changed) {
+            mVsyncModulator.onRefreshRateChangeInitiated();
+        }
         mPhaseOffsets->setRefreshRateType(info.type);
         const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
-        mVsyncModulator.onRefreshRateChangeInitiated();
         mVsyncModulator.setPhaseOffsets(early, gl, late);
     }
     mDesiredActiveConfigChanged = true;
@@ -1019,6 +1024,10 @@
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
         mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
         mDesiredActiveConfigChanged = false;
+        // Update scheduler with the correct vsync period as a no-op.
+        // Otherwise, there exists a race condition where we get stuck in the
+        // incorrect vsync period.
+        mScheduler->resyncToHardwareVsync(false, getVsyncPeriod());
         ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
         return false;
     }
@@ -1031,6 +1040,10 @@
         mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
         mDesiredActiveConfig.configId = display->getActiveConfig();
         mDesiredActiveConfigChanged = false;
+        // Update scheduler with the current vsync period as a no-op.
+        // Otherwise, there exists a race condition where we get stuck in the
+        // incorrect vsync period.
+        mScheduler->resyncToHardwareVsync(false, getVsyncPeriod());
         ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
         return false;
     }
@@ -1454,10 +1467,10 @@
         return;
     }
 
-    bool periodChanged = false;
-    mScheduler->addResyncSample(timestamp, &periodChanged);
-    if (periodChanged) {
-        mVsyncModulator.onRefreshRateChangeDetected();
+    bool periodFlushed = false;
+    mScheduler->addResyncSample(timestamp, &periodFlushed);
+    if (periodFlushed) {
+        mVsyncModulator.onRefreshRateChangeCompleted();
     }
 }