Merge GfxStreamBackend into virtio-gpu-gfxstream-renderer.h

These two both expose the C API of the library, and we want to move to a
stream_renderer_init instead of gfxstream_backend_init.

Keeps around GfxStreamBackend.h temporarily until downstreams have
replaced their references.

Bug: b/249823013
Test: presubmit & downstream
Change-Id: If919766d2d61694cea3b8cf5291fb5823f26b355
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index 2484f6a..6318cdc 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -81,7 +81,6 @@
         "FrameBuffer.cpp",
         "GfxStreamAgents.cpp",
         "virtio-gpu-gfxstream-renderer.cpp",
-        "GfxStreamBackend.cpp",
         "GfxStreamBackendInitOverride.cpp",
         "VirtioGpuTimelines.cpp",
     ],
diff --git a/stream-servers/CMakeLists.txt b/stream-servers/CMakeLists.txt
index 8849e58..3041363 100644
--- a/stream-servers/CMakeLists.txt
+++ b/stream-servers/CMakeLists.txt
@@ -108,7 +108,6 @@
 add_library(
     gfxstream_backend
     SHARED
-    GfxStreamBackend.cpp
     virtio-gpu-gfxstream-renderer.cpp)
 
 target_link_libraries(
diff --git a/stream-servers/GfxStreamBackend.cpp b/stream-servers/GfxStreamBackend.cpp
deleted file mode 100644
index de41e6d..0000000
--- a/stream-servers/GfxStreamBackend.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#include "GfxStreamBackend.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <fstream>
-#include <string>
-
-#include "FrameBuffer.h"
-#include "GfxStreamAgents.h"
-#include "VkCommonOperations.h"
-#include "VulkanDispatch.h"
-#include "aemu/base/files/MemStream.h"
-#include "aemu/base/Metrics.h"
-#include "aemu/base/files/PathUtils.h"
-#include "aemu/base/system/System.h"
-#include "host-common/AndroidPipe.h"
-#include "host-common/FeatureControl.h"
-#include "host-common/GfxstreamFatalError.h"
-#include "host-common/HostmemIdMapping.h"
-#include "host-common/address_space_device.h"
-#include "host-common/address_space_device.hpp"
-#include "host-common/address_space_graphics.h"
-#include "host-common/address_space_graphics_types.h"
-#include "host-common/android_pipe_device.h"
-#include "host-common/feature_control.h"
-#include "host-common/globals.h"
-#include "host-common/opengl/emugl_config.h"
-#include "host-common/opengles-pipe.h"
-#include "host-common/opengles.h"
-#include "host-common/refcount-pipe.h"
-#include "host-common/vm_operations.h"
-#include "host-common/window_agent.h"
-#include "render_api.h"
-#include "snapshot/interface.h"
-#include "vk_util.h"
-
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-#define GFXSTREAM_DEBUG_LEVEL 1
-
-#if GFXSTREAM_DEBUG_LEVEL >= 1
-#define GFXS_LOG(fmt, ...)                                                     \
-    do {                                                                       \
-        fprintf(stdout, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \
-        fflush(stdout);                                                        \
-    } while (0)
-
-#else
-#define GFXS_LOG(fmt,...)
-#endif
-
-extern "C" {
-#include "host-common/goldfish_pipe.h"
-#include "virtio-gpu-gfxstream-renderer.h"
-}  // extern "C"
-
-using android::AndroidPipe;
-using android::base::pj;
-using android::base::MetricsLogger;
-
-#ifdef _WIN32
-#define VG_EXPORT __declspec(dllexport)
-#else
-#define VG_EXPORT __attribute__((visibility("default")))
-#endif
-
-#define POST_CALLBACK_DISPLAY_TYPE_X 0
-#define POST_CALLBACK_DISPLAY_TYPE_WAYLAND_SHARED_MEM 1
-#define POST_CALLBACK_DISPLAY_TYPE_WINDOWS_HWND 2
-
-struct renderer_display_info;
-typedef void (*get_pixels_t)(void*, uint32_t, uint32_t);
-static get_pixels_t sGetPixelsFunc = 0;
-typedef void (*post_callback_t)(void*, uint32_t, int, int, int, int, int, unsigned char*);
-
-// For reading back rendered contents to display
-extern "C" VG_EXPORT void get_pixels(void* pixels, uint32_t bytes);
-
-static const GoldfishPipeServiceOps goldfish_pipe_service_ops = {
-        // guest_open()
-        [](GoldfishHwPipe* hwPipe) -> GoldfishHostPipe* {
-            return static_cast<GoldfishHostPipe*>(
-                    android_pipe_guest_open(hwPipe));
-        },
-        // guest_open_with_flags()
-        [](GoldfishHwPipe* hwPipe, uint32_t flags) -> GoldfishHostPipe* {
-            return static_cast<GoldfishHostPipe*>(
-                    android_pipe_guest_open_with_flags(hwPipe, flags));
-        },
-        // guest_close()
-        [](GoldfishHostPipe* hostPipe, GoldfishPipeCloseReason reason) {
-            static_assert((int)GOLDFISH_PIPE_CLOSE_GRACEFUL ==
-                                  (int)PIPE_CLOSE_GRACEFUL,
-                          "Invalid PIPE_CLOSE_GRACEFUL value");
-            static_assert(
-                    (int)GOLDFISH_PIPE_CLOSE_REBOOT == (int)PIPE_CLOSE_REBOOT,
-                    "Invalid PIPE_CLOSE_REBOOT value");
-            static_assert((int)GOLDFISH_PIPE_CLOSE_LOAD_SNAPSHOT ==
-                                  (int)PIPE_CLOSE_LOAD_SNAPSHOT,
-                          "Invalid PIPE_CLOSE_LOAD_SNAPSHOT value");
-            static_assert(
-                    (int)GOLDFISH_PIPE_CLOSE_ERROR == (int)PIPE_CLOSE_ERROR,
-                    "Invalid PIPE_CLOSE_ERROR value");
-
-            android_pipe_guest_close(hostPipe,
-                                     static_cast<PipeCloseReason>(reason));
-        },
-        // guest_pre_load()
-        [](QEMUFile* file) { (void)file; },
-        // guest_post_load()
-        [](QEMUFile* file) { (void)file; },
-        // guest_pre_save()
-        [](QEMUFile* file) { (void)file; },
-        // guest_post_save()
-        [](QEMUFile* file) { (void)file; },
-        // guest_load()
-        [](QEMUFile* file,
-           GoldfishHwPipe* hwPipe,
-           char* force_close) -> GoldfishHostPipe* {
-            (void)file;
-            (void)hwPipe;
-            (void)force_close;
-           return nullptr;
-        },
-        // guest_save()
-        [](GoldfishHostPipe* hostPipe, QEMUFile* file) {
-            (void)hostPipe;
-            (void)file;
-        },
-        // guest_poll()
-        [](GoldfishHostPipe* hostPipe) {
-            static_assert((int)GOLDFISH_PIPE_POLL_IN == (int)PIPE_POLL_IN,
-                          "invalid POLL_IN values");
-            static_assert((int)GOLDFISH_PIPE_POLL_OUT == (int)PIPE_POLL_OUT,
-                          "invalid POLL_OUT values");
-            static_assert((int)GOLDFISH_PIPE_POLL_HUP == (int)PIPE_POLL_HUP,
-                          "invalid POLL_HUP values");
-
-            return static_cast<GoldfishPipePollFlags>(
-                    android_pipe_guest_poll(hostPipe));
-        },
-        // guest_recv()
-        [](GoldfishHostPipe* hostPipe,
-           GoldfishPipeBuffer* buffers,
-           int numBuffers) -> int {
-            // NOTE: Assumes that AndroidPipeBuffer and GoldfishPipeBuffer
-            //       have exactly the same layout.
-            static_assert(
-                    sizeof(AndroidPipeBuffer) == sizeof(GoldfishPipeBuffer),
-                    "Invalid PipeBuffer sizes");
-        // We can't use a static_assert with offsetof() because in msvc, it uses
-        // reinterpret_cast.
-        // TODO: Add runtime assertion instead?
-        // https://developercommunity.visualstudio.com/content/problem/22196/static-assert-cannot-compile-constexprs-method-tha.html
-#ifndef _MSC_VER
-            static_assert(offsetof(AndroidPipeBuffer, data) ==
-                                  offsetof(GoldfishPipeBuffer, data),
-                          "Invalid PipeBuffer::data offsets");
-            static_assert(offsetof(AndroidPipeBuffer, size) ==
-                                  offsetof(GoldfishPipeBuffer, size),
-                          "Invalid PipeBuffer::size offsets");
-#endif
-            return android_pipe_guest_recv(
-                    hostPipe, reinterpret_cast<AndroidPipeBuffer*>(buffers),
-                    numBuffers);
-        },
-        // guest_send()
-        [](GoldfishHostPipe** hostPipe,
-           const GoldfishPipeBuffer* buffers,
-           int numBuffers) -> int {
-            return android_pipe_guest_send(
-                    reinterpret_cast<void**>(hostPipe),
-                    reinterpret_cast<const AndroidPipeBuffer*>(buffers),
-                    numBuffers);
-        },
-        // guest_wake_on()
-        [](GoldfishHostPipe* hostPipe, GoldfishPipeWakeFlags wakeFlags) {
-            android_pipe_guest_wake_on(hostPipe, static_cast<int>(wakeFlags));
-        },
-        // dma_add_buffer()
-        [](void* pipe, uint64_t paddr, uint64_t sz) {
-            // not considered for virtio
-        },
-        // dma_remove_buffer()
-        [](uint64_t paddr) {
-            // not considered for virtio
-        },
-        // dma_invalidate_host_mappings()
-        []() {
-            // not considered for virtio
-        },
-        // dma_reset_host_mappings()
-        []() {
-            // not considered for virtio
-        },
-        // dma_save_mappings()
-        [](QEMUFile* file) {
-            (void)file;
-        },
-        // dma_load_mappings()
-        [](QEMUFile* file) {
-            (void)file;
-        },
-};
-
-extern const QAndroidVmOperations* const gQAndroidVmOperations;
-
-static void default_post_callback(
-    void* context, uint32_t displayId, int width, int height, int ydir, int format, int frame_type, unsigned char* pixels) {
-    (void)context;
-    (void)width;
-    (void)height;
-    (void)ydir;
-    (void)format;
-    (void)frame_type;
-    (void)pixels;
-    // no-op
-}
-
-extern "C" VG_EXPORT void gfxstream_backend_init(
-    uint32_t display_width,
-    uint32_t display_height,
-    uint32_t display_type,
-    void* renderer_cookie,
-    int renderer_flags,
-    struct virgl_renderer_callbacks* virglrenderer_callbacks,
-    struct gfxstream_callbacks* gfxstreamcallbacks) {
-
-    // Set metrics callbacks
-    if (gfxstreamcallbacks) {
-        if (gfxstreamcallbacks->add_instant_event) {
-            MetricsLogger::add_instant_event_callback =
-                gfxstreamcallbacks->add_instant_event;
-        }
-        if (gfxstreamcallbacks->add_instant_event_with_metric) {
-            MetricsLogger::add_instant_event_with_metric_callback =
-                gfxstreamcallbacks->add_instant_event_with_metric;
-        }
-        if (gfxstreamcallbacks->add_instant_event_with_descriptor) {
-            MetricsLogger::add_instant_event_with_descriptor_callback =
-                gfxstreamcallbacks->add_instant_event_with_descriptor;
-        }
-        if (gfxstreamcallbacks->add_vulkan_out_of_memory_event) {
-            MetricsLogger::add_vulkan_out_of_memory_event =
-                gfxstreamcallbacks->add_vulkan_out_of_memory_event;
-        }
-        if (gfxstreamcallbacks->set_annotation) {
-            MetricsLogger::set_crash_annotation_callback =
-                gfxstreamcallbacks->set_annotation;
-        }
-        if (gfxstreamcallbacks->abort) {
-            emugl::setDieFunction(gfxstreamcallbacks->abort);
-        }
-    }
-
-    // Set non product-specific callbacks
-    vk_util::setVkCheckCallbacks(
-        std::make_unique<vk_util::VkCheckCallbacks>(vk_util::VkCheckCallbacks{
-            .onVkErrorOutOfMemory =
-                [](VkResult result, const char* function, int line) {
-                    auto fb = 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 = FrameBuffer::getFB();
-                    if (!fb) {
-                        ERR("FrameBuffer not yet initialized. Dropping out of memory event");
-                        return;
-                    }
-                    fb->logVulkanOutOfMemory(result, function, line, allocationSize);
-                }}));
-
-    gfxstream_backend_init_product_override();
-    // First we make some agents available.
-
-    GFXS_LOG("start. display dimensions: width %u height %u, renderer flags: 0x%x", display_width,
-             display_height, renderer_flags);
-
-    // Flags processing
-
-    // TODO: hook up "gfxstream egl" to the renderer flags
-    // GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT in crosvm
-    // as it's specified from launch_cvd.
-    // At the moment, use ANDROID_GFXSTREAM_EGL=1
-    // For test on GCE
-    if (android::base::getEnvironmentVariable("ANDROID_GFXSTREAM_EGL") == "1") {
-        android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
-        android::base::setEnvironmentVariable("ANDROID_EMUGL_LOG_PRINT", "1");
-        android::base::setEnvironmentVariable("ANDROID_EMUGL_VERBOSE", "1");
-    }
-    // end for test on GCE
-
-    android::base::setEnvironmentVariable("ANDROID_EMU_HEADLESS", "1");
-    android::base::setEnvironmentVariable("ANDROID_EMU_SANDBOX", "1");
-    bool enableVk =
-        !(renderer_flags & GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT);
-
-    bool egl2eglByEnv = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1";
-    bool egl2eglByFlag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT;
-    bool enable_egl2egl = egl2eglByFlag || egl2eglByEnv;
-    if (enable_egl2egl) {
-        android::base::setEnvironmentVariable("ANDROID_GFXSTREAM_EGL", "1");
-        android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
-    }
-
-    bool surfaceless =
-            renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT;
-    bool enableGlEs31Flag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_ENABLE_GLES31_BIT;
-    bool guestUsesAngle = renderer_flags & GFXSTREAM_RENDERER_FLAGS_GUEST_USES_ANGLE;
-    bool useVulkanNativeSwapchain =
-        renderer_flags & GFXSTREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT;
-
-    GFXS_LOG("Vulkan enabled? %d", enableVk);
-    GFXS_LOG("egl2egl enabled? %d", enable_egl2egl);
-    GFXS_LOG("surfaceless? %d", surfaceless);
-    GFXS_LOG("OpenGL ES 3.1 enabled? %d", enableGlEs31Flag);
-    GFXS_LOG("guest using ANGLE? %d", guestUsesAngle);
-    GFXS_LOG("use Vulkan native swapchain on the host? %d",
-             useVulkanNativeSwapchain);
-
-    // Need to manually set the GLES backend paths in gfxstream environment
-    // because the library search paths are not automatically set to include
-    // the directory in whioch the GLES backend resides.
-#if defined(__linux__)
-#define GFXSTREAM_LIB_SUFFIX ".so"
-#elif defined(__APPLE__)
-#define GFXSTREAM_LIB_SUFFIX ".dylib"
-#else // Windows
-#define GFXSTREAM_LIB_SUFFIX ".dll"
-#endif
-
-    feature_set_enabled_override(
-            kFeature_GLPipeChecksum, false);
-    feature_set_enabled_override(
-            kFeature_GLESDynamicVersion, true);
-    feature_set_enabled_override(
-            kFeature_PlayStoreImage, !enableGlEs31Flag);
-    feature_set_enabled_override(
-            kFeature_GLDMA, false);
-    feature_set_enabled_override(
-            kFeature_GLAsyncSwap, false);
-    feature_set_enabled_override(
-            kFeature_RefCountPipe, false);
-    feature_set_enabled_override(
-            kFeature_NoDelayCloseColorBuffer, true);
-    feature_set_enabled_override(
-            kFeature_NativeTextureDecompression, false);
-    feature_set_enabled_override(
-            kFeature_GLDirectMem, false);
-    feature_set_enabled_override(
-            kFeature_Vulkan, enableVk);
-    feature_set_enabled_override(
-            kFeature_VulkanSnapshots, false);
-    feature_set_enabled_override(
-            kFeature_VulkanNullOptionalStrings, true);
-    feature_set_enabled_override(
-            kFeature_VulkanShaderFloat16Int8, true);
-    feature_set_enabled_override(
-            kFeature_HostComposition, true);
-    feature_set_enabled_override(
-            kFeature_VulkanIgnoredHandles, true);
-    feature_set_enabled_override(
-            kFeature_VirtioGpuNext, true);
-    feature_set_enabled_override(
-            kFeature_VirtioGpuNativeSync, true);
-    feature_set_enabled_override(
-            kFeature_GuestUsesAngle, guestUsesAngle);
-    feature_set_enabled_override(
-            kFeature_VulkanQueueSubmitWithCommands, true);
-    feature_set_enabled_override(kFeature_VulkanNativeSwapchain,
-                                 useVulkanNativeSwapchain);
-    feature_set_enabled_override(
-            kFeature_VulkanBatchedDescriptorSetUpdate, true);
-    // TODO: Strictly speaking, renderer_flags check is insufficient because
-    // fence contexts require us to be running a new-enough guest kernel.
-    feature_set_enabled_override(
-           kFeature_VirtioGpuFenceContexts,
-           (renderer_flags & GFXSTREAM_RENDERER_FLAGS_ASYNC_FENCE_CB));
-    feature_set_enabled_override(kFeature_VulkanAstcLdrEmulation, true);
-    feature_set_enabled_override(kFeature_VulkanEtc2Emulation, true);
-    feature_set_enabled_override(kFeature_VulkanYcbcrEmulation, false);
-    feature_set_enabled_override(kFeature_ExternalBlob, false);
-
-    android::featurecontrol::productFeatureOverride();
-
-    if (useVulkanNativeSwapchain && !enableVk) {
-        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
-                            "can't enable vulkan native swapchain, Vulkan is disabled";
-    }
-
-    emugl::vkDispatch(false /* don't use test ICD */);
-
-    auto androidHw = aemu_get_android_hw();
-
-    androidHw->hw_gltransport_asg_writeBufferSize = 1048576;
-    androidHw->hw_gltransport_asg_writeStepSize = 262144;
-    androidHw->hw_gltransport_asg_dataRingSize = 524288;
-    androidHw->hw_gltransport_drawFlushInterval = 10000;
-
-    EmuglConfig config;
-
-    // Make all the console agents available.
-    android::emulation::injectGraphicsAgents(android::emulation::GfxStreamGraphicsAgentFactory());
-
-    emuglConfig_init(&config, true /* gpu enabled */, "auto",
-                     enable_egl2egl ? "swiftshader_indirect" : "host",
-                     64,          /* bitness */
-                     surfaceless, /* no window */
-                     false,       /* blacklisted */
-                     false,       /* has guest renderer */
-                     WINSYS_GLESBACKEND_PREFERENCE_AUTO,
-                     true /* force host gpu vulkan */);
-
-    emuglConfig_setupEnv(&config);
-
-    android_prepareOpenglesEmulation();
-
-    {
-        static emugl::RenderLibPtr renderLibPtr = initLibrary();
-        void* egldispatch = renderLibPtr->getEGLDispatch();
-        void* glesv2Dispatch = renderLibPtr->getGLESv2Dispatch();
-        android_setOpenglesEmulation(
-                renderLibPtr.get(), egldispatch, glesv2Dispatch);
-    }
-
-    int maj;
-    int min;
-    android_startOpenglesRenderer(
-        display_width, display_height, 1, 28,
-        getGraphicsAgents()->vm,
-        getGraphicsAgents()->emu,
-        getGraphicsAgents()->multi_display,
-        &maj, &min);
-
-    char* vendor = nullptr;
-    char* renderer = nullptr;
-    char* version = nullptr;
-
-    android_getOpenglesHardwareStrings(
-        &vendor, &renderer, &version);
-
-    GFXS_LOG("GL strings; [%s] [%s] [%s].\n",
-             vendor, renderer, version);
-
-    auto openglesRenderer = android_getOpenglesRenderer();
-
-    if (!openglesRenderer) {
-        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No renderer started, fatal";
-    }
-
-    address_space_set_vm_operations(getGraphicsAgents()->vm);
-    android_init_opengles_pipe();
-    android_opengles_pipe_set_recv_mode(2 /* virtio-gpu */);
-    android_init_refcount_pipe();
-
-    sGetPixelsFunc = android_getReadPixelsFunc();
-
-    pipe_virgl_renderer_init(renderer_cookie, renderer_flags, virglrenderer_callbacks);
-
-    GFXS_LOG("Started renderer");
-}
-
-extern "C" VG_EXPORT void gfxstream_backend_setup_window(
-        void* native_window_handle,
-        int32_t window_x,
-        int32_t window_y,
-        int32_t window_width,
-        int32_t window_height,
-        int32_t fb_width,
-        int32_t fb_height) {
-    android_showOpenglesWindow(native_window_handle, window_x, window_y,
-                               window_width, window_height, fb_width, fb_height,
-                               1.0f, 0, false, false);
-}
-
-extern "C" VG_EXPORT void gfxstream_backend_teardown() {
-    android_finishOpenglesRenderer();
-    android_hideOpenglesWindow();
-    android_stopOpenglesRenderer(true);
-}
-
-extern "C" VG_EXPORT void gfxstream_backend_set_screen_mask(int width, int height, const unsigned char* rgbaData) {
-    android_setOpenglesScreenMask(width, height, rgbaData);
-}
-
-extern "C" VG_EXPORT void get_pixels(void* pixels, uint32_t bytes) {
-    //TODO: support display > 0
-    sGetPixelsFunc(pixels, bytes, 0);
-}
-
-extern "C" VG_EXPORT void gfxstream_backend_getrender(char* buf, size_t bufSize, size_t* size) {
-    const char* render = "";
-    FrameBuffer* pFB = FrameBuffer::getFB();
-    if (pFB) {
-        const char* vendor = nullptr;
-        const char* version = nullptr;
-        pFB->getGLStrings(&vendor, &render, &version);
-    }
-    if (!buf || bufSize==0) {
-        if (size) *size = strlen(render);
-        return;
-    }
-    *buf = '\0';
-    strncat(buf, render, bufSize - 1);
-    if (size) *size = strlen(buf);
-}
-
-extern "C" const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops() {
-    return &goldfish_pipe_service_ops;
-}
-
diff --git a/stream-servers/GfxStreamBackend.h b/stream-servers/GfxStreamBackend.h
index 7dcf178..e0b5524 100644
--- a/stream-servers/GfxStreamBackend.h
+++ b/stream-servers/GfxStreamBackend.h
@@ -14,64 +14,6 @@
 
 #pragma once
 
-#include <stddef.h>
-
-extern "C" {
+// To not break existing imports of GfxStreamBackend.h until they are
+// refactored downstream.
 #include "virtio-gpu-gfxstream-renderer.h"
-#include "virgl_hw.h"
-}  // extern "C"
-
-struct gfxstream_callbacks {
-    /* Metrics callbacks */
-    void (*add_instant_event)(int64_t event_code);
-    void (*add_instant_event_with_descriptor)(int64_t event_code, int64_t descriptor);
-    void (*add_instant_event_with_metric)(int64_t event_code, int64_t metric_value);
-    void (*add_vulkan_out_of_memory_event)(int64_t result_code, uint32_t op_code,
-                                           const char* function, uint32_t line,
-                                           uint64_t allocation_size, bool is_host_side_result,
-                                           bool is_allocation);
-    void (*set_annotation)(const char* key, const char* value);
-    void (*abort)();
-};
-
-extern "C" VG_EXPORT void gfxstream_backend_init(
-    uint32_t display_width,
-    uint32_t display_height,
-    uint32_t display_type,
-    void* renderer_cookie,
-    int renderer_flags,
-    struct virgl_renderer_callbacks* virglrenderer_callbacks,
-    struct gfxstream_callbacks* gfxstreamcallbacks);
-
-extern "C" VG_EXPORT void gfxstream_backend_setup_window(
-        void* native_window_handle,
-        int32_t window_x,
-        int32_t window_y,
-        int32_t window_width,
-        int32_t window_height,
-        int32_t fb_width,
-        int32_t fb_height);
-
-extern "C" VG_EXPORT void gfxstream_backend_teardown(void);
-
-// Get the gfxstream backend render information.
-// example:
-//      /* Get the render string size */
-//      size_t size = 0
-//      gfxstream_backend_getrender(nullptr, 0, &size);
-//
-//      /* add extra space for '\0' */
-//      char * buf = malloc(size + 1);
-//
-//      /* Get the result render string */
-//      gfxstream_backend_getrender(buf, size+1, nullptr);
-//
-// if bufSize is less or equal the render string length, only bufSize-1 char copied.
-extern "C" VG_EXPORT void gfxstream_backend_getrender(
-      char* buf,
-      size_t bufSize,
-      size_t* size);
-
-// A customization point that allows the downstream to call their own functions when
-// gfxstream_backend_init is called.
-void gfxstream_backend_init_product_override();
diff --git a/stream-servers/GfxStreamBackendInitOverride.cpp b/stream-servers/GfxStreamBackendInitOverride.cpp
index cb274b5..0b7d0dc 100644
--- a/stream-servers/GfxStreamBackendInitOverride.cpp
+++ b/stream-servers/GfxStreamBackendInitOverride.cpp
@@ -12,6 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "GfxStreamBackend.h"
+#include "virtio-gpu-gfxstream-renderer.h"
 
 void gfxstream_backend_init_product_override() {}
\ No newline at end of file
diff --git a/stream-servers/gfxstream_unittest.cpp b/stream-servers/gfxstream_unittest.cpp
index e75170c..78beb9d 100644
--- a/stream-servers/gfxstream_unittest.cpp
+++ b/stream-servers/gfxstream_unittest.cpp
@@ -14,7 +14,7 @@
 
 #include <gtest/gtest.h>
 
-#include "GfxStreamBackend.h"
+#include "virtio-gpu-gfxstream-renderer.h"
 #include "host-common/testing/MockGraphicsAgentFactory.h"
 #include "OSWindow.h"
 #include "aemu/base/system/System.h"
diff --git a/stream-servers/virgl_hw.h b/stream-servers/virgl_hw.h
index d30e810..1543ba8 100644
--- a/stream-servers/virgl_hw.h
+++ b/stream-servers/virgl_hw.h
@@ -24,6 +24,8 @@
 #ifndef VIRGL_HW_H
 #define VIRGL_HW_H
 
+#include <stdint.h>
+
 struct virgl_box {
 	uint32_t x, y, z;
 	uint32_t w, h, d;
diff --git a/stream-servers/virtio-gpu-gfxstream-renderer.cpp b/stream-servers/virtio-gpu-gfxstream-renderer.cpp
index 0f00ece..3e0fe3f 100644
--- a/stream-servers/virtio-gpu-gfxstream-renderer.cpp
+++ b/stream-servers/virtio-gpu-gfxstream-renderer.cpp
@@ -17,8 +17,11 @@
 #include <type_traits>
 #include <unordered_map>
 
+#include "FrameBuffer.h"
+#include "GfxStreamAgents.h"
 #include "VirtioGpuTimelines.h"
 #include "aemu/base/AlignedBuf.h"
+#include "aemu/base/Metrics.h"
 #include "aemu/base/synchronization/Lock.h"
 #include "aemu/base/memory/SharedMemory.h"
 #include "aemu/base/ManagedDescriptor.hpp"
@@ -28,11 +31,16 @@
 #include "host-common/HostmemIdMapping.h"
 #include "host-common/address_space_device.h"
 #include "host-common/android_pipe_common.h"
+#include "host-common/android_pipe_device.h"
 #include "host-common/feature_control.h"
+#include "host-common/globals.h"
 #include "host-common/linux_types.h"
 #include "host-common/opengles.h"
+#include "host-common/opengles-pipe.h"
+#include "host-common/refcount-pipe.h"
 #include "host-common/vm_operations.h"
 #include "virtgpu_gfxstream_protocol.h"
+#include "vk_util.h"
 
 extern "C" {
 #include "virtio-gpu-gfxstream-renderer.h"
@@ -70,6 +78,23 @@
 
 #endif // !VIRTIO_GOLDFISH_EXPORT_API
 
+#define GFXSTREAM_DEBUG_LEVEL 1
+
+#if GFXSTREAM_DEBUG_LEVEL >= 1
+#define GFXS_LOG(fmt, ...)                                                     \
+    do {                                                                       \
+        fprintf(stdout, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \
+        fflush(stdout);                                                        \
+    } while (0)
+
+#else
+#define GFXS_LOG(fmt,...)
+#endif
+
+#define POST_CALLBACK_DISPLAY_TYPE_X 0
+#define POST_CALLBACK_DISPLAY_TYPE_WAYLAND_SHARED_MEM 1
+#define POST_CALLBACK_DISPLAY_TYPE_WINDOWS_HWND 2
+
 // Virtio Goldfish Pipe: Overview-----------------------------------------------
 //
 // Virtio Goldfish Pipe is meant for running goldfish pipe services with a
@@ -148,10 +173,12 @@
 // linear buffer if necessary, and then perform a corresponding pip operation
 // based on the box parameter's x and width values.
 
+using android::AndroidPipe;
 using android::base::AutoLock;
 using android::base::DescriptorType;
 using android::base::Lock;
 using android::base::ManagedDescriptor;
+using android::base::MetricsLogger;
 using android::base::SharedMemory;
 
 using android::emulation::HostmemIdMapping;
@@ -1928,6 +1955,453 @@
     return sRenderer()->vulkanInfo(res_handle, vulkan_info);
 }
 
+struct renderer_display_info;
+typedef void (*get_pixels_t)(void*, uint32_t, uint32_t);
+static get_pixels_t sGetPixelsFunc = 0;
+typedef void (*post_callback_t)(void*, uint32_t, int, int, int, int, int, unsigned char*);
+
+// For reading back rendered contents to display
+VG_EXPORT void get_pixels(void* pixels, uint32_t bytes);
+
+static const GoldfishPipeServiceOps goldfish_pipe_service_ops = {
+    // guest_open()
+    [](GoldfishHwPipe* hwPipe) -> GoldfishHostPipe* {
+        return static_cast<GoldfishHostPipe*>(
+            android_pipe_guest_open(hwPipe));
+    },
+    // guest_open_with_flags()
+    [](GoldfishHwPipe* hwPipe, uint32_t flags) -> GoldfishHostPipe* {
+        return static_cast<GoldfishHostPipe*>(
+            android_pipe_guest_open_with_flags(hwPipe, flags));
+    },
+    // guest_close()
+    [](GoldfishHostPipe* hostPipe, GoldfishPipeCloseReason reason) {
+        static_assert((int)GOLDFISH_PIPE_CLOSE_GRACEFUL ==
+                          (int)PIPE_CLOSE_GRACEFUL,
+                      "Invalid PIPE_CLOSE_GRACEFUL value");
+        static_assert(
+            (int)GOLDFISH_PIPE_CLOSE_REBOOT == (int)PIPE_CLOSE_REBOOT,
+            "Invalid PIPE_CLOSE_REBOOT value");
+        static_assert((int)GOLDFISH_PIPE_CLOSE_LOAD_SNAPSHOT ==
+                          (int)PIPE_CLOSE_LOAD_SNAPSHOT,
+                      "Invalid PIPE_CLOSE_LOAD_SNAPSHOT value");
+        static_assert(
+            (int)GOLDFISH_PIPE_CLOSE_ERROR == (int)PIPE_CLOSE_ERROR,
+            "Invalid PIPE_CLOSE_ERROR value");
+
+        android_pipe_guest_close(hostPipe,
+                                 static_cast<PipeCloseReason>(reason));
+    },
+    // guest_pre_load()
+    [](QEMUFile* file) { (void)file; },
+    // guest_post_load()
+    [](QEMUFile* file) { (void)file; },
+    // guest_pre_save()
+    [](QEMUFile* file) { (void)file; },
+    // guest_post_save()
+    [](QEMUFile* file) { (void)file; },
+    // guest_load()
+    [](QEMUFile* file,
+       GoldfishHwPipe* hwPipe,
+       char* force_close) -> GoldfishHostPipe* {
+        (void)file;
+        (void)hwPipe;
+        (void)force_close;
+        return nullptr;
+    },
+    // guest_save()
+    [](GoldfishHostPipe* hostPipe, QEMUFile* file) {
+        (void)hostPipe;
+        (void)file;
+    },
+    // guest_poll()
+    [](GoldfishHostPipe* hostPipe) {
+        static_assert((int)GOLDFISH_PIPE_POLL_IN == (int)PIPE_POLL_IN,
+                      "invalid POLL_IN values");
+        static_assert((int)GOLDFISH_PIPE_POLL_OUT == (int)PIPE_POLL_OUT,
+                      "invalid POLL_OUT values");
+        static_assert((int)GOLDFISH_PIPE_POLL_HUP == (int)PIPE_POLL_HUP,
+                      "invalid POLL_HUP values");
+
+        return static_cast<GoldfishPipePollFlags>(
+            android_pipe_guest_poll(hostPipe));
+    },
+    // guest_recv()
+    [](GoldfishHostPipe* hostPipe,
+       GoldfishPipeBuffer* buffers,
+       int numBuffers) -> int {
+        // NOTE: Assumes that AndroidPipeBuffer and GoldfishPipeBuffer
+        //       have exactly the same layout.
+        static_assert(
+            sizeof(AndroidPipeBuffer) == sizeof(GoldfishPipeBuffer),
+            "Invalid PipeBuffer sizes");
+    // We can't use a static_assert with offsetof() because in msvc, it uses
+    // reinterpret_cast.
+    // TODO: Add runtime assertion instead?
+    // https://developercommunity.visualstudio.com/content/problem/22196/static-assert-cannot-compile-constexprs-method-tha.html
+#ifndef _MSC_VER
+        static_assert(offsetof(AndroidPipeBuffer, data) ==
+                          offsetof(GoldfishPipeBuffer, data),
+                      "Invalid PipeBuffer::data offsets");
+        static_assert(offsetof(AndroidPipeBuffer, size) ==
+                          offsetof(GoldfishPipeBuffer, size),
+                      "Invalid PipeBuffer::size offsets");
+#endif
+        return android_pipe_guest_recv(
+            hostPipe, reinterpret_cast<AndroidPipeBuffer*>(buffers),
+            numBuffers);
+    },
+    // guest_send()
+    [](GoldfishHostPipe** hostPipe,
+       const GoldfishPipeBuffer* buffers,
+       int numBuffers) -> int {
+        return android_pipe_guest_send(
+            reinterpret_cast<void**>(hostPipe),
+            reinterpret_cast<const AndroidPipeBuffer*>(buffers),
+            numBuffers);
+    },
+    // guest_wake_on()
+    [](GoldfishHostPipe* hostPipe, GoldfishPipeWakeFlags wakeFlags) {
+        android_pipe_guest_wake_on(hostPipe, static_cast<int>(wakeFlags));
+    },
+    // dma_add_buffer()
+    [](void* pipe, uint64_t paddr, uint64_t sz) {
+        // not considered for virtio
+    },
+    // dma_remove_buffer()
+    [](uint64_t paddr) {
+        // not considered for virtio
+    },
+    // dma_invalidate_host_mappings()
+    []() {
+        // not considered for virtio
+    },
+    // dma_reset_host_mappings()
+    []() {
+        // not considered for virtio
+    },
+    // dma_save_mappings()
+    [](QEMUFile* file) {
+        (void)file;
+    },
+    // dma_load_mappings()
+    [](QEMUFile* file) {
+        (void)file;
+    },
+};
+
+extern const QAndroidVmOperations* const gQAndroidVmOperations;
+
+static void default_post_callback(
+    void* context, uint32_t displayId, int width, int height, int ydir, int format, int frame_type, unsigned char* pixels) {
+    (void)context;
+    (void)width;
+    (void)height;
+    (void)ydir;
+    (void)format;
+    (void)frame_type;
+    (void)pixels;
+    // no-op
+}
+
+VG_EXPORT void gfxstream_backend_init(
+    uint32_t display_width,
+    uint32_t display_height,
+    uint32_t display_type,
+    void* renderer_cookie,
+    int renderer_flags,
+    struct virgl_renderer_callbacks* virglrenderer_callbacks,
+    struct gfxstream_callbacks* gfxstreamcallbacks) {
+
+    // Set metrics callbacks
+    if (gfxstreamcallbacks) {
+        if (gfxstreamcallbacks->add_instant_event) {
+            MetricsLogger::add_instant_event_callback =
+                gfxstreamcallbacks->add_instant_event;
+        }
+        if (gfxstreamcallbacks->add_instant_event_with_metric) {
+            MetricsLogger::add_instant_event_with_metric_callback =
+                gfxstreamcallbacks->add_instant_event_with_metric;
+        }
+        if (gfxstreamcallbacks->add_instant_event_with_descriptor) {
+            MetricsLogger::add_instant_event_with_descriptor_callback =
+                gfxstreamcallbacks->add_instant_event_with_descriptor;
+        }
+        if (gfxstreamcallbacks->add_vulkan_out_of_memory_event) {
+            MetricsLogger::add_vulkan_out_of_memory_event =
+                gfxstreamcallbacks->add_vulkan_out_of_memory_event;
+        }
+        if (gfxstreamcallbacks->set_annotation) {
+            MetricsLogger::set_crash_annotation_callback =
+                gfxstreamcallbacks->set_annotation;
+        }
+        if (gfxstreamcallbacks->abort) {
+            emugl::setDieFunction(gfxstreamcallbacks->abort);
+        }
+    }
+
+    // Set non product-specific callbacks
+    vk_util::setVkCheckCallbacks(
+        std::make_unique<vk_util::VkCheckCallbacks>(vk_util::VkCheckCallbacks{
+            .onVkErrorOutOfMemory =
+                [](VkResult result, const char* function, int line) {
+                    auto fb = 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 = FrameBuffer::getFB();
+                    if (!fb) {
+                        ERR("FrameBuffer not yet initialized. Dropping out of memory event");
+                        return;
+                    }
+                    fb->logVulkanOutOfMemory(result, function, line, allocationSize);
+                }}));
+
+    gfxstream_backend_init_product_override();
+    // First we make some agents available.
+
+    GFXS_LOG("start. display dimensions: width %u height %u, renderer flags: 0x%x", display_width,
+             display_height, renderer_flags);
+
+    // Flags processing
+
+    // TODO: hook up "gfxstream egl" to the renderer flags
+    // GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT in crosvm
+    // as it's specified from launch_cvd.
+    // At the moment, use ANDROID_GFXSTREAM_EGL=1
+    // For test on GCE
+    if (android::base::getEnvironmentVariable("ANDROID_GFXSTREAM_EGL") == "1") {
+        android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
+        android::base::setEnvironmentVariable("ANDROID_EMUGL_LOG_PRINT", "1");
+        android::base::setEnvironmentVariable("ANDROID_EMUGL_VERBOSE", "1");
+    }
+    // end for test on GCE
+
+    android::base::setEnvironmentVariable("ANDROID_EMU_HEADLESS", "1");
+    android::base::setEnvironmentVariable("ANDROID_EMU_SANDBOX", "1");
+    bool enableVk =
+        !(renderer_flags & GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT);
+
+    bool egl2eglByEnv = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1";
+    bool egl2eglByFlag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT;
+    bool enable_egl2egl = egl2eglByFlag || egl2eglByEnv;
+    if (enable_egl2egl) {
+        android::base::setEnvironmentVariable("ANDROID_GFXSTREAM_EGL", "1");
+        android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
+    }
+
+    bool surfaceless =
+        renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT;
+    bool enableGlEs31Flag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_ENABLE_GLES31_BIT;
+    bool guestUsesAngle = renderer_flags & GFXSTREAM_RENDERER_FLAGS_GUEST_USES_ANGLE;
+    bool useVulkanNativeSwapchain =
+        renderer_flags & GFXSTREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT;
+
+    GFXS_LOG("Vulkan enabled? %d", enableVk);
+    GFXS_LOG("egl2egl enabled? %d", enable_egl2egl);
+    GFXS_LOG("surfaceless? %d", surfaceless);
+    GFXS_LOG("OpenGL ES 3.1 enabled? %d", enableGlEs31Flag);
+    GFXS_LOG("guest using ANGLE? %d", guestUsesAngle);
+    GFXS_LOG("use Vulkan native swapchain on the host? %d",
+             useVulkanNativeSwapchain);
+
+    // Need to manually set the GLES backend paths in gfxstream environment
+    // because the library search paths are not automatically set to include
+    // the directory in whioch the GLES backend resides.
+#if defined(__linux__)
+#define GFXSTREAM_LIB_SUFFIX ".so"
+#elif defined(__APPLE__)
+#define GFXSTREAM_LIB_SUFFIX ".dylib"
+#else // Windows
+#define GFXSTREAM_LIB_SUFFIX ".dll"
+#endif
+
+    feature_set_enabled_override(
+        kFeature_GLPipeChecksum, false);
+    feature_set_enabled_override(
+        kFeature_GLESDynamicVersion, true);
+    feature_set_enabled_override(
+        kFeature_PlayStoreImage, !enableGlEs31Flag);
+    feature_set_enabled_override(
+        kFeature_GLDMA, false);
+    feature_set_enabled_override(
+        kFeature_GLAsyncSwap, false);
+    feature_set_enabled_override(
+        kFeature_RefCountPipe, false);
+    feature_set_enabled_override(
+        kFeature_NoDelayCloseColorBuffer, true);
+    feature_set_enabled_override(
+        kFeature_NativeTextureDecompression, false);
+    feature_set_enabled_override(
+        kFeature_GLDirectMem, false);
+    feature_set_enabled_override(
+        kFeature_Vulkan, enableVk);
+    feature_set_enabled_override(
+        kFeature_VulkanSnapshots, false);
+    feature_set_enabled_override(
+        kFeature_VulkanNullOptionalStrings, true);
+    feature_set_enabled_override(
+        kFeature_VulkanShaderFloat16Int8, true);
+    feature_set_enabled_override(
+        kFeature_HostComposition, true);
+    feature_set_enabled_override(
+        kFeature_VulkanIgnoredHandles, true);
+    feature_set_enabled_override(
+        kFeature_VirtioGpuNext, true);
+    feature_set_enabled_override(
+        kFeature_VirtioGpuNativeSync, true);
+    feature_set_enabled_override(
+        kFeature_GuestUsesAngle, guestUsesAngle);
+    feature_set_enabled_override(
+        kFeature_VulkanQueueSubmitWithCommands, true);
+    feature_set_enabled_override(kFeature_VulkanNativeSwapchain,
+                                 useVulkanNativeSwapchain);
+    feature_set_enabled_override(
+        kFeature_VulkanBatchedDescriptorSetUpdate, true);
+    // TODO: Strictly speaking, renderer_flags check is insufficient because
+    // fence contexts require us to be running a new-enough guest kernel.
+    feature_set_enabled_override(
+        kFeature_VirtioGpuFenceContexts,
+        (renderer_flags & GFXSTREAM_RENDERER_FLAGS_ASYNC_FENCE_CB));
+    feature_set_enabled_override(kFeature_VulkanAstcLdrEmulation, true);
+    feature_set_enabled_override(kFeature_VulkanEtc2Emulation, true);
+    feature_set_enabled_override(kFeature_VulkanYcbcrEmulation, false);
+    feature_set_enabled_override(kFeature_ExternalBlob, false);
+
+    android::featurecontrol::productFeatureOverride();
+
+    if (useVulkanNativeSwapchain && !enableVk) {
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+            "can't enable vulkan native swapchain, Vulkan is disabled";
+    }
+
+    emugl::vkDispatch(false /* don't use test ICD */);
+
+    auto androidHw = aemu_get_android_hw();
+
+    androidHw->hw_gltransport_asg_writeBufferSize = 1048576;
+    androidHw->hw_gltransport_asg_writeStepSize = 262144;
+    androidHw->hw_gltransport_asg_dataRingSize = 524288;
+    androidHw->hw_gltransport_drawFlushInterval = 10000;
+
+    EmuglConfig config;
+
+    // Make all the console agents available.
+    android::emulation::injectGraphicsAgents(android::emulation::GfxStreamGraphicsAgentFactory());
+
+    emuglConfig_init(&config, true /* gpu enabled */, "auto",
+                     enable_egl2egl ? "swiftshader_indirect" : "host",
+                     64,          /* bitness */
+                     surfaceless, /* no window */
+                     false,       /* blocklisted */
+                     false,       /* has guest renderer */
+                     WINSYS_GLESBACKEND_PREFERENCE_AUTO,
+                     true /* force host gpu vulkan */);
+
+    emuglConfig_setupEnv(&config);
+
+    android_prepareOpenglesEmulation();
+
+    {
+        static emugl::RenderLibPtr renderLibPtr = initLibrary();
+        void* egldispatch = renderLibPtr->getEGLDispatch();
+        void* glesv2Dispatch = renderLibPtr->getGLESv2Dispatch();
+        android_setOpenglesEmulation(
+            renderLibPtr.get(), egldispatch, glesv2Dispatch);
+    }
+
+    int maj;
+    int min;
+    android_startOpenglesRenderer(
+        display_width, display_height, 1, 28,
+        getGraphicsAgents()->vm,
+        getGraphicsAgents()->emu,
+        getGraphicsAgents()->multi_display,
+        &maj, &min);
+
+    char* vendor = nullptr;
+    char* renderer = nullptr;
+    char* version = nullptr;
+
+    android_getOpenglesHardwareStrings(
+        &vendor, &renderer, &version);
+
+    GFXS_LOG("GL strings; [%s] [%s] [%s].\n",
+             vendor, renderer, version);
+
+    auto openglesRenderer = android_getOpenglesRenderer();
+
+    if (!openglesRenderer) {
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No renderer started, fatal";
+    }
+
+    address_space_set_vm_operations(getGraphicsAgents()->vm);
+    android_init_opengles_pipe();
+    android_opengles_pipe_set_recv_mode(2 /* virtio-gpu */);
+    android_init_refcount_pipe();
+
+    sGetPixelsFunc = android_getReadPixelsFunc();
+
+    pipe_virgl_renderer_init(renderer_cookie, renderer_flags, virglrenderer_callbacks);
+
+    GFXS_LOG("Started renderer");
+}
+
+VG_EXPORT void gfxstream_backend_setup_window(
+    void* native_window_handle,
+    int32_t window_x,
+    int32_t window_y,
+    int32_t window_width,
+    int32_t window_height,
+    int32_t fb_width,
+    int32_t fb_height) {
+    android_showOpenglesWindow(native_window_handle, window_x, window_y,
+                               window_width, window_height, fb_width, fb_height,
+                               1.0f, 0, false, false);
+}
+
+VG_EXPORT void gfxstream_backend_teardown() {
+    android_finishOpenglesRenderer();
+    android_hideOpenglesWindow();
+    android_stopOpenglesRenderer(true);
+}
+
+VG_EXPORT void gfxstream_backend_set_screen_mask(int width, int height, const unsigned char* rgbaData) {
+    android_setOpenglesScreenMask(width, height, rgbaData);
+}
+
+VG_EXPORT void get_pixels(void* pixels, uint32_t bytes) {
+    //TODO: support display > 0
+    sGetPixelsFunc(pixels, bytes, 0);
+}
+
+VG_EXPORT void gfxstream_backend_getrender(char* buf, size_t bufSize, size_t* size) {
+    const char* render = "";
+    FrameBuffer* pFB = FrameBuffer::getFB();
+    if (pFB) {
+        const char* vendor = nullptr;
+        const char* version = nullptr;
+        pFB->getGLStrings(&vendor, &render, &version);
+    }
+    if (!buf || bufSize==0) {
+        if (size) *size = strlen(render);
+        return;
+    }
+    *buf = '\0';
+    strncat(buf, render, bufSize - 1);
+    if (size) *size = strlen(buf);
+}
+
+const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops() {
+    return &goldfish_pipe_service_ops;
+}
+
 #define VIRGLRENDERER_API_PIPE_STRUCT_DEF(api) pipe_##api,
 
 static struct virgl_renderer_virtio_interface s_virtio_interface = {
diff --git a/stream-servers/virtio-gpu-gfxstream-renderer.h b/stream-servers/virtio-gpu-gfxstream-renderer.h
index 0ba9e92..973d7ec 100644
--- a/stream-servers/virtio-gpu-gfxstream-renderer.h
+++ b/stream-servers/virtio-gpu-gfxstream-renderer.h
@@ -5,6 +5,9 @@
  * implement an actual virtio goldfish pipe, but this hijacking of virgl  is
  * done in order to avoid any guest kernel changes. */
 
+#include <stddef.h>
+
+#include "virgl_hw.h"
 #include "virglrenderer.h"
 
 
@@ -163,6 +166,61 @@
 VG_EXPORT int stream_renderer_vulkan_info(uint32_t res_handle,
                                           struct stream_renderer_vulkan_info *vulkan_info);
 
+struct gfxstream_callbacks {
+    /* Metrics callbacks */
+    void (*add_instant_event)(int64_t event_code);
+    void (*add_instant_event_with_descriptor)(int64_t event_code, int64_t descriptor);
+    void (*add_instant_event_with_metric)(int64_t event_code, int64_t metric_value);
+    void (*add_vulkan_out_of_memory_event)(int64_t result_code, uint32_t op_code,
+                                           const char* function, uint32_t line,
+                                           uint64_t allocation_size, bool is_host_side_result,
+                                           bool is_allocation);
+    void (*set_annotation)(const char* key, const char* value);
+    void (*abort)();
+};
+
+VG_EXPORT void gfxstream_backend_init(
+    uint32_t display_width,
+    uint32_t display_height,
+    uint32_t display_type,
+    void* renderer_cookie,
+    int renderer_flags,
+    struct virgl_renderer_callbacks* virglrenderer_callbacks,
+    struct gfxstream_callbacks* gfxstreamcallbacks);
+
+VG_EXPORT void gfxstream_backend_setup_window(
+    void* native_window_handle,
+    int32_t window_x,
+    int32_t window_y,
+    int32_t window_width,
+    int32_t window_height,
+    int32_t fb_width,
+    int32_t fb_height);
+
+VG_EXPORT void gfxstream_backend_teardown(void);
+
+// Get the gfxstream backend render information.
+// example:
+//      /* Get the render string size */
+//      size_t size = 0
+//      gfxstream_backend_getrender(nullptr, 0, &size);
+//
+//      /* add extra space for '\0' */
+//      char * buf = malloc(size + 1);
+//
+//      /* Get the result render string */
+//      gfxstream_backend_getrender(buf, size+1, nullptr);
+//
+// if bufSize is less or equal the render string length, only bufSize-1 char copied.
+VG_EXPORT void gfxstream_backend_getrender(
+    char* buf,
+    size_t bufSize,
+    size_t* size);
+
+// A customization point that allows the downstream to call their own functions when
+// gfxstream_backend_init is called.
+void gfxstream_backend_init_product_override();
+
 #else
 
 #define VG_EXPORT