// Copyright (C) 2022 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 "EmulationGl.h"

#include <algorithm>
#include <cstring>
#include <optional>
#include <vector>

#include "DisplaySurfaceGl.h"
#include "GLESVersionDetector.h"
#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
#include "OpenGLESDispatch/GLESv2Dispatch.h"
#include "OpenGLESDispatch/OpenGLDispatchLoader.h"
#include "RenderThreadInfoGl.h"
#include "aemu/base/misc/StringUtils.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/feature_control.h"
#include "host-common/logging.h"
#include "host-common/opengl/misc.h"

namespace gfxstream {
namespace gl {
namespace {

static void EGLAPIENTRY EglDebugCallback(EGLenum error,
                                         const char *command,
                                         EGLint messageType,
                                         EGLLabelKHR threadLabel,
                                         EGLLabelKHR objectLabel,
                                         const char *message) {
    GL_LOG("command:%s message:%s", command, message);
}

static void GL_APIENTRY GlDebugCallback(GLenum source,
                                        GLenum type,
                                        GLuint id,
                                        GLenum severity,
                                        GLsizei length,
                                        const GLchar *message,
                                        const void *userParam) {
    GL_LOG("message:%s", message);
}

static const GLint kGles2ContextAttribsESOrGLCompat[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,  //
    EGL_NONE,                       //
};

static const GLint kGles2ContextAttribsCoreGL[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,                                                 //
    EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,  //
    EGL_NONE,                                                                      //
};

static const GLint kGles3ContextAttribsESOrGLCompat[] = {
    EGL_CONTEXT_CLIENT_VERSION, 3,  //
    EGL_NONE,                       //
};

static const GLint kGles3ContextAttribsCoreGL[] = {
    EGL_CONTEXT_CLIENT_VERSION, 3,                                                 //
    EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,  //
    EGL_NONE,                                                                      //
};

static bool validateGles2Context(EGLDisplay display) {
    const GLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_NONE,
    };

    EGLint numConfigs = 0;
    EGLConfig config;
    if (!s_egl.eglChooseConfig(display, configAttribs, &config, 1, &numConfigs)) {
        ERR("Failed to find GLES 2.x config.");
        return false;
    }
    if (numConfigs != 1) {
        ERR("Failed to find exactly 1 GLES 2.x config: found %d.", numConfigs);
        return false;
    }

    const EGLint surfaceAttribs[] = {
        EGL_WIDTH, 1,
        EGL_HEIGHT, 1,
        EGL_NONE,
    };

    EGLSurface surface = s_egl.eglCreatePbufferSurface(display, config, surfaceAttribs);
    if (surface == EGL_NO_SURFACE) {
        ERR("Failed to create GLES 2.x pbuffer surface.");
        return false;
    }

    const GLint* contextAttribs = EmulationGl::getGlesMaxContextAttribs();
    EGLContext context = s_egl.eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    if (context == EGL_NO_CONTEXT) {
        ERR("Failed to create GLES 2.x context.");
        s_egl.eglDestroySurface(display, surface);
        return false;
    }

    if (!s_egl.eglMakeCurrent(display, surface, surface, context)) {
        ERR("Failed to make GLES 2.x context current.");
        s_egl.eglDestroySurface(display, surface);
        s_egl.eglDestroyContext(display, context);
        return false;
    }

    const char* extensions = (const char*)s_gles2.glGetString(GL_EXTENSIONS);
    if (extensions == nullptr) {
        ERR("Failed to query GLES 2.x context extensions.");
        s_egl.eglDestroySurface(display, surface);
        s_egl.eglDestroyContext(display, context);
        return false;
    }

    // It is rare but some drivers actually fail this...
    if (!s_egl.eglMakeCurrent(display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE)) {
        ERR("Failed to unbind GLES 2.x context.");
        s_egl.eglDestroySurface(display, surface);
        s_egl.eglDestroyContext(display, context);
        return false;
    }

