Merge changes from topic "virtio-gpu-gfxstream-aemu"

* changes:
  Add aemu-specific APIs to virtio-gpu-gfxstream-renderer.
  Move virtio-gpu-gfxstream-renderer to include/render-utils.

GitOrigin-RevId: f07e51995983e5d7d548740bcfc420b7dd3dbb86
Change-Id: Ide70cc5357fe6e65e0d48daa6788637fbcd6dd34
diff --git a/gl-host-common/include/host-common/opengles.h b/gl-host-common/include/host-common/opengles.h
index 0b67674..ab13187 100644
--- a/gl-host-common/include/host-common/opengles.h
+++ b/gl-host-common/include/host-common/opengles.h
@@ -24,6 +24,7 @@
 #include "render-utils/virtio_gpu_ops.h"
 
 #ifdef __cplusplus
+#include "host-common/opengl/misc.h"
 #include "render-utils/RenderLib.h"
 #endif
 
@@ -148,6 +149,7 @@
 }
 
 AEMU_EXPORT const gfxstream::RendererPtr& android_getOpenglesRenderer();
+EMUGL_COMMON_API void android_setOpenglesRenderer(gfxstream::RendererPtr* renderer);
 #endif
 
 AEMU_EXPORT struct AndroidVirtioGpuOps* android_getVirtioGpuOps(void);
diff --git a/gl-host-common/opengles.cpp b/gl-host-common/opengles.cpp
index 702dadc..a5b3de5 100644
--- a/gl-host-common/opengles.cpp
+++ b/gl-host-common/opengles.cpp
@@ -176,6 +176,7 @@
     //                             android::base::MemoryTracker::get());
 
     sRenderer = sRenderLib->initRenderer(width, height, sRendererUsesSubWindow, sEgl2egl);
+    android_setOpenglesRenderer(&sRenderer);
 
     // android::snapshot::Snapshotter::get().addOperationCallback(
     //         [](android::snapshot::Snapshotter::Operation op,
@@ -461,6 +462,10 @@
 
 const gfxstream::RendererPtr& android_getOpenglesRenderer() { return sRenderer; }
 
