// Copyright 2019 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 <cstdarg>
#include <cstdint>

#ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
#include <filesystem>
#include <fcntl.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include "aemu/base/files/StdioStream.h"
#endif  // ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT

#include "FrameBuffer.h"
#include "GfxStreamAgents.h"
#include "VirtioGpuFrontend.h"
#include "aemu/base/Metrics.h"
#ifdef GFXSTREAM_ENABLE_HOST_VK_SNAPSHOT
#include "aemu/base/files/StdioStream.h"
#endif
#include "aemu/base/system/System.h"
#include "gfxstream/Strings.h"
#include "gfxstream/host/Features.h"
#include "gfxstream/host/Tracing.h"
#include "host-common/FeatureControl.h"
#include "host-common/GraphicsAgentFactory.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/globals.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 "vulkan/VulkanDispatch.h"
#include "render-utils/RenderLib.h"
#include "vk_util.h"

extern "C" {
#include "gfxstream/virtio-gpu-gfxstream-renderer-unstable.h"
#include "gfxstream/virtio-gpu-gfxstream-renderer.h"
#include "host-common/goldfish_pipe.h"
}  // extern "C"

#define MAX_DEBUG_BUFFER_SIZE 512
#define ELLIPSIS "...\0"
#define ELLIPSIS_LEN 4

// Define the typedef for emulogger
typedef void (*emulogger)(char severity, const char* file, unsigned int line,
                          int64_t timestamp_us, const char* message);

// Template to enable the method call if gfxstream_logger_t equals emulogger
template<typename T>
typename std::enable_if<std::is_same<T, emulogger>::value, bool>::type
call_logger_if_valid(T logger, char severity, const char* file, unsigned int line, int64_t timestamp_us, const char* message) {
    // Call the logger and return true if the type matches
    if (!logger) { return false; }
    logger(severity, file, line, timestamp_us, message);
    return true;
}

// Template for invalid logger types (returns false if types don't match)
template<typename T>
typename std::enable_if<!std::is_same<T, emulogger>::value, bool>::type
call_logger_if_valid(T, char, const char*, unsigned int, int64_t, const char*) {
    // Return false if the type doesn't match
    return false;
}

void* globalUserData = nullptr;
stream_renderer_debug_callback globalDebugCallback = nullptr;

static void append_truncation_marker(char* buf, int remaining_size) {
    // Safely append truncation marker "..." if buffer has enough space
    if (remaining_size >= ELLIPSIS_LEN) {
        strncpy(buf + remaining_size - ELLIPSIS_LEN, ELLIPSIS, ELLIPSIS_LEN);
    } else if (remaining_size >= 1) {
        buf[remaining_size - 1] = '\0';
    } else {
        // Oh oh.. In theory this shouldn't happen.
        assert(false);
    }
}

static void log_with_prefix(char*& buf, int& remaining_size, const char* file, int line,
                            const char* pretty_function) {
    // Add logging prefix if necessary
    int formatted_len = snprintf(buf, remaining_size, "[%s(%d)] %s ", file, line, pretty_function);

    // Handle potential truncation
    if (formatted_len >= remaining_size) {
        append_truncation_marker(buf, remaining_size);
        remaining_size = 0;
    } else {
        buf += formatted_len;             // Adjust buf
        remaining_size -= formatted_len;  // Reduce remaining buffer size
    }
}

static char translate_severity(uint32_t type) {
    switch (type) {
        case STREAM_RENDERER_DEBUG_ERROR:
            return 'E';
        case STREAM_RENDERER_DEBUG_WARN:
            return 'W';
        case STREAM_RENDERER_DEBUG_INFO:
            return 'I';
        case STREAM_RENDERER_DEBUG_DEBUG:
            return 'D';
        default:
            return 'D';
    }
}

using android::AndroidPipe;
using android::base::ManagedDescriptor;
using android::base::MetricsLogger;
using gfxstream::host::VirtioGpuFrontend;

static VirtioGpuFrontend* sFrontend() {
    static VirtioGpuFrontend* p = new VirtioGpuFrontend;
    return p;
}