    s_egl.eglDestroyContext(display, context);
    s_egl.eglDestroySurface(display, surface);
    return true;
}

static std::optional<EGLConfig> getEmulationEglConfig(EGLDisplay display, bool allowWindowSurface) {
    GLint surfaceType = EGL_PBUFFER_BIT;

    if (allowWindowSurface) {
        surfaceType |= EGL_WINDOW_BIT;
    }

    // On Linux, we need RGB888 exactly, or eglMakeCurrent will fail,
    // as glXMakeContextCurrent needs to match the format of the
    // native pixmap.
    constexpr const EGLint kWantedRedSize = 8;
    constexpr const EGLint kWantedGreenSize = 8;
    constexpr const EGLint kWantedBlueSize = 8;

    const GLint configAttribs[] = {
        EGL_RED_SIZE, kWantedRedSize,             //
        EGL_GREEN_SIZE, kWantedGreenSize,         //
        EGL_BLUE_SIZE, kWantedBlueSize,           //
        EGL_SURFACE_TYPE, surfaceType,            //
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  //
        EGL_NONE,                                 //
    };

    EGLint numConfigs = 0;
    s_egl.eglGetConfigs(display, nullptr, 0, &numConfigs);

    std::vector<EGLConfig> configs(numConfigs);

    EGLint numMatchedConfigs = 0;
    s_egl.eglChooseConfig(display, configAttribs, configs.data(), numConfigs, &numMatchedConfigs);

    configs.resize(numMatchedConfigs);

    for (EGLConfig config : configs) {
        EGLint foundRedSize = 0;
        s_egl.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &foundRedSize);
        if (foundRedSize != kWantedRedSize) {
            continue;
        }

        EGLint foundGreenSize = 0;
        s_egl.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &foundGreenSize);
        if (foundGreenSize != kWantedGreenSize) {
            continue;
        }

        EGLint foundBlueSize = 0;
        s_egl.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &foundBlueSize);
        if (foundBlueSize != kWantedBlueSize) {
            continue;
        }

        return config;
    }

    return std::nullopt;
}

}  // namespace

