//
// Copyright 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "util/EGLWindow.h"
#include "common/unsafe_buffers.h"

#include <cassert>
#include <iostream>
#include <vector>

#include <string.h>

#include "common/hash_containers.h"
#include "common/system_utils.h"
#include "platform/Feature.h"
#include "platform/PlatformMethods.h"
#include "util/OSWindow.h"

namespace
{
constexpr EGLint kDefaultSwapInterval = 1;
}  // anonymous namespace

// ConfigParameters implementation.
ConfigParameters::ConfigParameters()
    : redBits(-1),
      greenBits(-1),
      blueBits(-1),
      alphaBits(-1),
      depthBits(-1),
      stencilBits(-1),
      // The default value of EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE is EGL_FALSE.
      webGLCompatibility(false),
      // The default value of EGL_CONTEXT_HARDENED_ANGLE is EGL_FALSE
      hardenedContext(false),
      // The default value of EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE is EGL_FALSE.
      robustResourceInit(false),
      componentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
      multisample(false),
      // The default value of EGL_CONTEXT_OPENGL_DEBUG is EGL_FALSE.
      debug(false),
      // The default value of EGL_CONTEXT_OPENGL_NO_ERROR_KHR is EGL_FALSE.
      noError(false),
      // The default value of EGL_EXTENSIONS_ENABLED_ANGLE is EGL_TRUE.
      extensionsEnabled(true),
      // The default value of EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM is EGL_TRUE.
      bindGeneratesResource(true),
      // The default value of CLIENT_ARRAYS_ANGLE is EGL_TRUE.
      clientArraysEnabled(true),
      // The default value of EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT is EGL_FALSE.
      robustAccess(false),
      // Tests that require EGL_PBUFFER_BIT should request it explicitly.
      pbuffer(false),
      // EGL_RENDER_BUFFER requires EGL 1.4+ or extension support.
      mutableRenderBuffer(false),
      samples(-1),
      // The default value of EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE is EGL_TRUE.
      contextProgramCacheEnabled(true),
      resetStrategy(EGL_NO_RESET_NOTIFICATION_EXT),
      colorSpace(EGL_COLORSPACE_LINEAR),
      swapInterval(kDefaultSwapInterval)
{}

ConfigParameters::~ConfigParameters() = default;

void ConfigParameters::reset()
{
    *this = ConfigParameters();
}

// GLWindowBase implementation.
GLWindowBase::GLWindowBase(GLint glesMajorVersion, EGLint glesMinorVersion)
    : mClientMajorVersion(glesMajorVersion), mClientMinorVersion(glesMinorVersion)
{}

GLWindowBase::~GLWindowBase() = default;

// EGLWindow implementation.
EGLWindow::EGLWindow(EGLint glesMajorVersion, EGLint glesMinorVersion)
    : GLWindowBase(glesMajorVersion, glesMinorVersion),
      mConfig(0),
      mDisplay(EGL_NO_DISPLAY),
      mSurface(EGL_NO_SURFACE),
      mContext(EGL_NO_CONTEXT),
      mEGLMajorVersion(0),
      mEGLMinorVersion(0)
{
    std::fill(mFeatures.begin(), mFeatures.end(), ANGLEFeatureStatus::Unknown);
}

EGLWindow::~EGLWindow()
{
    destroyGL();
}

void EGLWindow::swap()
{
    eglSwapBuffers(mDisplay, mSurface);
}

EGLConfig EGLWindow::getConfig() const
{
    return mConfig;
}

EGLDisplay EGLWindow::getDisplay() const
{
    return mDisplay;
}

EGLSurface EGLWindow::getSurface() const
{
    return mSurface;
}

EGLContext EGLWindow::getContext() const
{
    return mContext;
}

bool EGLWindow::isContextVersion(EGLint glesMajorVersion, EGLint glesMinorVersion) const
{
    return mClientMajorVersion == glesMajorVersion && mClientMinorVersion == glesMinorVersion;
}

GLWindowResult EGLWindow::initializeGLWithResult(OSWindow *osWindow,
                                                 angle::Library *glWindowingLibrary,
                                                 angle::GLESDriverType driverType,
                                                 const EGLPlatformParameters &platformParams,
                                                 const ConfigParameters &configParams)
{
    if (!initializeDisplay(osWindow, glWindowingLibrary, driverType, platformParams))
    {
        return GLWindowResult::Error;
    }
    GLWindowResult res = initializeSurface(osWindow, glWindowingLibrary, configParams);
    if (res != GLWindowResult::NoError)
    {
        return res;
    }
    if (!initializeContext())
    {
        return GLWindowResult::Error;
    }
    return GLWindowResult::NoError;
}

