//
// Copyright 2012 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.
//

// renderergl_utils.cpp: Conversion functions and other utility routines
// specific to the OpenGL renderer.

#include "libANGLE/renderer/gl/renderergl_utils.h"
#include "common/unsafe_buffers.h"

#include <array>
#include <limits>

#include "GLSLANG/ShaderLang.h"
#include "common/android_util.h"
#include "common/mathutil.h"
#include "common/platform.h"
#include "common/string_utils.h"
#include "gpu_info_util/SystemInfo.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Context.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/FenceNVGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/QueryGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "platform/autogen/FeaturesGL_autogen.h"
#include "platform/autogen/FrontendFeatures_autogen.h"

#include <EGL/eglext.h>
#include <algorithm>
#include <cctype>
#include <sstream>

using angle::CheckedNumeric;

namespace rx
{

namespace
{

const char *GetString(const FunctionsGL *functions, GLenum name)
{
    const char *cStr = reinterpret_cast<const char *>(functions->getString(name));
    if (cStr == nullptr)
    {
        return "";
    }
    return cStr;
}

bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
{
    ASSERT(version);

    std::string nativeVersionString(GetString(functions, GL_VERSION));
    size_t pos = nativeVersionString.find("Mesa");
    if (pos == std::string::npos)
    {
        return false;
    }

    int *data = version->data();
    ANGLE_UNSAFE_TODO(data[0] = data[1] = data[2] = 0);
    ANGLE_UNSAFE_TODO(
        std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2));

    return true;
}

int getAdrenoNumber(const FunctionsGL *functions)
{
    static int number = -1;
    if (number == -1)
    {
        const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
        if (ANGLE_UNSAFE_TODO(std::sscanf(nativeGLRenderer, "Adreno (TM) %d", &number)) < 1 &&
            ANGLE_UNSAFE_TODO(std::sscanf(nativeGLRenderer, "FD%d", &number)) < 1)
        {
            number = 0;
        }
    }
    return number;
}

int GetQualcommVersion(const FunctionsGL *functions)
{
    static int version = -1;
    if (version == -1)
    {
        const std::string nativeVersionString(GetString(functions, GL_VERSION));
        const size_t pos = nativeVersionString.find("V@");
        if (pos == std::string::npos ||
            ANGLE_UNSAFE_TODO(std::sscanf(nativeVersionString.c_str() + pos, "V@%d", &version)) < 1)
        {
            version = 0;
        }
    }
    return version;
}

int getMaliTNumber(const FunctionsGL *functions)
{
    static int number = -1;
    if (number == -1)
    {
        const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
        if (ANGLE_UNSAFE_TODO(std::sscanf(nativeGLRenderer, "Mali-T%d", &number)) < 1)
        {
            number = 0;
        }
    }
    return number;
}

int getMaliGNumber(const FunctionsGL *functions)
{
    static int number = -1;
    if (number == -1)
    {
        const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
        if (ANGLE_UNSAFE_TODO(std::sscanf(nativeGLRenderer, "Mali-G%d", &number)) < 1)
        {
            number = 0;
        }
    }
    return number;
}

bool IsAdreno3xx(const FunctionsGL *functions)
{
    int number = getAdrenoNumber(functions);
    return number != 0 && number >= 300 && number < 400;
}

bool IsAdreno42xOr3xx(const FunctionsGL *functions)
{
    int number = getAdrenoNumber(functions);
    return number != 0 && getAdrenoNumber(functions) < 430;
}

bool IsAdreno4xx(const FunctionsGL *functions)
{
    int number = getAdrenoNumber(functions);
    return number != 0 && number >= 400 && number < 500;
}

bool IsAdreno5xxOrOlder(const FunctionsGL *functions)
{
    int number = getAdrenoNumber(functions);
    return number != 0 && number < 600;
}

bool IsAdreno5xx(const FunctionsGL *functions)
{
    int number = getAdrenoNumber(functions);
    return number != 0 && number >= 500 && number < 600;
}

bool IsMaliT8xxOrOlder(const FunctionsGL *functions)
{
    int number = getMaliTNumber(functions);
    return number != 0 && number < 900;
}

bool IsMaliG31OrOlder(const FunctionsGL *functions)
{
    int number = getMaliGNumber(functions);
    return number != 0 && number <= 31;
}

bool IsMaliG72OrG76OrG51(const FunctionsGL *functions)
{
    int number = getMaliGNumber(functions);
    return number == 72 || number == 76 || number == 51;
}

bool IsMaliValhall(const FunctionsGL *functions)
{
    int number = getMaliGNumber(functions);
    return number == 57 || number == 77 || number == 68 || number == 78 || number == 310 ||
           number == 510 || number == 610 || number == 710 || number == 615 || number == 715;
}

bool IsPixel7OrPixel8(const FunctionsGL *functions)
{
    int number = getMaliGNumber(functions);
    return number == 710 || number == 715;
}

[[maybe_unused]] bool IsAndroidEmulator(const FunctionsGL *functions)
{
    constexpr char androidEmulator[] = "Android Emulator";
    const char *nativeGLRenderer     = GetString(functions, GL_RENDERER);
    return angle::BeginsWith(nativeGLRenderer, androidEmulator);
}

bool IsPowerVrRogue(const FunctionsGL *functions)
{
    constexpr char powerVRRogue[] = "PowerVR Rogue";
    const char *nativeGLRenderer  = GetString(functions, GL_RENDERER);
    return angle::BeginsWith(nativeGLRenderer, powerVRRogue);
}

bool IsHuaweiMaleoon(const FunctionsGL *functions)
{
    const char *nativeGLVendor   = GetString(functions, GL_VENDOR);
    const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
    return (std::string(nativeGLVendor).find("HUAWEI") != std::string::npos) &&
           (std::string(nativeGLRenderer).find("Maleoon") != std::string::npos);
}

bool PrecisionMeetsSpecForHighpFloat(const gl::TypePrecision &precision)
{
    return precision.range[0] >= 62 && precision.range[1] >= 62 && precision.precision >= 16;
}
}  // namespace

// Example GL_VENDOR, GL_RENDERER and GL_VERSION strings:
//   GL_VENDOR:   "Imagination Technologies"
//   GL_RENDERER: "PowerVR D-Series DXT-48-1536"
//   GL_VERSION:  "OpenGL ES 3.2 build 25.3@6908880"
//   GL_VENDOR:   "Imagination Technologies"
//   GL_RENDERER: "PowerVR D-Series DXT-48-1536"
//   GL_VERSION:  "OpenGL ES 3.2 build 26.1@7000000"
bool GetPowerVRDriverVersion(const std::string &vendorString,
                             const std::string &rendererString,
                             const std::string &versionString,
                             std::array<int, 2> *versionOut)
{
    ASSERT(versionOut);
    (*versionOut)[0] = 0;
    (*versionOut)[1] = 0;

    if (vendorString.find("Imagination") == std::string::npos)
    {
        return false;
    }

    if (rendererString.find("PowerVR") == std::string::npos)
    {
        return false;
    }

    size_t atPos = versionString.find('@');
    if (atPos == std::string::npos)
    {
        return false;
    }

    size_t startPos = atPos;
    while (startPos > 0 && !std::isspace(static_cast<unsigned char>(versionString[startPos - 1])))
    {
        --startPos;
    }

    // SAFETY: this offset is computed safely above.
    std::istringstream stream(ANGLE_UNSAFE_BUFFERS(&versionString[startPos]));
    int major = 0;
    int minor = 0;
    char dot  = 0;
    if (!(stream >> major >> dot >> minor) || dot != '.')
    {
        return false;
    }

    (*versionOut)[0] = major;
    (*versionOut)[1] = minor;
    return true;
}

SwapControlData::SwapControlData()
    : targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
{}

VendorID GetVendorID(const FunctionsGL *functions)
{
    std::string nativeVendorString(GetString(functions, GL_VENDOR));
    // Concatenate GL_RENDERER to the string being checked because some vendors put their names in
    // GL_RENDERER
    nativeVendorString += " ";
    nativeVendorString += GetString(functions, GL_RENDERER);

    if (nativeVendorString.find("NVIDIA") != std::string::npos)
    {
        return VENDOR_ID_NVIDIA;
    }
    else if (nativeVendorString.find("ATI") != std::string::npos ||
             nativeVendorString.find("AMD") != std::string::npos ||
             nativeVendorString.find("Radeon") != std::string::npos)
    {
        return VENDOR_ID_AMD;
    }
    else if (nativeVendorString.find("Qualcomm") != std::string::npos)
    {
        return VENDOR_ID_QUALCOMM;
    }
    else if (nativeVendorString.find("Intel") != std::string::npos)
    {
        return VENDOR_ID_INTEL;
    }
    else if (nativeVendorString.find("Imagination") != std::string::npos)
    {
        return VENDOR_ID_POWERVR;
    }
    else if (nativeVendorString.find("Vivante") != std::string::npos)
    {
        return VENDOR_ID_VIVANTE;
    }
    else if (nativeVendorString.find("Mali") != std::string::npos)
    {
        return VENDOR_ID_ARM;
    }
    else
    {
        return VENDOR_ID_UNKNOWN;
    }
}

uint32_t GetDeviceID(const FunctionsGL *functions)
{
    std::string nativeRendererString(GetString(functions, GL_RENDERER));
    constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
        {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
        {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
        {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
    };

    for (const auto &knownDeviceID : kKnownDeviceIDs)
    {
        if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
        {
            return knownDeviceID.second;
        }
    }

    return 0;
}

ShShaderOutput GetShaderOutputType(const angle::FeaturesGL &features, const FunctionsGL *functions)
{
    ASSERT(functions);

    if (functions->standard == STANDARD_GL_DESKTOP)
    {
        // GLSL outputs
        if (!features.emitMaxGlsl400ForTesting.enabled)
        {
            if (functions->isAtLeastGL(gl::Version(4, 5)))
            {
                return SH_GLSL_450_CORE_OUTPUT;
            }
            if (functions->isAtLeastGL(gl::Version(4, 4)))
            {
                return SH_GLSL_440_CORE_OUTPUT;
            }
            if (functions->isAtLeastGL(gl::Version(4, 3)))
            {
                return SH_GLSL_430_CORE_OUTPUT;
            }
            if (functions->isAtLeastGL(gl::Version(4, 2)))
            {
                return SH_GLSL_420_CORE_OUTPUT;
            }
            if (functions->isAtLeastGL(gl::Version(4, 1)))
            {
                return SH_GLSL_410_CORE_OUTPUT;
            }
        }
        if (functions->isAtLeastGL(gl::Version(4, 0)))
        {
            return SH_GLSL_400_CORE_OUTPUT;
        }
        if (functions->isAtLeastGL(gl::Version(3, 3)))
        {
            return SH_GLSL_330_CORE_OUTPUT;
        }
        ASSERT(functions->isAtLeastGL(gl::Version(3, 2)));
        return SH_GLSL_150_CORE_OUTPUT;
    }
    if (functions->standard == STANDARD_GL_ES)
    {
        // ESSL outputs
        return SH_ESSL_OUTPUT;
    }
    UNREACHABLE();
    return ShShaderOutput(0);
}

namespace nativegl_gl
{

static bool MeetsRequirements(const FunctionsGL *functions,
                              const nativegl::SupportRequirement &requirements)
{
    bool hasRequiredExtensions = false;
    for (const std::vector<std::string> &exts : requirements.requiredExtensions)
    {
        bool hasAllExtensionsInSet = true;
        for (const std::string &extension : exts)
        {
            if (!functions->hasExtension(extension))
            {
                hasAllExtensionsInSet = false;
                break;
            }
        }
        if (hasAllExtensionsInSet)
        {
            hasRequiredExtensions = true;
            break;
        }
    }
    if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
    {
        return false;
    }

    if (functions->version >= requirements.version)
    {
        return true;
    }
    else if (!requirements.versionExtensions.empty())
    {
        for (const std::string &extension : requirements.versionExtensions)
        {
            if (!functions->hasExtension(extension))
            {
                return false;
            }
        }
        return true;
    }
    else
    {
        return false;
    }
}

static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
                                                         const angle::FeaturesGL &features,
                                                         GLenum internalFormat)
{
    const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
    ASSERT(formatInfo.sized);

    // Query the current texture so it can be rebound afterwards
    GLint oldTextureBinding = 0;
    functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);

    // Create a small texture with the same format and type that gl::Texture would use
    GLuint texture = 0;
    functions->genTextures(1, &texture);
    functions->bindTexture(GL_TEXTURE_2D, texture);

    // Nearest filter needed for framebuffer completeness on some drivers.
    functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
        functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
    constexpr GLsizei kTextureSize = 16;
    functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
                          kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);

    // Query the current framebuffer so it can be rebound afterwards
    GLint oldFramebufferBinding = 0;
    functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);

    // Bind the texture to the framebuffer and check renderability
    GLuint fbo = 0;
    functions->genFramebuffers(1, &fbo);
    functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
    functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                                    0);

    bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;

    // Delete the framebuffer and restore the previous binding
    functions->deleteFramebuffers(1, &fbo);
    functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));

    // Delete the texture and restore the previous binding
    functions->deleteTextures(1, &texture);
    functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));

    if (!supported)
    {
        ANGLE_GL_CLEAR_ERRORS(functions);
    }

    ASSERT(functions->getError() == GL_NO_ERROR);
    return supported;
}

static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
                                                         const angle::FeaturesGL &features,
                                                         GLenum internalFormat)
{
    const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
    ASSERT(formatInfo.sized);

    // Query the current renderbuffer so it can be rebound afterwards
    GLint oldRenderbufferBinding = 0;
    functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);

    // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
    GLuint renderbuffer = 0;
    functions->genRenderbuffers(1, &renderbuffer);
    functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);

    nativegl::RenderbufferFormat renderbufferFormat =
        nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
    constexpr GLsizei kRenderbufferSize = 16;
    functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
                                   kRenderbufferSize, kRenderbufferSize);

    // Query the current framebuffer so it can be rebound afterwards
    GLint oldFramebufferBinding = 0;
    functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);

    // Bind the texture to the framebuffer and check renderability
    GLuint fbo = 0;
    functions->genFramebuffers(1, &fbo);
    functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
    functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                       renderbuffer);

    bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;

    // Delete the framebuffer and restore the previous binding
    functions->deleteFramebuffers(1, &fbo);
    functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));

    // Delete the renderbuffer and restore the previous binding
    functions->deleteRenderbuffers(1, &renderbuffer);
    functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));

    if (!supported)
    {
        ANGLE_GL_CLEAR_ERRORS(functions);
    }

    ASSERT(functions->getError() == GL_NO_ERROR);
    return supported;
}

static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
{
    if (*curVersion >= maxVersion)
    {
        *curVersion = maxVersion;
    }
}

