SF: Introduce DisplaySnapshot

DisplaySnapshot stores the immutable state of a physical display,
captured on hotplug. The SurfaceFlinger class stores a map from
PhysicalDisplayId to PhysicalDisplay, a new class that augments
this state with the sp<DisplayToken>.

Later, DisplayDevice will be removed, and SF::mDisplays will map
wp<DisplayToken> to compositionengine::Display.

Bug: 241285876
Test: libsurfaceflinger_unittest
Test: dumpsys SurfaceFlinger --displays
Change-Id: I172df87c4a7a9cf64659ff9cfbd6df195ee4bc8d
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3101885..e9e13ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -29,7 +29,6 @@
 #include <cutils/atomic.h>
 #include <cutils/compiler.h>
 #include <ftl/future.h>
-#include <ftl/small_map.h>
 #include <gui/BufferQueue.h>
 #include <gui/CompositorTiming.h>
 #include <gui/FrameTimestamps.h>
@@ -59,6 +58,8 @@
 #include <ui/FenceResult.h>
 
 #include "ClientCache.h"
+#include "Display/DisplayMap.h"
+#include "Display/PhysicalDisplay.h"
 #include "DisplayDevice.h"
 #include "DisplayHardware/HWC2.h"
 #include "DisplayHardware/PowerAdvisor.h"
@@ -515,7 +516,7 @@
     status_t getDisplayNativePrimaries(const sp<IBinder>& displayToken, ui::DisplayPrimaries&);
     status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode);
     status_t getBootDisplayModeSupport(bool* outSupport) const;
-    status_t setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id);
+    status_t setBootDisplayMode(const sp<display::DisplayToken>&, DisplayModeId);
     status_t clearBootDisplayMode(const sp<IBinder>& displayToken);
     void setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on);
     void setGameContentType(const sp<IBinder>& displayToken, bool on);
@@ -651,7 +652,7 @@
     void onInitializeDisplays() REQUIRES(mStateLock);
     // Sets the desired active mode bit. It obtains the lock, and sets mDesiredActiveMode.
     void setDesiredActiveMode(const ActiveModeInfo& info) REQUIRES(mStateLock);
-    status_t setActiveModeFromBackdoor(const sp<IBinder>& displayToken, int id);
+    status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId);
     // Sets the active mode and a new refresh rate in SF.
     void updateInternalStateWithChangedMode() REQUIRES(mStateLock);
     // Calls to setActiveMode on the main thread if there is a pending mode change
@@ -820,6 +821,10 @@
     // called when starting, or restarting after system_server death
     void initializeDisplays();
 
+    bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) const REQUIRES(mStateLock) {
+        return display->getDisplayToken() == mActiveDisplayToken;
+    }
+
     sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const
             REQUIRES(mStateLock) {
         return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
@@ -867,6 +872,21 @@
         return getDefaultDisplayDeviceLocked();
     }
 
+    using DisplayDeviceAndSnapshot =
+            std::pair<sp<DisplayDevice>, display::PhysicalDisplay::SnapshotRef>;
+
+    // Combinator for ftl::Optional<PhysicalDisplay>::and_then.
+    auto getDisplayDeviceAndSnapshot() REQUIRES(mStateLock) {
+        return [this](const display::PhysicalDisplay& display) REQUIRES(
+                       mStateLock) -> ftl::Optional<DisplayDeviceAndSnapshot> {
+            if (auto device = getDisplayDeviceLocked(display.snapshot().displayId())) {
+                return std::make_pair(std::move(device), display.snapshotRef());
+            }
+
+            return {};
+        };
+    }
+
     // Returns the first display that matches a `bool(const DisplayDevice&)` predicate.
     template <typename Predicate>
     sp<DisplayDevice> findDisplay(Predicate p) const REQUIRES(mStateLock) {
@@ -882,8 +902,13 @@
     // region of all screens presenting this layer stack.
     void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
 
-    bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) const REQUIRES(mStateLock) {
-        return display->getDisplayToken() == mActiveDisplayToken;
+    ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack)
+            REQUIRES(mStateLock) {
+        return {layerStack,
+                PhysicalDisplayId::tryCast(displayId)
+                        .and_then(display::getPhysicalDisplay(mPhysicalDisplays))
+                        .transform(&display::PhysicalDisplay::isInternal)
+                        .value_or(false)};
     }
 
     /*
@@ -959,21 +984,16 @@
     /*
      * Display identification
      */
-    sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const
+    sp<display::DisplayToken> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const
             REQUIRES(mStateLock) {
-        const sp<IBinder> nullToken;
-        return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken));
+        const sp<display::DisplayToken> nullToken;
+        return mPhysicalDisplays.get(displayId)
+                .transform([](const display::PhysicalDisplay& display) { return display.token(); })
+                .value_or(std::cref(nullToken));
     }
 
     std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
-            const sp<IBinder>& displayToken) const REQUIRES(mStateLock) {
-        for (const auto& [id, token] : mPhysicalDisplayTokens) {
-            if (token == displayToken) {
-                return id;
-            }
-        }
-        return {};
-    }
+            const sp<display::DisplayToken>&) const REQUIRES(mStateLock);
 
     // Returns the first display connected at boot.
     //
@@ -1063,7 +1083,7 @@
     /*
      * Misc
      */
-    std::vector<ui::ColorMode> getDisplayColorModes(const DisplayDevice&) REQUIRES(mStateLock);
+    std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId) REQUIRES(mStateLock);
 
     static int calculateMaxAcquiredBufferCount(Fps refreshRate,
                                                std::chrono::nanoseconds presentLatency);
@@ -1164,12 +1184,10 @@
     // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and
     // never removed, so take precedence over external and virtual displays.
     //
-    // The static capacities were chosen to exceed a typical number of physical/virtual displays.
-    //
     // May be read from any thread, but must only be written from the main thread.
-    ftl::SmallMap<wp<IBinder>, const sp<DisplayDevice>, 5> mDisplays GUARDED_BY(mStateLock);
-    ftl::SmallMap<PhysicalDisplayId, const sp<IBinder>, 3> mPhysicalDisplayTokens
-            GUARDED_BY(mStateLock);
+    display::DisplayMap<wp<IBinder>, const sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock);
+
+    display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock);
 
     struct {
         DisplayIdGenerator<GpuVirtualDisplayId> gpu;