bool EGLWindow::initializeGL(OSWindow *osWindow,
                             angle::Library *glWindowingLibrary,
                             angle::GLESDriverType driverType,
                             const EGLPlatformParameters &platformParams,
                             const ConfigParameters &configParams)
{
    return initializeGLWithResult(osWindow, glWindowingLibrary, driverType, platformParams,
                                  configParams) == GLWindowResult::NoError;
}

bool EGLWindow::initializeDisplay(OSWindow *osWindow,
                                  angle::Library *glWindowingLibrary,
                                  angle::GLESDriverType driverType,
                                  const EGLPlatformParameters &params)
{
    if (driverType == angle::GLESDriverType::ZinkEGL)
    {
        std::stringstream driDirStream;
        char s = angle::GetPathSeparator();
        driDirStream << angle::GetModuleDirectory() << "mesa" << s << "src" << s << "gallium" << s
                     << "targets" << s << "dri";

        std::string driDir = driDirStream.str();

        angle::SetEnvironmentVar("MESA_LOADER_DRIVER_OVERRIDE", "zink");
        angle::SetEnvironmentVar("LIBGL_DRIVERS_PATH", driDir.c_str());
    }

#if defined(ANGLE_USE_UTIL_LOADER)
    PFNEGLGETPROCADDRESSPROC getProcAddress;
    glWindowingLibrary->getAs("eglGetProcAddress", &getProcAddress);
    if (!getProcAddress)
    {
        fprintf(stderr, "Cannot load eglGetProcAddress\n");
        return false;
    }

    // Likely we will need to use a fallback to Library::getAs on non-ANGLE platforms.
    LoadUtilEGL(getProcAddress);
#endif  // defined(ANGLE_USE_UTIL_LOADER)

    // EGL_NO_DISPLAY + EGL_EXTENSIONS returns NULL before Android 10
    const char *extensionString =
        static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
    if (!extensionString)
    {
        // fallback to an empty string for strstr
        extensionString = "";
    }

    std::vector<EGLAttrib> displayAttributes;
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
    displayAttributes.push_back(params.renderer);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
    displayAttributes.push_back(params.majorVersion);
    displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
    displayAttributes.push_back(params.minorVersion);

    if (params.deviceType != EGL_DONT_CARE)
    {
        displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
        displayAttributes.push_back(params.deviceType);
    }

    if (params.presentPath != EGL_DONT_CARE)
    {
        if (ANGLE_UNSAFE_TODO(strstr(extensionString, "EGL_ANGLE_experimental_present_path")) ==
            nullptr)
        {
            destroyGL();
            return false;
        }

        displayAttributes.push_back(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE);
        displayAttributes.push_back(params.presentPath);
    }

    // Set debug layer settings if requested.
    if (params.debugLayersEnabled != EGL_DONT_CARE)
    {
        displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
        displayAttributes.push_back(params.debugLayersEnabled);
    }

    if (params.platformMethods)
    {
        static_assert(sizeof(EGLAttrib) == sizeof(params.platformMethods),
                      "Unexpected pointer size");
        displayAttributes.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX);
        displayAttributes.push_back(reinterpret_cast<EGLAttrib>(params.platformMethods));
    }

    if (params.displayPowerPreference != EGL_DONT_CARE)
    {
        displayAttributes.push_back(EGL_POWER_PREFERENCE_ANGLE);
        displayAttributes.push_back(params.displayPowerPreference);
    }

    std::vector<const char *> enabledFeatureOverrides;
    std::vector<const char *> disabledFeatureOverrides;

    for (angle::Feature feature : params.enabledFeatureOverrides)
    {
        enabledFeatureOverrides.push_back(angle::GetFeatureName(feature));
    }
    for (angle::Feature feature : params.disabledFeatureOverrides)
    {
        disabledFeatureOverrides.push_back(angle::GetFeatureName(feature));
    }

    const bool hasFeatureControlANGLE =
        ANGLE_UNSAFE_TODO(strstr(extensionString, "EGL_ANGLE_feature_control")) != nullptr;

    if (!hasFeatureControlANGLE &&
        (!enabledFeatureOverrides.empty() || !disabledFeatureOverrides.empty()))
    {
        fprintf(stderr, "Missing EGL_ANGLE_feature_control.\n");
        destroyGL();
        return false;
    }

    if (!disabledFeatureOverrides.empty())
    {
        disabledFeatureOverrides.push_back(nullptr);

        displayAttributes.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);
        displayAttributes.push_back(reinterpret_cast<EGLAttrib>(disabledFeatureOverrides.data()));
    }

    if (hasFeatureControlANGLE)
    {
        // Always enable exposeNonConformantExtensionsAndVersions in ANGLE tests.
        enabledFeatureOverrides.push_back("exposeNonConformantExtensionsAndVersions");
        enabledFeatureOverrides.push_back(nullptr);

        displayAttributes.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
        displayAttributes.push_back(reinterpret_cast<EGLAttrib>(enabledFeatureOverrides.data()));
    }

    displayAttributes.push_back(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE);
    displayAttributes.push_back(osWindow->getNativeDisplayPlatformType());

    displayAttributes.push_back(EGL_NONE);

    if (driverType == angle::GLESDriverType::SystemWGL)
        return false;

    if (IsANGLE(driverType) &&
        ANGLE_UNSAFE_TODO(strstr(extensionString, "EGL_ANGLE_platform_angle")))
    {
        mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
                                         reinterpret_cast<void *>(osWindow->getNativeDisplay()),
                                         &displayAttributes[0]);
    }
    else
    {
        mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    }

    if (mDisplay == EGL_NO_DISPLAY)
    {
        fprintf(stderr, "Failed to get display: 0x%X\n", eglGetError());
        destroyGL();
        return false;
    }

    if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE)
    {
        fprintf(stderr, "eglInitialize failed: 0x%X\n", eglGetError());
        destroyGL();
        return false;
    }

    queryFeatures();

    mPlatform = params;
    return true;
}

