Merge "gfxstream: host: add exportColorBuffer + exportBuffer functions" into main
diff --git a/host/Buffer.cpp b/host/Buffer.cpp
index b60a1ec..84459db 100644
--- a/host/Buffer.cpp
+++ b/host/Buffer.cpp
@@ -138,4 +138,12 @@
     return false;
 }
 
+std::optional<ManagedDescriptorInfo> Buffer::exportBlob() {
+    if (!mBufferVk) {
+        return std::nullopt;
+    }
+
+    return mBufferVk->exportBlob();
+}
+
 }  // namespace gfxstream
diff --git a/host/Buffer.h b/host/Buffer.h
index 414ff05..cf2b15e 100644
--- a/host/Buffer.h
+++ b/host/Buffer.h
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "BlobManager.h"
 #include "Handle.h"
 #include "aemu/base/files/Stream.h"
 #include "snapshot/LazySnapshotObj.h"
@@ -57,6 +58,7 @@
 
     void readToBytes(uint64_t offset, uint64_t size, void* outBytes);
     bool updateFromBytes(uint64_t offset, uint64_t size, const void* bytes);
+    std::optional<ManagedDescriptorInfo> exportBlob();
 
    private:
     Buffer(HandleType handle, uint64_t size);
diff --git a/host/ColorBuffer.cpp b/host/ColorBuffer.cpp
index 1664680..159f8e2 100644
--- a/host/ColorBuffer.cpp
+++ b/host/ColorBuffer.cpp
@@ -455,6 +455,14 @@
     return mColorBufferVk->waitSync();
 }
 
+std::optional<ManagedDescriptorInfo> ColorBuffer::exportBlob() {
+    if (!mColorBufferVk) {
+        return std::nullopt;
+    }
+
+    return mColorBufferVk->exportBlob();
+}
+
 #if GFXSTREAM_ENABLE_HOST_GLES
 bool ColorBuffer::glOpBlitFromCurrentReadBuffer() {
     if (!mColorBufferGl) {
diff --git a/host/ColorBuffer.h b/host/ColorBuffer.h
index 43a3330..ba6a9ad 100644
--- a/host/ColorBuffer.h
+++ b/host/ColorBuffer.h
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "BlobManager.h"
 #include "BorrowedImage.h"
 #include "FrameworkFormats.h"
 #include "Handle.h"
@@ -94,6 +95,7 @@
     bool importNativeResource(void* nativeResource, uint32_t type, bool preserveContent);
 
     int waitSync();
+    std::optional<ManagedDescriptorInfo> exportBlob();
 
 #if GFXSTREAM_ENABLE_HOST_GLES
     GLuint glOpGetTexture();
diff --git a/host/FrameBuffer.cpp b/host/FrameBuffer.cpp
index b44b5ea..399bd8d 100644
--- a/host/FrameBuffer.cpp
+++ b/host/FrameBuffer.cpp
@@ -2982,6 +2982,28 @@
     return colorBuffer->waitSync();
 }
 
+std::optional<ManagedDescriptorInfo> FrameBuffer::exportColorBuffer(HandleType colorBufferHandle) {
+    AutoLock mutex(m_lock);
+
+    ColorBufferPtr colorBuffer = findColorBuffer(colorBufferHandle);
+    if (!colorBuffer) {
+        return std::nullopt;
+    }
+
+    return colorBuffer->exportBlob();
+}
+
+std::optional<ManagedDescriptorInfo> FrameBuffer::exportBuffer(HandleType bufferHandle) {
+    AutoLock mutex(m_lock);
+
+    BufferPtr buffer = findBuffer(bufferHandle);
+    if (!buffer) {
+        return std::nullopt;
+    }
+
+    return buffer->exportBlob();
+}
+
 #if GFXSTREAM_ENABLE_HOST_GLES
 HandleType FrameBuffer::getEmulatedEglWindowSurfaceColorBufferHandle(HandleType p_surface) {
     AutoLock mutex(m_lock);
diff --git a/host/FrameBuffer.h b/host/FrameBuffer.h
index 9e7f58a..5a6e099 100644
--- a/host/FrameBuffer.h
+++ b/host/FrameBuffer.h
@@ -26,6 +26,7 @@
 #include <unordered_map>
 #include <unordered_set>
 
+#include "BlobManager.h"
 #include "Buffer.h"
 #include "ColorBuffer.h"
 #include "Compositor.h"
@@ -498,6 +499,8 @@
     bool invalidateColorBufferForVk(HandleType colorBufferHandle);
 
     int waitSyncColorBuffer(HandleType colorBufferHandle);
+    std::optional<ManagedDescriptorInfo> exportColorBuffer(HandleType colorBufferHandle);
+    std::optional<ManagedDescriptorInfo> exportBuffer(HandleType bufferHandle);
 
 #if GFXSTREAM_ENABLE_HOST_GLES
     // Retrieves the color buffer handle associated with |p_surface|.
diff --git a/host/vulkan/BufferVk.cpp b/host/vulkan/BufferVk.cpp
index 46f4540..a8ec4f3 100644
--- a/host/vulkan/BufferVk.cpp
+++ b/host/vulkan/BufferVk.cpp
@@ -45,5 +45,21 @@
     return updateBufferFromBytes(mHandle, offset, size, bytes);
 }
 
+std::optional<ManagedDescriptorInfo> BufferVk::exportBlob() {
+    uint32_t streamHandleType = 0;
+    auto vkHandle = getBufferExtMemoryHandle(mHandle, &streamHandleType);
+    if (vkHandle != VK_EXT_MEMORY_HANDLE_INVALID) {
+        ManagedDescriptor descriptor(dupExternalMemory(vkHandle));
+        return ManagedDescriptorInfo{
+            .descriptor = std::move(descriptor),
+            .handleType = streamHandleType,
+            .caching = 0,
+            .vulkanInfoOpt = std::nullopt,
+        };
+    } else {
+        return std::nullopt;
+    }
+}
+
 }  // namespace vk
