Surface: Add a SurfaceQueueOutput struct for replaced buffers

With IGBPs, this is provided back to clients via an output object, which
Surface doesn't currently provide.

This lets us notify clients when this happens.

BYPASS_IGBP_IGBC_API_REASON=warren buffers

Bug: 340933794
Flag: com.android.graphics.libgui.flags.wb_platform_api_improvements
Test: new SurfaceTest tests
Change-Id: I2ec5a0598988fdfcfe7356a14be0f99a206ef6a8
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 76d74fe..66e7ddd 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -741,11 +741,12 @@
     return res;
 }
 
-status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd) {
+status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd,
+                              SurfaceQueueBufferOutput* output) {
     if (buffer == nullptr) {
         return BAD_VALUE;
     }
-    return queueBuffer(buffer.get(), fd ? fd->get() : -1);
+    return queueBuffer(buffer.get(), fd ? fd->get() : -1, output);
 }
 
 status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) {
@@ -1195,7 +1196,8 @@
 
 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
 
-int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
+int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd,
+                         SurfaceQueueBufferOutput* surfaceOutput) {
     ATRACE_CALL();
     ALOGV("Surface::queueBuffer");
 
@@ -1245,16 +1247,26 @@
         onBufferQueuedLocked(slot, fence, output);
     }
 
+    if (surfaceOutput != nullptr) {
+        *surfaceOutput = {.bufferReplaced = output.bufferReplaced};
+    }
+
     return err;
 }
 
-int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers) {
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers,
+                          std::vector<SurfaceQueueBufferOutput>* queueBufferOutputs)
+#else
+int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers)
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+{
     ATRACE_CALL();
     ALOGV("Surface::queueBuffers");
 
     size_t numBuffers = buffers.size();
-    std::vector<IGraphicBufferProducer::QueueBufferInput> queueBufferInputs(numBuffers);
-    std::vector<IGraphicBufferProducer::QueueBufferOutput> queueBufferOutputs;
+    std::vector<IGraphicBufferProducer::QueueBufferInput> igbpQueueBufferInputs(numBuffers);
+    std::vector<IGraphicBufferProducer::QueueBufferOutput> igbpQueueBufferOutputs;
     std::vector<int> bufferSlots(numBuffers, -1);
     std::vector<sp<Fence>> bufferFences(numBuffers);
 
@@ -1280,12 +1292,13 @@
             IGraphicBufferProducer::QueueBufferInput input;
             getQueueBufferInputLocked(buffers[batchIdx].buffer, buffers[batchIdx].fenceFd,
                                       buffers[batchIdx].timestamp, &input);
+            input.slot = i;
             bufferFences[batchIdx] = input.fence;
-            queueBufferInputs[batchIdx] = input;
+            igbpQueueBufferInputs[batchIdx] = input;
         }
     }
     nsecs_t now = systemTime();
-    err = mGraphicBufferProducer->queueBuffers(queueBufferInputs, &queueBufferOutputs);
+    err = mGraphicBufferProducer->queueBuffers(igbpQueueBufferInputs, &igbpQueueBufferOutputs);
     {
         Mutex::Autolock lock(mMutex);
         mLastQueueDuration = systemTime() - now;
@@ -1295,10 +1308,21 @@
 
         for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
             onBufferQueuedLocked(bufferSlots[batchIdx], bufferFences[batchIdx],
-                                 queueBufferOutputs[batchIdx]);
+                                 igbpQueueBufferOutputs[batchIdx]);
         }
     }
 
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+    if (queueBufferOutputs != nullptr) {
+        queueBufferOutputs->clear();
+        queueBufferOutputs->resize(numBuffers);
+        for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
+            (*queueBufferOutputs)[batchIdx].bufferReplaced =
+                    igbpQueueBufferOutputs[batchIdx].bufferReplaced;
+        }
+    }
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
     return err;
 }