Plumb buffer latencies and present fences out of Composer HAL (hardware/interfaces code)

Bug: 337330263
Test: build
Flag: EXEMPT HAL interface change
Change-Id: I11aca94c808448b0e2b1dbd6f0ec4f54b3b217b7
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
index 3bb09cd..5a77e22 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
@@ -36,4 +36,10 @@
 parcelable PresentFence {
   long display;
   ParcelFileDescriptor fence;
+  @nullable android.hardware.graphics.composer3.PresentFence.LayerPresentFence[] layerPresentFences;
+  parcelable LayerPresentFence {
+    long layer;
+    ParcelFileDescriptor bufferFence;
+    long bufferLatencyNanos;
+  }
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index b757656..0d8ea76 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -27,4 +27,40 @@
      * The present fence for this display.
      */
     ParcelFileDescriptor fence;
+
+    /**
+     * A LayerPresentFence is provided by the server when a LayerCommand.pictureProfileId, specified
+     * by the client, results in the buffer being rendered on the display with some latency after
+     * the rest of the DisplayCommand has been rendered. This can happen due to the picture
+     * processing pipeline adding additional latency for the buffer, itself. LayerPresentFences are
+     * intended to arrive in the same order for each buffer submission on that layer.
+     *
+     * Note that this violates the SurfaceControl.Transaction API contract and therefore is only
+     * allowed on TV devices that require this feature to support high quality video playback on
+     * large displays.
+     */
+    parcelable LayerPresentFence {
+        /**
+         * The layer which this fence refers to.
+         */
+        long layer;
+
+        /**
+         * The present fence for the buffer contents.
+         *
+         * If the buffer ends up being dropped by the server and not rendered, this fence should be
+         * fired at the same time as the next buffer's present fence (or the display fence if
+         * picture processing for this layer was removed).
+         */
+        ParcelFileDescriptor bufferFence;
+
+        /**
+         * The latency that is required for applying picture processing to the layer's buffer.
+         */
+        long bufferLatencyNanos;
+    }
+    /**
+     * The LayerPresentFences for the display.
+     */
+    @nullable LayerPresentFence[] layerPresentFences;
 }
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index 07c9c6d..2196530 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -145,6 +145,18 @@
         return std::move(data.releasedLayers);
     }
 
+    // Get and clear saved layer present fences.
+    std::vector<PresentFence::LayerPresentFence> takeLayerPresentFences(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.layerPresentFences);
+    }
+
     // Get and clear saved present fence.
     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
@@ -223,6 +235,14 @@
         LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
         auto& data = mReturnData[presentFence.display];
         data.presentFence = std::move(presentFence.fence);
+
+        if (presentFence.layerPresentFences.has_value()) {
+            for (auto& optionalFence : presentFence.layerPresentFences.value()) {
+                if (optionalFence.has_value()) {
+                    data.layerPresentFences.push_back(std::move(optionalFence.value()));
+                }
+            }
+        }
     }
 
     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
@@ -260,6 +280,7 @@
         DisplayRequest displayRequests;
         std::vector<ChangedCompositionLayer> changedLayers;
         ndk::ScopedFileDescriptor presentFence;
+        std::vector<PresentFence::LayerPresentFence> layerPresentFences;
         std::vector<ReleaseFences::Layer> releasedLayers;
         PresentOrValidate::Result presentOrValidateState;