Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f6b1035 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

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
parent 41f1a9f8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+29 −0
Original line number Diff line number Diff line
@@ -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) {