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
This commit is contained in:
Jamie Gennis 2012-08-27 18:48:37 -07:00 committed by Android (Google) Code Review
parent 1847f7fd79
commit 72f096fb1a
5 changed files with 56 additions and 28 deletions

View File

@ -92,13 +92,11 @@ public:
};
// 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 @@ public:
// 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 @@ private:
// 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 @@ private:
// 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

View File

@ -31,10 +31,11 @@ namespace android {
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() {

View File

@ -81,12 +81,12 @@ static const char* scalingModeName(int scalingMode) {
}
}
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 @@ int BufferQueue::query(int what, int* outValue)
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 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
}
// 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 @@ status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
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 @@ status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
}
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 {

View File

@ -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 @@ CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
mBufferQueue->setSynchronousMode(true);
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
}
CpuConsumer::~CpuConsumer() {

View File

@ -67,8 +67,7 @@ public:
*/
FramebufferSurface::FramebufferSurface():
ConsumerBase(new BufferQueue(true, NUM_FRAME_BUFFERS,
new GraphicBufferAlloc())),
ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
fbDev(0),
mCurrentBufferSlot(-1),
mCurrentBuffer(0)