Surface: Provide more useful/platform-y buffer methods

These will be easier to use than having to use ANativeWindow
equivalents.

BYPASS_IGBP_IGBC_API_REASON=warren buffers

Flag: com.android.graphics.libgui.flags.wb_platform_api_improvements
Bug: 340933794
Test: new libgui_test tests, atest
Change-Id: I0343abb45aadf708ef6115fa108a3b4c402cfd47
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 685391e..97c0299 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -21,6 +21,8 @@
 #include <gui/Surface.h>
 
 #include <condition_variable>
+#include <cstddef>
+#include <cstdint>
 #include <deque>
 #include <mutex>
 #include <thread>
@@ -693,6 +695,50 @@
     return OK;
 }
 
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence) {
+    if (buffer == nullptr || outFence == nullptr) {
+        return BAD_VALUE;
+    }
+
+    android_native_buffer_t* anb;
+    int fd = -1;
+    status_t res = dequeueBuffer(&anb, &fd);
+    *buffer = GraphicBuffer::from(anb);
+    *outFence = sp<Fence>::make(fd);
+    return res;
+}
+
+status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd) {
+    if (buffer == nullptr) {
+        return BAD_VALUE;
+    }
+    return queueBuffer(buffer.get(), fd ? fd->get() : -1);
+}
+
+status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) {
+    if (nullptr == buffer) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+
+    uint64_t bufferId = buffer->getId();
+    for (int slot = 0; slot < Surface::NUM_BUFFER_SLOTS; ++slot) {
+        auto& bufferSlot = mSlots[slot];
+        if (bufferSlot.buffer != nullptr && bufferSlot.buffer->getId() == bufferId) {
+            bufferSlot.buffer = nullptr;
+            bufferSlot.dirtyRegion = Region::INVALID_REGION;
+            return mGraphicBufferProducer->detachBuffer(slot);
+        }
+    }
+
+    return BAD_VALUE;
+}
+
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
 int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
     using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
     using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;