GLWindowResult EGLWindow::initializeSurface(OSWindow *osWindow,
                                            angle::Library *glWindowingLibrary,
                                            const ConfigParameters &params)
{
    mConfigParams                 = params;
    const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);

    bool hasMutableRenderBuffer =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_KHR_mutable_render_buffer")) != nullptr;
    if (mConfigParams.mutableRenderBuffer && !hasMutableRenderBuffer)
    {
        fprintf(stderr, "Mising EGL_KHR_mutable_render_buffer.\n");
        destroyGL();
        return GLWindowResult::NoMutableRenderBufferSupport;
    }

    std::vector<EGLint> configAttributes = {
        EGL_SURFACE_TYPE,
        EGL_WINDOW_BIT | (params.pbuffer ? EGL_PBUFFER_BIT : 0) |
            (params.mutableRenderBuffer ? EGL_MUTABLE_RENDER_BUFFER_BIT_KHR : 0),
        EGL_RED_SIZE,
        (mConfigParams.redBits >= 0) ? mConfigParams.redBits : EGL_DONT_CARE,
        EGL_GREEN_SIZE,
        (mConfigParams.greenBits >= 0) ? mConfigParams.greenBits : EGL_DONT_CARE,
        EGL_BLUE_SIZE,
        (mConfigParams.blueBits >= 0) ? mConfigParams.blueBits : EGL_DONT_CARE,
        EGL_ALPHA_SIZE,
        (mConfigParams.alphaBits >= 0) ? mConfigParams.alphaBits : EGL_DONT_CARE,
        EGL_DEPTH_SIZE,
        (mConfigParams.depthBits >= 0) ? mConfigParams.depthBits : EGL_DONT_CARE,
        EGL_STENCIL_SIZE,
        (mConfigParams.stencilBits >= 0) ? mConfigParams.stencilBits : EGL_DONT_CARE,
        EGL_SAMPLE_BUFFERS,
        mConfigParams.multisample ? 1 : 0,
        EGL_SAMPLES,
        (mConfigParams.samples >= 0) ? mConfigParams.samples : EGL_DONT_CARE,
    };

    // Add dynamic attributes
    bool hasPixelFormatFloat =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_EXT_pixel_format_float")) != nullptr;
    if (!hasPixelFormatFloat && mConfigParams.componentType != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
    {
        fprintf(stderr, "Mising EGL_EXT_pixel_format_float.\n");
        destroyGL();
        return GLWindowResult::Error;
    }
    if (hasPixelFormatFloat)
    {
        configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT);
        configAttributes.push_back(mConfigParams.componentType);
    }

    // Finish the attribute list
    configAttributes.push_back(EGL_NONE);

    if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig))
    {
        fprintf(stderr, "Could not find a suitable EGL config!\n");
        destroyGL();
        return GLWindowResult::Error;
    }

    eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mConfigParams.redBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mConfigParams.greenBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mConfigParams.blueBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mConfigParams.alphaBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mConfigParams.depthBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mConfigParams.stencilBits);
    eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mConfigParams.samples);

    std::vector<EGLint> surfaceAttributes;
    if (ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_NV_post_sub_buffer")) != nullptr)
    {
        surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
        surfaceAttributes.push_back(EGL_TRUE);
    }

    bool hasRobustResourceInit =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization")) !=
        nullptr;
    if (hasRobustResourceInit)
    {
        surfaceAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
        surfaceAttributes.push_back(mConfigParams.robustResourceInit ? EGL_TRUE : EGL_FALSE);
    }

    bool hasGLColorSpace =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_KHR_gl_colorspace")) != nullptr;
    if (!hasGLColorSpace && mConfigParams.colorSpace != EGL_COLORSPACE_LINEAR)
    {
        fprintf(stderr, "Mising EGL_KHR_gl_colorspace.\n");
        destroyGL();
        return GLWindowResult::NoColorspaceSupport;
    }
    if (hasGLColorSpace)
    {
        surfaceAttributes.push_back(EGL_GL_COLORSPACE_KHR);
        surfaceAttributes.push_back(mConfigParams.colorSpace);
    }

    bool hasCreateSurfaceSwapInterval =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_ANGLE_create_surface_swap_interval")) !=
        nullptr;
    if (hasCreateSurfaceSwapInterval && mConfigParams.swapInterval != kDefaultSwapInterval)
    {
        surfaceAttributes.push_back(EGL_SWAP_INTERVAL_ANGLE);
        surfaceAttributes.push_back(mConfigParams.swapInterval);
    }

    surfaceAttributes.push_back(EGL_NONE);

    osWindow->resetNativeWindow();

    mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(),
                                      &surfaceAttributes[0]);
    EGLint error = eglGetError();
    if (error != EGL_SUCCESS || (mSurface == EGL_NO_SURFACE))
    {
        fprintf(stderr, "eglCreateWindowSurface failed: 0x%X\n", error);
        destroyGL();
        return GLWindowResult::Error;
    }

