Loading libs/gui/BufferItemConsumer.cpp +28 −4 Original line number Diff line number Diff line Loading @@ -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__) Loading Loading @@ -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); Loading libs/gui/ConsumerBase.cpp +53 −7 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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__) Loading Loading @@ -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; Loading Loading @@ -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); Loading libs/gui/include/gui/BufferItemConsumer.h +12 −2 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading libs/gui/include/gui/ConsumerBase.h +12 −4 Original line number Diff line number Diff line Loading @@ -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 { // ---------------------------------------------------------------------------- Loading Loading @@ -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); Loading Loading @@ -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. Loading libs/gui/tests/BufferItemConsumer_test.cpp +37 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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 = Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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 Loading
libs/gui/BufferItemConsumer.cpp +28 −4 Original line number Diff line number Diff line Loading @@ -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__) Loading Loading @@ -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); Loading
libs/gui/ConsumerBase.cpp +53 −7 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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__) Loading Loading @@ -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; Loading Loading @@ -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); Loading
libs/gui/include/gui/BufferItemConsumer.h +12 −2 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading
libs/gui/include/gui/ConsumerBase.h +12 −4 Original line number Diff line number Diff line Loading @@ -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 { // ---------------------------------------------------------------------------- Loading Loading @@ -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); Loading Loading @@ -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. Loading
libs/gui/tests/BufferItemConsumer_test.cpp +37 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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 = Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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