/*
* Copyright (C) 2011 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 "RenderControl.h"

#include <inttypes.h>
#include <string.h>

#include <atomic>
#include <memory>

#include "ChecksumCalculatorThreadInfo.h"
#include "FrameBuffer.h"
#include "GLESVersionDetector.h"
#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
#include "RenderThreadInfo.h"
#include "RenderThreadInfoGl.h"
#include "SyncThread.h"
#include "aemu/base/Tracing.h"
#include "host-common/feature_control.h"
#include "host-common/logging.h"
#include "host-common/misc.h"
#include "host-common/opengl/misc.h"
#include "host-common/sync_device.h"
#include "stream-servers/compressedTextureFormats/AstcCpuDecompressor.h"
#include "vulkan/VkCommonOperations.h"
#include "vulkan/VkDecoderGlobalState.h"

using android::base::AutoLock;
using android::base::Lock;
using emugl::emugl_sync_device_exists;
using emugl::emugl_sync_register_trigger_wait;
using gfxstream::GLESApi;
using gfxstream::GLESApi_CM;
using gfxstream::EmulatedEglFenceSync;

#define DEBUG_GRALLOC_SYNC 0
#define DEBUG_EGL_SYNC 0

#define RENDERCONTROL_DPRINT(...) do { \
    if (!VERBOSE_CHECK(gles)) { VERBOSE_ENABLE(gles); } \
    VERBOSE_TID_FUNCTION_DPRINT(gles, __VA_ARGS__); \
} while(0)

#if DEBUG_GRALLOC_SYNC
#define GRSYNC_DPRINT RENDERCONTROL_DPRINT
#else
#define GRSYNC_DPRINT(...)
#endif

#if DEBUG_EGL_SYNC
#define EGLSYNC_DPRINT RENDERCONTROL_DPRINT
#else
#define EGLSYNC_DPRINT(...)
#endif

// GrallocSync is a class that helps to reflect the behavior of
// gralloc_lock/gralloc_unlock on the guest.
// If we don't use this, apps that use gralloc buffers (such as webcam)
// will have out-of-order frames,
// as GL calls from different threads in the guest
// are allowed to arrive at the host in any ordering.
class GrallocSync {
public:
    GrallocSync() {
        // Having in-order webcam frames is nice, but not at the cost
        // of potential deadlocks;
        // we need to be careful of what situations in which
        // we actually lock/unlock the gralloc color buffer.
        //
        // To avoid deadlock:
        // we require rcColorBufferCacheFlush to be called
        // whenever gralloc_lock is called on the guest,
        // and we require rcUpdateWindowColorBuffer to be called
        // whenever gralloc_unlock is called on the guest.
        //
        // Some versions of the system image optimize out
        // the call to rcUpdateWindowColorBuffer in the case of zero
        // width/height, but since we're using that as synchronization,
        // that lack of calling can lead to a deadlock on the host
        // in many situations
        // (switching camera sides, exiting benchmark apps, etc).
        // So, we put GrallocSync under the feature control.
        mEnabled = feature_is_enabled(kFeature_GrallocSync);

        // There are two potential tricky situations to handle:
        // a. Multiple users of gralloc buffers that all want to
        // call gralloc_lock. This is obeserved to happen on older APIs
        // (<= 19).
        // b. The pipe doesn't have to preserve ordering of the
        // gralloc_lock and gralloc_unlock commands themselves.
        //
        // To handle a), notice the situation is one of one type of user
        // needing multiple locks that needs to exclude concurrent use
        // by another type of user. This maps well to a read/write lock,
        // where gralloc_lock and gralloc_unlock users are readers
        // and rcFlushWindowColorBuffer is the writer.
        // From the perspective of the host preparing and posting
        // buffers, these are indeed read/write operations.
        //
        // To handle b), we give up on locking when the state is observed
        // to be bad. lockState tracks how many color buffer locks there are.
        // If lockState < 0, it means we definitely have an unlock before lock
        // sort of situation, and should give up.
        lockState = 0;
    }

    // lockColorBufferPrepare is designed to handle
    // gralloc_lock/unlock requests, and uses the read lock.
    // When rcFlushWindowColorBuffer is called (when frames are posted),
    // we use the write lock (see GrallocSyncPostLock).
    void lockColorBufferPrepare() {
        int newLockState = ++lockState;
        if (mEnabled && newLockState == 1) {
            mGrallocColorBufferLock.lockRead();
        } else if (mEnabled) {
            GRSYNC_DPRINT("warning: recursive/multiple locks from guest!");
        }
    }
    void unlockColorBufferPrepare() {
        int newLockState = --lockState;
        if (mEnabled && newLockState == 0) mGrallocColorBufferLock.unlockRead();
    }
    android::base::ReadWriteLock mGrallocColorBufferLock;
private:
    bool mEnabled;
    std::atomic<int> lockState;
    DISALLOW_COPY_ASSIGN_AND_MOVE(GrallocSync);
};

class GrallocSyncPostLock : public android::base::AutoWriteLock {
public:
    GrallocSyncPostLock(GrallocSync& grallocsync) :
        android::base::AutoWriteLock(grallocsync.mGrallocColorBufferLock) { }
};

static GrallocSync* sGrallocSync() {
    static GrallocSync* g = new GrallocSync;
    return g;
}

static const GLint rendererVersion = 1;

// GLAsyncSwap version history:
// "ANDROID_EMU_NATIVE_SYNC": original version
// "ANDROIDEMU_native_sync_v2": +cleanup of sync objects
// "ANDROIDEMU_native_sync_v3": EGL_KHR_wait_sync
// "ANDROIDEMU_native_sync_v4": Correct eglGetSyncAttrib via rcIsSyncSignaled
// (We need all the different strings to not be prefixes of any other
// due to how they are checked for in the GL extensions on the guest)
static const char* kAsyncSwapStrV2 = "ANDROID_EMU_native_sync_v2";
static const char* kAsyncSwapStrV3 = "ANDROID_EMU_native_sync_v3";
static const char* kAsyncSwapStrV4 = "ANDROID_EMU_native_sync_v4";

// DMA version history:
// "ANDROID_EMU_dma_v1": add dma device and rcUpdateColorBufferDMA and do
// yv12 conversion on the GPU
// "ANDROID_EMU_dma_v2": adds DMA support glMapBufferRange (and unmap)
static const char* kDma1Str = "ANDROID_EMU_dma_v1";
static const char* kDma2Str = "ANDROID_EMU_dma_v2";
static const char* kDirectMemStr = "ANDROID_EMU_direct_mem";

// GLESDynamicVersion: up to 3.1 so far
static const char* kGLESDynamicVersion_2 = "ANDROID_EMU_gles_max_version_2";
static const char* kGLESDynamicVersion_3_0 = "ANDROID_EMU_gles_max_version_3_0";
static const char* kGLESDynamicVersion_3_1 = "ANDROID_EMU_gles_max_version_3_1";

// HWComposer Host Composition
static const char* kHostCompositionV1 = "ANDROID_EMU_host_composition_v1";
static const char* kHostCompositionV2 = "ANDROID_EMU_host_composition_v2";

// Vulkan
static const char* kVulkanFeatureStr = "ANDROID_EMU_vulkan";
static const char* kDeferredVulkanCommands = "ANDROID_EMU_deferred_vulkan_commands";
static const char* kVulkanNullOptionalStrings = "ANDROID_EMU_vulkan_null_optional_strings";
static const char* kVulkanCreateResourcesWithRequirements = "ANDROID_EMU_vulkan_create_resources_with_requirements";

// treat YUV420_888 as NV21
static const char* kYUV420888toNV21 = "ANDROID_EMU_YUV420_888_to_NV21";

// Cache YUV frame
static const char* kYUVCache = "ANDROID_EMU_YUV_Cache";

// GL protocol v2
static const char* kAsyncUnmapBuffer = "ANDROID_EMU_async_unmap_buffer";
// Vulkan: Correct marshaling for ignored handles
static const char* kVulkanIgnoredHandles = "ANDROID_EMU_vulkan_ignored_handles";

// virtio-gpu-next
static const char* kVirtioGpuNext = "ANDROID_EMU_virtio_gpu_next";

// address space subdevices
static const char* kHasSharedSlotsHostMemoryAllocator = "ANDROID_EMU_has_shared_slots_host_memory_allocator";

// vulkan free memory sync
static const char* kVulkanFreeMemorySync = "ANDROID_EMU_vulkan_free_memory_sync";

// virtio-gpu native sync
static const char* kVirtioGpuNativeSync = "ANDROID_EMU_virtio_gpu_native_sync";

// Struct defs for VK_KHR_shader_float16_int8
static const char* kVulkanShaderFloat16Int8 = "ANDROID_EMU_vulkan_shader_float16_int8";

// Async queue submit
static const char* kVulkanAsyncQueueSubmit = "ANDROID_EMU_vulkan_async_queue_submit";

// Host side tracing
static const char* kHostSideTracing = "ANDROID_EMU_host_side_tracing";

// Some frame commands we can easily make async
// rcMakeCurrent
// rcCompose
// rcDestroySyncKHR
static const char* kAsyncFrameCommands = "ANDROID_EMU_async_frame_commands";

// Queue submit with commands
static const char* kVulkanQueueSubmitWithCommands = "ANDROID_EMU_vulkan_queue_submit_with_commands";

// Batched descriptor set update
static const char* kVulkanBatchedDescriptorSetUpdate = "ANDROID_EMU_vulkan_batched_descriptor_set_update";

// Synchronized glBufferData call
static const char* kSyncBufferData = "ANDROID_EMU_sync_buffer_data";

// Async vkQSRI
static const char* kVulkanAsyncQsri = "ANDROID_EMU_vulkan_async_qsri";

// Read color buffer DMA
static const char* kReadColorBufferDma = "ANDROID_EMU_read_color_buffer_dma";

static void rcTriggerWait(uint64_t glsync_ptr,
                          uint64_t thread_ptr,
                          uint64_t timeline);

void registerTriggerWait() {
    emugl_sync_register_trigger_wait(rcTriggerWait);
}

static GLint rcGetRendererVersion()
{
    registerTriggerWait();

    sGrallocSync();
    return rendererVersion;
}

static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return EGL_FALSE;
    }
    fb->getEmulationGl().getEglVersion(major, minor);

    return EGL_TRUE;
}

static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    const char *str = s_egl.eglQueryString(fb->getDisplay(), name);
    if (!str) {
        return 0;
    }

    std::string eglStr(str);
    if ((fb->getMaxGLESVersion() >= GLES_DISPATCH_MAX_VERSION_3_0) &&
        feature_is_enabled(kFeature_GLESDynamicVersion) &&
        eglStr.find("EGL_KHR_create_context") == std::string::npos) {
        eglStr += "EGL_KHR_create_context ";
    }

    int len = eglStr.size() + 1;
    if (!buffer || len > bufferSize) {
        return -len;
    }

    strcpy((char *)buffer, eglStr.c_str());
    return len;
}

static bool shouldEnableAsyncSwap() {
    bool isPhone = true;
    bool playStoreImage = feature_is_enabled(
            kFeature_PlayStoreImage);
    return feature_is_enabled(kFeature_GLAsyncSwap) &&
           emugl_sync_device_exists() && (isPhone || playStoreImage) &&
           sizeof(void*) == 8;
}

static bool shouldEnableVirtioGpuNativeSync() {
    return feature_is_enabled(kFeature_VirtioGpuNativeSync);
}

static bool shouldEnableHostComposition() {
    return feature_is_enabled(kFeature_HostComposition);
}

static bool shouldEnableVulkan() {
    // TODO: Restrict further to devices supporting external memory.
    return feature_is_enabled(kFeature_Vulkan) &&
           goldfish_vk::VkDecoderGlobalState::get()->getHostFeatureSupport().supportsVulkan;
}

static bool shouldEnableDeferredVulkanCommands() {
    auto supportInfo =
        goldfish_vk::VkDecoderGlobalState::get()->
            getHostFeatureSupport();
    return supportInfo.supportsVulkan &&
           supportInfo.useDeferredCommands;
}

static bool shouldEnableCreateResourcesWithRequirements() {
    auto supportInfo =
        goldfish_vk::VkDecoderGlobalState::get()->
            getHostFeatureSupport();
    return supportInfo.supportsVulkan &&
           supportInfo.useCreateResourcesWithRequirements;
}

static bool shouldEnableVulkanShaderFloat16Int8() {
    return shouldEnableVulkan() &&
        feature_is_enabled(kFeature_VulkanShaderFloat16Int8);
}

static bool shouldEnableAsyncQueueSubmit() {
    return shouldEnableVulkan();
}

static bool shouldEnableVulkanAsyncQsri() {
    return shouldEnableVulkan() &&
        (feature_is_enabled(kFeature_GLAsyncSwap) ||
         (feature_is_enabled(kFeature_VirtioGpuNativeSync) &&
          feature_is_enabled(kFeature_VirtioGpuFenceContexts)));
}

const char* maxVersionToFeatureString(GLESDispatchMaxVersion version) {
    switch (version) {
        case GLES_DISPATCH_MAX_VERSION_2:
            return kGLESDynamicVersion_2;
        case GLES_DISPATCH_MAX_VERSION_3_0:
            return kGLESDynamicVersion_3_0;
        case GLES_DISPATCH_MAX_VERSION_3_1:
            return kGLESDynamicVersion_3_1;
        default:
            return kGLESDynamicVersion_2;
    }
}

static bool shouldEnableQueueSubmitWithCommands() {
    return shouldEnableVulkan() &&
        feature_is_enabled(kFeature_VulkanQueueSubmitWithCommands);
}

static bool shouldEnableBatchedDescriptorSetUpdate() {
    return shouldEnableVulkan() &&
        shouldEnableQueueSubmitWithCommands() &&
        feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate);
}

// OpenGL ES 3.x support involves changing the GL_VERSION string, which is
// assumed to be formatted in the following way:
// "OpenGL ES-CM 1.m <vendor-info>" or
// "OpenGL ES M.m <vendor-info>"
// where M is the major version number and m is minor version number.  If the
// GL_VERSION string doesn't reflect the maximum available version of OpenGL
// ES, many apps will not be able to detect support.  We need to mess with the
// version string in the first place since the underlying backend (whether it
// is Translator, SwiftShader, ANGLE, et al) may not advertise a GL_VERSION
// string reflecting their maximum capabilities.
std::string replaceESVersionString(const std::string& prev,
                                   const std::string& newver) {

    // There is no need to fiddle with the string
    // if we are in a ES 1.x context.
    // Such contexts are considered as a special case that must
    // be untouched.
    if (prev.find("ES-CM") != std::string::npos) {
        return prev;
    }

    size_t esStart = prev.find("ES ");
    size_t esEnd = prev.find(" ", esStart + 3);

    if (esStart == std::string::npos ||
        esEnd == std::string::npos) {
        // Account for out-of-spec version strings.
        fprintf(stderr, "%s: Error: invalid OpenGL ES version string %s\n",
                __func__, prev.c_str());
        return prev;
    }

    std::string res = prev.substr(0, esStart + 3);
    res += newver;
    res += prev.substr(esEnd);

    return res;
}

// If the GLES3 feature is disabled, we also want to splice out
// OpenGL extensions that should not appear in a GLES2 system.
void removeExtension(std::string& currExts, const std::string& toRemove) {
    size_t pos = currExts.find(toRemove);

    if (pos != std::string::npos)
        currExts.erase(pos, toRemove.length());
}

static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) {
    RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();

    // whatever we end up returning,
    // it will have a terminating \0,
    // so account for it here.
    std::string glStr;

    if (tInfo && tInfo->currContext.get()) {
        const char *str = nullptr;
        if (tInfo->currContext->clientVersion() > GLESApi_CM) {
            str = (const char *)s_gles2.glGetString(name);
        }
        else {
            str = (const char *)s_gles1.glGetString(name);
        }
        if (str) {
            glStr += str;
        }
    }

    // We add the maximum supported GL protocol number into GL_EXTENSIONS

    // filter extensions by name to match guest-side support
    GLESDispatchMaxVersion maxVersion = FrameBuffer::getFB()->getMaxGLESVersion();
    if (name == GL_EXTENSIONS) {
        glStr = filterExtensionsBasedOnMaxVersion(maxVersion, glStr);
    }

    bool isChecksumEnabled =
        feature_is_enabled(kFeature_GLPipeChecksum);
    bool asyncSwapEnabled = shouldEnableAsyncSwap();
    bool virtioGpuNativeSyncEnabled = shouldEnableVirtioGpuNativeSync();
    bool dma1Enabled =
        feature_is_enabled(kFeature_GLDMA);
    bool dma2Enabled =
        feature_is_enabled(kFeature_GLDMA2);
    bool directMemEnabled =
        feature_is_enabled(kFeature_GLDirectMem);
    bool hostCompositionEnabled = shouldEnableHostComposition();
    bool vulkanEnabled = shouldEnableVulkan();
    bool deferredVulkanCommandsEnabled =
        shouldEnableVulkan() && shouldEnableDeferredVulkanCommands();
    bool vulkanNullOptionalStringsEnabled =
        shouldEnableVulkan() && feature_is_enabled(kFeature_VulkanNullOptionalStrings);
    bool vulkanCreateResourceWithRequirementsEnabled =
        shouldEnableVulkan() && shouldEnableCreateResourcesWithRequirements();
    bool YUV420888toNV21Enabled =
        feature_is_enabled(kFeature_YUV420888toNV21);
    bool YUVCacheEnabled =
        feature_is_enabled(kFeature_YUVCache);
    bool AsyncUnmapBufferEnabled = feature_is_enabled(kFeature_AsyncComposeSupport);
    bool vulkanIgnoredHandlesEnabled =
        shouldEnableVulkan() && feature_is_enabled(kFeature_VulkanIgnoredHandles);
    bool virtioGpuNextEnabled =
        feature_is_enabled(kFeature_VirtioGpuNext);
    bool hasSharedSlotsHostMemoryAllocatorEnabled =
        feature_is_enabled(kFeature_HasSharedSlotsHostMemoryAllocator);
    bool vulkanFreeMemorySyncEnabled =
        shouldEnableVulkan();
    bool vulkanShaderFloat16Int8Enabled = shouldEnableVulkanShaderFloat16Int8();
    bool vulkanAsyncQueueSubmitEnabled = shouldEnableAsyncQueueSubmit();
    bool vulkanQueueSubmitWithCommands = shouldEnableQueueSubmitWithCommands();
    bool vulkanBatchedDescriptorSetUpdate = shouldEnableBatchedDescriptorSetUpdate();
    bool syncBufferDataEnabled = true;
    bool vulkanAsyncQsri = shouldEnableVulkanAsyncQsri();
    bool readColorBufferDma = directMemEnabled && hasSharedSlotsHostMemoryAllocatorEnabled;

    if (isChecksumEnabled && name == GL_EXTENSIONS) {
        glStr += ChecksumCalculatorThreadInfo::getMaxVersionString();
        glStr += " ";
    }

    if (asyncSwapEnabled && name == GL_EXTENSIONS) {
        glStr += kAsyncSwapStrV2;
        glStr += " "; // for compatibility with older system images
        // Only enable EGL_KHR_wait_sync (and above) for host gpu.
        if (emugl::getRenderer() == SELECTED_RENDERER_HOST) {
            glStr += kAsyncSwapStrV3;
            glStr += " ";
            glStr += kAsyncSwapStrV4;
            glStr += " ";
        }
    }

    if (dma1Enabled && name == GL_EXTENSIONS) {
        glStr += kDma1Str;
        glStr += " ";
    }

    if (dma2Enabled && name == GL_EXTENSIONS) {
        glStr += kDma2Str;
        glStr += " ";
    }

    if (directMemEnabled && name == GL_EXTENSIONS) {
        glStr += kDirectMemStr;
        glStr += " ";
    }

    if (hostCompositionEnabled && name == GL_EXTENSIONS) {
        glStr += kHostCompositionV1;
        glStr += " ";
    }

    if (hostCompositionEnabled && name == GL_EXTENSIONS) {
        glStr += kHostCompositionV2;
        glStr += " ";
    }

    if (vulkanEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanFeatureStr;
        glStr += " ";
    }

    if (deferredVulkanCommandsEnabled && name == GL_EXTENSIONS) {
        glStr += kDeferredVulkanCommands;
        glStr += " ";
    }

    if (vulkanNullOptionalStringsEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanNullOptionalStrings;
        glStr += " ";
    }

    if (vulkanCreateResourceWithRequirementsEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanCreateResourcesWithRequirements;
        glStr += " ";
    }

    if (YUV420888toNV21Enabled && name == GL_EXTENSIONS) {
        glStr += kYUV420888toNV21;
        glStr += " ";
    }

    if (YUVCacheEnabled && name == GL_EXTENSIONS) {
        glStr += kYUVCache;
        glStr += " ";
    }

    if (AsyncUnmapBufferEnabled && name == GL_EXTENSIONS) {
        glStr += kAsyncUnmapBuffer;
        glStr += " ";
    }

    if (vulkanIgnoredHandlesEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanIgnoredHandles;
        glStr += " ";
    }

    if (virtioGpuNextEnabled && name == GL_EXTENSIONS) {
        glStr += kVirtioGpuNext;
        glStr += " ";
    }

    if (hasSharedSlotsHostMemoryAllocatorEnabled && name == GL_EXTENSIONS) {
        glStr += kHasSharedSlotsHostMemoryAllocator;
        glStr += " ";
    }

    if (vulkanFreeMemorySyncEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanFreeMemorySync;
        glStr += " ";
    }

    if (vulkanShaderFloat16Int8Enabled && name == GL_EXTENSIONS) {
        glStr += kVulkanShaderFloat16Int8;
        glStr += " ";
    }

    if (vulkanAsyncQueueSubmitEnabled && name == GL_EXTENSIONS) {
        glStr += kVulkanAsyncQueueSubmit;
        glStr += " ";
    }

    if (vulkanQueueSubmitWithCommands && name == GL_EXTENSIONS) {
        glStr += kVulkanQueueSubmitWithCommands;
        glStr += " ";
    }

    if (vulkanBatchedDescriptorSetUpdate && name == GL_EXTENSIONS) {
        glStr += kVulkanBatchedDescriptorSetUpdate;
        glStr += " ";
    }

    if (virtioGpuNativeSyncEnabled && name == GL_EXTENSIONS) {
        glStr += kVirtioGpuNativeSync;
        glStr += " ";
    }

    if (syncBufferDataEnabled && name == GL_EXTENSIONS) {
        glStr += kSyncBufferData;
        glStr += " ";
    }

    if (vulkanAsyncQsri && name == GL_EXTENSIONS) {
        glStr += kVulkanAsyncQsri;
        glStr += " ";
    }

    if (readColorBufferDma && name == GL_EXTENSIONS) {
        glStr += kReadColorBufferDma;
        glStr += " ";
    }

    if (name == GL_EXTENSIONS) {

        GLESDispatchMaxVersion guestExtVer = GLES_DISPATCH_MAX_VERSION_2;
        if (feature_is_enabled(kFeature_GLESDynamicVersion)) {
            // If the image is in ES 3 mode, add GL_OES_EGL_image_external_essl3 for better Skia support.
            glStr += "GL_OES_EGL_image_external_essl3 ";
            guestExtVer = maxVersion;
        }

        // If we have a GLES3 implementation, add the corresponding
        // GLESv2 extensions as well.
        if (maxVersion > GLES_DISPATCH_MAX_VERSION_2) {
            glStr += "GL_OES_vertex_array_object ";
        }



        // ASTC LDR compressed texture support.
        const std::string& glExtensions =
            FrameBuffer::getFB()->hasEmulationGl()
                ? FrameBuffer::getFB()->getEmulationGl().getGlesExtensionsString()
                : "<no GL emulation>";
        const bool hasNativeAstc =
            glExtensions.find("GL_KHR_texture_compression_astc_ldr") != std::string::npos;
        const bool hasAstcDecompressor = goldfish_vk::AstcCpuDecompressor::get().available();
        if (hasNativeAstc || hasAstcDecompressor) {
            glStr += "GL_KHR_texture_compression_astc_ldr ";
        } else {
            INFO("rcGetGLString: ASTC not supported. CPU decompressor? %d. GL extensions: %s",
                 hasAstcDecompressor, glExtensions.c_str());
        }

        // Host side tracing support.
        glStr += kHostSideTracing;
        glStr += " ";

        if (feature_is_enabled(kFeature_AsyncComposeSupport)) {
            // Async makecurrent support.
            glStr += kAsyncFrameCommands;
            glStr += " ";
        }

        glStr += maxVersionToFeatureString(guestExtVer);
        glStr += " ";
    }

    if (name == GL_VERSION) {
        if (feature_is_enabled(kFeature_GLESDynamicVersion)) {
            switch (maxVersion) {
            // Underlying GLES implmentation's max version string
            // is allowed to be higher than the version of the request
            // for the context---it can create a higher version context,
            // and return simply the max possible version overall.
            case GLES_DISPATCH_MAX_VERSION_2:
                glStr = replaceESVersionString(glStr, "2.0");
                break;
            case GLES_DISPATCH_MAX_VERSION_3_0:
                glStr = replaceESVersionString(glStr, "3.0");
                break;
            case GLES_DISPATCH_MAX_VERSION_3_1:
                glStr = replaceESVersionString(glStr, "3.1");
                break;
            default:
                break;
            }
        } else {
            glStr = replaceESVersionString(glStr, "2.0");
        }
    }

    int nextBufferSize = glStr.size() + 1;

    if (!buffer || nextBufferSize > bufferSize) {
        return -nextBufferSize;
    }

    snprintf((char *)buffer, nextBufferSize, "%s", glStr.c_str());
    return nextBufferSize;
}

static EGLint rcGetNumConfigs(uint32_t* p_numAttribs)
{
    int numConfigs = 0, numAttribs = 0;

    FrameBuffer::getFB()->getConfigs()->getPackInfo(&numConfigs, &numAttribs);
    if (p_numAttribs) {
        *p_numAttribs = static_cast<uint32_t>(numAttribs);
    }
    return numConfigs;
}

static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer)
{
    GLuint bufferSize = (GLuint)bufSize;
    return FrameBuffer::getFB()->getConfigs()->packConfigs(bufferSize, buffer);
}

static EGLint rcChooseConfig(EGLint *attribs,
                             uint32_t attribs_size,
                             uint32_t *configs,
                             uint32_t configs_size)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    if (attribs_size == 0) {
        if (configs && configs_size > 0) {
            // Pick the first config
            *configs = 0;
            if (attribs) *attribs = EGL_NONE;
        }
    }

    return fb->getConfigs()->chooseConfig(
            attribs, (EGLint*)configs, (EGLint)configs_size);
}

static EGLint rcGetFBParam(EGLint param)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    EGLint ret = 0;

    switch(param) {
        case FB_WIDTH:
            ret = fb->getWidth();
            break;
        case FB_HEIGHT:
            ret = fb->getHeight();
            break;
        case FB_XDPI:
            ret = 72; // XXX: should be implemented
            break;
        case FB_YDPI:
            ret = 72; // XXX: should be implemented
            break;
        case FB_FPS:
            ret = 60;
            break;
        case FB_MIN_SWAP_INTERVAL:
            ret = 1; // XXX: should be implemented
            break;
        case FB_MAX_SWAP_INTERVAL:
            ret = 1; // XXX: should be implemented
            break;
        default:
            break;
    }

    return ret;
}

static uint32_t rcCreateContext(uint32_t config,
                                uint32_t share, uint32_t glVersion)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    HandleType ret = fb->createEmulatedEglContext(config, share, (GLESApi)glVersion);
    return ret;
}

static void rcDestroyContext(uint32_t context)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    fb->destroyEmulatedEglContext(context);
}

static uint32_t rcCreateWindowSurface(uint32_t config,
                                      uint32_t width, uint32_t height)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->createEmulatedEglWindowSurface(config, width, height);
}

static void rcDestroyWindowSurface(uint32_t windowSurface)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    fb->destroyEmulatedEglWindowSurface(windowSurface);
}

static uint32_t rcCreateColorBuffer(uint32_t width,
                                    uint32_t height, GLenum internalFormat)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->createColorBuffer(width, height, internalFormat,
                                 FRAMEWORK_FORMAT_GL_COMPATIBLE);
}

static uint32_t rcCreateColorBufferDMA(uint32_t width,
                                       uint32_t height, GLenum internalFormat,
                                       int frameworkFormat)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->createColorBuffer(width, height, internalFormat,
                                 (FrameworkFormat)frameworkFormat);
}

static int rcOpenColorBuffer2(uint32_t colorbuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }
    return fb->openColorBuffer( colorbuffer );
}

static void rcOpenColorBuffer(uint32_t colorbuffer)
{
    (void) rcOpenColorBuffer2(colorbuffer);
}

static void rcCloseColorBuffer(uint32_t colorbuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }
    fb->closeColorBuffer( colorbuffer );
}

static int rcFlushWindowColorBuffer(uint32_t windowSurface)
{
    GRSYNC_DPRINT("waiting for gralloc cb lock");
    GrallocSyncPostLock lock(*sGrallocSync());
    GRSYNC_DPRINT("lock gralloc cb lock {");

    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        GRSYNC_DPRINT("unlock gralloc cb lock");
        return -1;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(
        fb->getEmulatedEglWindowSurfaceColorBufferHandle(windowSurface));

    if (!fb->flushEmulatedEglWindowSurfaceColorBuffer(windowSurface)) {
        GRSYNC_DPRINT("unlock gralloc cb lock }");
        return -1;
    }

    // Update to Vulkan if necessary
    goldfish_vk::updateColorBufferFromGl(
        fb->getEmulatedEglWindowSurfaceColorBufferHandle(windowSurface));

    GRSYNC_DPRINT("unlock gralloc cb lock }");

    return 0;
}

// Note that even though this calls rcFlushWindowColorBuffer,
// the "Async" part is in the return type, which is void
// versus return type int for rcFlushWindowColorBuffer.
//
// The different return type, even while calling the same
// functions internally, will end up making the encoder
// and decoder use a different protocol. This is because
// the encoder generally obeys the following conventions:
//
// - The encoder will immediately send and wait for a command
//   result if the return type is not void.
// - The encoder will cache the command in a buffer and send
//   at a convenient time if the return type is void.
//
// It can also be expensive performance-wise to trigger
// sending traffic back to the guest. Generally, the more we avoid
// encoding commands that perform two-way traffic, the better.
//
// Hence, |rcFlushWindowColorBufferAsync| will avoid extra traffic;
// with return type void,
// the guest will not wait until this function returns,
// nor will it immediately send the command,
// resulting in more asynchronous behavior.
static void rcFlushWindowColorBufferAsync(uint32_t windowSurface)
{
    rcFlushWindowColorBuffer(windowSurface);
}

static void rcSetWindowColorBuffer(uint32_t windowSurface,
                                   uint32_t colorBuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }
    fb->setEmulatedEglWindowSurfaceColorBuffer(windowSurface, colorBuffer);
}

static EGLint rcMakeCurrent(uint32_t context,
                            uint32_t drawSurf, uint32_t readSurf)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return EGL_FALSE;
    }

    bool ret = fb->bindContext(context, drawSurf, readSurf);

    return (ret ? EGL_TRUE : EGL_FALSE);
}

static void rcFBPost(uint32_t colorBuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->post(colorBuffer);
}

static void rcFBSetSwapInterval(EGLint interval)
{
   // XXX: TBD - should be implemented
}

static void rcBindTexture(uint32_t colorBuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->bindColorBufferToTexture(colorBuffer);
}

static void rcBindRenderbuffer(uint32_t colorBuffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->bindColorBufferToRenderbuffer(colorBuffer);
}

static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer,
                                      EGLint postCount, int forRead)
{
    // gralloc_lock() on the guest calls rcColorBufferCacheFlush
    GRSYNC_DPRINT("waiting for gralloc cb lock");
    sGrallocSync()->lockColorBufferPrepare();
    GRSYNC_DPRINT("lock gralloc cb lock {");
    return 0;
}

static void rcReadColorBuffer(uint32_t colorBuffer,
                              GLint x, GLint y,
                              GLint width, GLint height,
                              GLenum format, GLenum type, void* pixels)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
}

static int rcUpdateColorBuffer(uint32_t colorBuffer,
                               GLint x, GLint y,
                               GLint width, GLint height,
                               GLenum format, GLenum type, void* pixels)
{
    FrameBuffer *fb = FrameBuffer::getFB();

    if (!fb) {
        GRSYNC_DPRINT("unlock gralloc cb lock");
        sGrallocSync()->unlockColorBufferPrepare();
        return -1;
    }

    // Since this is a modify operation, also read the current contents
    // of the VkImage, if any.
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);

    GRSYNC_DPRINT("unlock gralloc cb lock");
    sGrallocSync()->unlockColorBufferPrepare();

    // Update to Vulkan if necessary
    goldfish_vk::updateColorBufferFromGl(colorBuffer);

    return 0;
}

static int rcUpdateColorBufferDMA(uint32_t colorBuffer,
                                  GLint x, GLint y,
                                  GLint width, GLint height,
                                  GLenum format, GLenum type,
                                  void* pixels, uint32_t pixels_size)
{
    FrameBuffer *fb = FrameBuffer::getFB();

    if (!fb) {
        GRSYNC_DPRINT("unlock gralloc cb lock");
        sGrallocSync()->unlockColorBufferPrepare();
        return -1;
    }

    // Since this is a modify operation, also read the current contents
    // of the VkImage, if any.
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->updateColorBuffer(colorBuffer, x, y, width, height,
                          format, type, pixels);

    GRSYNC_DPRINT("unlock gralloc cb lock");
    sGrallocSync()->unlockColorBufferPrepare();

    // Update to Vulkan if necessary
    goldfish_vk::updateColorBufferFromGl(colorBuffer);

    return 0;
}

static uint32_t rcCreateClientImage(uint32_t context, EGLenum target, GLuint buffer)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->createEmulatedEglImage(context, target, buffer);
}

static int rcDestroyClientImage(uint32_t image)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->destroyEmulatedEglImage(image);
}

static void rcSelectChecksumHelper(uint32_t protocol, uint32_t reserved) {
    ChecksumCalculatorThreadInfo::setVersion(protocol);
}

// |rcTriggerWait| is called from the goldfish sync
// kernel driver whenever a native fence fd is created.
// We will then need to use the host to find out
// when to signal that native fence fd. We use
// SyncThread for that.
static void rcTriggerWait(uint64_t eglsync_ptr,
                          uint64_t thread_ptr,
                          uint64_t timeline) {
    if (thread_ptr == 1) {
        // Is vulkan sync fd;
        // just signal right away for now
        EGLSYNC_DPRINT("vkFence=0x%llx timeline=0x%llx", eglsync_ptr,
                       thread_ptr, timeline);
        SyncThread::get()->triggerWaitVk(reinterpret_cast<VkFence>(eglsync_ptr),
                                         timeline);
    } else {
        EmulatedEglFenceSync* fenceSync = reinterpret_cast<EmulatedEglFenceSync*>(eglsync_ptr);
        EGLSYNC_DPRINT(
                "eglsync=0x%llx fenceSync=%p thread_ptr=0x%llx "
                "timeline=0x%llx",
                eglsync_ptr, fenceSync, thread_ptr, timeline);
        SyncThread::get()->triggerWait(fenceSync, timeline);
    }
}

// |rcCreateSyncKHR| implements the guest's |eglCreateSyncKHR| by calling the
// host's implementation of |eglCreateSyncKHR|. A SyncThread is also notified
// for purposes of signaling any native fence fd's that get created in the
// guest off the sync object created here.
static void rcCreateSyncKHR(EGLenum type,
                            EGLint* attribs,
                            uint32_t num_attribs,
                            int destroyWhenSignaled,
                            uint64_t* outSync,
                            uint64_t* outSyncThread) {
    // Usually we expect rcTriggerWait to be registered
    // at the beginning in rcGetRendererVersion, called
    // on init for all contexts.
    // But if we are loading from snapshot, that's not
    // guaranteed, and we need to make sure
    // rcTriggerWait is registered.
    emugl_sync_register_trigger_wait(rcTriggerWait);

    FrameBuffer::getFB()->createEmulatedEglFenceSync(type,
                                                     destroyWhenSignaled,
                                                     outSync,
                                                     outSyncThread);
}

// |rcClientWaitSyncKHR| implements |eglClientWaitSyncKHR|
// on the guest through using the host's existing
// |eglClientWaitSyncKHR| implementation, which is done
// through the EmulatedEglFenceSync object.
static EGLint rcClientWaitSyncKHR(uint64_t handle,
                                  EGLint flags,
                                  uint64_t timeout) {
    RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
    if (!tInfo) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
            << "Render thread GL not available.";
    }

    FrameBuffer *fb = FrameBuffer::getFB();

    EGLSYNC_DPRINT("handle=0x%lx flags=0x%x timeout=%" PRIu64,
                handle, flags, timeout);

    EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);

    if (!fenceSync) {
        EGLSYNC_DPRINT("fenceSync null, return condition satisfied");
        return EGL_CONDITION_SATISFIED_KHR;
    }

    // Sometimes a gralloc-buffer-only thread is doing stuff with sync.
    // This happens all the time with YouTube videos in the browser.
    // In this case, create a context on the host just for syncing.
    if (!tInfo->currContext) {
        uint32_t gralloc_sync_cxt, gralloc_sync_surf;
        fb->createTrivialContext(0, // There is no context to share.
                                 &gralloc_sync_cxt,
                                 &gralloc_sync_surf);
        fb->bindContext(gralloc_sync_cxt,
                        gralloc_sync_surf,
                        gralloc_sync_surf);
        // This context is then cleaned up when the render thread exits.
    }

    return fenceSync->wait(timeout);
}

static void rcWaitSyncKHR(uint64_t handle,
                                  EGLint flags) {
    RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
    if (!tInfo) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
            << "Render thread GL not available.";
    }

    FrameBuffer *fb = FrameBuffer::getFB();

    EGLSYNC_DPRINT("handle=0x%lx flags=0x%x", handle, flags);

    EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);

    if (!fenceSync) { return; }

    // Sometimes a gralloc-buffer-only thread is doing stuff with sync.
    // This happens all the time with YouTube videos in the browser.
    // In this case, create a context on the host just for syncing.
    if (!tInfo->currContext) {
        uint32_t gralloc_sync_cxt, gralloc_sync_surf;
        fb->createTrivialContext(0, // There is no context to share.
                                 &gralloc_sync_cxt,
                                 &gralloc_sync_surf);
        fb->bindContext(gralloc_sync_cxt,
                        gralloc_sync_surf,
                        gralloc_sync_surf);
        // This context is then cleaned up when the render thread exits.
    }

    fenceSync->waitAsync();
}

static int rcDestroySyncKHR(uint64_t handle) {
    EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
    if (!fenceSync) return 0;
    fenceSync->decRef();
    return 0;
}

static void rcSetPuid(uint64_t puid) {
    RenderThreadInfo *tInfo = RenderThreadInfo::get();
    tInfo->m_puid = puid;
}

static int rcCompose(uint32_t bufferSize, void* buffer) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }
    return fb->compose(bufferSize, buffer, true);
}

static int rcComposeWithoutPost(uint32_t bufferSize, void* buffer) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }
    return fb->compose(bufferSize, buffer, false);
}

static int rcCreateDisplay(uint32_t* displayId) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    // Assume this API call always allocates a new displayId
    *displayId = FrameBuffer::s_invalidIdMultiDisplay;
    return fb->createDisplay(displayId);
}

static int rcCreateDisplayById(uint32_t displayId) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->createDisplay(displayId);
}

static int rcDestroyDisplay(uint32_t displayId) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->destroyDisplay(displayId);
}

static int rcSetDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->setDisplayColorBuffer(displayId, colorBuffer);
}

static int rcGetDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->getDisplayColorBuffer(displayId, colorBuffer);
}

static int rcGetColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->getColorBufferDisplay(colorBuffer, displayId);
}

static int rcGetDisplayPose(uint32_t displayId,
                            int32_t* x,
                            int32_t* y,
                            uint32_t* w,
                            uint32_t* h) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->getDisplayPose(displayId, x, y, w, h);
}

static int rcSetDisplayPose(uint32_t displayId,
                            int32_t x,
                            int32_t y,
                            uint32_t w,
                            uint32_t h) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->setDisplayPose(displayId, x, y, w, h);
}

static int rcSetDisplayPoseDpi(uint32_t displayId,
                               int32_t x,
                               int32_t y,
                               uint32_t w,
                               uint32_t h,
                               uint32_t dpi) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    return fb->setDisplayPose(displayId, x, y, w, h, dpi);
}

static void rcReadColorBufferYUV(uint32_t colorBuffer,
                                GLint x, GLint y,
                                GLint width, GLint height,
                                void* pixels, uint32_t pixels_size)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }

    fb->readColorBufferYUV(colorBuffer, x, y, width, height, pixels, pixels_size);
}

static int rcIsSyncSignaled(uint64_t handle) {
    EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
    if (!fenceSync) return 1; // assume destroyed => signaled
    return fenceSync->isSignaled() ? 1 : 0;
}

static void rcCreateColorBufferWithHandle(
    uint32_t width, uint32_t height, GLenum internalFormat, uint32_t handle)
{
    FrameBuffer *fb = FrameBuffer::getFB();

    if (!fb) {
        return;
    }

    fb->createColorBufferWithHandle(
        width, height, internalFormat,
        FRAMEWORK_FORMAT_GL_COMPATIBLE, handle);
}

static uint32_t rcCreateBuffer2(uint64_t size, uint32_t memoryProperty) {
    FrameBuffer* fb = FrameBuffer::getFB();
    if (!fb) {
        return 0;
    }

    return fb->createBuffer(size, memoryProperty);
}

static uint32_t rcCreateBuffer(uint32_t size) {
    return rcCreateBuffer2(size, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}

static void rcCloseBuffer(uint32_t buffer) {
    FrameBuffer* fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }
    fb->closeBuffer(buffer);
}

static int rcSetColorBufferVulkanMode2(uint32_t colorBuffer,
                                       uint32_t mode,
                                       uint32_t memoryProperty) {
    if (!goldfish_vk::isColorBufferVulkanCompatible(colorBuffer)) {
        fprintf(stderr,
                "%s: error: colorBuffer 0x%x is not Vulkan compatible\n",
                __func__, colorBuffer);
        return -1;
    }

#define VULKAN_MODE_VULKAN_ONLY 1

    bool modeIsVulkanOnly = mode == VULKAN_MODE_VULKAN_ONLY;

    if (!goldfish_vk::setupVkColorBuffer(colorBuffer, modeIsVulkanOnly,
                                         memoryProperty)) {
        fprintf(stderr,
                "%s: error: failed to create VkImage for colorBuffer 0x%x\n",
                __func__, colorBuffer);
        return -1;
    }

    if (!goldfish_vk::setColorBufferVulkanMode(colorBuffer, mode)) {
        fprintf(stderr,
                "%s: error: failed to set Vulkan mode for colorBuffer 0x%x\n",
                __func__, colorBuffer);
        return -1;
    }

    return 0;
}

static int rcSetColorBufferVulkanMode(uint32_t colorBuffer, uint32_t mode) {
    return rcSetColorBufferVulkanMode2(colorBuffer, mode,
                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}

static int32_t rcMapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa) {
    int32_t result = goldfish_vk::mapGpaToBufferHandle(bufferHandle, gpa);
    if (result < 0) {
        fprintf(stderr,
                "%s: error: failed to map gpa %" PRIx64 " to buffer handle 0x%x: %d\n",
                __func__, gpa, bufferHandle, result);
    }
    return result;
}

static int32_t rcMapGpaToBufferHandle2(uint32_t bufferHandle,
                                       uint64_t gpa,
                                       uint64_t size) {
    int32_t result = goldfish_vk::mapGpaToBufferHandle(bufferHandle, gpa, size);
    if (result < 0) {
        fprintf(stderr,
                "%s: error: failed to map gpa %" PRIx64 " to buffer handle 0x%x: %d\n",
                __func__, gpa, bufferHandle, result);
    }
    return result;
}

static void rcFlushWindowColorBufferAsyncWithFrameNumber(uint32_t windowSurface, uint32_t frameNumber) {
    android::base::traceCounter("gfxstreamFrameNumber", (int64_t)frameNumber);
    rcFlushWindowColorBufferAsync(windowSurface);
}

static void rcSetTracingForPuid(uint64_t puid, uint32_t enable, uint64_t time) {
    if (enable) {
        android::base::setGuestTime(time);
        android::base::enableTracing();
    } else {
        android::base::disableTracing();
    }
}

static void rcMakeCurrentAsync(uint32_t context, uint32_t drawSurf, uint32_t readSurf) {
    AEMU_SCOPED_THRESHOLD_TRACE_CALL();
    FrameBuffer* fb = FrameBuffer::getFB();
    if (!fb) { return; }

    fb->bindContext(context, drawSurf, readSurf);
}

static void rcComposeAsync(uint32_t bufferSize, void* buffer) {
    FrameBuffer* fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }
    fb->compose(bufferSize, buffer, true);
}

static void rcComposeAsyncWithoutPost(uint32_t bufferSize, void* buffer) {
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return;
    }
    fb->compose(bufferSize, buffer, false);
}

static void rcDestroySyncKHRAsync(uint64_t handle) {
    EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
    if (!fenceSync) return;
    fenceSync->decRef();
}

static int rcReadColorBufferDMA(uint32_t colorBuffer,
                                GLint x, GLint y,
                                GLint width, GLint height,
                                GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
{
    FrameBuffer *fb = FrameBuffer::getFB();
    if (!fb) {
        return -1;
    }

    // Update from Vulkan if necessary
    goldfish_vk::readColorBufferToGl(colorBuffer);

    fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
    return 0;
}

static void rcSetProcessMetadata(char* key, RenderControlByte* valuePtr, uint32_t valueSize) {
    RenderThreadInfo* tInfo = RenderThreadInfo::get();
    if (strcmp(key, "process_name") == 0) {
        // We know this is a c formatted string
        tInfo->m_processName = std::string((char*) valuePtr);
    }
}

static int rcGetHostExtensionsString(uint32_t bufferSize, void* buffer) {
    // TODO(b/233939967): split off host extensions from GL extensions.
    return rcGetGLString(GL_EXTENSIONS, buffer, bufferSize);
}

void initRenderControlContext(renderControl_decoder_context_t *dec)
{
    dec->rcGetRendererVersion = rcGetRendererVersion;
    dec->rcGetEGLVersion = rcGetEGLVersion;
    dec->rcQueryEGLString = rcQueryEGLString;
    dec->rcGetGLString = rcGetGLString;
    dec->rcGetNumConfigs = rcGetNumConfigs;
    dec->rcGetConfigs = rcGetConfigs;
    dec->rcChooseConfig = rcChooseConfig;
    dec->rcGetFBParam = rcGetFBParam;
    dec->rcCreateContext = rcCreateContext;
    dec->rcDestroyContext = rcDestroyContext;
    dec->rcCreateWindowSurface = rcCreateWindowSurface;
    dec->rcDestroyWindowSurface = rcDestroyWindowSurface;
    dec->rcCreateColorBuffer = rcCreateColorBuffer;
    dec->rcOpenColorBuffer = rcOpenColorBuffer;
    dec->rcCloseColorBuffer = rcCloseColorBuffer;
    dec->rcSetWindowColorBuffer = rcSetWindowColorBuffer;
    dec->rcFlushWindowColorBuffer = rcFlushWindowColorBuffer;
    dec->rcMakeCurrent = rcMakeCurrent;
    dec->rcFBPost = rcFBPost;
    dec->rcFBSetSwapInterval = rcFBSetSwapInterval;
    dec->rcBindTexture = rcBindTexture;
    dec->rcBindRenderbuffer = rcBindRenderbuffer;
    dec->rcColorBufferCacheFlush = rcColorBufferCacheFlush;
    dec->rcReadColorBuffer = rcReadColorBuffer;
    dec->rcUpdateColorBuffer = rcUpdateColorBuffer;
    dec->rcOpenColorBuffer2 = rcOpenColorBuffer2;
    dec->rcCreateClientImage = rcCreateClientImage;
    dec->rcDestroyClientImage = rcDestroyClientImage;
    dec->rcSelectChecksumHelper = rcSelectChecksumHelper;
    dec->rcCreateSyncKHR = rcCreateSyncKHR;
    dec->rcClientWaitSyncKHR = rcClientWaitSyncKHR;
    dec->rcFlushWindowColorBufferAsync = rcFlushWindowColorBufferAsync;
    dec->rcDestroySyncKHR = rcDestroySyncKHR;
    dec->rcSetPuid = rcSetPuid;
    dec->rcUpdateColorBufferDMA = rcUpdateColorBufferDMA;
    dec->rcCreateColorBufferDMA = rcCreateColorBufferDMA;
    dec->rcWaitSyncKHR = rcWaitSyncKHR;
    dec->rcCompose = rcCompose;
    dec->rcCreateDisplay = rcCreateDisplay;
    dec->rcDestroyDisplay = rcDestroyDisplay;
    dec->rcSetDisplayColorBuffer = rcSetDisplayColorBuffer;
    dec->rcGetDisplayColorBuffer = rcGetDisplayColorBuffer;
    dec->rcGetColorBufferDisplay = rcGetColorBufferDisplay;
    dec->rcGetDisplayPose = rcGetDisplayPose;
    dec->rcSetDisplayPose = rcSetDisplayPose;
    dec->rcSetColorBufferVulkanMode = rcSetColorBufferVulkanMode;
    dec->rcReadColorBufferYUV = rcReadColorBufferYUV;
    dec->rcIsSyncSignaled = rcIsSyncSignaled;
    dec->rcCreateColorBufferWithHandle = rcCreateColorBufferWithHandle;
    dec->rcCreateBuffer = rcCreateBuffer;
    dec->rcCreateBuffer2 = rcCreateBuffer2;
    dec->rcCloseBuffer = rcCloseBuffer;
    dec->rcSetColorBufferVulkanMode2 = rcSetColorBufferVulkanMode2;
    dec->rcMapGpaToBufferHandle = rcMapGpaToBufferHandle;
    dec->rcMapGpaToBufferHandle2 = rcMapGpaToBufferHandle2;
    dec->rcFlushWindowColorBufferAsyncWithFrameNumber = rcFlushWindowColorBufferAsyncWithFrameNumber;
    dec->rcSetTracingForPuid = rcSetTracingForPuid;
    dec->rcMakeCurrentAsync = rcMakeCurrentAsync;
    dec->rcComposeAsync = rcComposeAsync;
    dec->rcDestroySyncKHRAsync = rcDestroySyncKHRAsync;
    dec->rcComposeWithoutPost = rcComposeWithoutPost;
    dec->rcComposeAsyncWithoutPost = rcComposeAsyncWithoutPost;
    dec->rcCreateDisplayById = rcCreateDisplayById;
    dec->rcSetDisplayPoseDpi = rcSetDisplayPoseDpi;
    dec->rcReadColorBufferDMA = rcReadColorBufferDMA;
    dec->rcSetProcessMetadata = rcSetProcessMetadata;
    dec->rcGetHostExtensionsString = rcGetHostExtensionsString;
}