#if defined(ANGLE_USE_UTIL_LOADER)
    LoadUtilGLES(eglGetProcAddress);
#endif  // defined(ANGLE_USE_UTIL_LOADER)

    return GLWindowResult::NoError;
}

GLWindowContext EGLWindow::getCurrentContextGeneric()
{
    return reinterpret_cast<GLWindowContext>(mContext);
}

GLWindowContext EGLWindow::createContextGeneric(GLWindowContext share)
{
    EGLContext shareContext = reinterpret_cast<EGLContext>(share);
    return reinterpret_cast<GLWindowContext>(createContext(shareContext, nullptr));
}

EGLContext EGLWindow::createContext(EGLContext share, EGLint *extraAttributes)
{
    const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);

    // EGL_KHR_create_context is required to request a ES3+ context.
    bool hasKHRCreateContext =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_KHR_create_context")) != nullptr;
    if (mClientMajorVersion > 2 && !(mEGLMajorVersion > 1 || mEGLMinorVersion >= 5) &&
        !hasKHRCreateContext)
    {
        fprintf(stderr, "EGL_KHR_create_context incompatibility.\n");
        return EGL_NO_CONTEXT;
    }

    // EGL_CONTEXT_OPENGL_DEBUG is only valid as of EGL 1.5.
    bool hasDebug = mEGLMinorVersion >= 5;
    if (mConfigParams.debug && !hasDebug)
    {
        fprintf(stderr, "EGL 1.5 is required for EGL_CONTEXT_OPENGL_DEBUG.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasWebGLCompatibility =
        ANGLE_UNSAFE_TODO(
            strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility")) != nullptr;
    if ((mConfigParams.webGLCompatibility || mConfigParams.hardenedContext) &&
        !hasWebGLCompatibility)
    {
        fprintf(stderr, "EGL_ANGLE_create_context_webgl_compatibility missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasCreateContextExtensionsEnabled =
        ANGLE_UNSAFE_TODO(
            strstr(displayExtensions, "EGL_ANGLE_create_context_extensions_enabled")) != nullptr;
    if (!mConfigParams.extensionsEnabled && !hasCreateContextExtensionsEnabled)
    {
        fprintf(stderr, "EGL_ANGLE_create_context_extensions_enabled missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasRobustness = ANGLE_UNSAFE_TODO(strstr(displayExtensions,
                                                  "EGL_EXT_create_context_robustness")) != nullptr;
    if ((mConfigParams.robustAccess ||
         mConfigParams.resetStrategy != EGL_NO_RESET_NOTIFICATION_EXT) &&
        !hasRobustness)
    {
        fprintf(stderr, "EGL_EXT_create_context_robustness missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasBindGeneratesResource =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions,
                                 "EGL_CHROMIUM_create_context_bind_generates_resource")) != nullptr;
    if (!mConfigParams.bindGeneratesResource && !hasBindGeneratesResource)
    {
        // Non-default state requested without the extension present
        fprintf(stderr, "EGL_CHROMIUM_create_context_bind_generates_resource missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasClientArraysExtension =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_ANGLE_create_context_client_arrays")) !=
        nullptr;
    if (!mConfigParams.clientArraysEnabled && !hasClientArraysExtension)
    {
        // Non-default state requested without the extension present
        fprintf(stderr, "EGL_ANGLE_create_context_client_arrays missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasProgramCacheControlExtension =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_ANGLE_program_cache_control ")) != nullptr;
    if (!mConfigParams.contextProgramCacheEnabled && !hasProgramCacheControlExtension)
    {
        // Non-default state requested without the extension present
        fprintf(stderr, "EGL_ANGLE_program_cache_control missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasKHRCreateContextNoError =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_KHR_create_context_no_error")) != nullptr;
    if (mConfigParams.noError && !hasKHRCreateContextNoError)
    {
        fprintf(stderr, "EGL_KHR_create_context_no_error missing.\n");
        return EGL_NO_CONTEXT;
    }

    bool hasRobustResourceInit =
        ANGLE_UNSAFE_TODO(strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization")) !=
        nullptr;
    if (mConfigParams.robustResourceInit && !hasRobustResourceInit)
    {
        fprintf(stderr, "EGL_ANGLE_robust_resource_initialization missing.\n");
        return EGL_NO_CONTEXT;
    }

    eglBindAPI(EGL_OPENGL_ES_API);
    if (eglGetError() != EGL_SUCCESS)
    {
        fprintf(stderr, "Error on eglBindAPI.\n");
        return EGL_NO_CONTEXT;
    }

    std::vector<EGLint> contextAttributes;
    for (EGLint *extraAttrib = extraAttributes;
         extraAttrib != nullptr && extraAttrib[0] != EGL_NONE; ANGLE_UNSAFE_TODO(extraAttrib += 2))
    {
        contextAttributes.push_back(extraAttrib[0]);
        contextAttributes.push_back(ANGLE_UNSAFE_TODO(extraAttrib[1]));
    }

    if (hasKHRCreateContext)
    {
        contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
        contextAttributes.push_back(mClientMajorVersion);

        contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
        contextAttributes.push_back(mClientMinorVersion);

        // Note that the Android loader currently doesn't handle this flag despite reporting 1.5.
        // Work around this by only using the debug bit when we request a debug context.
        if (hasDebug && mConfigParams.debug)
        {
            contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG);
            contextAttributes.push_back(mConfigParams.debug ? EGL_TRUE : EGL_FALSE);
        }

        // TODO (http://anglebug.com/42264345)
        // Mesa does not allow EGL_CONTEXT_OPENGL_NO_ERROR_KHR for GLES1.
        if (hasKHRCreateContextNoError && mConfigParams.noError)
        {
            contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR);
            contextAttributes.push_back(mConfigParams.noError ? EGL_TRUE : EGL_FALSE);
        }

        if (hasWebGLCompatibility)
        {
            contextAttributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE);
            contextAttributes.push_back(mConfigParams.webGLCompatibility ? EGL_TRUE : EGL_FALSE);

            contextAttributes.push_back(EGL_CONTEXT_HARDENED_ANGLE);
            contextAttributes.push_back(mConfigParams.hardenedContext ? EGL_TRUE : EGL_FALSE);
        }

        if (hasCreateContextExtensionsEnabled)
        {
            contextAttributes.push_back(EGL_EXTENSIONS_ENABLED_ANGLE);
            contextAttributes.push_back(mConfigParams.extensionsEnabled ? EGL_TRUE : EGL_FALSE);
        }

        if (hasRobustness)
        {
            contextAttributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT);
            contextAttributes.push_back(mConfigParams.robustAccess ? EGL_TRUE : EGL_FALSE);

            contextAttributes.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
            contextAttributes.push_back(mConfigParams.resetStrategy);
        }

        if (hasBindGeneratesResource)
        {
            contextAttributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM);
            contextAttributes.push_back(mConfigParams.bindGeneratesResource ? EGL_TRUE : EGL_FALSE);
        }

        if (hasClientArraysExtension)
        {
            contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE);
            contextAttributes.push_back(mConfigParams.clientArraysEnabled ? EGL_TRUE : EGL_FALSE);
        }

        if (hasProgramCacheControlExtension)
        {
            contextAttributes.push_back(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE);
            contextAttributes.push_back(mConfigParams.contextProgramCacheEnabled ? EGL_TRUE
                                                                                 : EGL_FALSE);
        }

        bool hasBackwardsCompatibleContextExtension =
            ANGLE_UNSAFE_TODO(strstr(displayExtensions,
                                     "EGL_ANGLE_create_context_backwards_compatible")) != nullptr;
        if (hasBackwardsCompatibleContextExtension)
        {
            // Always request the exact context version that the config wants
            contextAttributes.push_back(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE);
            contextAttributes.push_back(EGL_FALSE);
        }

        if (hasRobustResourceInit)
        {
            contextAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
            contextAttributes.push_back(mConfigParams.robustResourceInit ? EGL_TRUE : EGL_FALSE);
        }
    }
    contextAttributes.push_back(EGL_NONE);

    EGLContext context = eglCreateContext(mDisplay, mConfig, share, &contextAttributes[0]);
    if (context == EGL_NO_CONTEXT)
    {
        fprintf(stderr, "eglCreateContext failed: 0x%X\n", eglGetError());
        return EGL_NO_CONTEXT;
    }

    return context;
}