static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
                                                 const angle::FeaturesGL &features,
                                                 GLenum internalFormat,
                                                 gl::Version *maxSupportedESVersion)
{
    ASSERT(functions->getError() == GL_NO_ERROR);

    gl::TextureCaps textureCaps;

    const nativegl::InternalFormat &formatInfo =
        nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
    textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
    textureCaps.filterable =
        textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
    textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
    textureCaps.renderbuffer      = MeetsRequirements(functions, formatInfo.renderbuffer);
    textureCaps.blendable         = textureCaps.renderbuffer || textureCaps.textureAttachment;

    // Do extra renderability validation for some formats.
    if (internalFormat == GL_R16F || internalFormat == GL_RG16F || internalFormat == GL_RGB16F)
    {
        // SupportRequirement can't currently express a condition of the form (version && extension)
        // || other extensions, so do the (version && extension) part here.
        if (functions->isAtLeastGLES(gl::Version(3, 0)) &&
            functions->hasGLESExtension("GL_EXT_color_buffer_half_float"))
        {
            textureCaps.textureAttachment = true;
            textureCaps.renderbuffer      = true;
        }
    }

    // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
    // if the format is supported unless we try to create a framebuffer.
    // Renderability of signed normalized formats is optional on desktop GL.
    if (internalFormat == GL_RGBA16F ||
        (functions->standard == STANDARD_GL_DESKTOP &&
         (internalFormat == GL_R8_SNORM || internalFormat == GL_R16_SNORM ||
          internalFormat == GL_RG8_SNORM || internalFormat == GL_RG16_SNORM ||
          internalFormat == GL_RGBA8_SNORM || internalFormat == GL_RGBA16_SNORM)))
    {
        if (textureCaps.textureAttachment)
        {
            textureCaps.textureAttachment =
                CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
        }
        if (textureCaps.renderbuffer)
        {
            textureCaps.renderbuffer =
                CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
        }
    }

    // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
    // extension GL_ARB_internalformat_query
    if (textureCaps.renderbuffer && functions->getInternalformativ)
    {
        GLenum queryInternalFormat = internalFormat;

        if (internalFormat == GL_BGRA8_EXT || internalFormat == GL_BGRA_EXT)
        {
            // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
            // drivers.  It seems however that allocating a multisampled renderbuffer of this format
            // succeeds. To avoid breaking multisampling for this format, query the supported sample
            // counts for GL_RGBA8 instead.
            queryInternalFormat = GL_RGBA8;
        }

        ANGLE_GL_CLEAR_ERRORS(functions);
        GLint numSamples = 0;
        functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
                                       1, &numSamples);
        GLenum error = functions->getError();
        if (error != GL_NO_ERROR)
        {
            ERR() << "glGetInternalformativ generated error " << gl::FmtHex(error) << " for format "
                  << gl::FmtHex(queryInternalFormat) << ". Skipping multisample checks.";
            numSamples = 0;
        }

        if (numSamples > 0)
        {
            std::vector<GLint> samples(numSamples);
            functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
                                           static_cast<GLsizei>(samples.size()), &samples[0]);

            for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
            {
                if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
                {
                    continue;
                }

                // Supporting MSAA=1 is not required on OpenGL for non-conformant drivers.
                if (features.disableMSAASampleCount1.enabled && samples[sampleIndex] == 1)
                {
                    continue;
                }

                // Some NVIDIA drivers expose multisampling modes implemented as a combination of
                // multisampling and supersampling. These are non-conformant and should not be
                // exposed through ANGLE. Query which formats are conformant from the driver if
                // supported.
                GLint conformant = GL_TRUE;
                if (functions->getInternalformatSampleivNV)
                {
                    ASSERT(functions->getError() == GL_NO_ERROR);
                    functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
                                                           samples[sampleIndex], GL_CONFORMANT_NV,
                                                           1, &conformant);
                    // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
                    // drivers. Assume that formats with large sample counts are non-conformant in
                    // case the query generates an error.
                    if (functions->getError() != GL_NO_ERROR)
                    {
                        conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
                    }
                }
                if (conformant == GL_TRUE)
                {
                    if (gl::isPow2(samples[sampleIndex]))
                    {
                        textureCaps.sampleCounts.insert(samples[sampleIndex]);
                    }
                    else
                    {
                        WARN() << "Skipping unexpected sample count " << samples[sampleIndex]
                               << " for internal format " << gl::FmtHex(queryInternalFormat) << ".";
                    }
                }
            }
        }
    }

    // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers in these
    // required formats with up to the value of MAX_SAMPLES multisamples, with the exception of
    // signed and unsigned integer formats."
    const gl::InternalFormat &glFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
    if (textureCaps.renderbuffer && !glFormatInfo.isInt() &&
        glFormatInfo.isRequiredRenderbufferFormat(gl::Version(3, 0)) &&
        textureCaps.sampleCounts.getMaxSamples() < 4)
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    ASSERT(functions->getError() == GL_NO_ERROR);
    return textureCaps;
}

static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
{
    GLint result = 0;
    functions->getIntegerv(name, &result);
    return result;
}

static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
{
    GLint result;
    functions->getIntegeri_v(name, index, &result);
    return result;
}

static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
{
    GLint result[2] = {};
    functions->getIntegerv(name, result);
    return ANGLE_UNSAFE_TODO(result[index]);
}

static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
{
    // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
    // caps that are defined as 64-bit values in core spec, but were introduced earlier in
    // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
    if (!functions->getInteger64v)
    {
        GLint result = 0;
        functions->getIntegerv(name, &result);
        return static_cast<GLint64>(result);
    }
    else
    {
        GLint64 result = 0;
        functions->getInteger64v(name, &result);
        return result;
    }
}

static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
{
    GLfloat result = 0.0f;
    functions->getFloatv(name, &result);
    return result;
}

static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
{
    std::array<GLfloat, 2> result = {};
    functions->getFloatv(name, result.data());
    return result[index];
}

static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
                                            GLenum shaderType,
                                            GLenum precisionType)
{
    gl::TypePrecision precision;
    functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
                                        &precision.precision);
    return precision;
}

static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
{
    GLint result;
    functions->getQueryiv(target, name, &result);
    return result;
}

void CapCombinedLimitToESShaders(GLint *combinedLimit, gl::ShaderMap<GLint> &perShaderLimit)
{
    GLint combinedESLimit = 0;
    for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
    {
        combinedESLimit += perShaderLimit[shaderType];
    }

    *combinedLimit = std::min(*combinedLimit, combinedESLimit);
}