extern "C" {

void stream_renderer_log(uint32_t type, const char* file, int line, const char* pretty_function,
                         const char* format, ...) {

    char printbuf[MAX_DEBUG_BUFFER_SIZE];
    char* buf = printbuf;
    int remaining_size = MAX_DEBUG_BUFFER_SIZE;
    static_assert(MAX_DEBUG_BUFFER_SIZE > 4);

    // Add the logging prefix if needed
#ifdef CONFIG_AEMU
    static gfxstream_logger_t gfx_logger = get_gfx_stream_logger();
    if (!gfx_logger) {
        log_with_prefix(buf, remaining_size, file, line, pretty_function);
    }
#else
    log_with_prefix(buf, remaining_size, file, line, pretty_function);
#endif

    // Format the message with variable arguments
    va_list args;
    va_start(args, format);
    int formatted_len = vsnprintf(buf, remaining_size, format, args);
    va_end(args);

    // Handle potential truncation
    if (formatted_len >= remaining_size) {
        append_truncation_marker(buf, remaining_size);
    }

#ifdef CONFIG_AEMU
    // Forward to emulator?
    if (call_logger_if_valid(gfx_logger, translate_severity(type), file, line, 0, printbuf)) {
        return;
    }
#endif

    // To a gfxstream debugger?
    if (globalUserData && globalDebugCallback) {
        struct stream_renderer_debug debug = {0};
        debug.debug_type = type;
        debug.message = &printbuf[0];
        globalDebugCallback(globalUserData, &debug);
    } else {
        // Cannot use logging routines, fallback to stderr
        fprintf(stderr, "stream_renderer_log error: %s\n", printbuf);
    }
}

VG_EXPORT int stream_renderer_resource_create(struct stream_renderer_resource_create_args* args,
                                              struct iovec* iov, uint32_t num_iovs) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_create()");

    return sFrontend()->createResource(args, iov, num_iovs);
}

VG_EXPORT void stream_renderer_resource_unref(uint32_t res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_unref()");

    sFrontend()->unrefResource(res_handle);
}

VG_EXPORT void stream_renderer_context_destroy(uint32_t handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_context_destroy()");

    sFrontend()->destroyContext(handle);
}

VG_EXPORT int stream_renderer_submit_cmd(struct stream_renderer_command* cmd) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_submit_cmd()");

    return sFrontend()->submitCmd(cmd);
}

VG_EXPORT int stream_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, uint32_t level,
                                                uint32_t stride, uint32_t layer_stride,
                                                struct stream_renderer_box* box, uint64_t offset,
                                                struct iovec* iov, int iovec_cnt) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_transfer_read_iov()");

    return sFrontend()->transferReadIov(handle, offset, box, iov, iovec_cnt);
}

VG_EXPORT int stream_renderer_transfer_write_iov(uint32_t handle, uint32_t ctx_id, int level,
                                                 uint32_t stride, uint32_t layer_stride,
                                                 struct stream_renderer_box* box, uint64_t offset,
                                                 struct iovec* iovec, unsigned int iovec_cnt) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_transfer_write_iov()");

    return sFrontend()->transferWriteIov(handle, offset, box, iovec, iovec_cnt);
}

VG_EXPORT void stream_renderer_get_cap_set(uint32_t set, uint32_t* max_ver, uint32_t* max_size) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_get_cap_set()");

    GFXSTREAM_TRACE_NAME_TRACK(GFXSTREAM_TRACE_TRACK_FOR_CURRENT_THREAD(),
                               "Main Virtio Gpu Thread");

    // `max_ver` not useful
    return sFrontend()->getCapset(set, max_size);
}

VG_EXPORT void stream_renderer_fill_caps(uint32_t set, uint32_t version, void* caps) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_fill_caps()");

    // `version` not useful
    return sFrontend()->fillCaps(set, caps);
}

VG_EXPORT int stream_renderer_resource_attach_iov(int res_handle, struct iovec* iov, int num_iovs) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_attach_iov()");

    return sFrontend()->attachIov(res_handle, iov, num_iovs);
}

VG_EXPORT void stream_renderer_resource_detach_iov(int res_handle, struct iovec** iov,
                                                   int* num_iovs) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_detach_iov()");

    return sFrontend()->detachIov(res_handle);
}