-}  // namespace gfxstream
\ No newline at end of file
+}  // namespace gfxstream
diff --git a/host/vulkan/BufferVk.h b/host/vulkan/BufferVk.h
index 9016fd7..1df6b55 100644
--- a/host/vulkan/BufferVk.h
+++ b/host/vulkan/BufferVk.h
@@ -15,6 +15,8 @@
 #include <memory>
 #include <vector>
 
+#include "BlobManager.h"
+
 namespace gfxstream {
 namespace vk {
 
@@ -28,6 +30,8 @@
 
     bool updateFromBytes(uint64_t offset, uint64_t size, const void* bytes);
 
+    std::optional<ManagedDescriptorInfo> exportBlob();
+
    private:
     BufferVk(uint32_t handle);
 
diff --git a/host/vulkan/ColorBufferVk.cpp b/host/vulkan/ColorBufferVk.cpp
index 9461510..cd82b15 100644
--- a/host/vulkan/ColorBufferVk.cpp
+++ b/host/vulkan/ColorBufferVk.cpp
@@ -80,5 +80,19 @@
 
 int ColorBufferVk::waitSync() { return waitSyncVkColorBuffer(mHandle); }
 
+std::optional<ManagedDescriptorInfo> ColorBufferVk::exportBlob() {
+    auto info = exportColorBufferMemory(mHandle);
+    if (info) {
+        return ManagedDescriptorInfo{
+            .descriptor = std::move((*info).descriptor),
+            .handleType = (*info).streamHandleType,
+            .caching = 0,
+            .vulkanInfoOpt = std::nullopt,
+        };
+    } else {
+        return std::nullopt;
+    }
+}
+
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/host/vulkan/ColorBufferVk.h b/host/vulkan/ColorBufferVk.h
index 81e1e42..e7187b9 100644
--- a/host/vulkan/ColorBufferVk.h
+++ b/host/vulkan/ColorBufferVk.h
@@ -17,6 +17,7 @@
 #include <memory>
 #include <vector>
 
+#include "BlobManager.h"
 #include "FrameworkFormats.h"
 #include "aemu/base/files/Stream.h"
 
@@ -43,6 +44,7 @@
     void onSave(android::base::Stream* stream);
 
     int waitSync();
+    std::optional<ManagedDescriptorInfo> exportBlob();
 
    private:
     ColorBufferVk(uint32_t handle);