void GenerateCaps(const FunctionsGL *functions,
                  const angle::FeaturesGL &features,
                  gl::Caps *caps,
                  gl::TextureCapsMap *textureCapsMap,
                  gl::Extensions *extensions,
                  gl::Limitations *limitations,
                  gl::Version *maxSupportedESVersion,
                  ShPixelLocalStorageOptions *plsOptions)
{
    // Start by assuming ES3.1 support and work down
    *maxSupportedESVersion = gl::Version(3, 1);

    // Desktop GL below 3.2 is not supported
    if (functions->standard == STANDARD_GL_DESKTOP && !functions->isAtLeastGL(gl::Version(3, 2)))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
    }

    // Texture format support checks
    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
    for (GLenum internalFormat : allFormats)
    {
        gl::TextureCaps textureCaps =
            GenerateTextureFormatCaps(functions, features, internalFormat, maxSupportedESVersion);
        textureCapsMap->insert(internalFormat, textureCaps);
    }

    // Table 6.28, implementation dependent values
    if (functions->isAtLeastGL(gl::Version(4, 3)) ||
        functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
        functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);

        // Work around the null driver limitations.
        if (caps->maxElementIndex == 0)
        {
            caps->maxElementIndex = 0xFFFF;
        }
    }
    else
    {
        // Doesn't affect ES3 support, can use a pre-defined limit
        caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
    }

    if (features.limitWebglMaxTextureSizeTo4096.enabled)
    {
        limitations->webGLTextureSizeLimit = 4096;
    }
    else if (features.limitWebglMaxTextureSizeTo8192.enabled)
    {
        limitations->webGLTextureSizeLimit = 8192;
    }

    GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
    if (features.limitMax3dArrayTextureSizeTo1024.enabled)
    {
        max3dArrayTextureSizeLimit = 1024;
    }

    if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
        functions->hasGLESExtension("GL_OES_texture_3D"))
    {
        caps->max3DTextureSize = std::min(
            {QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE), max3dArrayTextureSizeLimit});
    }
    else
    {
        // Can't support ES3 without 3D textures
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE);  // GL 1.0 / ES 2.0
    caps->maxCubeMapTextureSize =
        QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE);  // GL 1.3 / ES 2.0

    if (functions->isAtLeastGL(gl::Version(3, 0)) ||
        functions->hasGLExtension("GL_EXT_texture_array") ||
        functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxArrayTextureLayers = std::min(
            {QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), max3dArrayTextureSizeLimit});
    }
    else
    {
        // Can't support ES3 without array textures
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    if (functions->isAtLeastGL(gl::Version(1, 5)) ||
        functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
        functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    if (functions->isAtLeastGL(gl::Version(3, 0)) ||
        functions->hasGLExtension("GL_EXT_framebuffer_object") ||
        functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
        caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
    }
    else if (functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
        caps->maxColorAttachments = 1;
    }
    else
    {
        // Can't support ES2 without framebuffers and renderbuffers
        LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
    }

    if (functions->isAtLeastGL(gl::Version(2, 0)) ||
        functions->hasGLExtension("ARB_draw_buffers") ||
        functions->isAtLeastGLES(gl::Version(3, 0)) ||
        functions->hasGLESExtension("GL_EXT_draw_buffers"))
    {
        caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
    }
    else
    {
        // Framebuffer is required to have at least one drawbuffer even if the extension is not
        // supported
        caps->maxDrawBuffers = 1;
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    caps->maxViewportWidth =
        QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0);  // GL 1.0 / ES 2.0
    caps->maxViewportHeight =
        QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1);  // GL 1.0 / ES 2.0

    if (functions->standard == STANDARD_GL_DESKTOP &&
        (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
    {
        // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query.  Use
        // GL_POINT_SIZE_RANGE instead.
        caps->minAliasedPointSize =
            std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
        caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
    }
    else
    {
        caps->minAliasedPointSize =
            std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
        caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
    }

    caps->minAliasedLineWidth =
        QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0);  // GL 1.2 / ES 2.0
    caps->maxAliasedLineWidth =
        QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1);  // GL 1.2 / ES 2.0

    // Table 6.29, implementation dependent values (cont.)
    if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxElementsIndices  = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
        caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
    }
    else
    {
        // Doesn't impact supported version
    }

    if (functions->isAtLeastGL(gl::Version(4, 1)) ||
        functions->hasGLExtension("GL_ARB_get_program_binary") ||
        functions->isAtLeastGLES(gl::Version(3, 0)) ||
        functions->hasGLESExtension("GL_OES_get_program_binary"))
    {
        // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
        // format is available.
        GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
        if (numBinaryFormats > 0)
        {
            caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
        }
    }
    else
    {
        // Doesn't impact supported version
    }

    // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
    // GL_ARB_ES2_compatibility exists
    if (functions->isAtLeastGL(gl::Version(4, 1)) ||
        functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
        functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->vertexHighpFloat   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
        caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
        caps->vertexLowpFloat    = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
        caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
        caps->fragmentMediumpFloat =
            QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
        caps->fragmentLowpFloat  = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
        caps->vertexHighpInt     = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
        caps->vertexMediumpInt   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
        caps->vertexLowpInt      = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
        caps->fragmentHighpInt   = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
        caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
        caps->fragmentLowpInt    = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);

        // highp support is required.
        if (!PrecisionMeetsSpecForHighpFloat(caps->fragmentHighpFloat))
        {
            LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
        }
    }
    else
    {
        // Doesn't impact supported version, set some default values
        caps->vertexHighpFloat.setIEEEFloat();
        caps->vertexMediumpFloat.setIEEEFloat();
        caps->vertexLowpFloat.setIEEEFloat();
        caps->fragmentHighpFloat.setIEEEFloat();
        caps->fragmentMediumpFloat.setIEEEFloat();
        caps->fragmentLowpFloat.setIEEEFloat();
        caps->vertexHighpInt.setTwosComplementInt(32);
        caps->vertexMediumpInt.setTwosComplementInt(32);
        caps->vertexLowpInt.setTwosComplementInt(32);
        caps->fragmentHighpInt.setTwosComplementInt(32);
        caps->fragmentMediumpInt.setTwosComplementInt(32);
        caps->fragmentLowpInt.setTwosComplementInt(32);
    }

    if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
        functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
        caps->maxServerWaitTimeout =
            std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // Table 6.31, implementation dependent vertex shader limits
    if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
        caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
        caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
    }
    else
    {
        // Can't support ES2 version without these caps
        LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 1)) ||
        functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
        functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
        caps->maxFragmentUniformVectors =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
    }
    else
    {
        // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
        caps->maxVertexUniformVectors =
            caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
        // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
        caps->maxFragmentUniformVectors =
            caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
    }

    if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxVertexOutputComponents =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
    }
    else
    {
        // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
        // safe limit instead of limiting the supported ES version.
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // Table 6.32, implementation dependent fragment shader limits
    if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
        caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
    }
    else
    {
        // Can't support ES2 version without these caps
        LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
    }

    if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->maxFragmentInputComponents =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
    }
    else
    {
        // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
        // safe limit instead of limiting the supported ES version.
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
        caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
    }
    else
    {
        // Can't support ES3 without texel offset, could possibly be emulated in the shader
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // Table 6.33, implementation dependent aggregate shader limits
    if (nativegl::SupportsUniformBufferObjects(functions))
    {
        caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
        caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
        caps->maxUniformBufferBindings =
            QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
        caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
        caps->uniformBufferOffsetAlignment =
            QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
        caps->maxCombinedUniformBlocks =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
        caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
            QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
        caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
            QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);

        caps->maxUniformBlockSize =
            std::min<GLint64>(gl::IMPLEMENTATION_MAX_UNIFORM_BLOCK_SIZE, caps->maxUniformBlockSize);
    }
    else
    {
        // Can't support ES3 without uniform blocks
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    if (functions->standard == STANDARD_GL_DESKTOP &&
        (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
    {
        caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
    }
    else if (functions->standard == STANDARD_GL_DESKTOP ||
             functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
    }
    else if (functions->standard == STANDARD_GL_DESKTOP)
    {
        caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 1)) ||
        functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
        functions->isAtLeastGLES(gl::Version(2, 0)))
    {
        caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
    }
    else
    {
        // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
        caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
    }

    // Determine the max combined texture image units by adding the vertex and fragment limits.  If
    // the real cap is queried, it would contain the limits for shader types that are not available
    // to ES.
    caps->maxCombinedTextureImageUnits =
        QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);

    // Table 6.34, implementation dependent transform feedback limits
    if (nativegl::SupportsTransformFeedback(functions))
    {
        caps->maxTransformFeedbackInterleavedComponents =
            QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
        caps->maxTransformFeedbackSeparateAttributes =
            QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
        caps->maxTransformFeedbackSeparateComponents =
            QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
    }
    else
    {
        // Can't support ES3 without transform feedback
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    GLint sampleCountLimit = std::numeric_limits<GLint>::max();
    if (features.limitMaxMSAASamplesTo4.enabled)
    {
        sampleCountLimit = 4;
    }

    // Table 6.35, Framebuffer Dependent Values
    if (functions->isAtLeastGL(gl::Version(3, 0)) ||
        functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
        functions->isAtLeastGLES(gl::Version(3, 0)) ||
        functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
    {
        caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
    // However having it available on OpenGL ES 2 is a specification bug, and using this
    // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
    // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
    // GL_ARB_gpu_shader5)

    // Check if sampler objects are supported
    if (!nativegl::SupportsSamplerObjects(functions))
    {
        // Can't support ES3 without sampler objects
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // Can't support ES3 without texture swizzling
    if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
        !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
        !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
        !functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));

        // Texture swizzling is required to work around the luminance texture format not being
        // present in the core profile
        if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
        {
            LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
        }
    }

    // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
    // desktop OpenGL versions starting from 3.3 with the bit packing extension.
    if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
        !(functions->isAtLeastGL(gl::Version(3, 2)) &&
          functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
        !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
        !functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // ES3 needs to support explicit layout location qualifiers, while it might be possible to
    // fake them in our side, we currently don't support that.
    if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
        !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
        !functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    if (!functions->isAtLeastGL(gl::Version(4, 3)) &&
        !functions->hasGLExtension("GL_ARB_stencil_texturing") &&
        !functions->isAtLeastGLES(gl::Version(3, 1)))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
    {
        caps->maxFramebufferWidth  = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
        caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
        caps->maxFramebufferSamples =
            std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (nativegl::SupportsSampleMask(functions))
    {
        caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
        caps->maxColorTextureSamples =
            std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
        caps->maxDepthTextureSamples =
            std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
        caps->maxIntegerSamples =
            std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (nativegl::SupportsVertexAttributeBindings(functions))
    {
        caps->maxVertexAttribRelativeOffset =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
        caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);

        // OpenGL 4.3 has no limit on maximum value of stride.
        // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
        if (features.emulateMaxVertexAttribStride.enabled ||
            (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
        {
            caps->maxVertexAttribStride = 2048;
        }
        else
        {
            caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
        }
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
        // Set maxVertexAttribBindings anyway, a number of places assume this value is at least as
        // much as maxVertexAttributes.
        caps->maxVertexAttribBindings = caps->maxVertexAttributes;
    }

    if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
    {
        caps->maxCombinedShaderOutputResources =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
        caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
        caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
        caps->maxShaderStorageBufferBindings =
            QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
        caps->maxShaderStorageBlockSize =
            QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
        caps->maxCombinedShaderStorageBlocks =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
        caps->shaderStorageBufferOffsetAlignment =
            QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (nativegl::SupportsCompute(functions))
    {
        for (GLuint index = 0u; index < 3u; ++index)
        {
            caps->maxComputeWorkGroupCount[index] =
                QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);

            caps->maxComputeWorkGroupSize[index] =
                QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
        }
        caps->maxComputeWorkGroupInvocations =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
        caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
        caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
        caps->maxComputeSharedMemorySize =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
        caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
        caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
        caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
        caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
        caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
            QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
    {
        caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_texture_gather"))
    {
        caps->minProgramTextureGatherOffset =
            QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
        caps->maxProgramTextureGatherOffset =
            QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_shader_image_load_store"))
    {
        caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
        caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
        caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
        caps->maxCombinedImageUniforms =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
        if (features.forceMaxCombinedShaderOutputResources.enabled)
        {
            caps->maxCombinedShaderOutputResources = caps->maxCombinedImageUniforms +
                                                     caps->maxCombinedShaderStorageBlocks +
                                                     caps->maxColorAttachments;
        }
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
        functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
    {
        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
        caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
            QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
        caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
            QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
        caps->maxAtomicCounterBufferBindings =
            QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
        caps->maxAtomicCounterBufferSize =
            QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
        caps->maxCombinedAtomicCounterBuffers =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
        caps->maxCombinedAtomicCounters =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
    }
    else
    {
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
    // if the max uniform vectors is too large.  Artificially limit the maximum until the test is
    // updated.
    caps->maxVertexUniformVectors = std::min(1024, caps->maxVertexUniformVectors);
    caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
        std::min(caps->maxVertexUniformVectors * 4,
                 caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
    caps->maxFragmentUniformVectors = std::min(1024, caps->maxFragmentUniformVectors);
    caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
        std::min(caps->maxFragmentUniformVectors * 4,
                 caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);

    // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
    // be held. This disallows writing to buffers indirectly through transform feedback, thus
    // disallowing ES3.
    if (!CanMapBufferForRead(functions))
    {
        LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
    }

    // GL_OES_texture_cube_map_array
    if (nativegl::SupportsCubeMapArrayTextures(functions))
    {
        extensions->textureCubeMapArrayOES = true;
        extensions->textureCubeMapArrayEXT = true;
    }
    else
    {
        // Can't support ES3.2 without cube map array textures
        LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
    }

    if (!nativegl::SupportsVertexArrayObjects(functions) ||
        features.syncAllVertexArraysToDefault.enabled)
    {
        // ES 3.1 vertex bindings are not emulated on the default vertex array
        LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
    }

    // Extension support
    extensions->setTextureExtensionSupport(*textureCapsMap);

    // Expose this extension only when we support the formats or we're running on top of a native
    // ES driver.
    extensions->textureCompressionAstcLdrKHR =
        extensions->textureCompressionAstcLdrKHR &&
        (features.allowAstcFormats.enabled || functions->standard == STANDARD_GL_ES);
    extensions->textureCompressionAstcHdrKHR =
        extensions->textureCompressionAstcLdrKHR &&
        functions->hasExtension("GL_KHR_texture_compression_astc_hdr");
    extensions->textureCompressionAstcSliced3dKHR =
        (extensions->textureCompressionAstcLdrKHR &&
         functions->hasExtension("GL_KHR_texture_compression_astc_sliced_3d")) ||
        extensions->textureCompressionAstcHdrKHR;
    extensions->elementIndexUintOES = functions->standard == STANDARD_GL_DESKTOP ||
                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                      functions->hasGLESExtension("GL_OES_element_index_uint");
    extensions->getProgramBinaryOES = caps->programBinaryFormats.size() > 0;
    extensions->readFormatBgraEXT   = functions->isAtLeastGL(gl::Version(1, 2)) ||
                                    functions->hasGLExtension("GL_EXT_bgra") ||
                                    functions->hasGLESExtension("GL_EXT_read_format_bgra");
    extensions->pixelBufferObjectNV = nativegl::SupportsPixelBufferObjects(functions);
    extensions->mapbufferOES = functions->isAtLeastGL(gl::Version(1, 5)) ||
                               functions->isAtLeastGLES(gl::Version(3, 0)) ||
                               functions->hasGLESExtension("GL_OES_mapbuffer");
    extensions->mapBufferRangeEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
                                    functions->hasGLExtension("GL_ARB_map_buffer_range") ||
                                    functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                    functions->hasGLESExtension("GL_EXT_map_buffer_range");
    extensions->textureNpotOES = functions->standard == STANDARD_GL_DESKTOP ||
                                 functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                 functions->hasGLESExtension("GL_OES_texture_npot");
    // Note that we could emulate EXT_draw_buffers on ES 3.0's core functionality.
    extensions->drawBuffersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
                                 functions->hasGLExtension("ARB_draw_buffers") ||
                                 functions->hasGLESExtension("GL_EXT_draw_buffers");
    extensions->drawBuffersIndexedEXT = !features.disableDrawBuffersIndexed.enabled &&
                                        nativegl::SupportsDrawBuffersIndexed(functions);
    extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT;
    extensions->textureStorageEXT     = functions->standard == STANDARD_GL_DESKTOP ||
                                    functions->hasGLESExtension("GL_EXT_texture_storage");
    extensions->textureFilterAnisotropicEXT =
        functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
        functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
    extensions->occlusionQueryBooleanEXT = nativegl::SupportsOcclusionQueries(functions);
    caps->maxTextureAnisotropy =
        extensions->textureFilterAnisotropicEXT
            ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
            : 0.0f;
    extensions->fenceNV = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
    extensions->blendMinmaxEXT = functions->isAtLeastGL(gl::Version(1, 5)) ||
                                 functions->hasGLExtension("GL_EXT_blend_minmax") ||
                                 functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                 functions->hasGLESExtension("GL_EXT_blend_minmax");
    extensions->framebufferBlitNV = functions->isAtLeastGL(gl::Version(3, 0)) ||
                                    functions->hasGLExtension("GL_EXT_framebuffer_blit") ||
                                    functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                    functions->hasGLESExtension("GL_NV_framebuffer_blit");
    extensions->framebufferBlitANGLE =
        extensions->framebufferBlitNV || functions->hasGLESExtension("GL_ANGLE_framebuffer_blit");
    extensions->framebufferMultisampleANGLE =
        extensions->framebufferBlitANGLE && caps->maxSamples > 0;
    extensions->multisampledRenderToTextureEXT =
        !features.disableMultisampledRenderToTexture.enabled &&
        (functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture") ||
         functions->hasGLESExtension("GL_IMG_multisampled_render_to_texture"));
    extensions->multisampledRenderToTexture2EXT =
        !features.disableMultisampledRenderToTexture.enabled &&
        extensions->multisampledRenderToTextureEXT &&
        functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture2");
    extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) ||
                                         functions->hasGLExtension("GL_ARB_fragment_shader") ||
                                         functions->hasGLESExtension("GL_OES_standard_derivatives");
    extensions->shaderTextureLodEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
                                      functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
                                      functions->hasGLESExtension("GL_EXT_shader_texture_lod");
    extensions->fragDepthEXT = functions->standard == STANDARD_GL_DESKTOP ||
                               functions->hasGLESExtension("GL_EXT_frag_depth");
    extensions->conservativeDepthEXT = functions->isAtLeastGL(gl::Version(4, 2)) ||
                                       functions->hasGLExtension("GL_ARB_conservative_depth") ||
                                       functions->hasGLESExtension("GL_EXT_conservative_depth");
    extensions->depthClampEXT         = nativegl::SupportsDepthClamp(functions);
    extensions->polygonOffsetClampEXT = nativegl::SupportsPolygonOffsetClamp(functions);

    extensions->polygonModeNV    = nativegl::SupportsPolygonMode(functions);
    extensions->polygonModeANGLE = extensions->polygonModeNV;

    // This functionality is provided by Shader Model 5 and should be available in GLSL 4.00
    // or even in older versions with GL_ARB_sample_shading and GL_ARB_gpu_shader5. However,
    // some OpenGL implementations (e.g., macOS) that do not support higher context versions
    // do not pass the tests so GLSL 4.20 is required here.
    extensions->sampleVariablesOES = functions->isAtLeastGL(gl::Version(4, 2)) ||
                                     functions->isAtLeastGLES(gl::Version(3, 2)) ||
                                     functions->hasGLESExtension("GL_OES_sample_variables");
    // Some drivers do not support sample qualifiers in ESSL 3.00, so ESSL 3.10 is required on ES.
    extensions->shaderMultisampleInterpolationOES =
        functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
        (functions->isAtLeastGLES(gl::Version(3, 1)) &&
         functions->hasGLESExtension("GL_OES_shader_multisample_interpolation"));
    if (extensions->shaderMultisampleInterpolationOES)
    {
        caps->minInterpolationOffset =
            QuerySingleGLFloat(functions, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES);
        caps->maxInterpolationOffset =
            QuerySingleGLFloat(functions, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES);
        caps->subPixelInterpolationOffsetBits =
            QuerySingleGLInt(functions, GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES);
    }

    if (features.multiviewViaViewportArray.enabled)
    {
        extensions->multiviewOVR  = true;
        extensions->multiview2OVR = true;
        // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
        const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
        // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
        const int maxViewports       = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
        caps->maxViews               = static_cast<GLuint>(std::min(maxLayers, maxViewports));
    }

    extensions->fboRenderMipmapOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
                                     functions->hasGLExtension("GL_EXT_framebuffer_object") ||
                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                     functions->hasGLESExtension("GL_OES_fbo_render_mipmap");

    extensions->textureBorderClampEXT =
        !features.disableTextureClampToBorder.enabled &&
        (functions->standard == STANDARD_GL_DESKTOP ||
         functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
         functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
         functions->hasGLESExtension("GL_NV_texture_border_clamp"));
    extensions->textureBorderClampOES = extensions->textureBorderClampEXT;

    // This functionality is supported on macOS but the extension
    // strings are not listed there for historical reasons.
    extensions->textureMirrorClampToEdgeEXT =
        !features.disableTextureMirrorClampToEdge.enabled &&
        (IsMac() || functions->isAtLeastGL(gl::Version(4, 4)) ||
         functions->hasGLExtension("GL_ARB_texture_mirror_clamp_to_edge") ||
         functions->hasGLExtension("GL_EXT_texture_mirror_clamp") ||
         functions->hasGLExtension("GL_ATI_texture_mirror_once") ||
         functions->hasGLESExtension("GL_EXT_texture_mirror_clamp_to_edge"));

    extensions->textureShadowLodEXT = functions->hasExtension("GL_EXT_texture_shadow_lod");

    extensions->multiDrawIndirectEXT = true;
    extensions->instancedArraysANGLE = nativegl::SupportsInstancing(functions);
    extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
    extensions->unpackSubimageEXT  = nativegl::SupportsUnpackSubImage(functions);
    // Some drivers do not support this extension in ESSL 3.00, so ESSL 3.10 is required on ES.
    extensions->shaderNoperspectiveInterpolationNV =
        functions->isAtLeastGL(gl::Version(3, 0)) ||
        (functions->isAtLeastGLES(gl::Version(3, 1)) &&
         functions->hasGLESExtension("GL_NV_shader_noperspective_interpolation"));
    extensions->packSubimageNV       = nativegl::SupportsPackSubImage(functions);
    extensions->vertexArrayObjectOES = nativegl::SupportsVertexArrayObjects(functions);
    extensions->debugMarkerEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
                                 functions->hasGLExtension("GL_KHR_debug") ||
                                 functions->hasGLExtension("GL_EXT_debug_marker") ||
                                 functions->isAtLeastGLES(gl::Version(3, 2)) ||
                                 functions->hasGLESExtension("GL_KHR_debug") ||
                                 functions->hasGLESExtension("GL_EXT_debug_marker");
    extensions->EGLImageOES         = functions->hasGLESExtension("GL_OES_EGL_image");
    extensions->EGLImageExternalOES = functions->hasGLESExtension("GL_OES_EGL_image_external");
    extensions->EGLImageExternalWrapModesEXT =
        functions->hasExtension("GL_EXT_EGL_image_external_wrap_modes");
    extensions->EGLImageExternalEssl3OES =
        functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
    extensions->EGLImageArrayEXT = functions->hasGLESExtension("GL_EXT_EGL_image_array");

    extensions->EGLSyncOES = functions->hasGLESExtension("GL_OES_EGL_sync");

    if (!features.disableTimestampQueries.enabled &&
        (functions->isAtLeastGL(gl::Version(3, 3)) ||
         functions->hasGLExtension("GL_ARB_timer_query") ||
         functions->hasGLESExtension("GL_EXT_disjoint_timer_query")))
    {
        extensions->disjointTimerQueryEXT = true;

        // If we can't query the counter bits, leave them at 0.
        if (!features.queryCounterBitsGeneratesErrors.enabled)
        {
            caps->queryCounterBitsTimeElapsed =
                QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
            caps->queryCounterBitsTimestamp =
                QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
        }
    }

    extensions->multisampleCompatibilityEXT = nativegl::SupportsMultisampleComatibility(functions);

    extensions->robustnessEXT = functions->isAtLeastGL(gl::Version(4, 5)) ||
                                functions->hasGLExtension("GL_KHR_robustness") ||
                                functions->hasGLExtension("GL_ARB_robustness") ||
                                functions->isAtLeastGLES(gl::Version(3, 2)) ||
                                functions->hasGLESExtension("GL_KHR_robustness") ||
                                functions->hasGLESExtension("GL_EXT_robustness");
    extensions->robustnessKHR = functions->isAtLeastGL(gl::Version(4, 5)) ||
                                functions->hasGLExtension("GL_KHR_robustness") ||
                                functions->isAtLeastGLES(gl::Version(3, 2)) ||
                                functions->hasGLESExtension("GL_KHR_robustness");

    extensions->robustBufferAccessBehaviorKHR =
        extensions->robustnessEXT &&
        (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
         functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));

    extensions->stencilTexturingANGLE = functions->isAtLeastGL(gl::Version(4, 3)) ||
                                        functions->hasGLExtension("GL_ARB_stencil_texturing") ||
                                        functions->isAtLeastGLES(gl::Version(3, 1));

    if (features.supportsShaderFramebufferFetchEXT.enabled && extensions->drawBuffersIndexedAny())
    {
        // We can support PLS natively, probably in tiled memory.
        extensions->shaderPixelLocalStorageANGLE         = true;
        extensions->shaderPixelLocalStorageCoherentANGLE = true;
        plsOptions->type             = ShPixelLocalStorageType::FramebufferFetch;
        plsOptions->fragmentSyncType = ShFragmentSynchronizationType::Automatic;
        plsOptions->supportsNoncoherent =
            features.supportsShaderFramebufferFetchNonCoherentEXT.enabled;
    }
    else
    {
        bool hasFragmentShaderImageLoadStore = false;
        if (functions->isAtLeastGL(gl::Version(4, 2)) ||
            functions->hasGLExtension("GL_ARB_shader_image_load_store"))
        {
            // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
            // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
            //
            // MAX_FRAGMENT_IMAGE_UNIFORMS is at least 8 on Desktop Core and ARB.
            hasFragmentShaderImageLoadStore = true;
        }
        else if (functions->isAtLeastGLES(gl::Version(3, 1)))
        {
            // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
            // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
            //
            // ES 3.1, Table 20.44: MAX_FRAGMENT_IMAGE_UNIFORMS can be 0.
            hasFragmentShaderImageLoadStore =
                caps->maxShaderImageUniforms[gl::ShaderType::Fragment] >= 4;
        }
        if (hasFragmentShaderImageLoadStore &&
            (features.supportsFragmentShaderInterlockNV.enabled ||
             features.supportsFragmentShaderOrderingINTEL.enabled ||
             features.supportsFragmentShaderInterlockARB.enabled))
        {
            // If shader image load/store can be coherent, prefer it over
            // EXT_shader_framebuffer_fetch_non_coherent.
            extensions->shaderPixelLocalStorageANGLE         = true;
            extensions->shaderPixelLocalStorageCoherentANGLE = true;
            plsOptions->type = ShPixelLocalStorageType::ImageLoadStore;
            // Prefer vendor-specific extensions first. The PixelLocalStorageTest.Coherency test
            // doesn't always pass on Intel when we use the ARB extension.
            if (features.supportsFragmentShaderInterlockNV.enabled)
            {
                plsOptions->fragmentSyncType =
                    ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL;
            }
            else if (features.supportsFragmentShaderOrderingINTEL.enabled)
            {
                plsOptions->fragmentSyncType =
                    ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL;
            }
            else
            {
                ASSERT(features.supportsFragmentShaderInterlockARB.enabled);
                plsOptions->fragmentSyncType =
                    ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL;
            }
            // OpenGL ES only allows read/write access to "r32*" images.
            plsOptions->supportsNativeRGBA8ImageFormats =
                functions->standard != StandardGL::STANDARD_GL_ES;
        }
        else if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
        {
            ASSERT(plsOptions->fragmentSyncType == ShFragmentSynchronizationType::NotSupported);
            extensions->shaderPixelLocalStorageANGLE = true;
            plsOptions->type                         = ShPixelLocalStorageType::FramebufferFetch;
        }
        else if (hasFragmentShaderImageLoadStore)
        {
            ASSERT(plsOptions->fragmentSyncType == ShFragmentSynchronizationType::NotSupported);
            extensions->shaderPixelLocalStorageANGLE = true;
            plsOptions->type                         = ShPixelLocalStorageType::ImageLoadStore;
            // OpenGL ES only allows read/write access to "r32*" images.
            plsOptions->supportsNativeRGBA8ImageFormats =
                functions->standard != StandardGL::STANDARD_GL_ES;
        }
        plsOptions->supportsNoncoherent = true;
    }

    // EXT_shader_framebuffer_fetch.
    if (features.supportsShaderFramebufferFetchEXT.enabled)
    {
        extensions->shaderFramebufferFetchEXT = true;
    }

    // TODO(http://anglebug.com/42266350): Support ARM_shader_framebuffer_fetch

    // EXT_shader_framebuffer_fetch_non_coherent.
    if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
    {
        extensions->shaderFramebufferFetchNonCoherentEXT = true;
    }

    extensions->copyTextureCHROMIUM = true;

    extensions->textureStorageMultisample2dArrayOES =
        nativegl::Supports2DMultisampleArrayTextures(functions);

    extensions->multiviewMultisampleANGLE =
        extensions->textureStorageMultisample2dArrayOES && extensions->multiviewOVR;

    extensions->textureMultisampleANGLE = nativegl::Supports2DMultisampleTextures(functions);

    extensions->textureSRGBDecodeEXT = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
                                       functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");

    // ETC1 is a strict subset of ETC2 and the GL backend does not emulate ETC2 formats.
    // This extension is exposed only if its functionality can be supported by the native driver.
    extensions->compressedETC1RGB8SubTextureEXT =
        functions->isAtLeastGL(gl::Version(4, 3)) ||
        functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
        functions->isAtLeastGLES(gl::Version(3, 0)) ||
        functions->hasGLESExtension("GL_EXT_compressed_ETC1_RGB8_sub_texture");

#if ANGLE_ENABLE_CGL
    VendorID vendor = GetVendorID(functions);
    if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
    {
        // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of
        // sampler states.  Disable this extension when we would advertise any ES version
        // that has samplers.
        extensions->textureSRGBDecodeEXT = false;
    }
#endif

    extensions->sRGBWriteControlEXT =
        !features.srgbBlendingBroken.enabled && nativegl::SupportsSRGBWriteControl(functions);

    if (features.bgraTexImageFormatsBroken.enabled)
    {
        extensions->textureFormatBGRA8888EXT = false;
    }

    // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
    // glInvalidateFramebuffer is available
    extensions->discardFramebufferEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
                                        functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                        functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
                                        functions->hasGLESExtension("GL_ARB_invalidate_subdata");

    extensions->translatedShaderSourceANGLE = true;

    if (nativegl::SupportsRectangleTextures(functions))
    {
        extensions->textureRectangleANGLE = true;
        caps->maxRectangleTextureSize =
            QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
    }

    // OpenGL 4.3 (and above) and OpenGL ES 3.2 can support all features and constants defined in
    // GL_EXT_geometry_shader.
    bool hasCoreGSSupport =
        functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2));
    // OpenGL 4.0 adds the support for instanced geometry shader
    // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
    // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
    // GL_ARB_shader_image_load_store adds images to geometry shader
    bool hasInstancedGSSupport = functions->isAtLeastGL(gl::Version(4, 0)) &&
                                 functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
                                 functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
                                 functions->hasGLExtension("GL_ARB_shader_image_load_store");
    if (hasCoreGSSupport || functions->hasGLESExtension("GL_OES_geometry_shader") ||
        functions->hasGLESExtension("GL_EXT_geometry_shader") || hasInstancedGSSupport)
    {
        extensions->geometryShaderEXT = functions->hasGLESExtension("GL_EXT_geometry_shader") ||
                                        hasCoreGSSupport || hasInstancedGSSupport;
        extensions->geometryShaderOES = functions->hasGLESExtension("GL_OES_geometry_shader") ||
                                        hasCoreGSSupport || hasInstancedGSSupport;

        caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);

        // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
        // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
        // follows the one set by glProvokingVertex.
        // [OpenGL 4.3] Chapter 11.3.4.6
        // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
        // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
        // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
        // PROVOKING_VERTEX, then vertex selection follows the convention specified by
        // ProvokingVertex.
        caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
        if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
        {
            // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
            // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
            // [OpenGL 4.3] Chapter 13.4
            // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
            caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
        }

        caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
        caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
        caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
        caps->maxGeometryInputComponents =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
        caps->maxGeometryOutputComponents =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
        caps->maxGeometryOutputVertices =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
        caps->maxGeometryTotalOutputComponents =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
        caps->maxGeometryShaderInvocations =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
        caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
        caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
        caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
        caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
            QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
    }

    // The real combined caps contain limits for shader types that are not available to ES, so limit
    // the caps to the sum of vertex+fragment+geometry shader caps.
    CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
    CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
                                caps->maxShaderTextureImageUnits);
    CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
                                caps->maxShaderStorageBlocks);
    CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
    CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
                                caps->maxShaderAtomicCounterBuffers);
    CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);

    // EXT_blend_func_extended is not implemented on top of ARB_blend_func_extended
    // because the latter does not support fragment shader output layout qualifiers.
    extensions->blendFuncExtendedEXT = functions->isAtLeastGL(gl::Version(3, 3)) ||
                                       functions->hasGLESExtension("GL_EXT_blend_func_extended");
    if (extensions->blendFuncExtendedEXT)
    {
        // TODO(http://anglebug.com/40644593): Support greater values of
        // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
        // for more information about this limitation.
        caps->maxDualSourceDrawBuffers = 1;
    }

    // EXT_float_blend
    // Assume all desktop driver supports this by default.
    extensions->floatBlendEXT = functions->standard == STANDARD_GL_DESKTOP ||
                                functions->hasGLESExtension("GL_EXT_float_blend") ||
                                functions->isAtLeastGLES(gl::Version(3, 2));

    // ANGLE_base_vertex_base_instance
    extensions->baseVertexBaseInstanceANGLE =
        !features.disableBaseInstanceVertex.enabled &&
        (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
         functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
         functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex"));

    // EXT_base_instance
    // Unlike the ANGLE variant, this extension is exposed only if supported natively.
    extensions->baseInstanceEXT = !features.disableBaseInstanceVertex.enabled &&
                                  (functions->isAtLeastGL(gl::Version(4, 2)) ||
                                   functions->hasGLExtension("GL_ARB_base_instance") ||
                                   functions->hasGLESExtension("GL_EXT_base_instance"));

    // ANGLE_base_vertex_base_instance_shader_builtin
    extensions->baseVertexBaseInstanceShaderBuiltinANGLE = extensions->baseVertexBaseInstanceANGLE;

    // OES_draw_elements_base_vertex
    extensions->drawElementsBaseVertexOES =
        !features.disableBaseInstanceVertex.enabled &&
        (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
         functions->hasGLESExtension("GL_OES_draw_elements_base_vertex"));

    // EXT_draw_elements_base_vertex
    extensions->drawElementsBaseVertexEXT =
        !features.disableBaseInstanceVertex.enabled &&
        (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
         functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex"));

    // ANGLE_compressed_texture_etc
    // Expose this extension only when we support the formats or we're running on top of a native
    // ES driver.
    extensions->compressedTextureEtcANGLE =
        (features.allowETCFormats.enabled || functions->standard == STANDARD_GL_ES) &&
        gl::DetermineCompressedTextureETCSupport(*textureCapsMap);

    // When running on top of desktop OpenGL drivers and allow_etc_formats feature is not enabled,
    // mark ETC1 as emulated to hide it from WebGL clients.
    limitations->emulatedEtc1 =
        !features.allowETCFormats.enabled && functions->standard == STANDARD_GL_DESKTOP;

    // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
    // if those formats are not available.
    if (features.unsizedSRGBReadPixelsDoesntTransform.enabled &&
        !functions->isAtLeastGLES(gl::Version(3, 0)))
    {
        extensions->sRGBEXT = false;
    }

    extensions->provokingVertexANGLE = nativegl::SupportsProvokingVertex(functions);

    extensions->texture3DOES = nativegl::Supports3DTextures(functions);

    extensions->memoryObjectEXT = functions->hasGLExtension("GL_EXT_memory_object") ||
                                  functions->hasGLESExtension("GL_EXT_memory_object");
    extensions->semaphoreEXT = functions->hasGLExtension("GL_EXT_semaphore") ||
                               functions->hasGLESExtension("GL_EXT_semaphore");
    extensions->memoryObjectFdEXT = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
                                    functions->hasGLESExtension("GL_EXT_memory_object_fd");
    extensions->semaphoreFdEXT = !features.disableSemaphoreFd.enabled &&
                                 (functions->hasGLExtension("GL_EXT_semaphore_fd") ||
                                  functions->hasGLESExtension("GL_EXT_semaphore_fd"));
    extensions->gpuShader5EXT = functions->isAtLeastGL(gl::Version(4, 0)) ||
                                functions->isAtLeastGLES(gl::Version(3, 2)) ||
                                functions->hasGLExtension("GL_ARB_gpu_shader5") ||
                                functions->hasGLESExtension("GL_EXT_gpu_shader5") ||
                                functions->hasGLESExtension("GL_OES_gpu_shader5");
    extensions->gpuShader5OES     = extensions->gpuShader5EXT;
    extensions->shaderIoBlocksOES = nativegl::SupportsShaderIOBlocks(functions);
    extensions->shaderIoBlocksEXT = extensions->shaderIoBlocksOES;

    extensions->shadowSamplersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
                                    functions->isAtLeastGLES(gl::Version(3, 0)) ||
                                    functions->hasGLESExtension("GL_EXT_shadow_samplers");

    if (!features.disableClipControl.enabled)
    {
        extensions->clipControlEXT = nativegl::SupportsClipControl(functions);
    }

    if (features.disableRenderSnorm.enabled)
    {
        extensions->renderSnormEXT = false;
    }

    constexpr uint32_t kRequiredClipDistances                = 8;
    constexpr uint32_t kRequiredCullDistances                = 8;
    constexpr uint32_t kRequiredCombinedClipAndCullDistances = 8;

    // GL_APPLE_clip_distance cannot be implemented on top of GL_EXT_clip_cull_distance,
    // so require either native support or desktop GL.
    extensions->clipDistanceAPPLE = functions->isAtLeastGL(gl::Version(3, 0)) ||
                                    functions->hasGLESExtension("GL_APPLE_clip_distance");
    if (extensions->clipDistanceAPPLE)
    {
        caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_APPLE);

        if (caps->maxClipDistances < kRequiredClipDistances)
        {
            WARN() << "Disabling GL_APPLE_clip_distance because only " << caps->maxClipDistances
                   << " clip distances are supported by the driver.";
            extensions->clipDistanceAPPLE = false;
        }
    }

    extensions->clipCullDistanceEXT = nativegl::SupportsClipCullDistance(functions);
    if (extensions->clipCullDistanceEXT)
    {
        caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_EXT);
        caps->maxCullDistances = QuerySingleGLInt(functions, GL_MAX_CULL_DISTANCES_EXT);
        caps->maxCombinedClipAndCullDistances =
            QuerySingleGLInt(functions, GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT);

        if (caps->maxClipDistances < kRequiredClipDistances ||
            caps->maxCullDistances < kRequiredCullDistances ||
            caps->maxCombinedClipAndCullDistances < kRequiredCombinedClipAndCullDistances)
        {
            WARN() << "Disabling GL_EXT_clip_cull_distance because only " << caps->maxClipDistances
                   << " clip distances, " << caps->maxCullDistances << " cull distances and "
                   << caps->maxCombinedClipAndCullDistances
                   << " combined clip/cull distances are supported by the driver.";
            extensions->clipCullDistanceEXT = false;
        }
    }

    // Same as GL_EXT_clip_cull_distance but with cull distance support being optional.
    extensions->clipCullDistanceANGLE =
        (functions->isAtLeastGL(gl::Version(3, 0)) || extensions->clipCullDistanceEXT) &&
        caps->maxClipDistances >= kRequiredClipDistances;
    ASSERT(!extensions->clipCullDistanceANGLE || caps->maxClipDistances > 0);

    // GL_OES_shader_image_atomic
    //
    // Note that imageAtomicExchange() is allowed to accept float textures (of r32f format) in this
    // extension, but that's not supported by ARB_shader_image_load_store which this extension is
    // based on, neither in the spec it was merged into it.  This support was only added to desktop
    // GLSL in version 4.5
    if (functions->isAtLeastGL(gl::Version(4, 5)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
        functions->hasGLESExtension("GL_OES_shader_image_atomic"))
    {
        extensions->shaderImageAtomicOES = true;
    }

    // GL_OES_texture_buffer
    if (nativegl::SupportsTextureBufferObjects(functions))
    {
        caps->maxTextureBufferSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_BUFFER_SIZE);
        caps->textureBufferOffsetAlignment =
            QuerySingleGLInt(functions, GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
        extensions->textureBufferOES = true;
        extensions->textureBufferEXT = true;
    }
    else
    {
        // Can't support ES3.2 without texture buffer objects
        LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
    }

    extensions->YUVTargetEXT = functions->hasGLESExtension("GL_EXT_YUV_target");

    // GL_MESA_framebuffer_flip_y
    extensions->framebufferFlipYMESA = functions->hasGLESExtension("GL_MESA_framebuffer_flip_y") ||
                                       functions->hasGLExtension("GL_MESA_framebuffer_flip_y");

    // GL_KHR_parallel_shader_compile
    extensions->parallelShaderCompileKHR = !features.disableNativeParallelCompile.enabled &&
                                           (functions->maxShaderCompilerThreadsKHR != nullptr ||
                                            functions->maxShaderCompilerThreadsARB != nullptr);

    // GL_ANGLE_logic_op
    extensions->logicOpANGLE = nativegl::SupportsLogicOp(functions);

    // GL_EXT_clear_texture
    extensions->clearTextureEXT = !features.disableClearTexture.enabled &&
                                  (functions->isAtLeastGL(gl::Version(4, 4)) ||
                                   functions->hasGLESExtension("GL_EXT_clear_texture") ||
                                   functions->hasGLExtension("GL_ARB_clear_texture"));

    // GL_QCOM_tiled_rendering
    extensions->tiledRenderingQCOM = !features.disableTiledRendering.enabled &&
                                     functions->hasGLESExtension("GL_QCOM_tiled_rendering");

    extensions->blendEquationAdvancedKHR =
        !features.disableBlendEquationAdvanced.enabled &&
        (functions->hasGLExtension("GL_NV_blend_equation_advanced") ||
         functions->hasGLExtension("GL_KHR_blend_equation_advanced") ||
         functions->isAtLeastGLES(gl::Version(3, 2)) ||
         functions->hasGLESExtension("GL_KHR_blend_equation_advanced"));
    extensions->blendEquationAdvancedCoherentKHR =
        !features.disableBlendEquationAdvanced.enabled &&
        nativegl::SupportsBlendEquationAdvancedCoherent(functions);

    // Check if the driver clamps constant blend color
    if (IsQualcomm(GetVendorID(functions)))
    {
        // Backup current state
        float oldColor[4];
        functions->getFloatv(GL_BLEND_COLOR, oldColor);

        // Probe clamping
        float color[4];
        functions->blendColor(2.0, 0.0, 0.0, 0.0);
        functions->getFloatv(GL_BLEND_COLOR, color);
        limitations->noUnclampedBlendColor = color[0] == 1.0;

        // Restore previous state
        functions->blendColor(oldColor[0], oldColor[1], oldColor[2], oldColor[3]);
    }

    if (features.limitMaxBufferSizeTo1gb.enabled)
    {
        limitations->maxBufferBytes = 1 << 30;
    }

    if (features.roundUp3dTextureSizeToPOTForLimit.enabled)
    {
        limitations->roundUp3DTextureSizeToPOTForLimit = true;
    }
}

bool GetSystemInfoVendorIDAndDeviceID(const FunctionsGL *functions,
                                      angle::SystemInfo *outSystemInfo,
                                      angle::VendorID *outVendor,
                                      angle::DeviceID *outDevice)
{
    // Get vendor from GL itself, so on multi-GPU systems the correct GPU is selected.
    *outVendor = GetVendorID(functions);
    *outDevice = 0;

    // Gather additional information from the system to detect multi-GPU scenarios. Do not collect
    // system info on Android as it may use Vulkan which can crash on older devices. All the system
    // info we need is available in the version and renderer strings on Android.
    bool isGetSystemInfoSuccess = !IsAndroid() && angle::GetSystemInfo(outSystemInfo);

    // Get the device id from system info, corresponding to the vendor of the active GPU.
    if (isGetSystemInfoSuccess && !outSystemInfo->gpus.empty())
    {
        if (*outVendor == VENDOR_ID_UNKNOWN)
        {
            // If vendor ID is unknown, take the best estimate of the active GPU.  Chances are there
            // is only one GPU anyway.
            *outVendor = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].vendorId;
            *outDevice = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].deviceId;
        }
        else
        {
            for (const angle::GPUDeviceInfo &gpu : outSystemInfo->gpus)
            {
                if (*outVendor == gpu.vendorId)
                {
                    // Note that deviceId may not necessarily have been possible to retrieve.
                    *outDevice = gpu.deviceId;
                    break;
                }
            }
        }
    }
    else
    {
        // If system info is not available, attempt to deduce the device from GL itself.
        *outDevice = GetDeviceID(functions);
    }

    return isGetSystemInfoSuccess;
}

