AidlComposer: use a reader/writer per display

In order to call HWC from different threads, with one thread per
display, separate commands and their results per display.

AidlComposer:
- Add a maps from display to a ComposerClientReader and a
  ComposerClientWriter. Each reader/writer will be used by a single
  display. AidlComposer is generally threadsafe, except for these
  objects. (The other members are pointers to proxy binders, which can
  have their methods safely called from multiple threads.) Use an
  ftl::SharedMutex to guard access to the maps. The client is
  responsible for ensuring they do not attempt to access the same
  reader/writer concurrently from multiple threads. Different threads
  can access different readers/writers concurrently, but the mutex
  ensures that adding or deleting an entry does not impact access to the
  objects.
- Add a `Display` parameter to execute[Commands] and resetCommands, so
  that it only affects the intended writer. The callers already know
  which Display they care about, so pass it in.
- If no displays support DisplayCapability.MULTI_THREADED_PRESENT, use a
  single reader for all displays. This is required for backwards
  compatibility.

[Hidl]ComposerHal, MockComposer:
- update APIs for executeCommands and resetCommands
- implement onHotPlug[Connect/Disconnect]

HWComposer, fuzzer:
- pass the display to new APIs

Bug: 241285491
Test: make, boot
Change-Id: I2b62e4965b12b3c653e6c00f9f6ab4f48b506b18
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index f2a59a5..d84efe7 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -17,10 +17,12 @@
 #pragma once
 
 #include "ComposerHal.h"
+#include <ftl/shared_mutex.h>
+#include <ftl/small_map.h>
 
+#include <functional>
 #include <optional>
 #include <string>
-#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -70,10 +72,10 @@
 
     // Reset all pending commands in the command buffer. Useful if you want to
     // skip a frame but have already queued some commands.
-    void resetCommands() override;
+    void resetCommands(Display) override;
 
     // Explicitly flush all pending commands in the command buffer.
-    Error executeCommands() override;
+    Error executeCommands(Display) override;
 
     uint32_t getMaxVirtualDisplayCount() override;
     Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format,
@@ -228,16 +230,29 @@
 
     Error getPhysicalDisplayOrientation(Display displayId,
                                         AidlTransform* outDisplayOrientation) override;
+    void onHotplugConnect(Display) override;
+    void onHotplugDisconnect(Display) override;
 
 private:
     // Many public functions above simply write a command into the command
     // queue to batch the calls.  validateDisplay and presentDisplay will call
     // this function to execute the command queue.
-    Error execute();
+    Error execute(Display) REQUIRES_SHARED(mMutex);
 
     // returns the default instance name for the given service
     static std::string instance(const std::string& serviceName);
 
+    ftl::Optional<std::reference_wrapper<ComposerClientWriter>> getWriter(Display)
+            REQUIRES_SHARED(mMutex);
+    ftl::Optional<std::reference_wrapper<ComposerClientReader>> getReader(Display)
+            REQUIRES_SHARED(mMutex);
+    void addDisplay(Display) EXCLUDES(mMutex);
+    void removeDisplay(Display) EXCLUDES(mMutex);
+    void addReader(Display) REQUIRES(mMutex);
+    void removeReader(Display) REQUIRES(mMutex);
+
+    bool hasMultiThreadedPresentSupport(Display);
+
     // 64KiB minus a small space for metadata such as read/write pointers
     static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
     // Max number of buffers that may be cached for a given layer
@@ -245,8 +260,25 @@
     // 1. Tightly coupling this cache to the max size of BufferQueue
     // 2. Adding an additional slot for the layer caching feature in SurfaceFlinger (see: Planner.h)
     static const constexpr uint32_t kMaxLayerBufferCount = BufferQueue::NUM_BUFFER_SLOTS + 1;
-    ComposerClientWriter mWriter;
-    ComposerClientReader mReader;
+
+    // Without DisplayCapability::MULTI_THREADED_PRESENT, we use a single reader
+    // for all displays. With the capability, we use a separate reader for each
+    // display.
+    bool mSingleReader = true;
+    // Invalid displayId used as a key to mReaders when mSingleReader is true.
+    static constexpr int64_t kSingleReaderKey = 0;
+
+    // TODO (b/256881188): Use display::PhysicalDisplayMap instead of hard-coded `3`
+    ftl::SmallMap<Display, ComposerClientWriter, 3> mWriters GUARDED_BY(mMutex);
+    ftl::SmallMap<Display, ComposerClientReader, 3> mReaders GUARDED_BY(mMutex);
+    // Protect access to mWriters and mReaders with a shared_mutex. Adding and
+    // removing a display require exclusive access, since the iterator or the
+    // writer/reader may be invalidated. Other calls need shared access while
+    // using the writer/reader, so they can use their display's writer/reader
+    // without it being deleted or the iterator being invalidated.
+    // TODO (b/257958323): Use std::shared_mutex and RAII once they support
+    // threading annotations.
+    ftl::SharedMutex mMutex;
 
     // Aidl interface
     using AidlIComposer = aidl::android::hardware::graphics::composer3::IComposer;