std::unique_ptr<EmulationGl> EmulationGl::create(uint32_t width, uint32_t height,
                                                 gfxstream::host::FeatureSet features,
                                                 bool allowWindowSurface, bool egl2egl) {
    // Loads the glestranslator function pointers.
    if (!LazyLoadedEGLDispatch::get()) {
        ERR("Failed to load EGL dispatch.");
        return nullptr;
    }
    if (!LazyLoadedGLESv1Dispatch::get()) {
        ERR("Failed to load GLESv1 dispatch.");
        return nullptr;
    }
    if (!LazyLoadedGLESv2Dispatch::get()) {
        ERR("Failed to load GLESv2 dispatch.");
        return nullptr;
    }

    if (s_egl.eglUseOsEglApi) {
        s_egl.eglUseOsEglApi(egl2egl, EGL_FALSE);
    }


    std::unique_ptr<EmulationGl> emulationGl(new EmulationGl());

    emulationGl->mFeatures = features;
    emulationGl->mWidth = width;
    emulationGl->mHeight = height;

    emulationGl->mEglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (emulationGl->mEglDisplay == EGL_NO_DISPLAY) {
        ERR("Failed to get EGL display.");
        return nullptr;
    }

    GL_LOG("call eglInitialize");
    if (!s_egl.eglInitialize(emulationGl->mEglDisplay,
                             &emulationGl->mEglVersionMajor,
                             &emulationGl->mEglVersionMinor)) {
        ERR("Failed to eglInitialize.");
        return nullptr;
    }

    if (s_egl.eglSetNativeTextureDecompressionEnabledANDROID) {
        s_egl.eglSetNativeTextureDecompressionEnabledANDROID(
            emulationGl->mEglDisplay,
            emulationGl->mFeatures.NativeTextureDecompression.enabled);
    }

    if (s_egl.eglSetProgramBinaryLinkStatusEnabledANDROID) {
        s_egl.eglSetProgramBinaryLinkStatusEnabledANDROID(
            emulationGl->mEglDisplay,
            emulationGl->mFeatures.GlProgramBinaryLinkStatus.enabled);
    }

    s_egl.eglBindAPI(EGL_OPENGL_ES_API);

#ifdef ENABLE_GL_LOG
    if (s_egl.eglDebugMessageControlKHR) {
        const EGLAttrib controls[] = {
            EGL_DEBUG_MSG_CRITICAL_KHR,
            EGL_TRUE,
            EGL_DEBUG_MSG_ERROR_KHR,
            EGL_TRUE,
            EGL_DEBUG_MSG_WARN_KHR,
            EGL_TRUE,
            EGL_DEBUG_MSG_INFO_KHR,
            EGL_FALSE,
            EGL_NONE,
            EGL_NONE,
        };

        if (s_egl.eglDebugMessageControlKHR(&EglDebugCallback, controls) == EGL_SUCCESS) {
            GL_LOG("Successfully set eglDebugMessageControlKHR");
        } else {
            GL_LOG("Failed to eglDebugMessageControlKHR");
        }
    } else {
        GL_LOG("eglDebugMessageControlKHR not available");
    }
#endif

    emulationGl->mEglVendor = s_egl.eglQueryString(emulationGl->mEglDisplay, EGL_VENDOR);

    const std::string eglExtensions = s_egl.eglQueryString(emulationGl->mEglDisplay, EGL_EXTENSIONS);
    android::base::split<std::string>(eglExtensions, " ",
                                      [&](const std::string& found) {
                                        emulationGl->mEglExtensions.insert(found);
                                      });

    if (!emulationGl->hasEglExtension("EGL_KHR_gl_texture_2D_image")) {
        ERR("Failed to find required EGL_KHR_gl_texture_2D_image extension.");
        return nullptr;
    }

    emulationGl->mGlesDispatchMaxVersion
        = calcMaxVersionFromDispatch(emulationGl->mFeatures, emulationGl->mEglDisplay);
    if (s_egl.eglSetMaxGLESVersion) {
        // eglSetMaxGLESVersion must be called before any context binding
        // because it changes how we initialize the dispatcher table.
        s_egl.eglSetMaxGLESVersion(emulationGl->mGlesDispatchMaxVersion);
    }

    int glesVersionMajor;
    int glesVersionMinor;
    emugl::getGlesVersion(&glesVersionMajor, &glesVersionMinor);
    emulationGl->mGlesVersionMajor = glesVersionMajor;
    emulationGl->mGlesVersionMinor = glesVersionMinor;

    if (!validateGles2Context(emulationGl->mEglDisplay)) {
        ERR("Failed to validate creating GLES 2.x context.");
        return nullptr;
    }

    // TODO (b/207426737): Remove the Imagination-specific workaround.
    const bool disableFastBlit =
        emulationGl->mEglVendor.find("Imagination Technologies") != std::string::npos;

    emulationGl->mFastBlitSupported =
        (emulationGl->mGlesDispatchMaxVersion > GLES_DISPATCH_MAX_VERSION_2) &&
        !disableFastBlit &&
        (emugl::getRenderer() == SELECTED_RENDERER_HOST ||
         emugl::getRenderer() == SELECTED_RENDERER_SWIFTSHADER_INDIRECT ||
         emugl::getRenderer() == SELECTED_RENDERER_ANGLE_INDIRECT);

    auto eglConfigOpt = getEmulationEglConfig(emulationGl->mEglDisplay, allowWindowSurface);
    if (!eglConfigOpt) {
        ERR("Failed to find config for emulation GL.");
        return nullptr;
    }
    emulationGl->mEglConfig = *eglConfigOpt;

    const GLint* maxContextAttribs = getGlesMaxContextAttribs();

    emulationGl->mEglContext = s_egl.eglCreateContext(emulationGl->mEglDisplay,
                                                      emulationGl->mEglConfig,
                                                      EGL_NO_CONTEXT,
                                                      maxContextAttribs);
    if (emulationGl->mEglContext == EGL_NO_CONTEXT) {
        ERR("Failed to create context, error 0x%x.", s_egl.eglGetError());
        return nullptr;
    }

    // Create another context which shares with the default context to be
    // used when we bind the pbuffer. This prevents switching the drawable
    // binding back and forth on the framebuffer context.
    // The main purpose of it is to solve a "blanking" behaviour we see on
    // on Mac platform when switching binded drawable for a context however
    // it is more efficient on other platforms as well.
    auto pbufferSurfaceGl = DisplaySurfaceGl::createPbufferSurface(emulationGl->mEglDisplay,
                                                                   emulationGl->mEglConfig,
                                                                   emulationGl->mEglContext,
                                                                   maxContextAttribs,
                                                                   /*width=*/1,
                                                                   /*height=*/1);
    if (!pbufferSurfaceGl) {
        ERR("Failed to create pbuffer display surface.");
        return nullptr;
    }
    auto* pbufferSurfaceGlPtr = pbufferSurfaceGl.get();

    emulationGl->mPbufferSurface = std::make_unique<gfxstream::DisplaySurface>(
        /*width=*/1,
        /*height=*/1,
        std::move(pbufferSurfaceGl));

    emulationGl->mEmulatedEglConfigs =
        std::make_unique<EmulatedEglConfigList>(emulationGl->mEglDisplay,
                                                emulationGl->mGlesDispatchMaxVersion,
                                                emulationGl->mFeatures);
    if (emulationGl->mEmulatedEglConfigs->empty()) {
        ERR("Failed to initialize emulated configs.");
        return nullptr;
    }

    const bool hasEsOrEs2Context =
        std::any_of(emulationGl->mEmulatedEglConfigs->begin(),
                    emulationGl->mEmulatedEglConfigs->end(),
                    [](const EmulatedEglConfig& config) {
                        const GLint renderableType = config.getRenderableType();
                        return renderableType & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
                    });
    if (!hasEsOrEs2Context) {
        ERR("Failed to find any usable guest EGL configs.");
        return nullptr;
    }

    RecursiveScopedContextBind contextBind(pbufferSurfaceGlPtr->getContextHelper());
    if (!contextBind.isOk()) {
        ERR("Failed to make pbuffer context and surface current");
        return nullptr;
    }

#ifdef ENABLE_GL_LOG
    bool debugSetup = false;
    if (s_gles2.glDebugMessageCallback) {
        s_gles2.glEnable(GL_DEBUG_OUTPUT);
        s_gles2.glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        s_gles2.glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
                                      GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
        s_gles2.glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
                                      GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
        s_gles2.glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
                                      GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_TRUE);
        s_gles2.glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
                                      GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr,
                                      GL_TRUE);
        s_gles2.glDebugMessageCallback(&GlDebugCallback, nullptr);
        debugSetup = s_gles2.glGetError() == GL_NO_ERROR;
        if (!debugSetup) {
            ERR("Failed to set up glDebugMessageCallback");
        } else {
            GL_LOG("Successfully set up glDebugMessageCallback");
        }
    }
    if (s_gles2.glDebugMessageCallbackKHR && !debugSetup) {
        s_gles2.glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE,
                                         GL_DEBUG_SEVERITY_HIGH_KHR, 0, nullptr,
                                         GL_TRUE);
        s_gles2.glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE,
                                         GL_DEBUG_SEVERITY_MEDIUM_KHR, 0, nullptr,
                                         GL_TRUE);
        s_gles2.glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE,
                                         GL_DEBUG_SEVERITY_LOW_KHR, 0, nullptr,
                                         GL_TRUE);
        s_gles2.glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE,
                                         GL_DEBUG_SEVERITY_NOTIFICATION_KHR, 0, nullptr,
                                         GL_TRUE);
        s_gles2.glDebugMessageCallbackKHR(&GlDebugCallback, nullptr);
        debugSetup = s_gles2.glGetError() == GL_NO_ERROR;
        if (!debugSetup) {
            ERR("Failed to set up glDebugMessageCallbackKHR");
        } else {
            GL_LOG("Successfully set up glDebugMessageCallbackKHR");
        }
    }
    if (!debugSetup) {
        GL_LOG("glDebugMessageCallback and glDebugMessageCallbackKHR not available");
    }