VG_EXPORT void stream_renderer_ctx_attach_resource(int ctx_id, int res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_ctx_attach_resource()");

    sFrontend()->attachResource(ctx_id, res_handle);
}

VG_EXPORT void stream_renderer_ctx_detach_resource(int ctx_id, int res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_ctx_detach_resource()");

    sFrontend()->detachResource(ctx_id, res_handle);
}

VG_EXPORT int stream_renderer_resource_get_info(int res_handle,
                                                struct stream_renderer_resource_info* info) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_get_info()");

    return sFrontend()->getResourceInfo(res_handle, info);
}

VG_EXPORT void stream_renderer_flush(uint32_t res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_flush()");

    sFrontend()->flushResource(res_handle);
}

VG_EXPORT int stream_renderer_create_blob(uint32_t ctx_id, uint32_t res_handle,
                                          const struct stream_renderer_create_blob* create_blob,
                                          const struct iovec* iovecs, uint32_t num_iovs,
                                          const struct stream_renderer_handle* handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_create_blob()");

    sFrontend()->createBlob(ctx_id, res_handle, create_blob, handle);
    return 0;
}

VG_EXPORT int stream_renderer_export_blob(uint32_t res_handle,
                                          struct stream_renderer_handle* handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_export_blob()");

    return sFrontend()->exportBlob(res_handle, handle);
}

VG_EXPORT int stream_renderer_resource_map(uint32_t res_handle, void** hvaOut, uint64_t* sizeOut) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_map()");

    return sFrontend()->resourceMap(res_handle, hvaOut, sizeOut);
}

VG_EXPORT int stream_renderer_resource_unmap(uint32_t res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_unmap()");

    return sFrontend()->resourceUnmap(res_handle);
}

VG_EXPORT int stream_renderer_context_create(uint32_t ctx_id, uint32_t nlen, const char* name,
                                             uint32_t context_init) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_context_create()");

    return sFrontend()->createContext(ctx_id, nlen, name, context_init);
}

VG_EXPORT int stream_renderer_create_fence(const struct stream_renderer_fence* fence) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_create_fence()");

    if (fence->flags & STREAM_RENDERER_FLAG_FENCE_SHAREABLE) {
        int ret = sFrontend()->acquireContextFence(fence->ctx_id, fence->fence_id);
        if (ret) {
            return ret;
        }
    }

    if (fence->flags & STREAM_RENDERER_FLAG_FENCE_RING_IDX) {
        sFrontend()->createFence(fence->fence_id, VirtioGpuRingContextSpecific{
                                                      .mCtxId = fence->ctx_id,
                                                      .mRingIdx = fence->ring_idx,
                                                  });
    } else {
        sFrontend()->createFence(fence->fence_id, VirtioGpuRingGlobal{});
    }

    return 0;
}

VG_EXPORT int stream_renderer_export_fence(uint64_t fence_id,
                                           struct stream_renderer_handle* handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_export_fence()");

    return sFrontend()->exportFence(fence_id, handle);
}

VG_EXPORT int stream_renderer_platform_import_resource(int res_handle, int res_info,
                                                       void* resource) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_platform_import_resource()");

    return sFrontend()->platformImportResource(res_handle, res_info, resource);
}

VG_EXPORT void* stream_renderer_platform_create_shared_egl_context() {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_platform_create_shared_egl_context()");

    return sFrontend()->platformCreateSharedEglContext();
}

VG_EXPORT int stream_renderer_platform_destroy_shared_egl_context(void* context) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_platform_destroy_shared_egl_context()");

    return sFrontend()->platformDestroySharedEglContext(context);
}

VG_EXPORT int stream_renderer_wait_sync_resource(uint32_t res_handle) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_wait_sync_resource()");

    return sFrontend()->waitSyncResource(res_handle);
}

VG_EXPORT int stream_renderer_resource_map_info(uint32_t res_handle, uint32_t* map_info) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_resource_map_info()");

    return sFrontend()->resourceMapInfo(res_handle, map_info);
}

