BufferQueue: release mutex while allocating. DO NOT MERGE
BufferQueueProducer::allocateBuffers used to keep the BufferQueueCore
mutex while doing the buffer allocation, which would cause the consumer
(which also needs the mutex) to block if the allocation takes a long
time.
Instead, release the mutex while doing the allocation, and grab it again
before filling the slots. Keep a bool state and a condvar to prevent
other producers from trying to allocate the slots while the mutex is
released.
Bug: 11792166
Change-Id: I4ab1319995ef892be2beba892f1fdbf50ce0416d
(cherry picked from commit ea96044470a29133321c681080870b9d31f81a19)
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index cfcb7a5..1050e3b 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -120,6 +120,9 @@
// in one of the slots.
bool stillTracking(const BufferItem* item) const;
+ // waitWhileAllocatingLocked blocks until mIsAllocating is false.
+ void waitWhileAllocatingLocked() const;
+
// mAllocator is the connection to SurfaceFlinger that is used to allocate
// new GraphicBuffer objects.
sp<IGraphicBufferAlloc> mAllocator;
@@ -234,6 +237,15 @@
// mSidebandStream is a handle to the sideband buffer stream, if any
sp<NativeHandle> mSidebandStream;
+ // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which
+ // releases mMutex while doing the allocation proper). Producers should not modify any of the
+ // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to
+ // false.
+ bool mIsAllocating;
+
+ // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
+ // becomes false.
+ mutable Condition mIsAllocatingCondition;
}; // class BufferQueueCore
} // namespace android