bool Has9thGenIntelGPU(const angle::SystemInfo &systemInfo)
{
    for (const angle::GPUDeviceInfo &deviceInfo : systemInfo.gpus)
    {
        if (IsIntel(deviceInfo.vendorId) && Is9thGenIntel(deviceInfo.deviceId))
        {
            return true;
        }
    }

    return false;
}

void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
{
    angle::VendorID vendor;
    angle::DeviceID device;
    angle::SystemInfo systemInfo;

    bool isGetSystemInfoSuccess =
        GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);

    bool isAMD           = IsAMD(vendor);
    bool isApple         = IsAppleGPU(vendor);
    bool isIntel         = IsIntel(vendor);
    bool isNvidia        = IsNvidia(vendor);
    bool isQualcomm      = IsQualcomm(vendor);
    bool isVMWare        = IsVMWare(vendor);
    bool hasAMD          = systemInfo.hasAMDGPU();
    bool isMali          = IsARM(vendor);
    bool isHuaweiMaleoon = IsHuaweiMaleoon(functions);

    std::array<int, 3> mesaVersion = {0, 0, 0};
    bool isMesa                    = IsMesa(functions, &mesaVersion);

    int qualcommVersion = -1;
    if (!isMesa && isQualcomm)
    {
        qualcommVersion = GetQualcommVersion(functions);
    }

    // Don't use 1-bit alpha formats on desktop GL with AMD drivers.
    ANGLE_FEATURE_CONDITION(features, avoid1BitAlphaTextureFormats,
                            functions->standard == STANDARD_GL_DESKTOP && isAMD);

    ANGLE_FEATURE_CONDITION(features, RGBA4IsNotSupportedForColorRendering,
                            functions->standard == STANDARD_GL_DESKTOP && isIntel);

    // Although "Sandy Bridge", "Ivy Bridge", and "Haswell" may support GL_ARB_ES3_compatibility
    // extension, ETC2/EAC formats are emulated there. Newer Intel GPUs support them natively.
    ANGLE_FEATURE_CONDITION(
        features, allowETCFormats,
        isIntel && !IsSandyBridge(device) && !IsIvyBridge(device) && !IsHaswell(device));

    // Mesa always exposes ASTC extension but only Intel Gen9, Gen11, and Gen12 have hardware
    // support for it. Newer Intel GPUs (Gen12.5+) do not support ASTC.
    ANGLE_FEATURE_CONDITION(features, allowAstcFormats,
                            !isMesa || isIntel && (Is9thGenIntel(device) || IsGeminiLake(device) ||
                                                   IsCoffeeLake(device) || Is11thGenIntel(device) ||
                                                   Is12thGenIntel(device)));

    // Ported from gpu_driver_bug_list.json (#183)
    ANGLE_FEATURE_CONDITION(features, emulateAbsIntFunction, IsApple() && isIntel);

    ANGLE_FEATURE_CONDITION(features, addAndTrueToLoopCondition, IsApple() && isIntel);

    // https://anglebug.com/42266803
    ANGLE_FEATURE_CONDITION(features, clearsWithGapsNeedFlush,
                            !isMesa && isQualcomm && qualcommVersion < 490);

    ANGLE_FEATURE_CONDITION(features, doesSRGBClearsOnLinearFramebufferAttachments,
                            isIntel || isAMD);

    ANGLE_FEATURE_CONDITION(features, emulateMaxVertexAttribStride,
                            IsLinux() && functions->standard == STANDARD_GL_DESKTOP && isAMD);
    ANGLE_FEATURE_CONDITION(
        features, useUnusedBlocksWithStandardOrSharedLayout,
        (IsApple() && functions->standard == STANDARD_GL_DESKTOP) || (IsLinux() && isAMD));

    ANGLE_FEATURE_CONDITION(features, vertexIDDoesNotIncludeBaseVertex, IsApple() && isAMD);

    // Triggers a bug on Marshmallow Adreno (4xx?) driver.
    // http://anglebug.com/40096454
    ANGLE_FEATURE_CONDITION(features, dontInitializeUninitializedLocals, !isMesa && isQualcomm);

    ANGLE_FEATURE_CONDITION(features, finishDoesNotCauseQueriesToBeAvailable,
                            functions->standard == STANDARD_GL_DESKTOP && isNvidia);

    // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
    ANGLE_FEATURE_CONDITION(features, alwaysCallUseProgramAfterLink, true);

    ANGLE_FEATURE_CONDITION(features, unpackOverlappingRowsSeparatelyUnpackBuffer, isNvidia);
    ANGLE_FEATURE_CONDITION(features, packOverlappingRowsSeparatelyPackBuffer, isNvidia);
    // Mali GLES computes readPixels row_stride as (int32_t)(row_length*bpp)*8;
    // wraps negative when the byte pitch >= 0x10000000 -> OOB write into the
    // PBO's cmem mapping. Route through readPixelsRowByRow so Mali only ever
    // sees PACK_ROW_LENGTH=0. Also apply to Imagination GPUs which crash on
    // the new test. crbug.com/529867799
    ANGLE_FEATURE_CONDITION(features, packLargeRowLengthSeparatelyPackBuffer,
                            isMali || IsPowerVR(vendor));

    std::array<int, 2> powerVRVersion = {0, 0};
    bool isPowerVRDriver =
        GetPowerVRDriverVersion(GetVendorString(functions), GetRendererString(functions),
                                GetVersionString(functions), &powerVRVersion);
    ANGLE_FEATURE_CONDITION(features, splitLevel0PboFullSubImage2D,
                            isPowerVRDriver && powerVRVersion < (std::array<int, 2>{26, 2}));

    // TODO(crbug.com/548127218): conditionalize this workaround on PowerVR
    // driver version.
    ANGLE_FEATURE_CONDITION(features, uploadOversizedMipLevelsViaUnpackBuffer, isPowerVRDriver);

    ANGLE_FEATURE_CONDITION(features, initializeCurrentVertexAttributes, isNvidia);

    ANGLE_FEATURE_CONDITION(features, unpackLastRowSeparatelyForPaddingInclusion,
                            IsApple() || isNvidia);
    ANGLE_FEATURE_CONDITION(features, packLastRowSeparatelyForPaddingInclusion,
                            IsApple() || isNvidia);

    ANGLE_FEATURE_CONDITION(features, removeInvariantAndCentroidForESSL3,
                            functions->isAtMostGL(gl::Version(4, 1)) ||
                                (functions->standard == STANDARD_GL_DESKTOP && isAMD));

    // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
    // 364 are known to be affected, at least up to 375.
    ANGLE_FEATURE_CONDITION(features, emulateAtan2Float, isNvidia);

    ANGLE_FEATURE_CONDITION(features, reapplyUBOBindingsAfterUsingBinaryProgram,
                            isAMD || IsAndroid());

    // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
    // 390 are known to be affected. Versions after that are expected not to be affected.
    ANGLE_FEATURE_CONDITION(features, clampFragDepth, isNvidia);

    // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
    // not affected.
    ANGLE_FEATURE_CONDITION(features, rewriteRepeatedAssignToSwizzled, isNvidia);

    // TODO(jmadill): Narrow workaround range for specific devices.

    ANGLE_FEATURE_CONDITION(features, clampPointSize, IsAndroid() || isNvidia);

    // Ported from gpu_driver_bug_list.json (#246, #258)
    ANGLE_FEATURE_CONDITION(features, dontUseLoopsToInitializeVariables,
                            (!isMesa && isQualcomm) || (isIntel && IsApple()));

    ANGLE_FEATURE_CONDITION(features, avoidBindFragDataLocation, !isMesa && isQualcomm);

    ANGLE_FEATURE_CONDITION(features, unsizedSRGBReadPixelsDoesntTransform, !isMesa && isQualcomm);

    ANGLE_FEATURE_CONDITION(features, queryCounterBitsGeneratesErrors, IsNexus5X(vendor, device));

    bool isAndroidLessThan14 = IsAndroid() && GetAndroidSDKVersion() < 34;
    bool isAndroidAtLeast14  = IsAndroid() && GetAndroidSDKVersion() >= 34;
    bool isIntelLinuxLessThanKernelVersion5 =
        isIntel && IsLinux() && GetLinuxOSVersion() < OSVersion(5, 0, 0);
    ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo4096,
                            isAndroidLessThan14 || isIntelLinuxLessThanKernelVersion5);
    ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo8192, isAndroidAtLeast14);
    // On Apple switchable graphics, GL_MAX_SAMPLES may differ between the GPUs.
    // 4 is a lowest common denominator that is always supported.
    ANGLE_FEATURE_CONDITION(features, limitMaxMSAASamplesTo4,
                            IsAndroid() || (IsApple() && (isIntel || isAMD || isNvidia)));
    ANGLE_FEATURE_CONDITION(features, disableMSAASampleCount1, isHuaweiMaleoon);
    ANGLE_FEATURE_CONDITION(features, limitMax3dArrayTextureSizeTo1024,
                            isIntelLinuxLessThanKernelVersion5);
    ANGLE_FEATURE_CONDITION(features, roundUp3dTextureSizeToPOTForLimit,
                            isPowerVRDriver && powerVRVersion < (std::array<int, 2>{26, 2}));

    ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, IsApple());

    // NVidia and PowerVR Rogue report MAX_COMBINED_SHADER_OUTPUT_RESOURCES incorrectly.
    // Force it to the sum of all sublimits.
    ANGLE_FEATURE_CONDITION(features, forceMaxCombinedShaderOutputResources,
                            isNvidia || IsPowerVrRogue(functions));

    // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
    // on AMD and Android devices.
    // This test is also flaky on Linux Nvidia. So we just turn it on everywhere and don't rely on
    // driver since security is important.
    ANGLE_FEATURE_CONDITION(
        features, clampArrayAccess,
        IsAndroid() || isAMD || !functions->hasExtension("GL_KHR_robust_buffer_access_behavior"));

    ANGLE_FEATURE_CONDITION(features, resetTexImage2DBaseLevel,
                            IsApple() && isIntel && GetMacOSVersion() >= OSVersion(10, 12, 4));

    ANGLE_FEATURE_CONDITION(features, resetBaseLevelForASTCImage, IsPowerVR(vendor));
    ANGLE_FEATURE_CONDITION(features, recreateImmutableTextureOnBaseLevelIncrease,
                            IsPowerVR(vendor));
    ANGLE_FEATURE_CONDITION(features, resetTexStorage2DBaseLevel, IsPowerVR(vendor));
    ANGLE_FEATURE_CONDITION(features, recreateTextureOnTexImage3dDepthIncrease,
                            isQualcomm && IsAndroid());

    ANGLE_FEATURE_CONDITION(features, useTempForNonZeroBaseLevelGenMipmapUsingCopyImageSubData,
                            IsPowerVR(vendor));

    ANGLE_FEATURE_CONDITION(features, adjustSrcDstRegionForBlitFramebuffer,
                            IsLinux() || (IsAndroid() && (isNvidia || isMali)) ||
                                (IsWindows() && isNvidia) ||
                                (IsApple() && functions->standard == STANDARD_GL_ES));

    ANGLE_FEATURE_CONDITION(features, clipSrcRegionForBlitFramebuffer,
                            IsApple() || (IsLinux() && isAMD));

    ANGLE_FEATURE_CONDITION(features, RGBDXT1TexturesSampleZeroAlpha, IsApple());

    ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple());

    ANGLE_FEATURE_CONDITION(features, emulatePrimitiveRestartFixedIndex,
                            functions->standard == STANDARD_GL_DESKTOP &&
                                functions->isAtLeastGL(gl::Version(3, 1)) &&
                                !functions->isAtLeastGL(gl::Version(4, 3)));
    ANGLE_FEATURE_CONDITION(
        features, setPrimitiveRestartFixedIndexForDrawArrays,
        features->emulatePrimitiveRestartFixedIndex.enabled && IsApple() && isIntel);

    ANGLE_FEATURE_CONDITION(features, removeDynamicIndexingOfSwizzledVector,
                            IsApple() || IsAndroid() || IsWindows());

    // Ported from gpu_driver_bug_list.json (#184)
    ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, IsApple() && isIntel);

    // Workaround for the widespread OpenGL ES driver implementaion bug
    ANGLE_FEATURE_CONDITION(features, readPixelsUsingImplementationColorReadFormatForNorm16,
                            !isIntel && functions->standard == STANDARD_GL_ES &&
                                functions->isAtLeastGLES(gl::Version(3, 1)) &&
                                functions->hasGLESExtension("GL_EXT_texture_norm16"));

    // anglebug.com/40644715
    ANGLE_FEATURE_CONDITION(features, flushBeforeDeleteTextureIfCopiedTo, IsApple() && isIntel);

    // anglebug.com/40096480
    // Seems to affect both Intel and AMD GPUs. Enable workaround for all GPUs on macOS.
    ANGLE_FEATURE_CONDITION(features, rewriteRowMajorMatrices,
                            // IsApple() && functions->standard == STANDARD_GL_DESKTOP);
                            // TODO(anglebug.com/40096480): diagnose crashes with this workaround.
                            false);

    ANGLE_FEATURE_CONDITION(features, disableDrawBuffersIndexed, IsWindows() && isAMD);

    ANGLE_FEATURE_CONDITION(
        features, disableSemaphoreFd,
        IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));

    ANGLE_FEATURE_CONDITION(
        features, disableTimestampQueries,
        (IsLinux() && isVMWare) || (IsAndroid() && isNvidia) ||
            (IsAndroid() && GetAndroidSDKVersion() < 27 && IsAdreno5xxOrOlder(functions)) ||
            (!isMesa && IsMaliT8xxOrOlder(functions)) || (!isMesa && IsMaliG31OrOlder(functions)));

    ANGLE_FEATURE_CONDITION(features, decodeEncodeSRGBForGenerateMipmap, IsApple());

    // anglebug.com/42263273
    // The (redundant) explicit exclusion of Windows AMD is because the workaround fails
    // Texture2DRGTest.TextureRGUNormTest on that platform, and the test is skipped. If
    // you'd like to enable the workaround on Windows AMD, please fix the test first.
    ANGLE_FEATURE_CONDITION(
        features, emulateCopyTexImage2DFromRenderbuffers,
        IsApple() && functions->standard == STANDARD_GL_ES && !(isAMD && IsWindows()));

    // anglebug.com/40096747
    // Replace copyTexImage2D with texImage2D + copyTexSubImage2D to bypass driver bug.
    ANGLE_FEATURE_CONDITION(features, emulateCopyTexImage2D, isApple);

    // anglebug.com/486067696
    ANGLE_FEATURE_CONDITION(features, forceLumaWorkaroundForSameTextureCopyTexImage2D,
                            isHuaweiMaleoon && functions->isAtLeastGLES(gl::Version(3, 0)));

    // Don't attempt to use the discrete GPU on NVIDIA-based MacBook Pros, since the
    // driver is unstable in this situation.
    //
    // Note that this feature is only set here in order to advertise this workaround
    // externally. GPU switching support must be enabled or disabled early, during display
    // initialization, before these features are set up.
    bool isDualGPUMacWithNVIDIA = false;
    if (IsApple() && functions->standard == STANDARD_GL_DESKTOP)
    {
        if (isGetSystemInfoSuccess)
        {
            // The full system information must be queried to see whether it's a dual-GPU
            // NVIDIA MacBook Pro since it's likely that the integrated GPU will be active
            // when these features are initialized.
            isDualGPUMacWithNVIDIA = systemInfo.isMacSwitchable && systemInfo.hasNVIDIAGPU();
        }
    }
    ANGLE_FEATURE_CONDITION(features, disableGPUSwitchingSupport, isDualGPUMacWithNVIDIA);

    // Workaround issue in NVIDIA GL driver on Linux when TSAN is enabled
    // http://crbug.com/1094869
    bool isTSANBuild = false;