bool EGLWindow::initializeContext()
{
    mContext = createContext(EGL_NO_CONTEXT, nullptr);
    if (mContext == EGL_NO_CONTEXT)
    {
        destroyGL();
        return false;
    }

    if (!makeCurrent())
    {
        destroyGL();
        return false;
    }

    // Without EGL_ANGLE_create_context_backwards_compatible and specifying
    // EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE = EGL_FALSE, ANGLE will create a context with
    // the maximum conformant version the display supports. If the extension is not supported, we
    // need to query the actual context version, so each test can behave accordingly.
    // EGL 1.5 Spec
    // 3.7.1.1 OpenGL and OpenGL ES Context Versions
    //   The context returned must be the specified version, or a later version which is
    //   backwards compatible with that version.
    bool hasBackwardsCompatibleContextExtension = angle::CheckExtensionExists(
        eglQueryString(mDisplay, EGL_EXTENSIONS), "EGL_ANGLE_create_context_backwards_compatible");
    if (!hasBackwardsCompatibleContextExtension)
    {
        std::pair<EGLint, EGLint> version = angle::GetCurrentContextVersion();
        // There's no OpenGL ES version "0.x". There is "x.0", though, so we can only check the
        // first.
        if (version.first == 0)
        {
            fprintf(stderr, "Failed to query the current context version: 0x%X\n", eglGetError());
            return false;
        }

        mClientMajorVersion = version.first;
        mClientMinorVersion = version.second;
    }

    return true;
}

