CpuConsumer: Properly track acquired buffers
CpuConsumer cannot simply assume a slot's buffer is the same buffer
between acquire and release, and therefore it could be possible for
the same slot to get used for a second acquired buffer, if there's a
producer disconnect in between. This would cause a problem when the
first buffer is released by the consumer.
Instead, use an independent list of acquired buffers to properly track
their state.
Bug: 8291751
Change-Id: I0241ad8704e53d47318c7179b13daed8181b1fab
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index 93dff32..4b956c7 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -37,7 +37,7 @@
* This queue is synchronous by default.
*/
-class CpuConsumer: public ConsumerBase
+class CpuConsumer : public ConsumerBase
{
public:
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
@@ -88,14 +88,25 @@
// Maximum number of buffers that can be locked at a time
uint32_t mMaxLockedBuffers;
+ status_t releaseAcquiredBufferLocked(int lockedIdx);
+
virtual void freeBufferLocked(int slotIndex);
- // Array for tracking pointers passed to the consumer, matching the
- // mSlots indexing
- struct LockedSlot {
+ // Tracking for buffers acquired by the user
+ struct AcquiredBuffer {
+ // Need to track the original mSlot index and the buffer itself because
+ // the mSlot entry may be freed/reused before the acquired buffer is
+ // released.
+ int mSlot;
sp<GraphicBuffer> mGraphicBuffer;
void *mBufferPointer;
- } mLockedSlots[BufferQueue::NUM_BUFFER_SLOTS];
+
+ AcquiredBuffer() :
+ mSlot(BufferQueue::INVALID_BUFFER_SLOT),
+ mBufferPointer(NULL) {
+ }
+ };
+ Vector<AcquiredBuffer> mAcquiredBuffers;
// Count of currently locked buffers
uint32_t mCurrentLockedBuffers;