diff options
author | 2024-09-16 05:19:46 +0000 | |
---|---|---|
committer | 2024-09-16 17:10:14 +0000 | |
commit | 3f6b1035c388e5db0232b9a4a4bf713f5df93058 (patch) | |
tree | 4c4d783194cd5c63fdd8261459dcc8fff9545b5a | |
parent | 41f1a9f8f99272550d3e268d95960e5da23b80b9 (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.txt | 1 | ||||
-rw-r--r-- | native/android/surface_control.cpp | 29 |
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) { |