void EGLWindow::destroyGL()
{
    destroyContext();
    destroySurface();

    if (mDisplay != EGL_NO_DISPLAY)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
    }
}

void EGLWindow::destroySurface()
{
    if (mSurface != EGL_NO_SURFACE)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
    }
}

void EGLWindow::destroyContext()
{
    if (mContext != EGL_NO_CONTEXT)
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        assert(mDisplay != EGL_NO_DISPLAY);
        eglDestroyContext(mDisplay, mContext);
        mContext = EGL_NO_CONTEXT;
    }
}

bool EGLWindow::isGLInitialized() const
{
    return mSurface != EGL_NO_SURFACE && mContext != EGL_NO_CONTEXT && mDisplay != EGL_NO_DISPLAY;
}

// Find an EGLConfig that is an exact match for the specified attributes. EGL_FALSE is returned if
// the EGLConfig is found.  This indicates that the EGLConfig is not supported.  Surface type is
// special-cased as it's possible for a config to return support for both EGL_WINDOW_BIT and
// EGL_PBUFFER_BIT even though only one of them is requested.
EGLBoolean EGLWindow::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config)
{
    EGLint numConfigs = 0;
    eglGetConfigs(dpy, nullptr, 0, &numConfigs);
    std::vector<EGLConfig> allConfigs(numConfigs);
    eglGetConfigs(dpy, allConfigs.data(), static_cast<EGLint>(allConfigs.size()), &numConfigs);

    for (size_t i = 0; i < allConfigs.size(); i++)
    {
        bool matchFound = true;
        for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE;
             ANGLE_UNSAFE_TODO(curAttrib += 2))
        {
            if (ANGLE_UNSAFE_TODO(curAttrib[1]) == EGL_DONT_CARE)
            {
                continue;
            }

            EGLint actualValue = EGL_DONT_CARE;
            eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue);
            if ((curAttrib[0] == EGL_SURFACE_TYPE &&
                 (ANGLE_UNSAFE_TODO(curAttrib[1]) & actualValue) !=
                     ANGLE_UNSAFE_TODO(curAttrib[1])) ||
                (curAttrib[0] != EGL_SURFACE_TYPE &&
                 ANGLE_UNSAFE_TODO(curAttrib[1]) != actualValue))
            {
                matchFound = false;
                break;
            }
        }

        if (matchFound)
        {
            *config = allConfigs[i];
            return EGL_TRUE;
        }
    }

    return EGL_FALSE;
}

