BLASTBufferQueue: Handler allocateBuffers on thread.

allocateBuffers is a one-way method in the IGBP interface. In
the non-BLAST case the IGBP is hosted in SF and allocateBuffers
is therefore a one-way binder call executed asynchronously on an
SF binder thread. In the BLAST case the IGBP will be in process and so
allocateBuffers will execute in a blocking fashion. Callers don't like
being blocked when they weren't before, so we want to emulate this
behavior in BLASTBufferQueue. We introduce a Surface subclass
(BBQSurface) which overrides allocateBuffers and pushes the operation to
a new thread.

Bug: 168504871
Test: asit/perf/appstartup_all_apps_cyclic_dropcache_test . Enabling
BLAST triggers regression, but applying this removes the regression.

Change-Id: If6bb411e021ba2e0886dfe96b1a1a1489e3627b8
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 0b94219..82c963b 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -23,6 +23,7 @@
 #include <gui/BLASTBufferQueue.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/GLConsumer.h>
+#include <gui/Surface.h>
 
 #include <utils/Trace.h>
 
@@ -352,4 +353,26 @@
             (!mInitialCallbackReceived && mNumAcquired == 1);
 }
 
+class BBQSurface : public Surface {
+public:
+    BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp) :
+        Surface(igbp, controlledByApp) {
+    }
+    void allocateBuffers() override {
+        uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
+        uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
+        auto gbp = getIGraphicBufferProducer();
+        std::thread ([reqWidth, reqHeight, gbp=getIGraphicBufferProducer(),
+                      reqFormat=mReqFormat, reqUsage=mReqUsage] () {
+            gbp->allocateBuffers(reqWidth, reqHeight,
+                                 reqFormat, reqUsage);
+
+        }).detach();
+    }
+};
+
+sp<Surface> BLASTBufferQueue::getSurface() {
+    return new BBQSurface(mProducer, true);
+}
+
 } // namespace android
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 634a7aa..d9644d1 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -72,6 +72,7 @@
     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
         return mProducer;
     }
+    sp<Surface> getSurface();
 
     void onBufferFreed(const wp<GraphicBuffer>&/* graphicBuffer*/) override { /* TODO */ }
     void onFrameReplaced(const BufferItem& item) override {onFrameAvailable(item);}
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index a68f2e7..800b8ef 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -120,7 +120,7 @@
      * delay during dequeueBuffer. If there are already the maximum number of
      * buffers allocated, this function has no effect.
      */
-    void allocateBuffers();
+    virtual void allocateBuffers();
 
     /* Sets the generation number on the IGraphicBufferProducer and updates the
      * generation number on any buffers attached to the Surface after this call.