single buffer mode for BufferQueue

Bug: 9891035
Change-Id: Id1ab5f911a6dc4c1d8235e65775b3d3635231ad4
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 95ba095..45488ff 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -72,6 +72,7 @@
     mOverrideMaxBufferCount(0),
     mConsumerControlledByApp(false),
     mDequeueBufferCannotBlock(false),
+    mUseAsyncBuffer(true),
     mConnectedApi(NO_CONNECTED_API),
     mAbandoned(false),
     mFrameCounter(0),
@@ -100,7 +101,8 @@
 }
 
 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
-    if (count < 2 || count > NUM_BUFFER_SLOTS)
+    const int minBufferCount = mUseAsyncBuffer ? 2 : 1;
+    if (count < minBufferCount || count > NUM_BUFFER_SLOTS)
         return BAD_VALUE;
 
     mDefaultMaxBufferCount = count;
@@ -1033,6 +1035,17 @@
     return setDefaultMaxBufferCountLocked(bufferCount);
 }
 
+status_t BufferQueue::disableAsyncBuffer() {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mMutex);
+    if (mConsumerListener != NULL) {
+        ST_LOGE("disableAsyncBuffer: consumer already connected!");
+        return INVALID_OPERATION;
+    }
+    mUseAsyncBuffer = false;
+    return NO_ERROR;
+}
+
 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
     ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
@@ -1049,8 +1062,17 @@
 }
 
 int BufferQueue::getMinUndequeuedBufferCount(bool async) const {
-    return (mDequeueBufferCannotBlock || async) ?
-                mMaxAcquiredBufferCount+1 : mMaxAcquiredBufferCount;
+    // if dequeueBuffer is allowed to error out, we don't have to
+    // add an extra buffer.
+    if (!mUseAsyncBuffer)
+        return mMaxAcquiredBufferCount;
+
+    // we're in async mode, or we want to prevent the app to
+    // deadlock itself, we throw-in an extra buffer to guarantee it.
+    if (mDequeueBufferCannotBlock || async)
+        return mMaxAcquiredBufferCount+1;
+
+    return mMaxAcquiredBufferCount;
 }
 
 int BufferQueue::getMinMaxBufferCountLocked(bool async) const {