bool EGLWindow::makeCurrentGeneric(GLWindowContext context)
{
    EGLContext eglContext = reinterpret_cast<EGLContext>(context);
    return makeCurrent(eglContext);
}

bool EGLWindow::makeCurrent()
{
    return makeCurrent(mContext);
}

EGLWindow::Image EGLWindow::createImage(GLWindowContext context,
                                        Enum target,
                                        ClientBuffer buffer,
                                        const Attrib *attrib_list)
{
    return eglCreateImage(getDisplay(), context, target, buffer, attrib_list);
}

EGLWindow::Image EGLWindow::createImageKHR(GLWindowContext context,
                                           Enum target,
                                           ClientBuffer buffer,
                                           const AttribKHR *attrib_list)
{
    return eglCreateImageKHR(getDisplay(), context, target, buffer, attrib_list);
}

EGLBoolean EGLWindow::destroyImage(Image image)
{
    return eglDestroyImage(getDisplay(), image);
}

EGLBoolean EGLWindow::destroyImageKHR(Image image)
{
    return eglDestroyImageKHR(getDisplay(), image);
}

EGLWindow::Sync EGLWindow::createSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
    return eglCreateSync(dpy, type, attrib_list);
}

EGLWindow::Sync EGLWindow::createSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
{
    return eglCreateSyncKHR(dpy, type, attrib_list);
}

EGLBoolean EGLWindow::destroySync(EGLDisplay dpy, Sync sync)
{
    return eglDestroySync(dpy, sync);
}

EGLBoolean EGLWindow::destroySyncKHR(EGLDisplay dpy, Sync sync)
{
    return eglDestroySyncKHR(dpy, sync);
}