#ifdef THREAD_SANITIZER
    isTSANBuild = true;
#endif
    ANGLE_FEATURE_CONDITION(features, disableNativeParallelCompile,
                            isTSANBuild && IsLinux() && isNvidia);

    // anglebug.com/40096712
    ANGLE_FEATURE_CONDITION(features, emulatePackSkipRowsAndPackSkipPixels, IsApple());

    // http://crbug.com/1042393
    // XWayland defaults to a 1hz refresh rate when the "surface is not visible", which sometimes
    // causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
    // from the driver.
    ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsXWayland());

    ANGLE_FEATURE_CONDITION(features, bindTransformFeedbackBufferBeforeBindBufferRange, IsApple());

    // http://crbug.com/1137851
    // Speculative fix for above issue, users can enable it via flags.
    // http://crbug.com/1187475
    // Disable on Mesa 20 / Intel
    ANGLE_FEATURE_CONDITION(features, disableSyncControlSupport,
                            IsLinux() && isIntel && isMesa && mesaVersion[0] == 20);

    ANGLE_FEATURE_CONDITION(features, keepBufferShadowCopy, !CanMapBufferForRead(functions));

    ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple());

    ANGLE_FEATURE_CONDITION(features, promotePackedFormatsTo8BitPerChannel, IsApple() && hasAMD);

    // http://crbug.com/40166134
    // If output variable gl_FragColor is written by fragment shader, it may cause context lost with
    // Adreno 42x and 3xx.
    ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables, IsAdreno42xOr3xx(functions));

    // http://crbug.com/40155422
    // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
    // now.
    ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
                            IsApple() && IsIntel(vendor) && !IsHaswell(device));
    ANGLE_FEATURE_CONDITION(features, syncAllVertexArraysToDefault,
                            !nativegl::SupportsVertexArrayObjects(functions));

    // NVIDIA OpenGL ES emulated profile cannot handle client arrays
    ANGLE_FEATURE_CONDITION(features, syncDefaultVertexArraysToDefault,
                            nativegl::CanUseDefaultVertexArrayObject(functions) && !isNvidia);

    // http://crbug.com/1181193
    // On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
    // leaked via GL_RENDERER. We workaround this too improve user security.
    ANGLE_FEATURE_CONDITION(features, sanitizeAMDGPURendererString, IsLinux() && hasAMD);

    // http://crbug.com/1187513
    // http://anglebug.com/519646871
    // Several drivers are buggy with context switching. It needs to unbind fbo before context
    // switching to workadround the driver issues.
    ANGLE_FEATURE_CONDITION(features, unbindFBOBeforeSwitchingContext,
                            IsPowerVR(vendor) || (IsWindows() && isNvidia));

    // http://crbug.com/1181068 and http://crbug.com/783979
    ANGLE_FEATURE_CONDITION(features, flushOnFramebufferChange,
                            IsApple() && Has9thGenIntelGPU(systemInfo));

    // Disable GL_EXT_multisampled_render_to_texture on a bunch of different configurations:

    // http://crbug.com/490379
    // http://crbug.com/767913
    bool isAdreno4xxOnAndroidLessThan51 =
        IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() < 22;

    // http://crbug.com/612474
    bool isAdreno4xxOnAndroid70 =
        IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() == 24;
    bool isAdreno5xxOnAndroidLessThan70 =
        IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() < 24;

    // http://crbug.com/663811
    bool isAdreno5xxOnAndroid71 =
        IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() == 25;

    // http://crbug.com/594016
    bool isLinuxVivante = IsLinux() && IsVivante(device);

    // http://anglebug.com/42266736
    bool isWindowsNVIDIA = IsWindows() && IsNvidia(vendor);

    // Temporarily disable on all of Android. http://crbug.com/1417485
    ANGLE_FEATURE_CONDITION(features, disableMultisampledRenderToTexture,
                            isAdreno4xxOnAndroidLessThan51 || isAdreno4xxOnAndroid70 ||
                                isAdreno5xxOnAndroidLessThan70 || isAdreno5xxOnAndroid71 ||
                                isLinuxVivante || isWindowsNVIDIA);

    // http://crbug.com/1181068
    ANGLE_FEATURE_CONDITION(features, uploadTextureDataInChunks, IsApple());

    // https://crbug.com/1060012
    ANGLE_FEATURE_CONDITION(features, emulateImmutableCompressedTexture3D, isQualcomm);

    // https://crbug.com/1300575
    ANGLE_FEATURE_CONDITION(features, emulateRGB10, functions->standard == STANDARD_GL_DESKTOP);

    // https://anglebug.com/42264072
    ANGLE_FEATURE_CONDITION(features, alwaysUnbindFramebufferTexture2D,
                            isNvidia && (IsWindows() || IsLinux()));

    // https://anglebug.com/42265877
    ANGLE_FEATURE_CONDITION(features, disableTextureClampToBorder, false);

    // https://anglebug.com/42265995
    ANGLE_FEATURE_CONDITION(features, passHighpToPackUnormSnormBuiltins, isQualcomm);

    // https://anglebug.com/42266348
    ANGLE_FEATURE_CONDITION(features, emulateClipDistanceState, isQualcomm);

    // https://anglebug.com/42266817
    ANGLE_FEATURE_CONDITION(features, emulateClipOrigin,
                            !isMesa && isQualcomm && qualcommVersion < 490 &&
                                functions->hasGLESExtension("GL_EXT_clip_control"));

    // https://anglebug.com/42266740
    ANGLE_FEATURE_CONDITION(features, explicitFragmentLocations, isQualcomm);

    // Desktop GLSL-only fragment synchronization extensions. These are injected internally by the
    // compiler to make pixel local storage coherent.
    // https://anglebug.com/40096838
    ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockNV,
                            functions->isAtLeastGL(gl::Version(4, 3)) &&
                                functions->hasGLExtension("GL_NV_fragment_shader_interlock"));
    ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderOrderingINTEL,
                            functions->isAtLeastGL(gl::Version(4, 4)) &&
                                functions->hasGLExtension("GL_INTEL_fragment_shader_ordering"));
    ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockARB,
                            functions->isAtLeastGL(gl::Version(4, 5)) &&
                                functions->hasGLExtension("GL_ARB_fragment_shader_interlock"));

    ANGLE_FEATURE_CONDITION(features, multiviewViaViewportArray,
                            functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
                                functions->hasGLExtension("GL_NV_viewport_array2"));

    // EXT_shader_framebuffer_fetch
    ANGLE_FEATURE_CONDITION(features, supportsShaderFramebufferFetchEXT,
                            functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch"));

    // EXT_shader_framebuffer_fetch_non_coherent
    ANGLE_FEATURE_CONDITION(
        features, supportsShaderFramebufferFetchNonCoherentEXT,
        functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch_non_coherent"));

    // https://crbug.com/1356053
    ANGLE_FEATURE_CONDITION(features, bindCompleteFramebufferForTimerQueries, isMali);

    // http://crbug.com/534468209
    ANGLE_FEATURE_CONDITION(features, flushQueriesBeforeDeletingOrUnbindingFbo, isMali);

    // http://crbug.com/546252753
    ANGLE_FEATURE_CONDITION(features, finishBeforeBlitFramebufferMultiAttachment, isMali);

    // https://crbug.com/40264674
    ANGLE_FEATURE_CONDITION(features, disableClipControl, IsMaliG72OrG76OrG51(functions));

    // https://anglebug.com/42266811
    ANGLE_FEATURE_CONDITION(features, resyncDepthRangeOnClipControl, !isMesa && isQualcomm);

    // https://anglebug.com/42266745
    ANGLE_FEATURE_CONDITION(features, disableRenderSnorm,
                            isMesa && (mesaVersion < (std::array<int, 3>{21, 3, 0}) ||
                                       (mesaVersion < (std::array<int, 3>{23, 3, 0}) &&
                                        functions->standard == STANDARD_GL_ES)));

    // https://anglebug.com/42266748
    ANGLE_FEATURE_CONDITION(features, disableTextureMirrorClampToEdge,
                            functions->standard == STANDARD_GL_ES && isMesa &&
                                mesaVersion < (std::array<int, 3>{23, 1, 7}));

    // Mali bug: http://anglebug.com/42266610
    // Linux speculative bugs: http://crbug.com/427956856, http://anglebug.com/431097618
    ANGLE_FEATURE_CONDITION(features, disableBaseInstanceVertex,
                            IsMaliValhall(functions) || IsLinux());

    // Mali: http://crbug.com/40063287
    // Nvidia: http://crbug.com/328015191
    ANGLE_FEATURE_CONDITION(features, scalarizeVecAndMatConstructorArgs, isMali || isNvidia);

    // http://crbug.com/40066076
    ANGLE_FEATURE_CONDITION(features, ensureNonEmptyBufferIsBoundForDraw, IsApple() || IsAndroid());

    // https://anglebug.com/42266857
    ANGLE_FEATURE_CONDITION(features, preTransformTextureCubeGradDerivatives, isApple);

    // https://crbug.com/40279678
    ANGLE_FEATURE_CONDITION(features, useIntermediateTextureForGenerateMipmap,
                            IsPixel7OrPixel8(functions));

    // SRGB blending does not appear to work correctly on the Nexus 5 + other QC devices. Writing to
    // an SRGB framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same
    // value. Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
    ANGLE_FEATURE_CONDITION(features, srgbBlendingBroken, IsQualcomm(vendor));

    // BGRA formats do not appear to be accepted by the qualcomm driver despite the extension being
    // exposed.
    ANGLE_FEATURE_CONDITION(features, bgraTexImageFormatsBroken, !isMesa && isQualcomm);

    // https://crbug.com/520656244
    ANGLE_FEATURE_CONDITION(features, reattachFboDepthStencilOnReallocation,
                            !isMesa && isQualcomm && qualcommVersion < 878);

    // http://crbug.com/507508103
    ANGLE_FEATURE_CONDITION(features, dontInvalidateIncompleteFBOs,
                            !isMesa && isQualcomm && qualcommVersion < 881);

    // glGenerateMipmap may silently fail on mesa or mali. The failure mode is different on each
    // driver, but in both cases ensuring that the full mip chain is explicitly defined prior to
    // mipmap generation avoids the problem.
    ANGLE_FEATURE_CONDITION(features, recreateMipmapLevelsBeforeGenerate, isMesa || isMali);

    // https://github.com/flutter/flutter/issues/47164
    // https://github.com/flutter/flutter/issues/47804
    // Some devices expose the QCOM tiled memory extension string but don't actually provide the
    // start and end tiling functions.
    bool missingTilingEntryPoints = functions->hasGLESExtension("GL_QCOM_tiled_rendering") &&
                                    (!functions->startTilingQCOM || !functions->endTilingQCOM);

    // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
    ANGLE_FEATURE_CONDITION(features, disableTiledRendering,
                            missingTilingEntryPoints || IsAdreno3xx(functions));

    // Intel desktop GL drivers fail many Skia blend tests.
    // Block on older Qualcomm and ARM, following Skia's blocklists.
    ANGLE_FEATURE_CONDITION(
        features, disableBlendEquationAdvanced,
        (isIntel && IsWindows()) || IsAdreno4xx(functions) || IsAdreno5xx(functions) || isMali);

    // Adreno drivers cache some internal values based on glSampleCoverage and
    // number of samples in currently bound FBO and require to reset sample
    // coverage each time FBO changes.
    ANGLE_FEATURE_CONDITION(features, resetSampleCoverageOnFBOChange, isQualcomm);

    // Mali 400 series drivers fail linking shaders when passthrough shaders are enabled. Likely due
    // to not querying correct information from varyings and uniforms.
    ANGLE_FEATURE_CONDITION(features, disablePassthroughShaders, IsAdreno4xx(functions));

    // IMG GL drivers crash in glClearTexImage on various format/type combinations such as packed
    // types, LUMA and depth stencil.
    ANGLE_FEATURE_CONDITION(features, disableClearTexImageForRobustInit, IsPowerVR(vendor));

    // Disable EXT_clear_texture entirely on IMG as a speculative fix for driver crashes.
    ANGLE_FEATURE_CONDITION(features, disableClearTexture, IsPowerVR(vendor));

    // Forces a flush before generating a mipmap, which avoids bad states in the IMG driver.
    ANGLE_FEATURE_CONDITION(features, flushBeforeGenerateMipmap, IsPowerVR(vendor));

    // IMG GL drivers crash while compiling shaders with more than the limit of uniform blocks.
    ANGLE_FEATURE_CONDITION(features, validateMaxPerStageUniformBlocksAtCompileTime,
                            IsPowerVR(vendor));

    // Some drivers have compilation issues when shaders declare too many output varyings.
    // crbug.com/529991907
    ANGLE_FEATURE_CONDITION(features, limitOutputVaryingsTo256AtCompileTime, IsPowerVR(vendor));

    // crbug.com/529509587 -- IMG GLSL frontend OOB-writes during semantic analysis of a struct
    // constructor whose array-typed member receives a constant array-constructor argument with a
    // precision mismatch.  The workaround avoids all complex expressions, not just constant arrays
    // just in case.
    ANGLE_FEATURE_CONDITION(features, avoidComplexExpressionsInStructConstructor,
                            IsPowerVR(vendor));

    // http://crbug.com/499602793
    ANGLE_FEATURE_CONDITION(features, reattachTextureToFboAfterLayerIncrease,
                            IsPowerVR(vendor) && IsAndroid());

    // crbug.com/553172761
    ANGLE_FEATURE_CONDITION(features, useTexSubImageForClientDataNpotUploads,
                            false /* IsPowerVR(vendor) */);

    // Mac Intel drivers are unable to allocate buffers larger than ~1gb
    ANGLE_FEATURE_CONDITION(features, limitMaxBufferSizeTo1gb, isApple && isIntel);

    // Default to state validation disabled. It is extremely costly and should only be enabled
    // explicitly when debugging.
    ANGLE_FEATURE_CONDITION(features, validateState, false);
}

void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
{
    VendorID vendor = GetVendorID(functions);
    bool isQualcomm = IsQualcomm(vendor);
    bool isMali     = IsARM(vendor);

    std::array<int, 3> mesaVersion = {0, 0, 0};
    bool isMesa                    = IsMesa(functions, &mesaVersion);

    // Program binaries don't contain transform feedback varyings on multiple vendors' GPUs.
    // https://crbug.com/442879525 for the latest example on Imagination / PowerVR.
    ANGLE_FEATURE_CONDITION(features, disableProgramCachingForTransformFeedback,
                            (!isMesa && isQualcomm) || IsPowerVR(vendor) || isMali);
    // https://crbug.com/480992
    // Disable shader program cache to workaround PowerVR Rogue issues.
    ANGLE_FEATURE_CONDITION(features, disableProgramBinary, IsPowerVrRogue(functions));

    // The compile and link jobs need a context, and previous experiments showed setting up temp
    // contexts in threads for the sake of program link triggers too many driver bugs.  See
    // https://chromium-review.googlesource.com/c/angle/angle/+/4774785 for context.
    //
    // As a result, the compile and link jobs are done in the same thread as the call.  If the
    // native driver supports parallel compile/link, it's still done internally by the driver, and
    // ANGLE supports delaying post-compile and post-link operations until that is done.
    ANGLE_FEATURE_CONDITION(features, compileJobIsThreadSafe, false);
    ANGLE_FEATURE_CONDITION(features, linkJobIsThreadSafe, false);

    ANGLE_FEATURE_CONDITION(features, cacheCompiledShader, true);

    // GL_EXT_clip_cull_distance and GL_NV_shader_noperspective_interpolation are broken on QCOM
    // without ANGLE workarounds: the former does not allow built-in redeclarations outside of
    // interface blocks and the latter does not compile unless the shader version is at least 310
    // es.
    ANGLE_FEATURE_CONDITION(features, clipCullDistanceBrokenWithPassthroughShaders, isQualcomm);
    ANGLE_FEATURE_CONDITION(features, noperspectiveInterpolationBrokenWithPassthroughShaders,
                            isQualcomm);
    ANGLE_FEATURE_CONDITION(features, setNeedInitOnInvalidation, true);
}

void ReInitializeFeaturesAtGPUSwitch(const FunctionsGL *functions, angle::FeaturesGL *features)
{
    angle::VendorID vendor;
    angle::DeviceID device;
    angle::SystemInfo systemInfo;

    GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);

    // http://crbug.com/1144207
    // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
    // now.
    // We need to reinitialize this feature when switching between buggy and non-buggy GPUs.
    ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
                            IsApple() && IsIntel(vendor) && !IsHaswell(device));
}

}  // namespace nativegl_gl