#endif

    emulationGl->mGlesVendor = (const char*)s_gles2.glGetString(GL_VENDOR);
    emulationGl->mGlesRenderer = (const char*)s_gles2.glGetString(GL_RENDERER);
    emulationGl->mGlesVersion = (const char*)s_gles2.glGetString(GL_VERSION);
    emulationGl->mGlesExtensions = (const char*)s_gles2.glGetString(GL_EXTENSIONS);

    s_gles2.glGetError();
    GLint numDeviceUuids = 0;
    s_gles2.glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &numDeviceUuids);
    if (numDeviceUuids == 1) {
        GlesUuid uuid{};
        s_gles2.glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, 0, uuid.data());
        emulationGl->mGlesDeviceUuid = uuid;
    }

    emulationGl->mGlesVulkanInteropSupported = false;
    if (s_egl.eglQueryVulkanInteropSupportANDROID) {
        emulationGl->mGlesVulkanInteropSupported = s_egl.eglQueryVulkanInteropSupportANDROID();
    }

    emulationGl->mTextureDraw = std::make_unique<TextureDraw>();
    if (!emulationGl->mTextureDraw) {
        ERR("Failed to initialize TextureDraw.");
        return nullptr;
    }

    emulationGl->mCompositorGl = std::make_unique<CompositorGl>(emulationGl->mTextureDraw.get());

    emulationGl->mDisplayGl = std::make_unique<DisplayGl>(emulationGl->mTextureDraw.get());

    {
        auto surface1 = DisplaySurfaceGl::createPbufferSurface(emulationGl->mEglDisplay,
                                                               emulationGl->mEglConfig,
                                                               emulationGl->mEglContext,
                                                               getGlesMaxContextAttribs(),
                                                               /*width=*/1,
                                                               /*height=*/1);
        if (!surface1) {
            ERR("Failed to create pbuffer surface for ReadbackWorkerGl.");
            return nullptr;
        }

        auto surface2 = DisplaySurfaceGl::createPbufferSurface(emulationGl->mEglDisplay,
                                                               emulationGl->mEglConfig,
                                                               emulationGl->mEglContext,
                                                               getGlesMaxContextAttribs(),
                                                               /*width=*/1,
                                                               /*height=*/1);
        if (!surface2) {
            ERR("Failed to create pbuffer surface for ReadbackWorkerGl.");
            return nullptr;
        }

        emulationGl->mReadbackWorkerGl = std::make_unique<ReadbackWorkerGl>(std::move(surface1),
                                                                            std::move(surface2));
    }

    return emulationGl;
}

