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

Commit 60809ebb authored by Jim Shargo's avatar Jim Shargo Committed by Android (Google) Code Review
Browse files

Merge "libgui: Add simpler methods to ConsumerBase and BufferItemConsumer." into main

parents d2ce9b79 28e9d655
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -21,8 +21,11 @@

#include <inttypes.h>

#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
#include <ui/BufferQueueDefs.h>
#include <ui/GraphicBuffer.h>

#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -87,17 +90,38 @@ status_t BufferItemConsumer::acquireBuffer(BufferItem *item,

status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
        const sp<Fence>& releaseFence) {
    status_t err;
    Mutex::Autolock _l(mMutex);
    return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer,
                                           const sp<Fence>& releaseFence) {
    Mutex::Autolock _l(mMutex);

    err = addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
    if (buffer == nullptr) {
        return BAD_VALUE;
    }

    int slotIndex = getSlotForBufferLocked(buffer);
    if (slotIndex == INVALID_BUFFER_SLOT) {
        return BAD_VALUE;
    }

    return releaseBufferSlotLocked(slotIndex, buffer, releaseFence);
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
                                                     const sp<Fence>& releaseFence) {
    status_t err;

    err = addReleaseFenceLocked(slotIndex, buffer, releaseFence);
    if (err != OK) {
        BI_LOGE("Failed to addReleaseFenceLocked");
    }

    err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY,
            EGL_NO_SYNC_KHR);
    err = releaseBufferLocked(slotIndex, buffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
    if (err != OK && err != IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
        BI_LOGE("Failed to release buffer: %s (%d)",
                strerror(-err), err);
+53 −7
Original line number Diff line number Diff line
@@ -30,9 +30,10 @@
#include <cutils/atomic.h>

#include <gui/BufferItem.h>
#include <gui/ConsumerBase.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/ConsumerBase.h>
#include <ui/BufferQueueDefs.h>

#include <private/gui/ComposerService.h>

@@ -40,6 +41,8 @@
#include <utils/String8.h>
#include <utils/Trace.h>

#include <com_android_graphics_libgui_flags.h>

// Macros for including the ConsumerBase name in log messages
#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -96,6 +99,35 @@ void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) {
    abandon();
}

int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) {
    if (!buffer) {
        return BufferQueue::INVALID_BUFFER_SLOT;
    }

    uint64_t id = buffer->getId();
    for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
        auto& slot = mSlots[i];
        if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) {
            return i;
        }
    }

    return BufferQueue::INVALID_BUFFER_SLOT;
}

status_t ConsumerBase::detachBufferLocked(int slotIndex) {
    status_t result = mConsumer->detachBuffer(slotIndex);

    if (result != NO_ERROR) {
        CB_LOGE("Failed to detach buffer: %d", result);
        return result;
    }

    freeBufferLocked(slotIndex);

    return result;
}

void ConsumerBase::freeBufferLocked(int slotIndex) {
    CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
    mSlots[slotIndex].mGraphicBuffer = nullptr;
@@ -252,16 +284,30 @@ status_t ConsumerBase::detachBuffer(int slot) {
        return NO_INIT;
    }

    status_t result = mConsumer->detachBuffer(slot);
    if (result != NO_ERROR) {
        CB_LOGE("Failed to detach buffer: %d", result);
        return result;
    return detachBufferLocked(slot);
}

    freeBufferLocked(slot);
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) {
    CB_LOGV("detachBuffer");
    Mutex::Autolock lock(mMutex);

    return result;
    if (mAbandoned) {
        CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
        return NO_INIT;
    }
    if (buffer == nullptr) {
        return BAD_VALUE;
    }

    int slotIndex = getSlotForBufferLocked(buffer);
    if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
        return BAD_VALUE;
    }

    return detachBufferLocked(slotIndex);
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
    Mutex::Autolock _l(mMutex);
+12 −2
Original line number Diff line number Diff line
@@ -17,13 +17,15 @@
#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H
#define ANDROID_GUI_BUFFERITEMCONSUMER_H

#include <gui/ConsumerBase.h>
#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueue.h>
#include <gui/ConsumerBase.h>

#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer"