VG_EXPORT int stream_renderer_vulkan_info(uint32_t res_handle,
                                          struct stream_renderer_vulkan_info* vulkan_info) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY,
                          "stream_renderer_vulkan_info()");

    return sFrontend()->vulkanInfo(res_handle, vulkan_info);
}

VG_EXPORT int stream_renderer_suspend() {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_suspend()");

    // TODO: move pauseAllPreSave() here after kumquat updated.

    return 0;
}

// Work in progress. Disabled for now but code is present to get build CI.
static constexpr const bool kEnableFrontendSnapshots = false;

VG_EXPORT int stream_renderer_snapshot(const char* dir) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_snapshot()");

#ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
    std::filesystem::path snapshotDirectory = std::string(dir);

    if (kEnableFrontendSnapshots) {
        gfxstream::host::snapshot::VirtioGpuFrontendSnapshot snapshot;
        if (sFrontend()->snapshot(snapshot)) {
            stream_renderer_error("Failed to save snapshot: failed to snapshot frontend.");
            return -1;
        }
        std::filesystem::path snapshotPath = snapshotDirectory / "gfxstream_snapshot.txtproto";
        int snapshotFd = open(snapshotPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0660);
        if (snapshotFd < 0) {
            stream_renderer_error("Failed to save snapshot: failed to open %s", snapshotPath.c_str());
            return -1;
        }
        google::protobuf::io::FileOutputStream snapshotOutputStream(snapshotFd);
        snapshotOutputStream.SetCloseOnDelete(true);
        if (!google::protobuf::TextFormat::Print(snapshot, &snapshotOutputStream)) {
            stream_renderer_error("Failed to save snapshot: failed to serialize to stream.");
            return -1;
        }
    }

    std::filesystem::path snapshotBinaryPath = snapshotDirectory / "gfxstream_snapshot.bin";

    std::unique_ptr<android::base::StdioStream> stream(new android::base::StdioStream(
        fopen(snapshotBinaryPath.c_str(), "wb"), android::base::StdioStream::kOwner));

    android_getOpenglesRenderer()->pauseAllPreSave();
    android::snapshot::SnapshotSaveStream saveStream{
        .stream = stream.get(),
    };

    android_getOpenglesRenderer()->save(saveStream.stream, saveStream.textureSaver);
    return 0;
#else
    stream_renderer_error("Snapshot save requested without support.");
    return -EINVAL;
#endif
}

VG_EXPORT int stream_renderer_restore(const char* dir) {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_restore()");

#ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT
    std::filesystem::path snapshotDirectory = std::string(dir);

    std::filesystem::path snapshotBinaryPath = snapshotDirectory / "gfxstream_snapshot.bin";
    std::unique_ptr<android::base::StdioStream> stream(new android::base::StdioStream(
        fopen(snapshotBinaryPath.c_str(), "rb"), android::base::StdioStream::kOwner));
    android::snapshot::SnapshotLoadStream loadStream{
        .stream = stream.get(),
    };
    android_getOpenglesRenderer()->load(loadStream.stream, loadStream.textureLoader);
    // In end2end tests, we don't really do snapshot save for render threads.
    // We will need to resume all render threads without waiting for snapshot.
    android_getOpenglesRenderer()->resumeAll(false);

    if (kEnableFrontendSnapshots) {
        std::filesystem::path snapshotPath = snapshotDirectory / "gfxstream_snapshot.txtproto";
        int snapshotFd = open(snapshotPath.c_str(), O_RDONLY);
        if (snapshotFd < 0) {
            stream_renderer_error("Failed to restore snapshot: failed to open %s",
                                snapshotPath.c_str());
            return -1;
        }
        google::protobuf::io::FileInputStream snapshotInputStream(snapshotFd);
        snapshotInputStream.SetCloseOnDelete(true);
        gfxstream::host::snapshot::VirtioGpuFrontendSnapshot snapshot;
        if (!google::protobuf::TextFormat::Parse(&snapshotInputStream, &snapshot)) {
            stream_renderer_error("Failed to restore snapshot: failed to parse from file.");
            return -1;
        }
        if (sFrontend()->restore(snapshot) < 0) {
            stream_renderer_error("Failed to restore snapshot: failed to restore frontend.");
            return -1;
        }
    }

    return 0;
#else
    stream_renderer_error("Snapshot save requested without support.");
    return -EINVAL;
#endif
}