namespace nativegl
{

bool SupportsVertexArrayObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_OES_vertex_array_object") ||
           functions->isAtLeastGL(gl::Version(3, 0)) ||
           functions->hasGLExtension("GL_ARB_vertex_array_object");
}
bool SupportsVertexAttributeBindings(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 3)) ||
           functions->isAtLeastGLES(gl::Version(3, 1)) ||
           functions->hasGLExtension("GL_ARB_vertex_attrib_binding");
}

bool SupportsTextureBufferObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 3)) ||
           functions->isAtLeastGLES(gl::Version(3, 2)) ||
           functions->hasGLESExtension("GL_OES_texture_buffer") ||
           functions->hasGLESExtension("GL_EXT_texture_buffer") ||
           functions->hasGLExtension("GL_ARB_texture_buffer_object");
}

bool SupportsPixelBufferObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(2, 1)) ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLExtension("GL_ARB_pixel_buffer_object") ||
           functions->hasGLExtension("GL_EXT_pixel_buffer_object") ||
           functions->hasGLESExtension("GL_NV_pixel_buffer_object");
}
bool SupportsSamplerObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->isAtLeastGL(gl::Version(3, 3)) ||
           functions->hasGLExtension("ARB_sampler_objects");
}

bool CanUseDefaultVertexArrayObject(const FunctionsGL *functions)
{
    return (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0;
}

bool CanUseClientSideArrays(const FunctionsGL *functions, GLuint vao)
{
    // Can use client arrays on GLES or GL compatability profile only on the default VAO
    return CanUseDefaultVertexArrayObject(functions) && vao == 0;
}

bool SupportsSettingCubemapSeamless(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 2));
}
bool SupportsLogicOp(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(2, 0));
}

