BQ: Modify consumer buffer count interfaces
- Rename setDefaultMaxBufferCount() to setMaxBufferCount(). Modify it
to be hard maximum on the number of buffers that can't be overwritten
by the producer.
- Enforce the maximum buffer count in setMaxAcquiredBufferCount(),
setMaxDequeuedBufferCount(), and setAsyncMode().
- Remove mOverrideMaxBufferCount as it's no longer needed since
overriding is no longer possible.
- Expose setMaxAcquiredBufferCount() in GLConsumer.
- Remove disableAsyncBuffer(), it was only being used for single buffer
mode. Single buffer mode is now achievable with setMaxBufferCount().
Bug 13174928
Change-Id: Ia33799f42751272a711fbd8559f7602ce9f18e4f
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp
index 3155766..ddf3aa8 100644
--- a/cmds/flatland/GLHelper.cpp
+++ b/cmds/flatland/GLHelper.cpp
@@ -207,7 +207,7 @@
sp<GLConsumer> glc = new GLConsumer(consumer, name,
GL_TEXTURE_EXTERNAL_OES, false, true);
glc->setDefaultBufferSize(w, h);
- glc->setDefaultMaxBufferCount(3);
+ producer->setMaxDequeuedBufferCount(2);
glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
sp<ANativeWindow> anw = new Surface(producer);
diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h
index cde302f..b2daae4 100644
--- a/include/gui/BufferQueueConsumer.h
+++ b/include/gui/BufferQueueConsumer.h
@@ -100,20 +100,8 @@
// is 1x1.
virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height);
- // setDefaultMaxBufferCount sets the default value for the maximum buffer
- // count (the initial default is 2). If the producer has requested a
- // buffer count using setBufferCount, the default buffer count will only
- // take effect if the producer sets the count back to zero.
- //
- // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
- virtual status_t setDefaultMaxBufferCount(int bufferCount);
-
- // disableAsyncBuffer disables the extra buffer used in async mode
- // (when both producer and consumer have set their "isControlledByApp"
- // flag) and has dequeueBuffer() return WOULD_BLOCK instead.
- //
- // This can only be called before connect().
- virtual status_t disableAsyncBuffer();
+ // see IGraphicBufferConsumer::setMaxBufferCount
+ virtual status_t setMaxBufferCount(int bufferCount);
// setMaxAcquiredBufferCount sets the maximum number of buffers that can
// be acquired by the consumer at one time (default 1). This call will
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index c6643ea..e824124 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -105,12 +105,6 @@
// connected, mDequeueCondition must be broadcast.
int getMaxBufferCountLocked(bool async) const;
- // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots
- // that will be used if the producer does not override the buffer slot
- // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The
- // initial default is 2.
- status_t setDefaultMaxBufferCountLocked(int count);
-
// freeBufferLocked frees the GraphicBuffer and sync resources for the
// given slot.
void freeBufferLocked(int slot);
@@ -196,10 +190,6 @@
// synchronous mode.
mutable Condition mDequeueCondition;
- // mUseAsyncBuffer indicates whether an extra buffer is used in async mode
- // to prevent dequeueBuffer from blocking.
- bool mUseAsyncBuffer;
-
// mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to
// block. This flag is set during connect when both the producer and
// consumer are controlled by the application.
@@ -222,11 +212,9 @@
// is specified.
android_dataspace mDefaultBufferDataSpace;
- // mDefaultMaxBufferCount is the default limit on the number of buffers that
- // will be allocated at one time. This default limit is set by the consumer.
- // The limit (as opposed to the default limit) may be overriden by the
- // producer.
- int mDefaultMaxBufferCount;
+ // mMaxBufferCount is the limit on the number of buffers that will be
+ // allocated at one time. This limit can be set by the consumer.
+ int mMaxBufferCount;
// 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
@@ -240,13 +228,6 @@
// via setMaxDequeuedBufferCount.
int mMaxDequeuedBufferCount;
- // mOverrideMaxBufferCount defaults to false and is set to true once the
- // producer has called setMaxDequeuedBufferCount or setAsyncMode. Once it is
- // set mDefaultMaxBufferCount is ignored and the max buffer count is
- // calculated based on mMaxAcquiredBufferCount, mMaxDequeuedBufferCount, and
- // mAsyncMode.
- bool mOverrideMaxBufferCount;
-
// mBufferHasBeenQueued is true once a buffer has been queued. It is reset
// when something causes all buffers to be freed (e.g., changing the buffer
// count).
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index c35c7be..0e4acee 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -112,11 +112,6 @@
// union fence.
void setReleaseFence(const sp<Fence>& fence);
- // setDefaultMaxBufferCount sets the default limit on the maximum number
- // of buffers that will be allocated at one time. The image producer may
- // override the limit.
- status_t setDefaultMaxBufferCount(int bufferCount);
-
// getTransformMatrix retrieves the 4x4 texture coordinate transform matrix
// associated with the texture image set by the most recent call to
// updateTexImage.
@@ -201,6 +196,7 @@
status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
status_t setConsumerUsageBits(uint32_t usage);
status_t setTransformHint(uint32_t hint);
+ status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
// detachFromContext detaches the GLConsumer from the calling thread's
// current OpenGL ES context. This context must be the same as the context
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 60ec9cc..d4c9ee5 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -188,32 +188,28 @@
// * BAD_VALUE - either w or h was zero
virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0;
- // setDefaultMaxBufferCount sets the default value for the maximum buffer
- // count (the initial default is 2). If the producer has requested a
- // buffer count using setBufferCount, the default buffer count will only
- // take effect if the producer sets the count back to zero.
+ // setMaxBufferCount sets the maximum value for the number of buffers used
+ // in the buffer queue (the initial default is NUM_BUFFER_SLOTS). If a call
+ // to setMaxAcquiredBufferCount (by the consumer), or a call to setAsyncMode
+ // or setMaxDequeuedBufferCount (by the producer), would cause this value to
+ // be exceeded then that call will fail. This call will fail if a producer
+ // is connected to the BufferQueue.
//
- // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
+ // The count must be between 1 and NUM_BUFFER_SLOTS, inclusive. The count
+ // cannot be less than maxAcquiredBufferCount.
//
// Return of a value other than NO_ERROR means an error has occurred:
// * BAD_VALUE - bufferCount was out of range (see above).
- virtual status_t setDefaultMaxBufferCount(int bufferCount) = 0;
-
- // disableAsyncBuffer disables the extra buffer used in async mode
- // (when both producer and consumer have set their "isControlledByApp"
- // flag) and has dequeueBuffer() return WOULD_BLOCK instead.
- //
- // This can only be called before consumerConnect().
- //
- // Return of a value other than NO_ERROR means an error has occurred:
- // * INVALID_OPERATION - attempting to call this after consumerConnect.
- virtual status_t disableAsyncBuffer() = 0;
+ // * INVALID_OPERATION - attempting to call this after a producer connected.
+ virtual status_t setMaxBufferCount(int bufferCount) = 0;
// setMaxAcquiredBufferCount sets the maximum number of buffers that can
// be acquired by the consumer at one time (default 1). This call will
// fail if a producer is connected to the BufferQueue.
//
- // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS.
+ // maxAcquiredBuffers must be (inclusive) between 1 and
+ // MAX_MAX_ACQUIRED_BUFFERS. It also cannot cause the maxBufferCount value
+ // to be exceeded.
//
// Return of a value other than NO_ERROR means an error has occurred:
// * BAD_VALUE - maxAcquiredBuffers was out of range (see above).
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 91502e2..5b84bdc 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -99,8 +99,9 @@
// Return of a value other than NO_ERROR means an error has occurred:
// * NO_INIT - the buffer queue has been abandoned.
// * BAD_VALUE - one of the below conditions occurred:
- // * bufferCount was out of range (see above)
- // * client has one or more buffers dequeued
+ // * bufferCount was out of range (see above)
+ // * client has one or more buffers dequeued
+ // * this call would cause the maxBufferCount value to be exceeded
virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) = 0;
// Set the async flag if the producer intends to asynchronously queue
@@ -116,7 +117,9 @@
//
// Return of a value other than NO_ERROR means an error has occurred:
// * NO_INIT - the buffer queue has been abandoned.
- // * BAD_VALUE - client has one or more buffers dequeued
+ // * BAD_VALUE - one of the below conditions occurred:
+ // * client has one or more buffers dequeued
+ // * this call would cause the maxBufferCount value to be exceeded
virtual status_t setAsyncMode(bool async) = 0;
// dequeueBuffer requests a new buffer slot for the client to use. Ownership
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 25b6719..ed2331b 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -170,8 +170,6 @@
virtual int connect(int api);
virtual int disconnect(int api);
virtual int setBufferCount(int bufferCount);
- virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
- virtual int setAsyncMode(bool async);
virtual int setBuffersDimensions(uint32_t width, uint32_t height);
virtual int setBuffersUserDimensions(uint32_t width, uint32_t height);
virtual int setBuffersFormat(PixelFormat format);
@@ -185,6 +183,8 @@
virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
public:
+ virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
+ virtual int setAsyncMode(bool async);
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
virtual int unlockAndPost();
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index bb3e1b0..950a074 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -482,24 +482,29 @@
return NO_ERROR;
}
-status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
+status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
ATRACE_CALL();
- Mutex::Autolock lock(mCore->mMutex);
- return mCore->setDefaultMaxBufferCountLocked(bufferCount);
-}
-status_t BufferQueueConsumer::disableAsyncBuffer() {
- ATRACE_CALL();
+ if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
+ return BAD_VALUE;
+ }
Mutex::Autolock lock(mCore->mMutex);
- if (mCore->mConsumerListener != NULL) {
- BQ_LOGE("disableAsyncBuffer: consumer already connected");
+ if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("setMaxBufferCount: producer is already connected");
return INVALID_OPERATION;
}
- BQ_LOGV("disableAsyncBuffer");
- mCore->mUseAsyncBuffer = false;
+ if (bufferCount < mCore->mMaxAcquiredBufferCount) {
+ BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
+ "mMaxAcquiredBufferCount (%d)", bufferCount,
+ mCore->mMaxAcquiredBufferCount);
+ return BAD_VALUE;
+ }
+
+ mCore->mMaxBufferCount = bufferCount;
return NO_ERROR;
}
@@ -521,6 +526,15 @@
return INVALID_OPERATION;
}
+ if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
+ (mCore->mAsyncMode ? 1 : 0)) > mCore->mMaxBufferCount) {
+ BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would exceed "
+ "the maxBufferCount (%d) (maxDequeued %d async %d)",
+ maxAcquiredBuffers, mCore->mMaxBufferCount,
+ mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode);
+ return BAD_VALUE;
+ }
+
BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
return NO_ERROR;
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index d297112..8b97c2a 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -30,9 +30,6 @@
#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
-template <typename T>
-static inline T max(T a, T b) { return a > b ? a : b; }
-
namespace android {
static String8 getUniqueName() {
@@ -56,16 +53,14 @@
mFreeSlots(),
mFreeBuffers(),
mDequeueCondition(),
- mUseAsyncBuffer(true),
mDequeueBufferCannotBlock(false),
mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
mDefaultWidth(1),
mDefaultHeight(1),
mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
- mDefaultMaxBufferCount(2),
+ mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
mMaxAcquiredBufferCount(1),
mMaxDequeuedBufferCount(1),
- mOverrideMaxBufferCount(false),
mBufferHasBeenQueued(false),
mFrameCounter(0),
mTransformHint(0),
@@ -145,10 +140,6 @@
int BufferQueueCore::getMinUndequeuedBufferCountLocked(bool async) const {
// If dequeueBuffer is allowed to error out, we don't have to add an
// extra buffer.
- if (!mUseAsyncBuffer) {
- return mMaxAcquiredBufferCount;
- }
-
if (mDequeueBufferCannotBlock || async) {
return mMaxAcquiredBufferCount + 1;
}
@@ -161,15 +152,11 @@
}
int BufferQueueCore::getMaxBufferCountLocked(bool async) const {
- int minMaxBufferCount = getMinMaxBufferCountLocked(async);
+ int maxBufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
+ (async ? 1 : 0);
- int maxBufferCount = max(mDefaultMaxBufferCount, minMaxBufferCount);
- if (mOverrideMaxBufferCount) {
- int bufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
- (async ? 1 : 0);
- assert(bufferCount >= minMaxBufferCount);
- maxBufferCount = bufferCount;
- }
+ // limit maxBufferCount by mMaxBufferCount always
+ maxBufferCount = std::min(mMaxBufferCount, maxBufferCount);
// Any buffers that are dequeued by the producer or sitting in the queue
// waiting to be consumed need to have their slots preserved. Such buffers
@@ -185,22 +172,6 @@
return maxBufferCount;
}
-status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
- const int minBufferCount = mUseAsyncBuffer ? 2 : 1;
- if (count < minBufferCount || count > BufferQueueDefs::NUM_BUFFER_SLOTS) {
- BQ_LOGV("setDefaultMaxBufferCount: invalid count %d, should be in "
- "[%d, %d]",
- count, minBufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- }
-
- BQ_LOGV("setDefaultMaxBufferCount: setting count to %d", count);
- mDefaultMaxBufferCount = count;
- mDequeueCondition.broadcast();
-
- return NO_ERROR;
-}
-
void BufferQueueCore::freeBufferLocked(int slot) {
BQ_LOGV("freeBufferLocked: slot %d", slot);
bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 61878f6..8cc0cfa 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -115,13 +115,20 @@
return BAD_VALUE;
}
+ if (bufferCount > mCore->mMaxBufferCount) {
+ BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would "
+ "exceed the maxBufferCount (%d) (maxAcquired %d async %d)",
+ maxDequeuedBuffers, mCore->mMaxBufferCount,
+ mCore->mMaxAcquiredBufferCount, mCore->mAsyncMode);
+ return BAD_VALUE;
+ }
+
// Here we are guaranteed that the producer doesn't have any dequeued
// buffers and will release all of its buffer references. We don't
// clear the queue, however, so that currently queued buffers still
// get displayed.
mCore->freeAllBuffersLocked();
mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
- mCore->mOverrideMaxBufferCount = true;
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
} // Autolock scope
@@ -156,8 +163,17 @@
}
}
+ if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount +
+ (async ? 1 : 0)) > mCore->mMaxBufferCount) {
+ BQ_LOGE("setAsyncMode(%d): this call would cause the "
+ "maxBufferCount (%d) to be exceeded (maxAcquired %d "
+ "maxDequeued %d)", async,mCore->mMaxBufferCount,
+ mCore->mMaxAcquiredBufferCount,
+ mCore->mMaxDequeuedBufferCount);
+ return BAD_VALUE;
+ }
+
mCore->mAsyncMode = async;
- mCore->mOverrideMaxBufferCount = true;
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
} // Autolock scope
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index be5075c..5394fb6 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -183,12 +183,6 @@
mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
}
-status_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) {
- Mutex::Autolock lock(mMutex);
- return mConsumer->setDefaultMaxBufferCount(bufferCount);
-}
-
-
status_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h)
{
Mutex::Autolock lock(mMutex);
@@ -1048,6 +1042,11 @@
return mConsumer->setTransformHint(hint);
}
+status_t GLConsumer::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
+ Mutex::Autolock lock(mMutex);
+ return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers);
+}
+
void GLConsumer::dumpLocked(String8& result, const char* prefix) const
{
result.appendFormat(
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index b86f4c5..d2f482e 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -43,8 +43,7 @@
CONSUMER_DISCONNECT,
GET_RELEASED_BUFFERS,
SET_DEFAULT_BUFFER_SIZE,
- SET_DEFAULT_MAX_BUFFER_COUNT,
- DISABLE_ASYNC_BUFFER,
+ SET_MAX_BUFFER_COUNT,
SET_MAX_ACQUIRED_BUFFER_COUNT,
SET_CONSUMER_NAME,
SET_DEFAULT_BUFFER_FORMAT,
@@ -172,21 +171,11 @@
return reply.readInt32();
}
- virtual status_t setDefaultMaxBufferCount(int bufferCount) {
+ virtual status_t setMaxBufferCount(int bufferCount) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
data.writeInt32(bufferCount);
- status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- return reply.readInt32();
- }
-
- virtual status_t disableAsyncBuffer() {
- Parcel data, reply;
- data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
+ status_t result = remote()->transact(SET_MAX_BUFFER_COUNT, data, &reply);
if (result != NO_ERROR) {
return result;
}
@@ -363,16 +352,10 @@
reply->writeInt32(result);
return NO_ERROR;
}
- case SET_DEFAULT_MAX_BUFFER_COUNT: {
+ case SET_MAX_BUFFER_COUNT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
int bufferCount = data.readInt32();
- status_t result = setDefaultMaxBufferCount(bufferCount);
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case DISABLE_ASYNC_BUFFER: {
- CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- status_t result = disableAsyncBuffer();
+ status_t result = setMaxBufferCount(bufferCount);
reply->writeInt32(result);
return NO_ERROR;
}
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 115e4db..514b5fc 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -189,6 +189,9 @@
EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
+
+ EXPECT_EQ(OK, mConsumer->setMaxBufferCount(5));
+ EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(5));
}
TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
@@ -206,6 +209,28 @@
BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
}
+TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
+ createBufferQueue();
+ sp<DummyConsumer> dc(new DummyConsumer);
+ mConsumer->consumerConnect(dc, false);
+
+ // Test single buffer mode
+ EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
+}
+
+TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
+ createBufferQueue();
+ sp<DummyConsumer> dc(new DummyConsumer);
+ mConsumer->consumerConnect(dc, false);
+
+ EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
+ EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
+ BufferQueue::NUM_BUFFER_SLOTS + 1));
+
+ EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
+ EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
+}
+
TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
createBufferQueue();
sp<DummyConsumer> dc(new DummyConsumer);
diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp b/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp
index 9776733..b4e25f3 100644
--- a/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp
@@ -134,8 +134,6 @@
}
};
- ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
-
runProducerThread(new PT());
// Allow three frames to be rendered and queued before starting the
diff --git a/libs/gui/tests/SurfaceTextureGLToGL_test.cpp b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
index 6edbfb8..b3f6066 100644
--- a/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
@@ -29,8 +29,9 @@
mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
// This test requires 3 buffers to avoid deadlock because we're
- // both producer and consumer, and only using one thread.
- mST->setDefaultMaxBufferCount(3);
+ // both producer and consumer, and only using one thread. Set max dequeued
+ // to 2, and max acquired already defaults to 1.
+ ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(2));
// Do the producer side of things
EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
@@ -81,7 +82,8 @@
mST->setDefaultBufferSize(texWidth, texHeight);
// This test requires 3 buffers to complete run on a single thread.
- mST->setDefaultMaxBufferCount(3);
+ // Set max dequeued to 2, and max acquired already defaults to 1.
+ ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(2));
// Do the producer side of things
EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
@@ -330,7 +332,8 @@
enum { texHeight = 64 };
// This test requires 3 buffers to complete run on a single thread.
- mST->setDefaultMaxBufferCount(3);
+ // Set max dequeued to 2, and max acquired already defaults to 1.
+ ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(2));
// Set the user buffer size.
native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
@@ -387,7 +390,8 @@
enum { texHeight = 16 };
// This test requires 3 buffers to complete run on a single thread.
- mST->setDefaultMaxBufferCount(3);
+ // Set max dequeued to 2, and max acquired already defaults to 1.
+ ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(2));
// Set the transform hint.
mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
@@ -448,7 +452,8 @@
enum { texHeight = 16 };
// This test requires 3 buffers to complete run on a single thread.
- mST->setDefaultMaxBufferCount(3);
+ // Set max dequeued to 2, and max acquired already defaults to 1.
+ ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(2));
// Set the transform hint.
mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index fad133f..0e85b90 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -190,7 +190,6 @@
enum { texHeight = 16 };
enum { numFrames = 1024 };
- ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
texWidth, texHeight));
ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
@@ -658,8 +657,6 @@
Mutex mMutex;
};
- ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
-
sp<Thread> pt(new ProducerThread(mANW));
pt->run();
diff --git a/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
index 1cd101e..f74ac3d 100644
--- a/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
@@ -361,7 +361,6 @@
TEST_F(SurfaceTextureMultiContextGLTest,
UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
- ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
// produce two frames and consume them both on the primary context
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
@@ -388,7 +387,6 @@
TEST_F(SurfaceTextureMultiContextGLTest,
AttachAfterDisplayTerminatedSucceeds) {
- ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
// produce two frames and consume them both on the primary context
ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 6ef3295..5574c7e 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -66,7 +66,7 @@
GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
- mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
+ mConsumer->setMaxAcquiredBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
}
status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 3180d29..07ed57d 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -92,7 +92,6 @@
mConsumer->setConsumerName(ConsumerBase::mName);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
- mConsumer->setDefaultMaxBufferCount(2);
}
VirtualDisplaySurface::~VirtualDisplaySurface() {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5ff79a9..33af4a5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -135,9 +135,8 @@
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
- mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
#else
- mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
+ mProducer->setMaxDequeuedBufferCount(2);
#endif
const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());