Create EGLImages during buffer allocation

EGLImage creation is now performed on an async binder thread, so now GPU
composition should rarely be stalled by expensive image creation.

Bug: 129008989
Test: systrace
Change-Id: I9732f866933a8950a4c69ff51d5ac1622bbb3470
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 5fb3f0b..d87228f 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -59,6 +59,13 @@
     }
 }
 
+void BufferQueue::ProxyConsumerListener::onBufferAllocated(const BufferItem& item) {
+    sp<ConsumerListener> listener(mConsumerListener.promote());
+    if (listener != nullptr) {
+        listener->onBufferAllocated(item);
+    }
+}
+
 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
     sp<ConsumerListener> listener(mConsumerListener.promote());
     if (listener != nullptr) {
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index a462b03..e657488 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -530,6 +530,13 @@
                 return NO_INIT;
             }
 
+            if (mCore->mConsumerListener != nullptr) {
+                BufferItem item;
+                item.mGraphicBuffer = graphicBuffer;
+                item.mSlot = *outSlot;
+                mCore->mConsumerListener->onBufferAllocated(item);
+            }
+
             VALIDATE_CONSISTENCY();
         } // Autolock scope
     }
@@ -1414,6 +1421,13 @@
                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
                         *slot);
 
+                if (mCore->mConsumerListener != nullptr) {
+                    BufferItem item;
+                    item.mGraphicBuffer = buffers[i];
+                    item.mSlot = *slot;
+                    mCore->mConsumerListener->onBufferAllocated(item);
+                }
+
                 // Make sure the erase is done after all uses of the slot
                 // iterator since it will be invalid after this point.
                 mCore->mFreeSlots.erase(slot);
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index abd9921..1e94cc1 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -131,6 +131,8 @@
     }
 }
 
+void ConsumerBase::onBufferAllocated(const BufferItem& /*item*/) {}
+
 void ConsumerBase::onBuffersReleased() {
     Mutex::Autolock lock(mMutex);
 
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index 85ac304..ea9045c 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -28,7 +28,8 @@
     ON_FRAME_REPLACED,
     ON_BUFFERS_RELEASED,
     ON_SIDEBAND_STREAM_CHANGED,
-    LAST = ON_SIDEBAND_STREAM_CHANGED,
+    ON_BUFFER_ALLOCATED,
+    LAST = ON_BUFFER_ALLOCATED,
 };
 
 } // Anonymous namespace
@@ -54,6 +55,11 @@
                                                                        item);
     }
 
+    void onBufferAllocated(const BufferItem& item) override {
+        callRemoteAsync<decltype(&IConsumerListener::onBufferAllocated)>(Tag::ON_BUFFER_ALLOCATED,
+                                                                         item);
+    }
+
     void onBuffersReleased() override {
         callRemoteAsync<decltype(&IConsumerListener::onBuffersReleased)>(Tag::ON_BUFFERS_RELEASED);
     }
@@ -89,6 +95,8 @@
             return callLocalAsync(data, reply, &IConsumerListener::onFrameAvailable);
         case Tag::ON_FRAME_REPLACED:
             return callLocalAsync(data, reply, &IConsumerListener::onFrameReplaced);
+        case Tag::ON_BUFFER_ALLOCATED:
+            return callLocalAsync(data, reply, &IConsumerListener::onBufferAllocated);
         case Tag::ON_BUFFERS_RELEASED:
             return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased);
         case Tag::ON_SIDEBAND_STREAM_CHANGED:
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index da95274..721427b 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -61,6 +61,7 @@
         void onDisconnect() override;
         void onFrameAvailable(const BufferItem& item) override;
         void onFrameReplaced(const BufferItem& item) override;
+        void onBufferAllocated(const BufferItem& item) override;
         void onBuffersReleased() override;
         void onSidebandStreamChanged() override;
         void addAndGetFrameTimestamps(
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index 366ced3..7c26482 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -141,6 +141,7 @@
     // classes if they want the notification.
     virtual void onFrameAvailable(const BufferItem& item) override;
     virtual void onFrameReplaced(const BufferItem& item) override;
+    virtual void onBufferAllocated(const BufferItem& item) override;
     virtual void onBuffersReleased() override;
     virtual void onSidebandStreamChanged() override;
 
diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h
index c082882..03fefbe 100644
--- a/libs/gui/include/gui/IConsumerListener.h
+++ b/libs/gui/include/gui/IConsumerListener.h
@@ -61,6 +61,13 @@
     // This is called without any lock held and can be called concurrently by multiple threads.
     virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */
 
+    // onBufferAllocated is called to notify the buffer consumer that the BufferQueue has allocated
+    // a GraphicBuffer for a particular slot. Only the GraphicBuffer pointer and the slot ID will
+    // be populated.
+    //
+    // This is called without any lock held and can be called concurrently by multiple threads.
+    virtual void onBufferAllocated(const BufferItem& /* item */) {} /* Asynchronous */
+
     // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released
     // its references to one or more GraphicBuffers contained in its slots. The buffer consumer
     // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers.