Add buffer release callback in NDK
Introduce a new API, ASurfaceTransaction_setBufferWithRelease, which provides C/C++ code with the ability to register a callback function that is executed when a buffer is ready to be reused. This functionality mirrors the existing Java Transaction#setBuffer API, allowing for correct buffer management if the buffer is released when its overwritten in a transaction before the transaction is applied.
Flag: EXEMPT NDK
Test: atest ASurfaceControlTest
Bug:362513091
Change-Id: Ifcb4ad7649b4ab7966f6378a2e71d3f1a3ea7c3e
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index 82cacca..d233902 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -145,6 +145,9 @@
* Buffers which are replaced or removed from the scene in the transaction invoking
* this callback may be reused after this point.
*
+ * Starting with API level 36, prefer using \a ASurfaceTransaction_OnBufferRelease to listen
+ * to when a buffer is ready to be reused.
+ *
* \param context Optional context provided by the client that is passed into
* the callback.
*
@@ -190,6 +193,35 @@
__INTRODUCED_IN(31);
/**
+ * The ASurfaceTransaction_OnBufferRelease callback is invoked when a buffer that was passed in
+ * ASurfaceTransaction_setBuffer is ready to be reused.
+ *
+ * This callback is guaranteed to be invoked if ASurfaceTransaction_setBuffer is called with a non
+ * null buffer. If the buffer in the transaction is replaced via another call to
+ * ASurfaceTransaction_setBuffer, the callback will be invoked immediately. Otherwise the callback
+ * will be invoked before the ASurfaceTransaction_OnComplete callback after the buffer was
+ * presented.
+ *
+ * If this callback is set, caller should not release the buffer using the
+ * ASurfaceTransaction_OnComplete.
+ *
+ * \param context Optional context provided by the client that is passed into the callback.
+ *
+ * \param release_fence_fd Returns the fence file descriptor used to signal the release of buffer
+ * associated with this callback. If this fence is valid (>=0), the buffer has not yet been released
+ * and the fence will signal when the buffer has been released. If the fence is -1 , the buffer is
+ * already released. The recipient of the callback takes ownership of the fence fd and is
+ * responsible for closing it.
+ *
+ * THREADING
+ * The callback can be invoked on any thread.
+ *
+ * Available since API level 36.
+ */
+typedef void (*ASurfaceTransaction_OnBufferRelease)(void* _Null_unspecified context,
+ int release_fence_fd) __INTRODUCED_IN(36);
+
+/**
* Returns the timestamp of when the frame was latched by the framework. Once a frame is
* latched by the framework, it is presented at the following hardware vsync.
*
@@ -251,7 +283,7 @@
/**
* The returns the fence used to signal the release of the PREVIOUS buffer set on
* this surface. If this fence is valid (>=0), the PREVIOUS buffer has not yet been released and the
- * fence will signal when the PREVIOUS buffer has been released. If the fence is -1 , the PREVIOUS
+ * fence will signal when the PREVIOUS buffer has been released. If the fence is -1, the PREVIOUS
* buffer is already released. The recipient of the callback takes ownership of the
* previousReleaseFenceFd and is responsible for closing it.
*
@@ -353,6 +385,9 @@
* Note that the buffer must be allocated with AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
* as the surface control might be composited using the GPU.
*
+ * Starting with API level 36, prefer using \a ASurfaceTransaction_setBufferWithRelease to
+ * set a buffer and a callback which will be invoked when the buffer is ready to be reused.
+ *
* Available since API level 29.
*/
void ASurfaceTransaction_setBuffer(ASurfaceTransaction* _Nonnull transaction,
@@ -361,6 +396,29 @@
__INTRODUCED_IN(29);
/**
+ * Updates the AHardwareBuffer displayed for \a surface_control. If not -1, the
+ * acquire_fence_fd should be a file descriptor that is signaled when all pending work
+ * for the buffer is complete and the buffer can be safely read.
+ *
+ * The frameworks takes ownership of the \a acquire_fence_fd passed and is responsible
+ * for closing it.
+ *
+ * Note that the buffer must be allocated with AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
+ * as the surface control might be composited using the GPU.
+ *
+ * When the buffer is ready to be reused, the ASurfaceTransaction_OnBufferRelease
+ * callback will be invoked. If the buffer is null, the callback will not be invoked.
+ *
+ * Available since API level 36.
+ */
+void ASurfaceTransaction_setBufferWithRelease(ASurfaceTransaction* _Nonnull transaction,
+ ASurfaceControl* _Nonnull surface_control,
+ AHardwareBuffer* _Nonnull buffer,
+ int acquire_fence_fd, void* _Null_unspecified context,
+ ASurfaceTransaction_OnBufferRelease _Nonnull func)
+ __INTRODUCED_IN(36);
+
+/**
* Updates the color for \a surface_control. This will make the background color for the
* ASurfaceControl visible in transparent regions of the surface. Colors \a r, \a g,
* and \a b must be within the range that is valid for \a dataspace. \a dataspace and \a alpha