SF: Move desired active mode management to DisplayDevice

SF would set the desired active mode on the specific DisplayDevice the
mode was requested and use it to swicth the active display mode.

Change-Id: Ib4f01ec63b2087ab2a81490051d1e029afc71854
Test: SF unit tests
Test: refresh rate switching is working on device with
more than one display
Bug: 187539899

Change-Id: Ie0e5ffe364f81775c2101ffd0cf2c596051947fa
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e7067eb..afd12b5 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -39,6 +39,8 @@
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
 
+#include "MainThreadGuard.h"
+
 #include "DisplayHardware/DisplayIdentification.h"
 #include "DisplayHardware/DisplayMode.h"
 #include "DisplayHardware/Hal.h"
@@ -46,6 +48,8 @@
 
 #include "Scheduler/RefreshRateConfigs.h"
 
+#include "TracedOrdinal.h"
+
 namespace android {
 
 class Fence;
@@ -181,10 +185,28 @@
      * Display mode management.
      */
     const DisplayModePtr& getActiveMode() const;
-    void setActiveMode(DisplayModeId);
-    status_t initiateModeChange(DisplayModeId modeId,
+
+    struct ActiveModeInfo {
+        DisplayModePtr mode;
+        scheduler::RefreshRateConfigEvent event = scheduler::RefreshRateConfigEvent::None;
+
+        bool operator!=(const ActiveModeInfo& other) const {
+            return mode != other.mode || event != other.event;
+        }
+    };
+
+    bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock);
+    std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock);
+    void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock);
+    ActiveModeInfo getUpcomingActiveMode() const REQUIRES(SF_MAIN_THREAD) {
+        return mUpcomingActiveMode;
+    }
+
+    void setActiveMode(DisplayModeId) REQUIRES(SF_MAIN_THREAD);
+    status_t initiateModeChange(const ActiveModeInfo&,
                                 const hal::VsyncPeriodChangeConstraints& constraints,
-                                hal::VsyncPeriodChangeTimeline* outTimeline) const;
+                                hal::VsyncPeriodChangeTimeline* outTimeline)
+            REQUIRES(SF_MAIN_THREAD);
 
     // Return the immutable list of supported display modes. The HWC may report different modes
     // after a hotplug reconnect event, in which case the DisplayDevice object will be recreated.
@@ -236,6 +258,8 @@
     const std::shared_ptr<compositionengine::Display> mCompositionDisplay;
 
     std::string mDisplayName;
+    std::string mActiveModeFPSTrace;
+    std::string mActiveModeFPSHwcTrace;
 
     const ui::Rotation mPhysicalOrientation;
     ui::Rotation mOrientation = ui::ROTATION_0;
@@ -260,6 +284,12 @@
 
     std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
     std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay;
+
+    mutable std::mutex mActiveModeLock;
+    ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock);
+    TracedOrdinal<bool> mDesiredActiveModeChanged
+            GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false};
+    ActiveModeInfo mUpcomingActiveMode GUARDED_BY(SF_MAIN_THREAD);
 };
 
 struct DisplayDeviceState {