namespace android {

class GraphicBuffer;
class String8;

/**
@@ -85,7 +87,15 @@ class BufferItemConsumer: public ConsumerBase
    status_t releaseBuffer(const BufferItem &item,
            const sp<Fence>& releaseFence = Fence::NO_FENCE);

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
    status_t releaseBuffer(const sp<GraphicBuffer>& buffer,
                           const sp<Fence>& releaseFence = Fence::NO_FENCE);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

private:
    status_t releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
                                     const sp<Fence>& releaseFence);

    void freeBufferLocked(int slotIndex) override;

    // mBufferFreedListener is the listener object that will be called when
+12 −4
Original line number Diff line number Diff line
@@ -17,18 +17,16 @@
#ifndef ANDROID_GUI_CONSUMERBASE_H
#define ANDROID_GUI_CONSUMERBASE_H

#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueueDefs.h>
#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/OccupancyTracker.h>

#include <ui/PixelFormat.h>

#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/threads.h>


namespace android {
// ----------------------------------------------------------------------------

@@ -81,7 +79,13 @@ public:
    void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);

    // See IGraphicBufferConsumer::detachBuffer
    status_t detachBuffer(int slot);
    status_t detachBuffer(int slot) __attribute((
            deprecated("Please use the GraphicBuffer variant--slots are deprecated.")));

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
    // See IGraphicBufferConsumer::detachBuffer
    status_t detachBuffer(const sp<GraphicBuffer>& buffer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

    // See IGraphicBufferConsumer::setDefaultBufferSize
    status_t setDefaultBufferSize(uint32_t width, uint32_t height);
@@ -150,6 +154,10 @@ protected:
    virtual void onBuffersReleased() override;
    virtual void onSidebandStreamChanged() override;

    virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer);

    virtual status_t detachBufferLocked(int slotIndex);

    // freeBufferLocked frees up the given buffer slot.  If the slot has been
    // initialized this will release the reference to the GraphicBuffer in that
    // slot.  Otherwise it has no effect.
+37 −1
Original line number Diff line number Diff line
@@ -17,10 +17,12 @@
#define LOG_TAG "BufferItemConsumer_test"
//#define LOG_NDEBUG 0

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
#include <ui/GraphicBuffer.h>

namespace android {

@@ -42,6 +44,17 @@ class BufferItemConsumerTest : public ::testing::Test {
        BufferItemConsumerTest* mTest;
    };

    struct TrackingProducerListener : public BnProducerListener {
        TrackingProducerListener(BufferItemConsumerTest* test) : mTest(test) {}

        virtual void onBufferReleased() override {}
        virtual bool needsReleaseNotify() override { return true; }
        virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
        virtual void onBufferDetached(int slot) override { mTest->HandleBufferDetached(slot); }

        BufferItemConsumerTest* mTest;
    };

    void SetUp() override {
        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
        mBIC =
@@ -51,7 +64,7 @@ class BufferItemConsumerTest : public ::testing::Test {
        mBFL = new BufferFreedListener(this);
        mBIC->setBufferFreedListener(mBFL);

        sp<IProducerListener> producerListener = new StubProducerListener();
        sp<IProducerListener> producerListener = new TrackingProducerListener(this);
        IGraphicBufferProducer::QueueBufferOutput bufferOutput;
        ASSERT_EQ(NO_ERROR,
                  mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
@@ -71,6 +84,13 @@ class BufferItemConsumerTest : public ::testing::Test {
        ALOGD("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
    }

    void HandleBufferDetached(int slot) {
        std::lock_guard<std::mutex> lock(mMutex);
        mDetachedBufferSlots.push_back(slot);
        ALOGD("HandleBufferDetached, slot=%d mDetachedBufferSlots-count=%zu", slot,
              mDetachedBufferSlots.size());
    }

    void DequeueBuffer(int* outSlot) {
        ASSERT_NE(outSlot, nullptr);

@@ -120,6 +140,7 @@ class BufferItemConsumerTest : public ::testing::Test {

    std::mutex mMutex;
    int mFreedBufferCount{0};
    std::vector<int> mDetachedBufferSlots = {};

    sp<BufferItemConsumer> mBIC;
    sp<BufferFreedListener> mBFL;
@@ -203,4 +224,19 @@ TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DeleteBufferItemConsumer) {
    ASSERT_EQ(1, GetFreedBufferCount());
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
// Test that delete BufferItemConsumer triggers onBufferFreed.
TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) {
    int slot;
    // Let buffer go through the cycle at least once.
    DequeueBuffer(&slot);
    QueueBuffer(slot);
    AcquireBuffer(&slot);

    sp<GraphicBuffer> buffer = mBuffers[slot];
    EXPECT_EQ(OK, mBIC->detachBuffer(buffer));
    EXPECT_THAT(mDetachedBufferSlots, testing::ElementsAre(slot));
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)

}  // namespace android