EmulationGl::~EmulationGl() {
    if (mPbufferSurface) {
        // TODO(b/267349580): remove after Mac issue fixed.
        mTextureDraw.release();
        // const auto* displaySurfaceGl =
        //    reinterpret_cast<const DisplaySurfaceGl*>(mPbufferSurface->getImpl());
        // RecursiveScopedContextBind contextBind(displaySurfaceGl->getContextHelper());
        // if (contextBind.isOk()) {
        //     mTextureDraw.reset();
        // } else {
        //     ERR("Failed to bind context for destroying TextureDraw.");
        // }
    }

    if (mEglDisplay != EGL_NO_DISPLAY) {
        s_egl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        if (mEglContext != EGL_NO_CONTEXT) {
            s_egl.eglDestroyContext(mEglDisplay, mEglContext);
            mEglContext = EGL_NO_CONTEXT;
        }
        mEglDisplay = EGL_NO_DISPLAY;
    }
}

std::unique_ptr<gfxstream::DisplaySurface> EmulationGl::createFakeWindowSurface() {
    return std::make_unique<gfxstream::DisplaySurface>(
        mWidth, mHeight,
        DisplaySurfaceGl::createPbufferSurface(
            mEglDisplay, mEglConfig, mEglContext, getGlesMaxContextAttribs(), mWidth, mHeight));
}

