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;