BQ: Flexible resizing
- Allow the producer to call setMaxDequeuedBufferCount and the
consumer to call setMaxAcquiredBufferCount when buffers are
currently dequeued/acquired as long as the new value is not less
than the number of dequeued/acquired buffers.
Bug 22768206
Change-Id: I599a4027a6ae9cb0a1c0d5ec60cb5e65b86a345b
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 9c1bbe4..92285e5 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -611,35 +611,59 @@
return BAD_VALUE;
}
- Mutex::Autolock lock(mCore->mMutex);
+ sp<IConsumerListener> listener;
+ { // Autolock scope
+ Mutex::Autolock lock(mCore->mMutex);
+ mCore->waitWhileAllocatingLocked();
- if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
- return INVALID_OPERATION;
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
+ return NO_INIT;
+ }
+
+ // The new maxAcquiredBuffers count should not be violated by the number
+ // of currently acquired buffers
+ int acquiredCount = 0;
+ for (int slot : mCore->mActiveBuffers) {
+ if (mSlots[slot].mBufferState.isAcquired()) {
+ acquiredCount++;
+ }
+ }
+ if (acquiredCount > maxAcquiredBuffers) {
+ BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
+ "count (%d) exceeds the current acquired buffer count (%d)",
+ maxAcquiredBuffers, acquiredCount);
+ return BAD_VALUE;
+ }
+
+ if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
+ (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 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 ||
+ mCore->mDequeueBufferCannotBlock);
+ return BAD_VALUE;
+ }
+
+ int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
+ return BAD_VALUE;
+ }
+
+ BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
+ mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
+ VALIDATE_CONSISTENCY();
+ if (delta < 0) {
+ listener = mCore->mConsumerListener;
+ }
+ }
+ // Call back without lock held
+ if (listener != NULL) {
+ listener->onBuffersReleased();
}
- if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
- (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 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 ||
- mCore->mDequeueBufferCannotBlock);
- return BAD_VALUE;
- }
-
- if (!mCore->adjustAvailableSlotsLocked(
- maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount)) {
- BQ_LOGE("setMaxAcquiredBufferCount: BufferQueue failed to adjust the "
- "number of available slots. Delta = %d",
- maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount);
- return BAD_VALUE;
- }
-
- BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
- mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
- VALIDATE_CONSISTENCY();
return NO_ERROR;
}