bool SupportsProvokingVertex(const FunctionsGL *functions)
{
    return functions->hasGLExtension("GL_ARB_provoking_vertex") ||
           functions->hasGLExtension("GL_EXT_provoking_vertex") ||
           functions->isAtLeastGL(gl::Version(3, 2));
}

bool SupportsPrimitiveRestartFixedIndex(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGL(gl::Version(4, 3));
}

bool SupportsPrimitiveRestart(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 1));
}

bool SupportsCompute(const FunctionsGL *functions)
{
    // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
    // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
    // GL version to 4.2.
    return (functions->isAtLeastGL(gl::Version(4, 3)) ||
            functions->isAtLeastGLES(gl::Version(3, 1)) ||
            (functions->isAtLeastGL(gl::Version(4, 2)) &&
             functions->hasGLExtension("GL_ARB_compute_shader") &&
             functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")));
}
bool SupportsCubeMapArrayTextures(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 0)) ||
           functions->hasGLESExtension("GL_OES_texture_cube_map_array") ||
           functions->hasGLESExtension("GL_EXT_texture_cube_map_array") ||
           functions->hasGLExtension("GL_ARB_texture_cube_map_array") ||
           functions->isAtLeastGLES(gl::Version(3, 2));
}

bool SupportsRectangleTextures(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 1)) ||
           functions->hasGLExtension("GL_ARB_texture_rectangle");
}
bool SupportsExternalTextures(const FunctionsGL *functions)
{
    return functions->hasGLESExtension("GL_OES_EGL_image_external");
}

bool Supports3DTextures(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(1, 2)) ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_OES_texture_3D");
}
bool Supports2DArrayTextures(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGL(gl::Version(3, 0));
}

bool Supports2DMultisampleTextures(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 2)) ||
           functions->hasGLExtension("GL_ARB_texture_multisample") ||
           functions->isAtLeastGLES(gl::Version(3, 1));
}
bool Supports2DMultisampleArrayTextures(const FunctionsGL *functions)
{
    // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
    // if we emulated texStorage* API on top of texImage*.
    return functions->isAtLeastGL(gl::Version(4, 3)) ||
           functions->hasGLExtension("GL_ARB_texture_storage_multisample") ||
           functions->hasGLESExtension("GL_OES_texture_storage_multisample_2d_array");
}
bool SupportsOcclusionQueries(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(1, 5)) ||
           functions->hasGLExtension("GL_ARB_occlusion_query2") ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
}
bool SupportsTransformFeedback(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 0)) ||
           functions->hasGLExtension("GL_ARB_transform_feedback2") ||
           functions->isAtLeastGLES(gl::Version(3, 0));
}
bool SupportsUniformBufferObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 1)) ||
           functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
           functions->isAtLeastGLES(gl::Version(3, 0));
}
bool SupportsCopyReadWriteBufferObjects(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGL(gl::Version(4, 2));
}
bool SupportsDrawIndirect(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 1)) ||
           functions->isAtLeastGL(gl::Version(4, 0)) ||
           functions->hasGLExtension("GL_ARB_draw_indirect");
}
bool SupportsSeparateFramebufferBindings(const FunctionsGL *functions)
{
    // Note: GL 3.2 is required for desktop GL
    return functions->standard == STANDARD_GL_DESKTOP ||
           functions->isAtLeastGLES(gl::Version(3, 0));
}

bool SupportsUnpackSubImage(const FunctionsGL *functions)
{
    return functions->standard == STANDARD_GL_DESKTOP ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_EXT_unpack_subimage");
}

bool SupportsPackSubImage(const FunctionsGL *functions)
{
    return functions->standard == STANDARD_GL_DESKTOP ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_NV_pack_subimage");
}
bool Supports3DUnpackParameters(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGL(gl::Version(1, 2));
}

bool SupportsClipControl(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 5)) ||
           functions->hasGLExtension("GL_ARB_clip_control") ||
           functions->hasGLESExtension("GL_EXT_clip_control");
}

bool SupportsDrawBuffersIndexed(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(4, 0)) ||
           (functions->hasGLExtension("GL_EXT_draw_buffers2") &&
            functions->hasGLExtension("GL_ARB_draw_buffers_blend")) ||
           functions->isAtLeastGLES(gl::Version(3, 2)) ||
           functions->hasGLESExtension("GL_OES_draw_buffers_indexed") ||
           functions->hasGLESExtension("GL_EXT_draw_buffers_indexed");
}

bool SupportsBlendEquationAdvancedCoherent(const FunctionsGL *functions)
{
    return functions->hasGLExtension("GL_NV_blend_equation_advanced_coherent") ||
           functions->hasGLExtension("GL_KHR_blend_equation_advanced_coherent") ||
           functions->isAtLeastGLES(gl::Version(3, 2)) ||
           functions->hasGLESExtension("GL_KHR_blend_equation_advanced_coherent");
}

bool SupportsPolygonMode(const FunctionsGL *functions)
{
    if (functions->standard == STANDARD_GL_DESKTOP)
    {
        return true;
    }

    if (functions->hasGLESExtension("GL_NV_polygon_mode"))
    {
        // Some GLES drivers expose the extension string without supporting its caps.
        // Try the extension-specific state query to check support.
        ANGLE_GL_CLEAR_ERRORS(functions);
        functions->isEnabled(GL_POLYGON_OFFSET_LINE_NV);
        if (functions->getError() == GL_NO_ERROR)
        {
            return true;
        }
        WARN() << "Not enabling GL_NV_polygon_mode because "
                  "its native driver support is incomplete.";
    }

    return false;
}

bool SupportsPolygonOffsetClamp(const FunctionsGL *functions)
{
    return functions->hasExtension("GL_EXT_polygon_offset_clamp");
}

bool SupportsDepthClamp(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 2)) ||
           functions->hasGLExtension("GL_ARB_depth_clamp") ||
           functions->hasGLESExtension("GL_EXT_depth_clamp");
}

bool SupportsSRGBWriteControl(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 0)) ||
           functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
           functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
           functions->hasGLESExtension("GL_EXT_sRGB_write_control");
}

bool SupportsMultisampleComatibility(const FunctionsGL *functions)
{
    // the EXT_multisample_compatibility is written against ES3.1 but can apply
    // to earlier versions so therefore we're only checking for the extension string
    // and not the specific GLES version.
    return functions->isAtLeastGL(gl::Version(1, 3)) ||
           functions->hasGLESExtension("GL_EXT_multisample_compatibility");
}

bool SupportsShaderIOBlocks(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 2)) ||
           functions->isAtLeastGLES(gl::Version(3, 2)) ||
           functions->hasGLESExtension("GL_OES_shader_io_blocks") ||
           functions->hasGLESExtension("GL_EXT_shader_io_blocks");
}

bool SupportsClipCullDistance(const FunctionsGL *functions)
{
    // GL_EXT_clip_cull_distance spec requires shader interface blocks to support
    // built-in array redeclarations on OpenGL ES.
    return functions->isAtLeastGL(gl::Version(4, 5)) ||
           (functions->isAtLeastGL(gl::Version(3, 0)) &&
            functions->hasGLExtension("GL_ARB_cull_distance")) ||
           (SupportsShaderIOBlocks(functions) &&
            functions->hasGLESExtension("GL_EXT_clip_cull_distance"));
}

bool SupportsSampleMask(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 2)) ||
           functions->isAtLeastGLES(gl::Version(3, 1)) ||
           functions->hasGLExtension("GL_ARB_texture_multisample");
}

bool SupportsRasterizerDiscard(const FunctionsGL *functions)
{
    return functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGL(gl::Version(3, 0));
}

bool SupportsInstancing(const FunctionsGL *functions)
{
    return functions->isAtLeastGL(gl::Version(3, 1)) ||
           (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
            (functions->hasGLExtension("GL_ARB_draw_instanced") ||
             functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
           functions->isAtLeastGLES(gl::Version(3, 0)) ||
           functions->hasGLESExtension("GL_EXT_instanced_arrays");
}

bool SupportsNativeRendering(const FunctionsGL *functions,
                             gl::TextureType type,
                             GLenum internalFormat)
{
    // Some desktop drivers allow rendering to formats that are not required by the spec, this is
    // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
    bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
                                  functions->hasGLExtension("GL_ARB_internalformat_query2");

    // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
    // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
    // render to the format.  Skip any native queries for compressed formats.
    const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);

    if (hasInternalFormatQuery && !internalFormatInfo.compressed)
    {
        GLint framebufferRenderable = GL_NONE;
        functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
                                       &framebufferRenderable);
        return framebufferRenderable != GL_NONE;
    }
    else
    {
        const nativegl::InternalFormat &nativeInfo =
            nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
        return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
    }
}

bool SupportsTexImage(gl::TextureType type)
{
    switch (type)
    {
            // Multi-sample texture types only support TexStorage data upload
        case gl::TextureType::_2DMultisample:
        case gl::TextureType::_2DMultisampleArray:
            return false;

        default:
            return true;
    }
}

bool UseTexImage2D(gl::TextureType textureType)
{
    return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
           textureType == gl::TextureType::Rectangle ||
           textureType == gl::TextureType::_2DMultisample ||
           textureType == gl::TextureType::External;
}

bool UseTexImage3D(gl::TextureType textureType)
{
    return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
           textureType == gl::TextureType::_2DMultisampleArray ||
           textureType == gl::TextureType::CubeMapArray;
}

