[hwc-batching] Surfaceflinger code for HWC batching support.

This CL adds the SurfaceFlinger side code for supporting the new
batched commands for createLayer/DestroyLayer.

Bug: 290685621
Test: atest VtsHalGraphicsComposer3_TargetTest
      atest PerInstance/GraphicsComposerAidlBatchedCommandTest
Change-Id: I1793bda0a1eac1c2cecd0c6ab00d5df9fd8d6d0a
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index c25f9dd..f7bfbce 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -271,7 +271,10 @@
             }
         }
     }
-
+    if (getLayerLifecycleBatchCommand()) {
+        mEnableLayerCommandBatchingFlag =
+                FlagManager::getInstance().enable_layer_command_batching();
+    }
     ALOGI("Loaded AIDL composer3 HAL service");
 }
 
@@ -407,25 +410,58 @@
 
 Error AidlComposer::createLayer(Display display, Layer* outLayer) {
     int64_t layer;
-    const auto status = mAidlComposerClient->createLayer(translate<int64_t>(display),
-                                                         kMaxLayerBufferCount, &layer);
-    if (!status.isOk()) {
-        ALOGE("createLayer failed %s", status.getDescription().c_str());
-        return static_cast<Error>(status.getServiceSpecificError());
+    Error error = Error::NONE;
+    if (!mEnableLayerCommandBatchingFlag) {
+        const auto status = mAidlComposerClient->createLayer(translate<int64_t>(display),
+                                                             kMaxLayerBufferCount, &layer);
+        if (!status.isOk()) {
+            ALOGE("createLayer failed %s", status.getDescription().c_str());
+            return static_cast<Error>(status.getServiceSpecificError());
+        }
+    } else {
+        // generate a unique layerID. map in AidlComposer with <SF_layerID, HWC_layerID>
+        // Add this as a new displayCommand in execute command.
+        // return the SF generated layerID instead of calling HWC
+        layer = mLayerID++;
+        mMutex.lock_shared();
+        if (auto writer = getWriter(display)) {
+            writer->get().setLayerLifecycleBatchCommandType(translate<int64_t>(display),
+                                                            translate<int64_t>(layer),
+                                                            LayerLifecycleBatchCommandType::CREATE);
+            writer->get().setNewBufferSlotCount(translate<int64_t>(display),
+                                                translate<int64_t>(layer), kMaxLayerBufferCount);
+        } else {
+            error = Error::BAD_DISPLAY;
+        }
+        mMutex.unlock_shared();
     }
-
     *outLayer = translate<Layer>(layer);
-    return Error::NONE;
+    return error;
 }
 
 Error AidlComposer::destroyLayer(Display display, Layer layer) {
-    const auto status = mAidlComposerClient->destroyLayer(translate<int64_t>(display),
-                                                          translate<int64_t>(layer));
-    if (!status.isOk()) {
-        ALOGE("destroyLayer failed %s", status.getDescription().c_str());
-        return static_cast<Error>(status.getServiceSpecificError());
+    Error error = Error::NONE;
+    if (!mEnableLayerCommandBatchingFlag) {
+        const auto status = mAidlComposerClient->destroyLayer(translate<int64_t>(display),
+                                                              translate<int64_t>(layer));
+        if (!status.isOk()) {
+            ALOGE("destroyLayer failed %s", status.getDescription().c_str());
+            return static_cast<Error>(status.getServiceSpecificError());
+        }
+    } else {
+        mMutex.lock_shared();
+        if (auto writer = getWriter(display)) {
+            writer->get()
+                    .setLayerLifecycleBatchCommandType(translate<int64_t>(display),
+                                                       translate<int64_t>(layer),
+                                                       LayerLifecycleBatchCommandType::DESTROY);
+        } else {
+            error = Error::BAD_DISPLAY;
+        }
+        mMutex.unlock_shared();
     }
-    return Error::NONE;
+
+    return error;
 }
 
 Error AidlComposer::getActiveConfig(Display display, Config* outConfig) {
@@ -591,6 +627,13 @@
     return Error::NONE;
 }
 
+bool AidlComposer::getLayerLifecycleBatchCommand() {
+    std::vector<Capability> capabilities = getCapabilities();
+    bool hasCapability = std::find(capabilities.begin(), capabilities.end(),
+                                   Capability::LAYER_LIFECYCLE_BATCH_COMMAND) != capabilities.end();
+    return hasCapability;
+}
+
 Error AidlComposer::getOverlaySupport(AidlOverlayProperties* outProperties) {
     const auto status = mAidlComposerClient->getOverlaySupport(outProperties);
     if (!status.isOk()) {
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 51ac1f5..316cdee 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -262,7 +262,7 @@
     void removeDisplay(Display) EXCLUDES(mMutex);
     void addReader(Display) REQUIRES(mMutex);
     void removeReader(Display) REQUIRES(mMutex);
-
+    bool getLayerLifecycleBatchCommand();
     bool hasMultiThreadedPresentSupport(Display);
 
     // 64KiB minus a small space for metadata such as read/write pointers
@@ -293,6 +293,8 @@
     ftl::SharedMutex mMutex;
 
     int32_t mComposerInterfaceVersion = 1;
+    bool mEnableLayerCommandBatchingFlag = false;
+    std::atomic<int64_t> mLayerID = 1;
 
     // Buffer slots for layers are cleared by setting the slot buffer to this buffer.
     sp<GraphicBuffer> mClearSlotBuffer;
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 9b77751..cb1faee 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -127,7 +127,7 @@
     DUMP_READ_ONLY_FLAG(display_protected);
     DUMP_READ_ONLY_FLAG(fp16_client_target);
     DUMP_READ_ONLY_FLAG(game_default_frame_rate);
-
+    DUMP_READ_ONLY_FLAG(enable_layer_command_batching);
 #undef DUMP_READ_ONLY_FLAG
 #undef DUMP_SERVER_FLAG
 #undef DUMP_FLAG_INTERVAL
@@ -201,6 +201,7 @@
 FLAG_MANAGER_READ_ONLY_FLAG(display_protected, "")
 FLAG_MANAGER_READ_ONLY_FLAG(fp16_client_target, "debug.sf.fp16_client_target")
 FLAG_MANAGER_READ_ONLY_FLAG(game_default_frame_rate, "")
+FLAG_MANAGER_READ_ONLY_FLAG(enable_layer_command_batching, "")
 
 /// Trunk stable server flags ///
 FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "")
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 3a509f6..2e1d6ae 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -66,6 +66,7 @@
     bool display_protected() const;
     bool fp16_client_target() const;
     bool game_default_frame_rate() const;
+    bool enable_layer_command_batching() const;
 
 protected:
     // overridden for unit tests
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
index 3f26448..1a28b81 100644
--- a/services/surfaceflinger/surfaceflinger_flags.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -32,6 +32,14 @@
 }
 
 flag {
+  name: "enable_layer_command_batching"
+  namespace: "core_graphics"
+  description: "This flag controls batching on createLayer/destroyLayer command with executeCommand."
+  bug: "290685621"
+  is_fixed_read_only: true
+}
+
+flag {
   name: "dont_skip_on_early"
   namespace: "core_graphics"
   description: "This flag is guarding the behaviour where SurfaceFlinger is trying to opportunistically present a frame when the configuration change from late to early"