summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2024-09-16 05:19:46 +0000
committer Vishnu Nair <vishnun@google.com> 2024-09-16 17:10:14 +0000
commit3f6b1035c388e5db0232b9a4a4bf713f5df93058 (patch)
tree4c4d783194cd5c63fdd8261459dcc8fff9545b5a
parent41f1a9f8f99272550d3e268d95960e5da23b80b9 (diff)
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: I49fd8d21adb34c193144035cfa2bee5bd6143dab
-rw-r--r--native/android/libandroid.map.txt1
-rw-r--r--native/android/surface_control.cpp29
2 files changed, 30 insertions, 0 deletions
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 346c87daec87..b20cb77adadf 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -273,6 +273,7 @@ LIBANDROID {
ASurfaceTransaction_fromJava; # introduced=34
ASurfaceTransaction_reparent; # introduced=29
ASurfaceTransaction_setBuffer; # introduced=29
+ ASurfaceTransaction_setBufferWithRelease; # introduced=36
ASurfaceTransaction_setBufferAlpha; # introduced=29
ASurfaceTransaction_setBufferDataSpace; # introduced=29
ASurfaceTransaction_setBufferTransparency; # introduced=29
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 6ce83cd7b765..e46db6bb3727 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -416,6 +416,35 @@ void ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
transaction->setBuffer(surfaceControl, graphic_buffer, fence);
}
+void ASurfaceTransaction_setBufferWithRelease(
+ ASurfaceTransaction* aSurfaceTransaction, ASurfaceControl* aSurfaceControl,
+ AHardwareBuffer* buffer, int acquire_fence_fd, void* _Null_unspecified context,
+ ASurfaceTransaction_OnBufferRelease aReleaseCallback) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(aSurfaceControl);
+ CHECK_NOT_NULL(aReleaseCallback);
+
+ sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ sp<GraphicBuffer> graphic_buffer(GraphicBuffer::fromAHardwareBuffer(buffer));
+
+ std::optional<sp<Fence>> fence = std::nullopt;
+ if (acquire_fence_fd != -1) {
+ fence = new Fence(acquire_fence_fd);
+ }
+
+ ReleaseBufferCallback releaseBufferCallback =
+ [context,
+ aReleaseCallback](const ReleaseCallbackId&, const sp<Fence>& releaseFence,
+ std::optional<uint32_t> /* currentMaxAcquiredBufferCount */) {
+ (*aReleaseCallback)(context, (releaseFence) ? releaseFence->dup() : -1);
+ };
+
+ transaction->setBuffer(surfaceControl, graphic_buffer, fence, /* frameNumber */ std::nullopt,
+ /* producerId */ 0, releaseBufferCallback);
+}
+
void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl, const ARect& source,
const ARect& destination, int32_t transform) {