EGLint EGLWindow::clientWaitSync(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
{
    return eglClientWaitSync(dpy, sync, flags, timeout);
}

EGLint EGLWindow::clientWaitSyncKHR(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
{
    return eglClientWaitSyncKHR(dpy, sync, flags, timeout);
}

EGLint EGLWindow::getEGLError()
{
    return eglGetError();
}

EGLWindow::Display EGLWindow::getCurrentDisplay()
{
    return eglGetCurrentDisplay();
}

EGLWindow::Surface EGLWindow::getCurrentSurface(EGLint readdraw)
{
    return eglGetCurrentSurface(readdraw);
}

EGLContext EGLWindow::getCurrentContext()
{
    return eglGetCurrentContext();
}

GLWindowBase::Surface EGLWindow::createPbufferSurface(const EGLint *attrib_list)
{
    return eglCreatePbufferSurface(getDisplay(), getConfig(), attrib_list);
}

EGLBoolean EGLWindow::destroySurface(Surface surface)
{
    return eglDestroySurface(getDisplay(), surface);
}

EGLBoolean EGLWindow::bindTexImage(EGLSurface surface, EGLint buffer)
{
    return eglBindTexImage(getDisplay(), surface, buffer);
}

EGLBoolean EGLWindow::releaseTexImage(EGLSurface surface, EGLint buffer)
{
    return eglReleaseTexImage(getDisplay(), surface, buffer);
}

bool EGLWindow::makeCurrent(EGLSurface draw, EGLSurface read, EGLContext context)
{
    if ((draw && !read) || (!draw && read))
    {
        fprintf(stderr, "eglMakeCurrent: setting only one of draw and read buffer is illegal\n");
        return false;
    }

    // if the draw buffer is a nullptr and a context is given, then we use mSurface,
    // because we didn't add this the gSurfaceMap, and it is the most likely
    // case that we actually wanted the default surface here.
    // TODO: This will need additional work when we want to support capture/replay
    // with a sourfaceless context.
    //
    // If no context is given then we also don't assign a surface
    if (!draw)
    {
        draw = read = context != EGL_NO_CONTEXT ? mSurface : EGL_NO_SURFACE;
    }

    if (isGLInitialized())
    {
        if (eglMakeCurrent(mDisplay, draw, read, context) == EGL_FALSE ||
            eglGetError() != EGL_SUCCESS)
        {
            fprintf(stderr, "Error during eglMakeCurrent.\n");
            return false;
        }
    }
    return true;
}

bool EGLWindow::makeCurrent(EGLContext context)
{
    return makeCurrent(mSurface, mSurface, context);
}

bool EGLWindow::setSwapInterval(EGLint swapInterval)
{
    if (eglSwapInterval(mDisplay, swapInterval) == EGL_FALSE || eglGetError() != EGL_SUCCESS)
    {
        fprintf(stderr, "Error during eglSwapInterval.\n");
        return false;
    }

    return true;
}

bool EGLWindow::hasError() const
{
    return eglGetError() != EGL_SUCCESS;
}

angle::GenericProc EGLWindow::getProcAddress(const char *name)
{
    return eglGetProcAddress(name);
}

// static
void GLWindowBase::Delete(GLWindowBase **window)
{
    delete *window;
    *window = nullptr;
}

// static
EGLWindow *EGLWindow::New(EGLint glesMajorVersion, EGLint glesMinorVersion)
{
    return new EGLWindow(glesMajorVersion, glesMinorVersion);
}

// static
void EGLWindow::Delete(EGLWindow **window)
{
    delete *window;
    *window = nullptr;
}

void EGLWindow::queryFeatures()
{
    // EGL_NO_DISPLAY + EGL_EXTENSIONS returns NULL before Android 10
    const char *extensionString =
        static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
    const bool hasFeatureControlANGLE =
        extensionString &&
        ANGLE_UNSAFE_TODO(strstr(extensionString, "EGL_ANGLE_feature_control")) != nullptr;

    if (!hasFeatureControlANGLE)
    {
        return;
    }

    angle::HashMap<std::string, angle::Feature> featureFromName;
    for (angle::Feature feature : angle::AllEnums<angle::Feature>())
    {
        featureFromName[angle::GetFeatureName(feature)] = feature;
    }

    EGLAttrib featureCount = -1;
    eglQueryDisplayAttribANGLE(mDisplay, EGL_FEATURE_COUNT_ANGLE, &featureCount);

    for (int index = 0; index < featureCount; index++)
    {
        const char *featureName   = eglQueryStringiANGLE(mDisplay, EGL_FEATURE_NAME_ANGLE, index);
        const char *featureStatus = eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, index);
        ASSERT(featureName != nullptr);
        ASSERT(featureStatus != nullptr);

        const angle::Feature feature = featureFromName[featureName];

        const bool isEnabled =
            ANGLE_UNSAFE_TODO(strcmp(featureStatus, angle::kFeatureStatusEnabled)) == 0;
        const bool isDisabled =
            ANGLE_UNSAFE_TODO(strcmp(featureStatus, angle::kFeatureStatusDisabled)) == 0;
        ASSERT(isEnabled || isDisabled);

        mFeatures[feature] = isEnabled ? ANGLEFeatureStatus::Enabled : ANGLEFeatureStatus::Disabled;
    }
}

bool EGLWindow::isFeatureEnabled(angle::Feature feature)
{
    return mFeatures[feature] == ANGLEFeatureStatus::Enabled;
}