VG_EXPORT int stream_renderer_resume() {
    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_resume()");

    // TODO: move resumeAll() here after kumquat updated.

    return 0;
}

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);
    },
    // wait_guest_recv()
    [](GoldfishHostPipe* hostPipe) { android_pipe_wait_guest_recv(hostPipe); },
    // 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);
    },
    // wait_guest_send()
    [](GoldfishHostPipe* hostPipe) { android_pipe_wait_guest_send(hostPipe); },
    // 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; },
};

static int stream_renderer_opengles_init(uint32_t display_width, uint32_t display_height,
                                         int renderer_flags, gfxstream::host::FeatureSet features) {
    stream_renderer_debug("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
    // STREAM_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");

    bool egl2eglByEnv = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1";
    bool egl2eglByFlag = renderer_flags & STREAM_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 & STREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT;

    android::featurecontrol::productFeatureOverride();

    gfxstream::vk::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 gfxstream::RenderLibPtr renderLibPtr = gfxstream::initLibrary();
        android_setOpenglesEmulation(renderLibPtr.get(), nullptr, nullptr);
    }

    int maj;
    int min;
    android_startOpenglesRenderer(display_width, display_height, 1, 28, getGraphicsAgents()->vm,
                                  getGraphicsAgents()->emu, getGraphicsAgents()->multi_display,
                                  &features, &maj, &min);

    char* vendor = nullptr;
    char* renderer = nullptr;
    char* version = nullptr;

    android_getOpenglesHardwareStrings(&vendor, &renderer, &version);

    stream_renderer_info("GL strings; [%s] [%s] [%s].", vendor, renderer, version);

    auto openglesRenderer = android_getOpenglesRenderer();

    if (!openglesRenderer) {
        stream_renderer_error("No renderer started, fatal");
        return -EINVAL;
    }

    address_space_set_vm_operations(getGraphicsAgents()->vm);
    android_init_opengles_pipe();
    android_opengles_pipe_set_recv_mode(2 /* virtio-gpu */);
    android_init_refcount_pipe();

    return 0;
}