/*static*/ const GLint* EmulationGl::getGlesMaxContextAttribs() {
    int glesMaj, glesMin;
    emugl::getGlesVersion(&glesMaj, &glesMin);
    if (shouldEnableCoreProfile()) {
        if (glesMaj == 2) {
            return kGles2ContextAttribsCoreGL;
        } else {
            return kGles3ContextAttribsCoreGL;
        }
    }
    if (glesMaj == 2) {
        return kGles2ContextAttribsESOrGLCompat;
    } else {
        return kGles3ContextAttribsESOrGLCompat;
    }
}

const EGLDispatch* EmulationGl::getEglDispatch() {
    return &s_egl;
}

const GLESv2Dispatch* EmulationGl::getGles2Dispatch() {
    return &s_gles2;
}

GLESDispatchMaxVersion EmulationGl::getGlesMaxDispatchVersion() const {
    return mGlesDispatchMaxVersion;
}

bool EmulationGl::hasEglExtension(const std::string& ext) const {
    return mEglExtensions.find(ext) != mEglExtensions.end();
}

void EmulationGl::getEglVersion(EGLint* major, EGLint* minor) const {
    if (major) {
        *major = mEglVersionMajor;
    }
    if (minor) {
        *minor = mEglVersionMinor;
    }
}

void EmulationGl::getGlesVersion(GLint* major, GLint* minor) const {
    if (major) {
        *major = mGlesVersionMajor;
    }
    if (minor) {
        *minor = mGlesVersionMinor;
    }
}

bool EmulationGl::isMesa() const { return mGlesVersion.find("Mesa") != std::string::npos; }

bool EmulationGl::isFastBlitSupported() const {
    return mFastBlitSupported;
}

void EmulationGl::disableFastBlitForTesting() {
    mFastBlitSupported = false;
}

bool EmulationGl::isAsyncReadbackSupported() const {
    return mGlesVersionMajor > 2;
}

std::unique_ptr<DisplaySurface> EmulationGl::createWindowSurface(
        uint32_t width,
        uint32_t height,
        EGLNativeWindowType window) {
    auto surfaceGl = DisplaySurfaceGl::createWindowSurface(mEglDisplay,
                                                           mEglConfig,
                                                           mEglContext,
                                                           getGlesMaxContextAttribs(),
                                                           window);
    if (!surfaceGl) {
        ERR("Failed to create DisplaySurfaceGl.");
        return nullptr;
    }

    return std::make_unique<DisplaySurface>(width,
                                            height,
                                            std::move(surfaceGl));
}

ContextHelper* EmulationGl::getColorBufferContextHelper() {
    if (!mPbufferSurface) {
        return nullptr;
    }

    const auto* surfaceGl = static_cast<const DisplaySurfaceGl*>(mPbufferSurface->getImpl());
    return surfaceGl->getContextHelper();
}

std::unique_ptr<BufferGl> EmulationGl::createBuffer(uint64_t size, HandleType handle) {
    return BufferGl::create(size, handle, getColorBufferContextHelper());
}

std::unique_ptr<BufferGl> EmulationGl::loadBuffer(android::base::Stream* stream) {
    return BufferGl::onLoad(stream, getColorBufferContextHelper());
}

bool EmulationGl::isFormatSupported(GLenum format) {
    const std::vector<GLenum> kUnhandledFormats = {
        GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8,
        GL_DEPTH_COMPONENT32F, GL_DEPTH32F_STENCIL8
    };

    if (std::find(kUnhandledFormats.begin(), kUnhandledFormats.end(), format) !=
            kUnhandledFormats.end()) {
        return false;
    }
    // TODO(b/356603558): add proper GL querying, for now preserve existing assumption
    return true;
}

