SF: Fix mode setting for secondary displays

Desired modes were only propagated to HWC for the "active" display, i.e.
generally the primary display and specially the rear display when in the
folded state. In other words, mode setting did not happen for external
displays, and the rear display when driving both displays concurrently.

Store per-display state for whether a mode set is pending. Propagate the
desired mode for both internal and external displays as long as they are
powered on.

Fixes: 277776378
Fixes: 289182528
Bug: 255635711
Bug: 255635821
Test: The 60 Hz constraint applies to both displays in concurrent mode.
Test: ADB `set-user-preferred-display-mode` applies to external display.
Test: DisplayModeSwitchingTest#inner{Xor,And}OuterDisplay
Test: DisplayModeSwitchingTest#powerOffDuringModeSet
Change-Id: I9da3a0be07f9fbb08f11485aa6ab9400259a4e09
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b07910d..f61f9a2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -638,7 +638,8 @@
 
     // ICompositor overrides:
     void configure() override REQUIRES(kMainThreadContext);
-    bool commit(const scheduler::FrameTarget&) override REQUIRES(kMainThreadContext);
+    bool commit(PhysicalDisplayId pacesetterId, const scheduler::FrameTargets&) override
+            REQUIRES(kMainThreadContext);
     CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
                                          const scheduler::FrameTargeters&) override
             REQUIRES(kMainThreadContext);
@@ -684,11 +685,10 @@
             REQUIRES(mStateLock);
 
     status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId);
-    // Sets the active mode and a new refresh rate in SF.
-    void updateInternalStateWithChangedMode() REQUIRES(mStateLock, kMainThreadContext);
-    // Calls to setActiveMode on the main thread if there is a pending mode change
-    // that needs to be applied.
-    void setActiveModeInHwcIfNeeded() REQUIRES(mStateLock, kMainThreadContext);
+
+    void initiateDisplayModeChanges() REQUIRES(mStateLock, kMainThreadContext);
+    void finalizeDisplayModeChange(DisplayDevice&) REQUIRES(mStateLock, kMainThreadContext);
+
     void clearDesiredActiveModeState(const sp<DisplayDevice>&) REQUIRES(mStateLock);
     // Called when active mode is no longer is progress
     void desiredActiveModeChangeDone(const sp<DisplayDevice>&) REQUIRES(mStateLock);
@@ -1011,7 +1011,9 @@
                                const DisplayDeviceState& drawingState)
             REQUIRES(mStateLock, kMainThreadContext);
 
-    void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected);
+    void dispatchDisplayHotplugEvent(PhysicalDisplayId, bool connected);
+    void dispatchDisplayModeChangeEvent(PhysicalDisplayId, const scheduler::FrameRateMode&)
+            REQUIRES(mStateLock);
 
     /*
      * VSYNC
@@ -1330,9 +1332,6 @@
     std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
     scheduler::PresentLatencyTracker mPresentLatencyTracker GUARDED_BY(kMainThreadContext);
 
-    // below flags are set by main thread only
-    bool mSetActiveModePending = false;
-
     bool mLumaSampling = true;
     sp<RegionSamplingThread> mRegionSamplingThread;
     sp<FpsReporter> mFpsReporter;