namespace {

int parseGfxstreamFeatures(const int renderer_flags,
                           const std::string& renderer_features,
                           gfxstream::host::FeatureSet& features) {
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, ExternalBlob,
        renderer_flags & STREAM_RENDERER_FLAGS_USE_EXTERNAL_BLOB);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(&features, VulkanExternalSync,
                                       renderer_flags & STREAM_RENDERER_FLAGS_VULKAN_EXTERNAL_SYNC);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GlAsyncSwap, false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GlDirectMem, false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GlDma, false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GlesDynamicVersion, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GlPipeChecksum, false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, GuestVulkanOnly,
        (renderer_flags & STREAM_RENDERER_FLAGS_USE_VK_BIT) &&
        !(renderer_flags & STREAM_RENDERER_FLAGS_USE_GLES_BIT));
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, HostComposition, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, NativeTextureDecompression, false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, NoDelayCloseColorBuffer, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, PlayStoreImage,
        !(renderer_flags & STREAM_RENDERER_FLAGS_USE_GLES_BIT));
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, RefCountPipe,
        /*Resources are ref counted via guest file objects.*/ false);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, SystemBlob,
        renderer_flags & STREAM_RENDERER_FLAGS_USE_SYSTEM_BLOB);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VirtioGpuFenceContexts, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VirtioGpuNativeSync, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VirtioGpuNext, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, Vulkan,
        renderer_flags & STREAM_RENDERER_FLAGS_USE_VK_BIT);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanBatchedDescriptorSetUpdate, features.VulkanBatchedDescriptorSetUpdate.enabled);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanIgnoredHandles, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanNativeSwapchain,
        renderer_flags & STREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanNullOptionalStrings, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanQueueSubmitWithCommands, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanShaderFloat16Int8, true);
    GFXSTREAM_SET_FEATURE_ON_CONDITION(
        &features, VulkanSnapshots,
        android::base::getEnvironmentVariable("ANDROID_GFXSTREAM_CAPTURE_VK_SNAPSHOT") == "1");

    for (const std::string& renderer_feature : gfxstream::Split(renderer_features, ",")) {
        if (renderer_feature.empty()) continue;

        const std::vector<std::string>& parts = gfxstream::Split(renderer_feature, ":");
        if (parts.size() != 2) {
            stream_renderer_error("Error: invalid renderer features: %s",
                                  renderer_features.c_str());
            return -EINVAL;
        }

        const std::string& feature_name = parts[0];

        auto feature_it = features.map.find(feature_name);
        if (feature_it == features.map.end()) {
            stream_renderer_error("Error: invalid renderer feature: '%s'", feature_name.c_str());
            return -EINVAL;
        }

        const std::string& feature_status = parts[1];
        if (feature_status != "enabled" && feature_status != "disabled") {
            stream_renderer_error("Error: invalid option %s for renderer feature: %s",
                                  feature_status.c_str(), feature_name.c_str());
            return -EINVAL;
        }

        auto& feature_info = feature_it->second;
        feature_info->enabled = feature_status == "enabled";
        feature_info->reason = "Overridden via STREAM_RENDERER_PARAM_RENDERER_FEATURES";

        stream_renderer_error("Gfxstream feature %s %s", feature_name.c_str(),
                              feature_status.c_str());
    }

    if (features.SystemBlob.enabled) {
        if (!features.ExternalBlob.enabled) {
            stream_renderer_error("The SystemBlob features requires the ExternalBlob feature.");
            return -EINVAL;
        }
#ifndef _WIN32
        stream_renderer_warn("Warning: USE_SYSTEM_BLOB has only been tested on Windows");
#endif
    }
    if (features.VulkanNativeSwapchain.enabled && !features.Vulkan.enabled) {
        stream_renderer_error("can't enable vulkan native swapchain, Vulkan is disabled");
        return -EINVAL;
    }

    return 0;
}

}  // namespace

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_DEBUG_CALLBACK, "DEBUG_CALLBACK"},
        {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;
    std::string renderer_features_str;
    stream_renderer_fence_callback fence_callback = nullptr;
    bool skip_opengles = false;

    // Iterate all parameters that we support.
    stream_renderer_debug("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) {
            stream_renderer_debug("%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.
            stream_renderer_debug("%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_NULL:
                break;
            case STREAM_RENDERER_PARAM_USER_DATA: {
                renderer_cookie = reinterpret_cast<void*>(static_cast<uintptr_t>(param.value));
                globalUserData = renderer_cookie;
                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_DEBUG_CALLBACK: {
                globalDebugCallback = reinterpret_cast<stream_renderer_debug_callback>(
                    static_cast<uintptr_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_RENDERER_FEATURES: {
                renderer_features_str =
                    std::string(reinterpret_cast<const char*>(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.
                stream_renderer_error(
                    "Skipping unknown parameter key: %llu. May need to upgrade gfxstream.",
                    static_cast<unsigned long long>(param.key));
                break;
            }
        }
    }
    stream_renderer_debug("Finished reading parameters");

    // Some required params not found.
    if (required_params.size() > 0) {
        stream_renderer_error("Missing required parameters:");
        for (uint64_t param : required_params) {
            stream_renderer_error("%s", get_param_string(param).c_str());
        }
        stream_renderer_error("Failing initialization intentionally");
        return -EINVAL;
    }

#if GFXSTREAM_UNSTABLE_VULKAN_EXTERNAL_SYNC
    renderer_flags |= STREAM_RENDERER_FLAGS_VULKAN_EXTERNAL_SYNC;
#endif

    gfxstream::host::FeatureSet features;
    int ret = parseGfxstreamFeatures(renderer_flags, renderer_features_str, features);
    if (ret) {
        stream_renderer_error("Failed to initialize: failed to parse Gfxstream features.");
        return ret;
    }

    stream_renderer_info("Gfxstream features:");
    for (const auto& [_, featureInfo] : features.map) {
        stream_renderer_info("    %s: %s (%s)", featureInfo->name.c_str(),
                             (featureInfo->enabled ? "enabled" : "disabled"),
                             featureInfo->reason.c_str());
    }

    gfxstream::host::InitializeTracing();

    // Set non product-specific callbacks
    gfxstream::vk::vk_util::setVkCheckCallbacks(
        std::make_unique<gfxstream::vk::vk_util::VkCheckCallbacks>(
            gfxstream::vk::vk_util::VkCheckCallbacks{
                .onVkErrorDeviceLost =
                    []() {
                        auto fb = gfxstream::FrameBuffer::getFB();
                        if (!fb) {
                            ERR("FrameBuffer not yet initialized. Dropping device lost event");
                            return;
                        }
                        fb->logVulkanDeviceLost();
                    },
                .onVkErrorOutOfMemory =
                    [](VkResult result, const char* function, int line) {
                        auto fb = gfxstream::FrameBuffer::getFB();
                        if (!fb) {
                            stream_renderer_error(
                                "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) {
                            stream_renderer_error(
                                "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, features);
        if (ret) {
            return ret;
        }
    }

    GFXSTREAM_TRACE_EVENT(GFXSTREAM_TRACE_STREAM_RENDERER_CATEGORY, "stream_renderer_init()");

    sFrontend()->init(renderer_cookie, features, fence_callback);
    gfxstream::FrameBuffer::waitUntilInitialized();

    stream_renderer_info("Gfxstream initialized successfully!");
    return 0;
}

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 stream_renderer_teardown() {
    android_finishOpenglesRenderer();
    android_hideOpenglesWindow();
    android_stopOpenglesRenderer(true);

    sFrontend()->teardown();
    stream_renderer_info("Gfxstream shut down completed!");
}

VG_EXPORT void gfxstream_backend_set_screen_mask(int width, int height,
                                                 const unsigned char* rgbaData) {
    android_setOpenglesScreenMask(width, height, rgbaData);
}

const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops() { return &goldfish_pipe_service_ops; }

static_assert(sizeof(struct stream_renderer_device_id) == 32,
              "stream_renderer_device_id must be 32 bytes");
static_assert(offsetof(struct stream_renderer_device_id, device_uuid) == 0,
              "stream_renderer_device_id.device_uuid must be at offset 0");
static_assert(offsetof(struct stream_renderer_device_id, driver_uuid) == 16,
              "stream_renderer_device_id.driver_uuid must be at offset 16");

static_assert(sizeof(struct stream_renderer_vulkan_info) == 36,
              "stream_renderer_vulkan_info must be 36 bytes");
static_assert(offsetof(struct stream_renderer_vulkan_info, memory_index) == 0,
              "stream_renderer_vulkan_info.memory_index must be at offset 0");
static_assert(offsetof(struct stream_renderer_vulkan_info, device_id) == 4,
              "stream_renderer_vulkan_info.device_id must be at offset 4");

static_assert(sizeof(struct stream_renderer_param_host_visible_memory_mask_entry) == 36,
              "stream_renderer_param_host_visible_memory_mask_entry must be 36 bytes");
static_assert(offsetof(struct stream_renderer_param_host_visible_memory_mask_entry, device_id) == 0,
              "stream_renderer_param_host_visible_memory_mask_entry.device_id must be at offset 0");
static_assert(
    offsetof(struct stream_renderer_param_host_visible_memory_mask_entry, memory_type_mask) == 32,
    "stream_renderer_param_host_visible_memory_mask_entry.memory_type_mask must be at offset 32");

static_assert(sizeof(struct stream_renderer_param_host_visible_memory_mask) == 16,
              "stream_renderer_param_host_visible_memory_mask must be 16 bytes");
static_assert(offsetof(struct stream_renderer_param_host_visible_memory_mask, entries) == 0,
              "stream_renderer_param_host_visible_memory_mask.entries must be at offset 0");
static_assert(offsetof(struct stream_renderer_param_host_visible_memory_mask, num_entries) == 8,
              "stream_renderer_param_host_visible_memory_mask.num_entries must be at offset 8");

static_assert(sizeof(struct stream_renderer_param) == 16, "stream_renderer_param must be 16 bytes");
static_assert(offsetof(struct stream_renderer_param, key) == 0,
              "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) {
    sFrontend()->setServiceOps(ops);
}

#endif  // CONFIG_AEMU

}  // extern "C"
