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
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 6689e84..db021ff 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -81,12 +81,12 @@
     }
 }
 
-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 @@
         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 @@
             }
 
             // 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 @@
     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 @@
 }
 
 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 {