bool SupportsTextureType(const FunctionsGL *functions, gl::TextureType type)
{
    switch (type)
    {
        case gl::TextureType::_2D:
            return true;
        case gl::TextureType::_2DArray:
            return Supports2DArrayTextures(functions);
        case gl::TextureType::_2DMultisample:
            return Supports2DMultisampleTextures(functions);
        case gl::TextureType::_2DMultisampleArray:
            return Supports2DMultisampleArrayTextures(functions);
        case gl::TextureType::_3D:
            return nativegl::Supports3DTextures(functions);
        case gl::TextureType::External:
            return nativegl::SupportsExternalTextures(functions);
        case gl::TextureType::Rectangle:
            return nativegl::SupportsRectangleTextures(functions);
        case gl::TextureType::CubeMap:
            return true;
        case gl::TextureType::CubeMapArray:
            return nativegl::SupportsCubeMapArrayTextures(functions);
        case gl::TextureType::Buffer:
            return nativegl::SupportsTextureBufferObjects(functions);
        default:
            UNREACHABLE();
            return false;
    }
}

GLenum GetTextureBindingQuery(gl::TextureType textureType)
{
    switch (textureType)
    {
        case gl::TextureType::_2D:
            return GL_TEXTURE_BINDING_2D;
        case gl::TextureType::_2DArray:
            return GL_TEXTURE_BINDING_2D_ARRAY;
        case gl::TextureType::_2DMultisample:
            return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
        case gl::TextureType::_2DMultisampleArray:
            return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
        case gl::TextureType::_3D:
            return GL_TEXTURE_BINDING_3D;
        case gl::TextureType::External:
            return GL_TEXTURE_BINDING_EXTERNAL_OES;
        case gl::TextureType::Rectangle:
            return GL_TEXTURE_BINDING_RECTANGLE;
        case gl::TextureType::CubeMap:
            return GL_TEXTURE_BINDING_CUBE_MAP;
        case gl::TextureType::CubeMapArray:
            return GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES;
        case gl::TextureType::Buffer:
            return GL_TEXTURE_BINDING_BUFFER;
        default:
            UNREACHABLE();
            return 0;
    }
}

GLenum GetTextureBindingTarget(gl::TextureType textureType)
{
    return ToGLenum(textureType);
}

GLenum GetTextureBindingTarget(gl::TextureTarget textureTarget)
{
    return ToGLenum(textureTarget);
}

bool SupportsBufferBinding(const FunctionsGL *functions, gl::BufferBinding type)
{
    switch (type)
    {
        case gl::BufferBinding::Array:
            return true;
        case gl::BufferBinding::AtomicCounter:
            return SupportsCompute(functions);
        case gl::BufferBinding::CopyRead:
            return SupportsCopyReadWriteBufferObjects(functions);
        case gl::BufferBinding::CopyWrite:
            return SupportsCopyReadWriteBufferObjects(functions);
        case gl::BufferBinding::DispatchIndirect:
            return SupportsCompute(functions);
        case gl::BufferBinding::DrawIndirect:
            return SupportsDrawIndirect(functions);
        case gl::BufferBinding::ElementArray:
            return true;
        case gl::BufferBinding::PixelPack:
            return SupportsPixelBufferObjects(functions);
        case gl::BufferBinding::PixelUnpack:
            return SupportsPixelBufferObjects(functions);
        case gl::BufferBinding::ShaderStorage:
            return SupportsCompute(functions);
        case gl::BufferBinding::TransformFeedback:
            return SupportsTransformFeedback(functions);
        case gl::BufferBinding::Uniform:
            return SupportsUniformBufferObjects(functions);
        case gl::BufferBinding::Texture:
            return SupportsTextureBufferObjects(functions);
        default:
            UNREACHABLE();
            return 0;
    }
}

BufferBindingQuery GetBufferBindingQuery(gl::BufferBinding bufferBinding)
{
    BufferBindingQuery query;
    switch (bufferBinding)
    {
        case gl::BufferBinding::Array:
            query.bindingQuery = GL_ARRAY_BUFFER_BINDING;
            break;
        case gl::BufferBinding::AtomicCounter:
            query.bindingQuery = GL_ATOMIC_COUNTER_BUFFER_BINDING;
            query.startQuery   = GL_ATOMIC_COUNTER_BUFFER_START;
            query.sizeQuery    = GL_ATOMIC_COUNTER_BUFFER_SIZE;
            break;
        case gl::BufferBinding::CopyRead:
            query.bindingQuery = GL_COPY_READ_BUFFER_BINDING;
            break;
        case gl::BufferBinding::CopyWrite:
            query.bindingQuery = GL_COPY_WRITE_BUFFER_BINDING;
            break;
        case gl::BufferBinding::DispatchIndirect:
            query.bindingQuery = GL_DISPATCH_INDIRECT_BUFFER_BINDING;
            break;
        case gl::BufferBinding::DrawIndirect:
            query.bindingQuery = GL_DRAW_INDIRECT_BUFFER_BINDING;
            break;
        case gl::BufferBinding::ElementArray:
            query.bindingQuery = GL_ELEMENT_ARRAY_BUFFER_BINDING;
            break;
        case gl::BufferBinding::PixelPack:
            query.bindingQuery = GL_PIXEL_PACK_BUFFER_BINDING;
            break;
        case gl::BufferBinding::PixelUnpack:
            query.bindingQuery = GL_PIXEL_UNPACK_BUFFER_BINDING;
            break;
        case gl::BufferBinding::ShaderStorage:
            query.bindingQuery = GL_SHADER_STORAGE_BUFFER_BINDING;
            query.startQuery   = GL_SHADER_STORAGE_BUFFER_START;
            query.sizeQuery    = GL_SHADER_STORAGE_BUFFER_SIZE;
            break;
        case gl::BufferBinding::TransformFeedback:
            query.bindingQuery = GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
            query.startQuery   = GL_TRANSFORM_FEEDBACK_BUFFER_START;
            query.sizeQuery    = GL_TRANSFORM_FEEDBACK_BUFFER_SIZE;
            break;
        case gl::BufferBinding::Uniform:
            query.bindingQuery = GL_UNIFORM_BUFFER_BINDING;
            query.startQuery   = GL_UNIFORM_BUFFER_START;
            query.sizeQuery    = GL_UNIFORM_BUFFER_SIZE;
            break;
        case gl::BufferBinding::Texture:
            query.bindingQuery = GL_TEXTURE_BUFFER_BINDING;
            break;
        default:
            UNREACHABLE();
            break;
    }

    return query;
}

GLenum GetBufferBindingStartQuery(gl::BufferBinding bufferBinding)
{
    switch (bufferBinding)
    {
        case gl::BufferBinding::Array:
            return GL_ARRAY_BUFFER_BINDING;
        case gl::BufferBinding::AtomicCounter:
            return GL_ATOMIC_COUNTER_BUFFER_BINDING;
        case gl::BufferBinding::CopyRead:
            return GL_COPY_READ_BUFFER_BINDING;
        case gl::BufferBinding::CopyWrite:
            return GL_COPY_WRITE_BUFFER_BINDING;
        case gl::BufferBinding::DispatchIndirect:
            return GL_DISPATCH_INDIRECT_BUFFER_BINDING;
        case gl::BufferBinding::DrawIndirect:
            return GL_DRAW_INDIRECT_BUFFER_BINDING;
        case gl::BufferBinding::ElementArray:
            return GL_ELEMENT_ARRAY_BUFFER_BINDING;
        case gl::BufferBinding::PixelPack:
            return GL_PIXEL_PACK_BUFFER_BINDING;
        case gl::BufferBinding::PixelUnpack:
            return GL_PIXEL_UNPACK_BUFFER_BINDING;
        case gl::BufferBinding::ShaderStorage:
            return GL_SHADER_STORAGE_BUFFER_BINDING;
        case gl::BufferBinding::TransformFeedback:
            return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
        case gl::BufferBinding::Uniform:
            return GL_UNIFORM_BUFFER_BINDING;
        case gl::BufferBinding::Texture:
            return GL_TEXTURE_BUFFER_BINDING;
        default:
            UNREACHABLE();
            return 0;
    }
}

std::string GetBufferBindingString(gl::BufferBinding bufferBinding)
{
    std::ostringstream os;
    os << bufferBinding << "_BINDING";
    return os.str();
}

}  // namespace nativegl

const FunctionsGL *GetFunctionsGL(const gl::Context *context)
{
    return GetImplAs<ContextGL>(context)->getFunctions();
}

StateManagerGL *GetStateManagerGL(const gl::Context *context)
{
    return GetImplAs<ContextGL>(context)->getStateManager();
}

BlitGL *GetBlitGL(const gl::Context *context)
{
    return GetImplAs<ContextGL>(context)->getBlitter();
}

ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
{
    return GetImplAs<ContextGL>(context)->getMultiviewClearer();
}

const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
{
    return GetImplAs<ContextGL>(context)->getFeaturesGL();
}

angle::FixedVector<uint8_t, 16> GetDepthOnePixel(GLenum type)
{
    angle::FixedVector<uint8_t, 16> result;
    switch (type)
    {
        case GL_UNSIGNED_SHORT:
        {
            uint16_t val = 0xFFFF;
            result.resize(2);
            ANGLE_UNSAFE_TODO(memcpy(result.data(), &val, 2));
            break;
        }
        case GL_UNSIGNED_INT:
        {
            uint32_t val = 0xFFFFFFFF;
            result.resize(4);
            ANGLE_UNSAFE_TODO(memcpy(result.data(), &val, 4));
            break;
        }
        case GL_FLOAT:
        {
            float val = 1.0f;
            result.resize(4);
            ANGLE_UNSAFE_TODO(memcpy(result.data(), &val, 4));
            break;
        }
        case GL_UNSIGNED_INT_24_8:
        {
            uint32_t val = 0xFFFFFF00;
            result.resize(4);
            ANGLE_UNSAFE_TODO(memcpy(result.data(), &val, 4));
            break;
        }
        case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
        {
            float d    = 1.0f;
            uint32_t s = 0;
            result.resize(8);
            ANGLE_UNSAFE_TODO(memcpy(result.data(), &d, 4));
            ANGLE_UNSAFE_TODO(memcpy(result.data() + 4, &s, 4));
            break;
        }
        default:
            UNREACHABLE();
            break;
    }
    return result;
}

void FillDepthOneMemory(GLenum type, angle::Span<uint8_t> span)
{
    angle::FixedVector<uint8_t, 16> pixelData = GetDepthOnePixel(type);
    CHECK(span.size() % pixelData.size() == 0);
    for (size_t offset = 0; offset < span.size(); offset += pixelData.size())
    {
        ANGLE_UNSAFE_TODO(memcpy(span.data() + offset, pixelData.data(), pixelData.size()));
    }
}

void ClearErrors(const FunctionsGL *functions,
                 const char *file,
                 const char *function,
                 unsigned int line)
{
    GLenum error = functions->getError();
    while (error != GL_NO_ERROR)
    {
        INFO() << "Preexisting GL error " << gl::FmtHex(error) << " as of " << file << ", "
               << function << ":" << line << ". ";

        // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
        // infinite loop.
        if (error == GL_CONTEXT_LOST)
        {
            return;
        }

        error = functions->getError();
    }
}

void ClearErrors(const gl::Context *context,
                 const char *file,
                 const char *function,
                 unsigned int line)
{
    const FunctionsGL *functions = GetFunctionsGL(context);
    ClearErrors(functions, file, function, line);
}

angle::Result CheckError(const gl::Context *context,
                         const char *call,
                         const char *file,
                         const char *function,
                         unsigned int line)
{
    return HandleError(context, GetFunctionsGL(context)->getError(), call, file, function, line);
}

angle::Result HandleError(const gl::Context *context,
                          GLenum error,
                          const char *call,
                          const char *file,
                          const char *function,
                          unsigned int line)
{
    const FunctionsGL *functions = GetFunctionsGL(context);
    if (ANGLE_UNLIKELY(error != GL_NO_ERROR))
    {
        ContextGL *contextGL = GetImplAs<ContextGL>(context);
        contextGL->handleError(error, "Unexpected driver error.", file, function, line);
        ERR() << "GL call " << call << " generated error " << gl::FmtHex(error) << " in " << file
              << ", " << function << ":" << line << ". ";

        // Check that only one GL error was generated, ClearErrors should have been called first.
        // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
        // infinite loop.
        GLenum nextError = functions->getError();
        while (nextError != GL_NO_ERROR && nextError != GL_CONTEXT_LOST)
        {
            ERR() << "Additional GL error " << gl::FmtHex(nextError) << " generated.";
            nextError = functions->getError();
        }

        return angle::Result::Stop;
    }

    return angle::Result::Continue;
}

bool CanMapBufferForRead(const FunctionsGL *functions)
{
    return (functions->mapBufferRange != nullptr) ||
           (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
}

uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
                                    GLenum target,
                                    size_t offset,
                                    size_t length,
                                    GLbitfield access)
{
    if (functions->mapBufferRange != nullptr)
    {
        return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
    }
    else if (functions->mapBuffer != nullptr &&
             (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
    {
        // Only the read and write bits are supported
        ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);

        GLenum accessEnum = 0;
        if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
        {
            accessEnum = GL_READ_WRITE;
        }
        else if (access == GL_MAP_READ_BIT)
        {
            accessEnum = GL_READ_ONLY;
        }
        else if (access == GL_MAP_WRITE_BIT)
        {
            accessEnum = GL_WRITE_ONLY;
        }
        else
        {
            UNREACHABLE();
            return nullptr;
        }

        return ANGLE_UNSAFE_TODO(static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) +
                                 offset);
    }
    else
    {
        // No options available
        UNREACHABLE();
        return nullptr;
    }
}

angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
                                                  const gl::Extents &size,
                                                  const gl::PixelStoreStateBase &state,
                                                  const gl::Buffer *pixelBuffer,
                                                  GLenum format,
                                                  GLenum type,
                                                  bool is3D,
                                                  const void *pixels,
                                                  bool *shouldApplyOut)
{
    if (pixelBuffer == nullptr)
    {
        *shouldApplyOut = false;
        return angle::Result::Continue;
    }

    // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
    // last byte read or written. If it is past the end of the buffer, we will need to use the
    // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.

    const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
    GLuint endByte                     = 0;
    ANGLE_CHECK_GL_MATH(contextGL,
                        glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
    GLuint rowPitch = 0;
    ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
                                                            state.rowLength, &rowPitch));

    CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
    CheckedNumeric<size_t> checkedEndByte =
        angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);

    // At this point checkedEndByte is the actual last byte read.
    // The driver adds an extra row padding (if any), mimic it.
    ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
    if (static_cast<size_t>(checkedPixelBytes.ValueOrDie()) * size.width < rowPitch)
    {
        checkedEndByte += rowPitch - checkedPixelBytes * size.width;
    }

    ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());

    *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
    return angle::Result::Continue;
}

std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
{
    using Type                         = ContextCreationTry::Type;
    constexpr EGLint kPlatformOpenGL   = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
    constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;

    std::vector<ContextCreationTry> contextsToTry;

    if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
    {
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
        contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));

        // On Mesa, do not try to create OpenGL context versions between 3.0 and
        // 3.2 because of compatibility problems. See crbug.com/659030
        //
        // The GL backend requires at least GL 3.2, so do not attempt to create
        // any older contexts even in legacy profile.
        if (!isMesaGLX)
        {
            contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
        }
    }

    if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
        requestedType == kPlatformOpenGLES)
    {
        contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
        contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
        contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
        contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
    }

    return contextsToTry;
}

std::string GetRendererString(const FunctionsGL *functions)
{
    return GetString(functions, GL_RENDERER);
}

std::string GetVendorString(const FunctionsGL *functions)
{
    return GetString(functions, GL_VENDOR);
}

std::string GetVersionString(const FunctionsGL *functions)
{
    return GetString(functions, GL_VERSION);
}

}  // namespace rx
