BufferQueue: use max acquired buffer count
This change makes BufferQueue derive the min undequeued buffer count from a max
acquired buffer count that is set by the consumer. This value may be set at
any time that a producer is not connected to the BufferQueue rather than at
BufferQueue construction time.
Change-Id: Icf9f1d91ec612a079968ba0a4621deffe48f4e22
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 5b68b05..0a95bb3 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -92,13 +92,11 @@
};
- // BufferQueue manages a pool of gralloc memory slots to be used
- // by producers and consumers.
- // allowSynchronousMode specifies whether or not synchronous mode can be
- // enabled.
- // bufferCount sets the minimum number of undequeued buffers for this queue
+ // BufferQueue manages a pool of gralloc memory slots to be used by
+ // producers and consumers. allowSynchronousMode specifies whether or not
+ // synchronous mode can be enabled by the producer. allocator is used to
+ // allocate all the needed gralloc buffers.
BufferQueue(bool allowSynchronousMode = true,
- int bufferCount = MIN_UNDEQUEUED_BUFFERS,
const sp<IGraphicBufferAlloc>& allocator = NULL);
virtual ~BufferQueue();
@@ -257,6 +255,11 @@
// take effect once the client sets the count back to zero.
status_t setDefaultMaxBufferCount(int bufferCount);
+ // setMaxAcquiredBufferCount sets the maximum number of buffers that can
+ // be acquired by the consumer at one time. This call will fail if a
+ // producer is connected to the BufferQueue.
+ status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
+
// isSynchronousMode returns whether the SurfaceTexture is currently in
// synchronous mode.
bool isSynchronousMode() const;
@@ -307,12 +310,16 @@
// given the current BufferQueue state.
int getMinMaxBufferCountLocked() const;
+ // getMinUndequeuedBufferCountLocked returns the minimum number of buffers
+ // that must remain in a state other than DEQUEUED.
+ int getMinUndequeuedBufferCountLocked() const;
+
// getMaxBufferCountLocked returns the maximum number of buffers that can
// be allocated at once. This value depends upon the following member
// variables:
//
// mSynchronousMode
- // mMinUndequeuedBuffers
+ // mMaxAcquiredBufferCount
// mDefaultMaxBufferCount
// mOverrideMaxBufferCount
//
@@ -442,9 +449,14 @@
// in requestBuffers() if a width and height of zero is specified.
uint32_t mDefaultHeight;
- // mMinUndequeuedBuffers is a constraint on the number of buffers
- // not dequeued at any time
- int mMinUndequeuedBuffers;
+ // mMaxAcquiredBufferCount is the number of buffers that the consumer may
+ // acquire at one time. It defaults to 1 and can be changed by the
+ // consumer via the setMaxAcquiredBufferCount method, but this may only be
+ // done when no producer is connected to the BufferQueue.
+ //
+ // This value is used to derive the value returned for the
+ // MIN_UNDEQUEUED_BUFFERS query by the producer.
+ int mMaxAcquiredBufferCount;
// mDefaultMaxBufferCount is the default limit on the number of buffers
// that will be allocated at one time. This default limit is set by the
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 218d929..57df39c 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -31,10 +31,11 @@
BufferItemConsumer::BufferItemConsumer(uint32_t consumerUsage,
int bufferCount, bool synchronousMode) :
- ConsumerBase(new BufferQueue(true, bufferCount) )
+ ConsumerBase(new BufferQueue(true) )
{
mBufferQueue->setConsumerUsageBits(consumerUsage);
mBufferQueue->setSynchronousMode(synchronousMode);
+ mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
}
BufferItemConsumer::~BufferItemConsumer() {
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 6689e84..db021ff 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -81,12 +81,12 @@
}
}
-BufferQueue::BufferQueue(bool allowSynchronousMode, int bufferCount,
+BufferQueue::BufferQueue(bool allowSynchronousMode,
const sp<IGraphicBufferAlloc>& allocator) :
mDefaultWidth(1),
mDefaultHeight(1),
- mMinUndequeuedBuffers(bufferCount),
- mDefaultMaxBufferCount(bufferCount + 1),
+ mMaxAcquiredBufferCount(1),
+ mDefaultMaxBufferCount(2),
mOverrideMaxBufferCount(0),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
@@ -233,8 +233,7 @@
value = mDefaultBufferFormat;
break;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
- value = mSynchronousMode ?
- (mMinUndequeuedBuffers-1) : mMinUndequeuedBuffers;
+ value = getMinUndequeuedBufferCountLocked();
break;
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
value = (mQueue.size() >= 2);
@@ -356,17 +355,18 @@
}
// See whether a buffer has been queued since the last
- // setBufferCount so we know whether to perform the
- // mMinUndequeuedBuffers check below.
+ // setBufferCount so we know whether to perform the min undequeued
+ // buffers check below.
if (mBufferHasBeenQueued) {
// make sure the client is not trying to dequeue more buffers
// than allowed.
- const int avail = maxBufferCount - (dequeuedCount+1);
- if (avail < (mMinUndequeuedBuffers-int(mSynchronousMode))) {
- ST_LOGE("dequeueBuffer: mMinUndequeuedBuffers=%d exceeded "
- "(dequeued=%d)",
- mMinUndequeuedBuffers-int(mSynchronousMode),
- dequeuedCount);
+ const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
+ const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
+ if (newUndequeuedCount < minUndequeuedCount) {
+ ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
+ "exceeded (dequeued=%d undequeudCount=%d)",
+ minUndequeuedCount, dequeuedCount,
+ newUndequeuedCount);
return -EBUSY;
}
}
@@ -954,6 +954,16 @@
return setDefaultMaxBufferCountLocked(bufferCount);
}
+status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mMutex);
+ if (mConnectedApi != NO_CONNECTED_API) {
+ return INVALID_OPERATION;
+ }
+ mMaxAcquiredBufferCount = maxAcquiredBuffers;
+ return OK;
+}
+
void BufferQueue::freeAllBuffersExceptHeadLocked() {
int head = -1;
if (!mQueue.empty()) {
@@ -996,7 +1006,12 @@
}
int BufferQueue::getMinMaxBufferCountLocked() const {
- return mSynchronousMode ? mMinUndequeuedBuffers : mMinUndequeuedBuffers + 1;
+ return getMinUndequeuedBufferCountLocked() + 1;
+}
+
+int BufferQueue::getMinUndequeuedBufferCountLocked() const {
+ return mSynchronousMode ? mMaxAcquiredBufferCount :
+ mMaxAcquiredBufferCount + 1;
}
int BufferQueue::getMaxBufferCountLocked() const {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index 242ac45..fc4a854 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -30,7 +30,7 @@
namespace android {
CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
- ConsumerBase(new BufferQueue(true, maxLockedBuffers) ),
+ ConsumerBase(new BufferQueue(true) ),
mMaxLockedBuffers(maxLockedBuffers),
mCurrentLockedBuffers(0)
{
@@ -41,6 +41,7 @@
mBufferQueue->setSynchronousMode(true);
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
+ mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
}
CpuConsumer::~CpuConsumer() {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index d601fca..7fb1159 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -67,8 +67,7 @@
*/
FramebufferSurface::FramebufferSurface():
- ConsumerBase(new BufferQueue(true, NUM_FRAME_BUFFERS,
- new GraphicBufferAlloc())),
+ ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
fbDev(0),
mCurrentBufferSlot(-1),
mCurrentBuffer(0)