+void android_setOpenglesRenderer(gfxstream::RendererPtr* renderer) {
+    sRenderer = *renderer;
+}
+
 void android_onGuestGraphicsProcessCreate(uint64_t puid) {
     if (sRenderer) {
         sRenderer->onGuestGraphicsProcessCreate(puid);
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index c33493f..b931feb 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -14,6 +14,10 @@
 # Magma decoder
 add_subdirectory(magma)
 
+if(CONFIG_AEMU)
+    add_compile_definitions(CONFIG_AEMU)
+endif()
+
 # Stream server core
 set(stream-server-core-sources
     Buffer.cpp
@@ -29,7 +33,6 @@
     PostWorker.cpp
     PostWorkerGl.cpp
     ReadBuffer.cpp
-    render_api.cpp
     RenderChannelImpl.cpp
     RenderThreadInfo.cpp
     RenderThreadInfoGl.cpp
@@ -107,6 +110,7 @@
 add_library(
     gfxstream_backend
     SHARED
+    render_api.cpp
     virtio-gpu-gfxstream-renderer.cpp)
 
 target_link_libraries(
diff --git a/host/GfxStreamBackendInitOverride.cpp b/host/GfxStreamBackendInitOverride.cpp
index dfcca14..9d8859d 100644
--- a/host/GfxStreamBackendInitOverride.cpp
+++ b/host/GfxStreamBackendInitOverride.cpp
@@ -12,6 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "virtio-gpu-gfxstream-renderer.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer.h"
 
 void gfxstream_backend_init_product_override() {}
diff --git a/host/VirtioGpuTimelines.h b/host/VirtioGpuTimelines.h
index de255c9..5b67beb 100644
--- a/host/VirtioGpuTimelines.h
+++ b/host/VirtioGpuTimelines.h
@@ -24,7 +24,7 @@
 #include <variant>
 
 #include "aemu/base/synchronization/Lock.h"
-#include "virtio-gpu-gfxstream-renderer.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer.h"
 #include "render-utils/virtio_gpu_ops.h"
 
 struct VirtioGpuRingGlobal {};
diff --git a/host/gfxstream_unittest.cpp b/host/gfxstream_unittest.cpp
index cedca19..d342deb 100644
--- a/host/gfxstream_unittest.cpp
+++ b/host/gfxstream_unittest.cpp
@@ -20,8 +20,8 @@
 #include "aemu/base/system/System.h"
 #include "host-common/testing/MockGraphicsAgentFactory.h"
 #include "virgl_hw.h"
-#include "virtio-gpu-gfxstream-renderer-unstable.h"
-#include "virtio-gpu-gfxstream-renderer.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer-unstable.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer.h"
 
 using android::base::sleepMs;
 
diff --git a/host/virtio-gpu-gfxstream-renderer.cpp b/host/virtio-gpu-gfxstream-renderer.cpp
index f3906b1..7c28dee 100644
--- a/host/virtio-gpu-gfxstream-renderer.cpp
+++ b/host/virtio-gpu-gfxstream-renderer.cpp
@@ -47,10 +47,17 @@
 #include "drm_fourcc.h"
 #include "host-common/goldfish_pipe.h"
 #include "virgl_hw.h"
-#include "virtio-gpu-gfxstream-renderer-unstable.h"
-#include "virtio-gpu-gfxstream-renderer.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer-unstable.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer.h"
 }  // extern "C"
 
+#if defined(_WIN32)
+struct iovec {
+    void* iov_base; /* Starting address */
+    size_t iov_len; /* Length in bytes */
+};
+#endif  // _WIN32
+
 #define DEBUG_VIRTIO_GOLDFISH_PIPE 0
 
 #if DEBUG_VIRTIO_GOLDFISH_PIPE
@@ -1647,6 +1654,11 @@
         return -EINVAL;
     }
 
+#ifdef CONFIG_AEMU
+    void setServiceOps(const GoldfishPipeServiceOps* ops) {
+        mServiceOps = ops;
+    }
+#endif  // CONFIG_AEMU
    private:
     void allocResource(PipeResEntry& entry, iovec* iov, int num_iovs) {
         VGPLOG("entry linear: %p", entry.linear);
@@ -1973,178 +1985,7 @@
     [](QEMUFile* file) { (void)file; },
 };
 
-VG_EXPORT int stream_renderer_init(struct stream_renderer_param* stream_renderer_params,
-                                   uint64_t num_params) {
-    // Required parameters.
-    std::unordered_set<uint64_t> required_params{STREAM_RENDERER_PARAM_USER_DATA,
-                                                 STREAM_RENDERER_PARAM_RENDERER_FLAGS,
-                                                 STREAM_RENDERER_PARAM_FENCE_CALLBACK};
-
-    // String names of the parameters.
-    std::unordered_map<uint64_t, std::string> param_strings{
-        {STREAM_RENDERER_PARAM_USER_DATA, "USER_DATA"},
-        {STREAM_RENDERER_PARAM_RENDERER_FLAGS, "RENDERER_FLAGS"},
-        {STREAM_RENDERER_PARAM_FENCE_CALLBACK, "FENCE_CALLBACK"},
-        {STREAM_RENDERER_PARAM_WIN0_WIDTH, "WIN0_WIDTH"},
-        {STREAM_RENDERER_PARAM_WIN0_HEIGHT, "WIN0_HEIGHT"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT,
-         "METRICS_CALLBACK_ADD_INSTANT_EVENT"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR,
-         "METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC,
-         "METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT,
-         "METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_SET_ANNOTATION, "METRICS_CALLBACK_SET_ANNOTATION"},
-        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ABORT, "METRICS_CALLBACK_ABORT"}};
-
-    // Print full values for these parameters:
-    // Values here must not be pointers (e.g. callback functions), to avoid potentially identifying
-    // someone via ASLR. Pointers in ASLR are randomized on boot, which means pointers may be
-    // different between users but similar across a single user's sessions.
-    // As a convenience, any value <= 4096 is also printed, to catch small or null pointer errors.
-    std::unordered_set<uint64_t> printed_param_values{STREAM_RENDERER_PARAM_RENDERER_FLAGS,
-                                                      STREAM_RENDERER_PARAM_WIN0_WIDTH,
-                                                      STREAM_RENDERER_PARAM_WIN0_HEIGHT};
-
-    // We may have unknown parameters, so this function is lenient.
-    auto get_param_string = [&](uint64_t key) -> std::string {
-        auto param_string = param_strings.find(key);
-        if (param_string != param_strings.end()) {
-            return param_string->second;
-        } else {
-            return "Unknown param with key=" + std::to_string(key);
-        }
-    };
-
-    // Initialization data.
-    uint32_t display_width = 0;
-    uint32_t display_height = 0;
-    void* renderer_cookie = nullptr;
-    int renderer_flags = 0;
-    stream_renderer_fence_callback fence_callback = NULL;
-
-    // Iterate all parameters that we support.
-    GFXS_LOG("Reading stream renderer parameters:");
-    for (uint64_t i = 0; i < num_params; ++i) {
-        stream_renderer_param& param = stream_renderer_params[i];
-
-        // Print out parameter we are processing. See comment above `printed_param_values` before
-        // adding new prints.
-        if (printed_param_values.find(param.key) != printed_param_values.end() ||
-            param.value <= 4096) {
-            GFXS_LOG("%s - %llu", get_param_string(param.key).c_str(),
-                     static_cast<unsigned long long>(param.value));
-        } else {
-            // If not full value, print that it was passed.
-            GFXS_LOG("%s", get_param_string(param.key).c_str());
-        }
-
-        // Removing every param we process will leave required_params empty if all provided.
-        required_params.erase(param.key);
-
-        switch (param.key) {
-            case STREAM_RENDERER_PARAM_USER_DATA: {
-                renderer_cookie = reinterpret_cast<void*>(static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_RENDERER_FLAGS: {
-                renderer_flags = static_cast<int>(param.value);
-                break;
-            }
-            case STREAM_RENDERER_PARAM_FENCE_CALLBACK: {
-                fence_callback = reinterpret_cast<stream_renderer_fence_callback>(
-                    static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_WIN0_WIDTH: {
-                display_width = static_cast<uint32_t>(param.value);
-                break;
-            }
-            case STREAM_RENDERER_PARAM_WIN0_HEIGHT: {
-                display_height = static_cast<uint32_t>(param.value);
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT: {
-                MetricsLogger::add_instant_event_callback =
-                    reinterpret_cast<stream_renderer_param_metrics_callback_add_instant_event>(
-                        static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR: {
-                MetricsLogger::add_instant_event_with_descriptor_callback = reinterpret_cast<
-                    stream_renderer_param_metrics_callback_add_instant_event_with_descriptor>(
-                    static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC: {
-                MetricsLogger::add_instant_event_with_metric_callback = reinterpret_cast<
-                    stream_renderer_param_metrics_callback_add_instant_event_with_metric>(
-                    static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT: {
-                MetricsLogger::add_vulkan_out_of_memory_event = reinterpret_cast<
-                    stream_renderer_param_metrics_callback_add_vulkan_out_of_memory_event>(
-                    static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_SET_ANNOTATION: {
-                MetricsLogger::set_crash_annotation_callback =
-                    reinterpret_cast<stream_renderer_param_metrics_callback_set_annotation>(
-                        static_cast<uintptr_t>(param.value));
-                break;
-            }
-            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ABORT: {
-                emugl::setDieFunction(
-                    reinterpret_cast<stream_renderer_param_metrics_callback_abort>(
-                        static_cast<uintptr_t>(param.value)));
-                break;
-            }
-            default: {
-                // We skip any parameters we don't recognize.
-                ERR("Skipping unknown parameter key: %llu. May need to upgrade gfxstream.",
-                    static_cast<unsigned long long>(param.key));
-                break;
-            }
-        }
-    }
-    GFXS_LOG("Finished reading parameters");
-
-    // Some required params not found.
-    if (required_params.size() > 0) {
-        ERR("Missing required parameters:");
-        for (uint64_t param : required_params) {
-            ERR("%s", get_param_string(param).c_str());
-        }
-        ERR("Failing initialization intentionally");
-        return -1;
-    }
-
-    // Set non product-specific callbacks
-    gfxstream::vk::vk_util::setVkCheckCallbacks(
-        std::make_unique<gfxstream::vk::vk_util::VkCheckCallbacks>(
-            gfxstream::vk::vk_util::VkCheckCallbacks{
-                .onVkErrorOutOfMemory =
-                    [](VkResult result, const char* function, int line) {
-                        auto fb = gfxstream::FrameBuffer::getFB();
-                        if (!fb) {
-                            ERR("FrameBuffer not yet initialized. Dropping out of memory event");
-                            return;
-                        }
-                        fb->logVulkanOutOfMemory(result, function, line);
-                    },
-                .onVkErrorOutOfMemoryOnAllocation =
-                    [](VkResult result, const char* function, int line,
-                       std::optional<uint64_t> allocationSize) {
-                        auto fb = gfxstream::FrameBuffer::getFB();
-                        if (!fb) {
-                            ERR("FrameBuffer not yet initialized. Dropping out of memory event");
-                            return;
-                        }
-                        fb->logVulkanOutOfMemory(result, function, line, allocationSize);
-                    }}));
-
+static int stream_renderer_opengles_init(uint32_t display_width, uint32_t display_height, int renderer_flags) {
     GFXS_LOG("start. display dimensions: width %u height %u, renderer flags: 0x%x", display_width,
              display_height, renderer_flags);
 
@@ -2290,6 +2131,196 @@
     android_opengles_pipe_set_recv_mode(2 /* virtio-gpu */);
     android_init_refcount_pipe();
 
+    return 0;
+}
+
+VG_EXPORT int stream_renderer_init(struct stream_renderer_param* stream_renderer_params,
+                                   uint64_t num_params) {
+    // Required parameters.
+    std::unordered_set<uint64_t> required_params{STREAM_RENDERER_PARAM_USER_DATA,
+                                                 STREAM_RENDERER_PARAM_RENDERER_FLAGS,
+                                                 STREAM_RENDERER_PARAM_FENCE_CALLBACK};
+
+    // String names of the parameters.
+    std::unordered_map<uint64_t, std::string> param_strings{
+        {STREAM_RENDERER_PARAM_USER_DATA, "USER_DATA"},
+        {STREAM_RENDERER_PARAM_RENDERER_FLAGS, "RENDERER_FLAGS"},
+        {STREAM_RENDERER_PARAM_FENCE_CALLBACK, "FENCE_CALLBACK"},
+        {STREAM_RENDERER_PARAM_WIN0_WIDTH, "WIN0_WIDTH"},
+        {STREAM_RENDERER_PARAM_WIN0_HEIGHT, "WIN0_HEIGHT"},
+        {STREAM_RENDERER_SKIP_OPENGLES_INIT, "SKIP_OPENGLES_INIT"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT,
+         "METRICS_CALLBACK_ADD_INSTANT_EVENT"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR,
+         "METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC,
+         "METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT,
+         "METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_SET_ANNOTATION, "METRICS_CALLBACK_SET_ANNOTATION"},
+        {STREAM_RENDERER_PARAM_METRICS_CALLBACK_ABORT, "METRICS_CALLBACK_ABORT"}};
+
+    // Print full values for these parameters:
+    // Values here must not be pointers (e.g. callback functions), to avoid potentially identifying
+    // someone via ASLR. Pointers in ASLR are randomized on boot, which means pointers may be
+    // different between users but similar across a single user's sessions.
+    // As a convenience, any value <= 4096 is also printed, to catch small or null pointer errors.
+    std::unordered_set<uint64_t> printed_param_values{STREAM_RENDERER_PARAM_RENDERER_FLAGS,
+                                                      STREAM_RENDERER_PARAM_WIN0_WIDTH,
+                                                      STREAM_RENDERER_PARAM_WIN0_HEIGHT};
+
+    // We may have unknown parameters, so this function is lenient.
+    auto get_param_string = [&](uint64_t key) -> std::string {
+        auto param_string = param_strings.find(key);
+        if (param_string != param_strings.end()) {
+            return param_string->second;
+        } else {
+            return "Unknown param with key=" + std::to_string(key);
+        }
+    };
+
+    // Initialization data.
+    uint32_t display_width = 0;
+    uint32_t display_height = 0;
+    void* renderer_cookie = nullptr;
+    int renderer_flags = 0;
+    stream_renderer_fence_callback fence_callback = NULL;
+    bool skip_opengles = false;
+
+    // Iterate all parameters that we support.
+    GFXS_LOG("Reading stream renderer parameters:");
+    for (uint64_t i = 0; i < num_params; ++i) {
+        stream_renderer_param& param = stream_renderer_params[i];
+
+        // Print out parameter we are processing. See comment above `printed_param_values` before
+        // adding new prints.
+        if (printed_param_values.find(param.key) != printed_param_values.end() ||
+            param.value <= 4096) {
+            GFXS_LOG("%s - %llu", get_param_string(param.key).c_str(),
+                     static_cast<unsigned long long>(param.value));
+        } else {
+            // If not full value, print that it was passed.
+            GFXS_LOG("%s", get_param_string(param.key).c_str());
+        }
+
+        // Removing every param we process will leave required_params empty if all provided.
+        required_params.erase(param.key);
+
+        switch (param.key) {
+            case STREAM_RENDERER_PARAM_USER_DATA: {
+                renderer_cookie = reinterpret_cast<void*>(static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_RENDERER_FLAGS: {
+                renderer_flags = static_cast<int>(param.value);
+                break;
+            }
+            case STREAM_RENDERER_PARAM_FENCE_CALLBACK: {
+                fence_callback = reinterpret_cast<stream_renderer_fence_callback>(
+                    static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_WIN0_WIDTH: {
+                display_width = static_cast<uint32_t>(param.value);
+                break;
+            }
+            case STREAM_RENDERER_PARAM_WIN0_HEIGHT: {
+                display_height = static_cast<uint32_t>(param.value);
+                break;
+            }
+            case STREAM_RENDERER_SKIP_OPENGLES_INIT: {
+                skip_opengles = static_cast<bool>(param.value);
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT: {
+                MetricsLogger::add_instant_event_callback =
+                    reinterpret_cast<stream_renderer_param_metrics_callback_add_instant_event>(
+                        static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_DESCRIPTOR: {
+                MetricsLogger::add_instant_event_with_descriptor_callback = reinterpret_cast<
+                    stream_renderer_param_metrics_callback_add_instant_event_with_descriptor>(
+                    static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_INSTANT_EVENT_WITH_METRIC: {
+                MetricsLogger::add_instant_event_with_metric_callback = reinterpret_cast<
+                    stream_renderer_param_metrics_callback_add_instant_event_with_metric>(
+                    static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ADD_VULKAN_OUT_OF_MEMORY_EVENT: {
+                MetricsLogger::add_vulkan_out_of_memory_event = reinterpret_cast<
+                    stream_renderer_param_metrics_callback_add_vulkan_out_of_memory_event>(
+                    static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_SET_ANNOTATION: {
+                MetricsLogger::set_crash_annotation_callback =
+                    reinterpret_cast<stream_renderer_param_metrics_callback_set_annotation>(
+                        static_cast<uintptr_t>(param.value));
+                break;
+            }
+            case STREAM_RENDERER_PARAM_METRICS_CALLBACK_ABORT: {
+                emugl::setDieFunction(
+                    reinterpret_cast<stream_renderer_param_metrics_callback_abort>(
+                        static_cast<uintptr_t>(param.value)));
+                break;
+            }
+            default: {
+                // We skip any parameters we don't recognize.
+                ERR("Skipping unknown parameter key: %llu. May need to upgrade gfxstream.",
+                    static_cast<unsigned long long>(param.key));
+                break;
+            }
+        }
+    }
+    GFXS_LOG("Finished reading parameters");
+
+    // Some required params not found.
+    if (required_params.size() > 0) {
+        ERR("Missing required parameters:");
+        for (uint64_t param : required_params) {
+            ERR("%s", get_param_string(param).c_str());
+        }
+        ERR("Failing initialization intentionally");
+        return -1;
+    }
+
+    // Set non product-specific callbacks
+    gfxstream::vk::vk_util::setVkCheckCallbacks(
+        std::make_unique<gfxstream::vk::vk_util::VkCheckCallbacks>(
+            gfxstream::vk::vk_util::VkCheckCallbacks{
+                .onVkErrorOutOfMemory =
+                    [](VkResult result, const char* function, int line) {
+                        auto fb = gfxstream::FrameBuffer::getFB();
+                        if (!fb) {
+                            ERR("FrameBuffer not yet initialized. Dropping out of memory event");
+                            return;
+                        }
+                        fb->logVulkanOutOfMemory(result, function, line);
+                    },
+                .onVkErrorOutOfMemoryOnAllocation =
+                    [](VkResult result, const char* function, int line,
+                       std::optional<uint64_t> allocationSize) {
+                        auto fb = gfxstream::FrameBuffer::getFB();
+                        if (!fb) {
+                            ERR("FrameBuffer not yet initialized. Dropping out of memory event");
+                            return;
+                        }
+                        fb->logVulkanOutOfMemory(result, function, line, allocationSize);
+                    }}));
+
+    if (!skip_opengles) {
+        // aemu currently does its own opengles initialization in
+        // qemu/android/android-emu/android/opengles.cpp.
+        int ret = stream_renderer_opengles_init(display_width, display_height, renderer_flags);
+        if (ret) {
+            return ret;
+        }
+    }
+
     sRenderer()->init(renderer_cookie, renderer_flags, fence_callback);
     gfxstream::FrameBuffer::waitUntilInitialized();
 
@@ -2353,4 +2384,13 @@
               "stream_renderer_param.key must be at offset 0");
 static_assert(offsetof(struct stream_renderer_param, value) == 8,
               "stream_renderer_param.value must be at offset 8");
+
+#ifdef CONFIG_AEMU
+
+VG_EXPORT void stream_renderer_set_service_ops(const GoldfishPipeServiceOps* ops) {
+    sRenderer()->setServiceOps(ops);
+}
+
+#endif  // CONFIG_AEMU
+
 }  // extern "C"
diff --git a/host/virtio-gpu-gfxstream-renderer-unstable.h b/include/render-utils/virtio-gpu-gfxstream-renderer-unstable.h
similarity index 82%
rename from host/virtio-gpu-gfxstream-renderer-unstable.h
rename to include/render-utils/virtio-gpu-gfxstream-renderer-unstable.h
index cb32bc8..bf962ef 100644
--- a/host/virtio-gpu-gfxstream-renderer-unstable.h
+++ b/include/render-utils/virtio-gpu-gfxstream-renderer-unstable.h
@@ -1,7 +1,7 @@
 #ifndef VIRTGPU_GFXSTREAM_RENDERER_UNSTABLE_H
 #define VIRTGPU_GFXSTREAM_RENDERER_UNSTABLE_H
 
-#include "virtio-gpu-gfxstream-renderer.h"
+#include "render-utils/virtio-gpu-gfxstream-renderer.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -11,6 +11,12 @@
 // in the mask, the bits HOST_VISIBLE and HOST_COHERENT will be removed.
 #define STREAM_RENDERER_PARAM_HOST_VISIBLE_MEMORY_MASK 8
 
+// Skip android opengles initiation. Used by aemu to skip android opengles initiation.
+// aemu does its own initialization in qemu/android/android/android-emu/android/opengles.cpp.
+// TODO(joshuaduong): Migrate aemu to use stream_renderer_init without this hack. This will
+// require adding more options to customize the feature flags, etc.
+#define STREAM_RENDERER_SKIP_OPENGLES_INIT 10
+
 // Information about one device's memory mask.
 struct stream_renderer_param_host_visible_memory_mask_entry {
     // Which device the mask applies to.
@@ -62,6 +68,10 @@
 
 VG_EXPORT void stream_renderer_flush(uint32_t res_handle);
 
+// Override the default GoldfishPipeServiceOps
+struct GoldfishPipeServiceOps;
+VG_EXPORT void stream_renderer_set_service_ops(const struct GoldfishPipeServiceOps* ops);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/host/virtio-gpu-gfxstream-renderer.h b/include/render-utils/virtio-gpu-gfxstream-renderer.h
similarity index 98%
rename from host/virtio-gpu-gfxstream-renderer.h
rename to include/render-utils/virtio-gpu-gfxstream-renderer.h
index 3201de0..1964aaa 100644
--- a/host/virtio-gpu-gfxstream-renderer.h
+++ b/include/render-utils/virtio-gpu-gfxstream-renderer.h
@@ -20,10 +20,7 @@
 #include <stddef.h>
 
 #if defined(_WIN32)
-struct iovec {
-    void* iov_base; /* Starting address */
-    size_t iov_len; /* Length in bytes */
-};
+struct iovec;
 #else
 #include <sys/uio.h>
 #endif