std::unique_ptr<ColorBufferGl> EmulationGl::createColorBuffer(uint32_t width, uint32_t height,
                                                              GLenum internalFormat,
                                                              FrameworkFormat frameworkFormat,
                                                              HandleType handle) {
    return ColorBufferGl::create(mEglDisplay, width, height, internalFormat, frameworkFormat,
                                 handle, getColorBufferContextHelper(), mTextureDraw.get(),
                                 isFastBlitSupported(), mFeatures);
}

std::unique_ptr<ColorBufferGl> EmulationGl::loadColorBuffer(android::base::Stream* stream) {
    return ColorBufferGl::onLoad(stream, mEglDisplay, getColorBufferContextHelper(),
                                 mTextureDraw.get(), isFastBlitSupported(), mFeatures);
}

std::unique_ptr<EmulatedEglContext> EmulationGl::createEmulatedEglContext(
        uint32_t emulatedEglConfigIndex,
        const EmulatedEglContext* sharedContext,
        GLESApi api,
        HandleType handle) {
    if (!mEmulatedEglConfigs) {
        ERR("EmulatedEglConfigs unavailable.");
        return nullptr;
    }

    const EmulatedEglConfig* emulatedEglConfig = mEmulatedEglConfigs->get(emulatedEglConfigIndex);
    if (!emulatedEglConfig) {
        ERR("Failed to find emulated EGL config %d", emulatedEglConfigIndex);
        return nullptr;
    }

    EGLConfig config = emulatedEglConfig->getHostEglConfig();
    EGLContext share = sharedContext ? sharedContext->getEGLContext() : EGL_NO_CONTEXT;

    return EmulatedEglContext::create(mEglDisplay, config, share, handle, api);
}

std::unique_ptr<EmulatedEglContext> EmulationGl::loadEmulatedEglContext(
        android::base::Stream* stream) {
    return EmulatedEglContext::onLoad(stream, mEglDisplay);
}

std::unique_ptr<EmulatedEglFenceSync> EmulationGl::createEmulatedEglFenceSync(
        EGLenum type,
        int destroyWhenSignaled) {
    const bool hasNativeFence = type == EGL_SYNC_NATIVE_FENCE_ANDROID;
    return EmulatedEglFenceSync::create(mEglDisplay,
                                        hasNativeFence,
                                        destroyWhenSignaled);

}

std::unique_ptr<EmulatedEglImage> EmulationGl::createEmulatedEglImage(
        EmulatedEglContext* context,
        EGLenum target,
        EGLClientBuffer buffer) {
    EGLContext eglContext = context ? context->getEGLContext() : EGL_NO_CONTEXT;
    return EmulatedEglImage::create(mEglDisplay, eglContext, target, buffer);
}

std::unique_ptr<EmulatedEglWindowSurface> EmulationGl::createEmulatedEglWindowSurface(
        uint32_t emulatedConfigIndex,
        uint32_t width,
        uint32_t height,
        HandleType handle) {
    if (!mEmulatedEglConfigs) {
        ERR("EmulatedEglConfigs unavailable.");
        return nullptr;
    }

    const EmulatedEglConfig* emulatedEglConfig = mEmulatedEglConfigs->get(emulatedConfigIndex);
    if (!emulatedEglConfig) {
        ERR("Failed to find emulated EGL config %d", emulatedConfigIndex);
        return nullptr;
    }

    EGLConfig config = emulatedEglConfig->getHostEglConfig();

    return EmulatedEglWindowSurface::create(mEglDisplay, config, width, height, handle);
}

std::unique_ptr<EmulatedEglWindowSurface> EmulationGl::loadEmulatedEglWindowSurface(
        android::base::Stream* stream,
        const ColorBufferMap& colorBuffers,
        const EmulatedEglContextMap& contexts) {
    return EmulatedEglWindowSurface::onLoad(stream, mEglDisplay, colorBuffers, contexts);
}

}  // namespace gl
}  // namespace gfxstream
