diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 0a95bb3db..3481c6f0f 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -41,6 +41,10 @@ public: enum { INVALID_BUFFER_SLOT = -1 }; enum { STALE_BUFFER_SLOT = 1, NO_BUFFER_AVAILABLE }; + // When in async mode we reserve two slots in order to guarantee that the + // producer and consumer can run asynchronously. + enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; + // ConsumerListener is the interface through which the BufferQueue notifies // the consumer of events that the consumer may wish to react to. Because // the consumer will generally have a mutex that is locked during calls from diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 4640149ac..2eee6f549 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -974,6 +974,11 @@ status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { ATRACE_CALL(); Mutex::Autolock lock(mMutex); + if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { + ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", + maxAcquiredBuffers); + return BAD_VALUE; + } if (mConnectedApi != NO_CONNECTED_API) { return INVALID_OPERATION; } diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 86017894a..817abb483 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -93,4 +93,25 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { ASSERT_EQ(INVALID_OPERATION, mBQ->acquireBuffer(&item)); } +TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { + sp dc(new DummyConsumer); + mBQ->consumerConnect(dc); + + ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(0)); + ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(-3)); + ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount( + BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1)); + ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(100)); +} + +TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { + sp dc(new DummyConsumer); + mBQ->consumerConnect(dc); + + ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(1)); + ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(2)); + ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount( + BufferQueue::MAX_MAX_ACQUIRED_BUFFERS)); +} + } // namespace android