BufferItemConsumer: Add onBufferFreedListener
This callback can reliably notify its listener when a GraphicBuffer is
being freed at the consumer end of a BufferQueue. This is extremely
useful when user of BufferItemConsumer caches the GraphicBuffer, so they
can listen to this callback and clean up resource properly.
Bug: 35114769
Test: Built system, flash marlin (should have no functional change as
the listener is optional).
Change-Id: I591cfd3ece697b1b4fb3efbeff987c7960422d24
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index ec77ec7..db7e944 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -37,6 +37,10 @@
public:
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
+ struct BufferFreedListener : public virtual RefBase {
+ virtual void onBufferFreed(const wp<GraphicBuffer>& graphicBuffer) = 0;
+ };
+
enum { DEFAULT_MAX_BUFFERS = -1 };
enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
@@ -57,6 +61,10 @@
// log messages.
void setName(const String8& name);
+ // setBufferFreedListener sets the listener object that will be notified
+ // when an old buffer is being freed.
+ void setBufferFreedListener(const wp<BufferFreedListener>& listener);
+
// Gets the next graphics buffer from the producer, filling out the
// passed-in BufferItem structure. Returns NO_BUFFER_AVAILABLE if the queue
// of buffers is empty, and INVALID_OPERATION if the maximum number of
@@ -81,6 +89,13 @@
status_t releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
+ private:
+ void freeBufferLocked(int slotIndex) override;
+
+ // mBufferFreedListener is the listener object that will be called when
+ // an old buffer is being freed. If it is not NULL it will be called from
+ // freeBufferLocked.
+ wp<BufferFreedListener> mBufferFreedListener;
};
} // namespace android
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 3491043..d9d50db 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -22,7 +22,7 @@
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
-//#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
//#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
//#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
//#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -57,6 +57,12 @@
mConsumer->setConsumerName(name);
}
+void BufferItemConsumer::setBufferFreedListener(
+ const wp<BufferFreedListener>& listener) {
+ Mutex::Autolock _l(mMutex);
+ mBufferFreedListener = listener;
+}
+
status_t BufferItemConsumer::acquireBuffer(BufferItem *item,
nsecs_t presentWhen, bool waitForFence) {
status_t err;
@@ -104,4 +110,14 @@
return err;
}
+void BufferItemConsumer::freeBufferLocked(int slotIndex) {
+ sp<BufferFreedListener> listener = mBufferFreedListener.promote();
+ if (listener != NULL && mSlots[slotIndex].mGraphicBuffer != NULL) {
+ // Fire callback if we have a listener registered and the buffer being freed is valid.
+ BI_LOGV("actually calling onBufferFreed");
+ listener->onBufferFreed(mSlots[slotIndex].mGraphicBuffer);
+ }
+ ConsumerBase::freeBufferLocked(slotIndex);
+}
+
} // namespace android