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/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 3c06899..9d42464 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -101,13 +101,20 @@
             return NO_INIT;
         }
 
-        // There must be no dequeued buffers when changing the buffer count.
+        // The new maxDequeuedBuffer count should not be violated by the number
+        // of currently dequeued buffers
+        int dequeuedCount = 0;
         for (int s : mCore->mActiveBuffers) {
             if (mSlots[s].mBufferState.isDequeued()) {
-                BQ_LOGE("setMaxDequeuedBufferCount: buffer owned by producer");
-                return BAD_VALUE;
+                dequeuedCount++;
             }
         }
+        if (dequeuedCount > maxDequeuedBuffers) {
+            BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer"
+                    "count (%d) exceeds the current dequeued buffer count (%d)",
+                    maxDequeuedBuffers, dequeuedCount);
+            return BAD_VALUE;
+        }
 
         int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
         bufferCount += maxDequeuedBuffers;
@@ -134,21 +141,16 @@
             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.
-        if (!mCore->adjustAvailableSlotsLocked(
-                maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount)) {
-            BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue failed to adjust "
-                    "the number of available slots. Delta = %d",
-                    maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount);
+        int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
+        if (!mCore->adjustAvailableSlotsLocked(delta)) {
             return BAD_VALUE;
         }
         mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
         VALIDATE_CONSISTENCY();
+        if (delta < 0) {
+            listener = mCore->mConsumerListener;
+        }
         mCore->mDequeueCondition.broadcast();
-        listener = mCore->mConsumerListener;
     } // Autolock scope
 
     // Call back without lock held