Wait for buffer allocation

In dequeueBuffer, if we don't have a free slot but are in the
process of allocating, we wait for that to complete instead of
kicking off our own allocation, as it's likely that the allocation
from allocateBuffers is able to finish earlier than if we'd kick
off our own allocation.

Test: Swipe up, see less initial buffer dequeue delay
Fixes: 111517695
Change-Id: I735d68e87fc7e2ff5b7ec3595f0ced5a94ebbf9c
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index c17a525..b353ffe 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -59,7 +59,8 @@
     mNextCallbackTicket(0),
     mCurrentCallbackTicket(0),
     mCallbackCondition(),
-    mDequeueTimeout(-1) {}
+    mDequeueTimeout(-1),
+    mDequeueWaitingForAllocation(false) {}
 
 BufferQueueProducer::~BufferQueueProducer() {}
 
@@ -383,6 +384,15 @@
     { // Autolock scope
         std::unique_lock<std::mutex> lock(mCore->mMutex);
 
+        // If we don't have a free buffer, but we are currently allocating, we wait until allocation
+        // is finished such that we don't allocate in parallel.
+        if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
+            mDequeueWaitingForAllocation = true;
+            mCore->waitWhileAllocatingLocked(lock);
+            mDequeueWaitingForAllocation = false;
+            mDequeueWaitingForAllocationCondition.notify_all();
+        }
+
         if (format == 0) {
             format = mCore->mDefaultBufferFormat;
         }
@@ -1421,6 +1431,12 @@
             mCore->mIsAllocating = false;
             mCore->mIsAllocatingCondition.notify_all();
             VALIDATE_CONSISTENCY();
+
+            // If dequeue is waiting for to allocate a buffer, release the lock until it's not
+            // waiting anymore so it can use the buffer we just allocated.
+            while (mDequeueWaitingForAllocation) {
+                mDequeueWaitingForAllocationCondition.wait(lock);
+            }
         } // Autolock scope
     }
 }