/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "include/core/SkMatrix.h"
#include "include/core/SkString.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkStringUtils.h"
#include "src/gpu/ganesh/GrDataUtils.h"
#include "src/gpu/ganesh/gl/GrGLUtil.h"
#include <stdio.h>

using namespace skia_private;

///////////////////////////////////////////////////////////////////////////////

#if GR_GL_LOG_CALLS
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
#endif

#if GR_GL_CHECK_ERROR
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
#endif

///////////////////////////////////////////////////////////////////////////////

GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
    if (!versionString) {
        SkDebugf("nullptr GL version string.");
        return kNone_GrGLStandard;
    }

    int major, minor;

    // check for desktop
    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return kGL_GrGLStandard;
    }

    // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
    int esMajor, esMinor;
    n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
    if (4 == n) {
        return kWebGL_GrGLStandard;
    }

    // check for ES 1
    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
    if (4 == n) {
        // we no longer support ES1.
        return kNone_GrGLStandard;
    }

    // check for ES2
    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return kGLES_GrGLStandard;
    }
    return kNone_GrGLStandard;
}

GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    if (!versionString) {
        SkDebugf("nullptr GL version string.");
        return GR_GL_INVALID_VER;
    }

    int major, minor;

    // check for mesa
    int mesaMajor, mesaMinor;
    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
    int esMajor, esMinor;
    n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile + 1, &major, &minor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    return GR_GL_INVALID_VER;
}

GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    SkASSERT(gl);
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    return GrGLGetVersionFromString((const char*)v);
}

static GrGLSLVersion get_glsl_version(const char* versionString) {
    SkASSERT(versionString);
    int major, minor;

    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

#ifdef SK_BUILD_FOR_ANDROID
    // android hack until the gpu vender updates their drivers
    n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }
#endif

    return GR_GLSL_INVALID_VER;
}

static GrGLVendor get_vendor(const char* vendorString) {
    SkASSERT(vendorString);
    if (0 == strcmp(vendorString, "ARM")) {
        return GrGLVendor::kARM;
    }
    if (0 == strcmp(vendorString, "Google Inc.")) {
        return GrGLVendor::kGoogle;
    }
    if (0 == strcmp(vendorString, "Imagination Technologies")) {
        return GrGLVendor::kImagination;
    }
    if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
        return GrGLVendor::kIntel;
    }
    if (0 == strcmp(vendorString, "Qualcomm") || 0 == strcmp(vendorString, "freedreno")) {
        return GrGLVendor::kQualcomm;
    }
    if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
        return GrGLVendor::kNVIDIA;
    }
    if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
        return GrGLVendor::kATI;
    }
    return GrGLVendor::kOther;
}

static GrGLRenderer get_renderer(const char* rendererString, const GrGLExtensions& extensions) {
    SkASSERT(rendererString);
    static const char kTegraStr[] = "NVIDIA Tegra";
    if (0 == strncmp(rendererString, kTegraStr, std::size(kTegraStr) - 1)) {
        // Tegra strings are not very descriptive. We distinguish between the modern and legacy
        // architectures by the presence of NV_path_rendering.
        return extensions.has("GL_NV_path_rendering") ? GrGLRenderer::kTegra
                                                      : GrGLRenderer::kTegra_PreK1;
    }
    int lastDigit;
    int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
    if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
        return GrGLRenderer::kPowerVR54x;
    }
    if (strstr(rendererString, "PowerVR B-Series")) {
        return GrGLRenderer::kPowerVRBSeries;
    }
    // certain iOS devices also use PowerVR54x GPUs
    static const char kAppleA4Str[] = "Apple A4";
    static const char kAppleA5Str[] = "Apple A5";
    static const char kAppleA6Str[] = "Apple A6";
    if (0 == strncmp(rendererString, kAppleA4Str, std::size(kAppleA4Str) - 1) ||
        0 == strncmp(rendererString, kAppleA5Str, std::size(kAppleA5Str) - 1) ||
        0 == strncmp(rendererString, kAppleA6Str, std::size(kAppleA6Str) - 1)) {
        return GrGLRenderer::kPowerVR54x;
    }
    static const char kPowerVRRogueStr[] = "PowerVR Rogue";
    static const char kAppleA7Str[] = "Apple A7";
    static const char kAppleA8Str[] = "Apple A8";
    if (0 == strncmp(rendererString, kPowerVRRogueStr, std::size(kPowerVRRogueStr) - 1) ||
        0 == strncmp(rendererString, kAppleA7Str, std::size(kAppleA7Str) - 1) ||
        0 == strncmp(rendererString, kAppleA8Str, std::size(kAppleA8Str) - 1)) {
        return GrGLRenderer::kPowerVRRogue;
    }
    int adrenoNumber;
    n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
    if (n < 1) {
        // retry with freedreno driver
        n = sscanf(rendererString, "FD%d", &adrenoNumber);
    }
    if (1 == n) {
        if (adrenoNumber >= 300) {
            if (adrenoNumber < 400) {
                return GrGLRenderer::kAdreno3xx;
            }
            if (adrenoNumber < 500) {
                return adrenoNumber >= 430 ? GrGLRenderer::kAdreno430
                                           : GrGLRenderer::kAdreno4xx_other;
            }
            if (adrenoNumber < 600) {
                return adrenoNumber == 530 ? GrGLRenderer::kAdreno530
                                           : GrGLRenderer::kAdreno5xx_other;
            }
            if (adrenoNumber < 700) {
                if (adrenoNumber == 615) {
                    return GrGLRenderer::kAdreno615;
                }
                if (adrenoNumber == 620) {
                    return GrGLRenderer::kAdreno620;
                }
                if (adrenoNumber == 630) {
                    return GrGLRenderer::kAdreno630;
                }
                if (adrenoNumber == 640) {
                    return GrGLRenderer::kAdreno640;
                }
                return GrGLRenderer::kAdreno6xx_other;
            }
        }
    }

    if (const char* intelString = strstr(rendererString, "Intel")) {
        // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
        if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
            0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
            return GrGLRenderer::kIntelHaswell;
        }
        if (strstr(intelString, "Sandybridge")) {
            return GrGLRenderer::kIntelSandyBridge;
        }
        if (strstr(intelString, "Bay Trail")) {
            return GrGLRenderer::kIntelValleyView;
        }
        // In Mesa, 'RKL' can be followed by 'Graphics', same for 'TGL' and 'ADL'.
        // Referenced from the following Mesa source code:
        // https://github.com/mesa3d/mesa/blob/master/include/pci_ids/iris_pci_ids.h
        if (strstr(intelString, "RKL")) {
            return GrGLRenderer::kIntelRocketLake;
        }
        if (strstr(intelString, "TGL")) {
            return GrGLRenderer::kIntelTigerLake;
        }
        // For Windows on ADL-S devices, 'AlderLake-S' might be followed by 'Intel(R)'.
        if (strstr(intelString, "ADL") || strstr(intelString, "AlderLake")) {
            return GrGLRenderer::kIntelAlderLake;
        }
        // For Windows on TGL or other ADL devices, we might only get 'Xe' from the string.
        // Since they are both 12th gen, we could temporarily use 'kIntelTigerLake' to cover
        // both TGL and ADL.
        if (strstr(intelString, "Xe")) {
            return GrGLRenderer::kIntelTigerLake;
        }
        // There are many possible intervening strings here:
        // 'Intel(R)' is a common prefix
        // 'Iris' may appear, followed by '(R)' or '(TM)'
        // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
        // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
        //
        // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
        // so just skip to that and handle two cases:
        if (const char* intelGfxString = strstr(intelString, "Graphics")) {
            int intelNumber;
            if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
                sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
                if (intelNumber == 2000 || intelNumber == 3000) {
                    return GrGLRenderer::kIntelSandyBridge;
                }
                if (intelNumber == 2500 || intelNumber == 4000) {
                    return GrGLRenderer::kIntelIvyBridge;
                }
                if (intelNumber >= 4200 && intelNumber <= 5200) {
                    return GrGLRenderer::kIntelHaswell;
                }
                if (intelNumber >= 400 && intelNumber <= 405) {
                    return GrGLRenderer::kIntelCherryView;
                }
                if (intelNumber >= 5300 && intelNumber <= 6300) {
                    return GrGLRenderer::kIntelBroadwell;
                }
                if (intelNumber >= 500 && intelNumber <= 505) {
                    return GrGLRenderer::kIntelApolloLake;
                }
                if (intelNumber >= 510 && intelNumber <= 580) {
                    return GrGLRenderer::kIntelSkyLake;
                }
                if (intelNumber >= 600 && intelNumber <= 605) {
                    return GrGLRenderer::kIntelGeminiLake;
                }
                // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
                // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
                if (intelNumber == 610 || intelNumber == 630) {
                    return strstr(intelString, "UHD") ? GrGLRenderer::kIntelCoffeeLake
                                                      : GrGLRenderer::kIntelKabyLake;
                }
                if (intelNumber >= 610 && intelNumber <= 650) {
                    return GrGLRenderer::kIntelKabyLake;
                }
                if (intelNumber == 655) {
                    return GrGLRenderer::kIntelCoffeeLake;
                }
                // 710/730/750/770 are all 12th gen UHD Graphics, but it's hard to distinguish
                // among RKL, TGL and ADL. We might temporarily use 'kIntelTigerLake' to cover all.
                if (intelNumber >= 710 && intelNumber <= 770) {
                    return GrGLRenderer::kIntelTigerLake;
                }
                if (intelNumber >= 910 && intelNumber <= 950) {
                    return GrGLRenderer::kIntelIceLake;
                }
            }
        }
    }

    // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
    static constexpr char kRadeonStr[] = "Radeon ";
    if (const char* amdString = strstr(rendererString, kRadeonStr)) {
        amdString += strlen(kRadeonStr);
        // Sometimes there is a (TM) and sometimes not.
        static constexpr char kTMStr[] = "(TM) ";
        if (!strncmp(amdString, kTMStr, strlen(kTMStr))) {
            amdString += strlen(kTMStr);
        }

        char amd0, amd1, amd2;
        int amdModel;
        n = sscanf(amdString, "R9 M3%c%c", &amd0, &amd1);
        if (2 == n && isdigit(amd0) && isdigit(amd1)) {
            return GrGLRenderer::kAMDRadeonR9M3xx;
        }

        n = sscanf(amdString, "R9 M4%c%c", &amd0, &amd1);
        if (2 == n && isdigit(amd0) && isdigit(amd1)) {
            return GrGLRenderer::kAMDRadeonR9M4xx;
        }

        n = sscanf(amdString, "HD 7%c%c%c Series", &amd0, &amd1, &amd2);
        if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
            return GrGLRenderer::kAMDRadeonHD7xxx;
        }

        n = sscanf(amdString, "Pro 5%c%c%c", &amd0, &amd1, &amd2);
        if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
            return GrGLRenderer::kAMDRadeonPro5xxx;
        }

        n = sscanf(amdString, "Pro Vega %i", &amdModel);
        if (1 == n) {
            return GrGLRenderer::kAMDRadeonProVegaxx;
        }
    }

    if (strstr(rendererString, "llvmpipe")) {
        return GrGLRenderer::kGalliumLLVM;
    }
    static const char kMaliGStr[] = "Mali-G";
    if (0 == strncmp(rendererString, kMaliGStr, std::size(kMaliGStr) - 1)) {
        return GrGLRenderer::kMaliG;
    }
    static const char kMaliTStr[] = "Mali-T";
    if (0 == strncmp(rendererString, kMaliTStr, std::size(kMaliTStr) - 1)) {
        return GrGLRenderer::kMaliT;
    }
    int mali400Num;
    if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
        mali400Num < 500) {
        return GrGLRenderer::kMali4xx;
    }

    if (strstr(rendererString, "WebGL")) {
        return GrGLRenderer::kWebGL;
    }

    return GrGLRenderer::kOther;
}

static bool is_commamd_buffer(const char* rendererString, const char* versionString) {
    SkASSERT(rendererString);
    SkASSERT(versionString);

    int major, minor;
    static const char kChromium[] = "Chromium";
    char suffix[std::size(kChromium)] = {0};
    return (0 == strcmp(rendererString, kChromium) ||
           (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
            0 == strcmp(kChromium, suffix)));
}

static bool is_virgl(const char* rendererString) {
    return !!strstr(rendererString, "virgl");
}

static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStandard standard,
                                                                        GrGLVendor vendor,
                                                                        const char* vendorString,
                                                                        const char* rendererString,
                                                                        const char* versionString) {
    SkASSERT(rendererString);
    SkASSERT(versionString);

    GrGLDriver driver               = GrGLDriver::kUnknown;
    GrGLDriverVersion driverVersion = GR_GL_DRIVER_UNKNOWN_VER;

    int major, minor, rev, driverMajor, driverMinor, driverPoint;
    // This is the same on ES and regular GL.
    if (!strcmp(vendorString, "freedreno")) {
        driver = GrGLDriver::kFreedreno;
    } else if (GR_IS_GR_GL(standard)) {
        if (vendor == GrGLVendor::kNVIDIA) {
            driver = GrGLDriver::kNVIDIA;
            int n = sscanf(versionString,
                           "%d.%d.%d NVIDIA %d.%d",
                           &major,
                           &minor,
                           &rev,
                           &driverMajor,
                           &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (n == 5) {
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else {
            int n = sscanf(versionString,
                           "%d.%d Mesa %d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor);
            if (n != 4) {
                n = sscanf(versionString,
                           "%d.%d (Core Profile) Mesa %d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor);
            }
            if (n == 4) {
                driver = GrGLDriver::kMesa;
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        }
    } else if (standard == kGLES_GrGLStandard) {
        if (vendor == GrGLVendor::kNVIDIA) {
            driver = GrGLDriver::kNVIDIA;
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d NVIDIA %d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (n == 4) {
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else if (vendor == GrGLVendor::kImagination) {
            int revision;
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d build %d.%d@%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor,
                           &revision);
            if (n == 5) {
                driver = GrGLDriver::kImagination;
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else {
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d Mesa %d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor);
            if (n == 4) {
                driver = GrGLDriver::kMesa;
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        }
    }

    if (driver == GrGLDriver::kUnknown) {
        if (vendor == GrGLVendor::kIntel) {
            // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
            driver = GrGLDriver::kIntel;

            // This is how the macOS version strings are structured. This might be different on
            // different
            //  OSes.
            int n = sscanf(versionString,
                           "%d.%d INTEL-%d.%d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor,
                           &driverPoint);
            if (n == 5) {
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
            }
        } else if (vendor == GrGLVendor::kQualcomm) {
            driver = GrGLDriver::kQualcomm;
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d V@%d.%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor);
            if (n == 4) {
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else if (vendor == GrGLVendor::kImagination) {
            int revision;
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d build %d.%d@%d",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor,
                           &revision);
            if (n == 5) {
                // Revision is a large number (looks like a source control revision number) that
                // doesn't fit into the 'patch' bits, so omit it until we need it.
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else if (vendor == GrGLVendor::kARM) {
            // Example:
            // OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3
            // It's unclear how to interpret what comes between "p" and "rel". Every string we've
            // seen so far has "0-01" there. We ignore it for now.
            int ignored0;
            int ignored1;
            int n = sscanf(versionString,
                           "OpenGL ES %d.%d v%d.r%dp%d-%drel",
                           &major,
                           &minor,
                           &driverMajor,
                           &driverMinor,
                           &ignored0,
                           &ignored1);
            if (n == 6) {
                driver = GrGLDriver::kARM;
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
        } else {
            static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
            if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
                driver = GrGLDriver::kAndroidEmulator;
            }
        }
    }
    return {driver, driverVersion};
}

// If this is detected as ANGLE then the ANGLE backend is returned along with rendererString
// stripped of "ANGLE(" and ")" at the start and end, respectively.
static std::tuple<GrGLANGLEBackend, SkString> get_angle_backend(const char* rendererString) {
    // crbug.com/1203705 ANGLE renderer will be "ANGLE (<gl-vendor>, <gl-renderer>, <gl-version>)"
    // on ANGLE's GL backend with related substitutions for the inner strings on other backends.
    static constexpr char kHeader[] = "ANGLE (";
    static constexpr size_t kHeaderLength = std::size(kHeader) - 1;
    int rendererLength = strlen(rendererString);
    if (!strncmp(rendererString, kHeader, kHeaderLength) &&
        rendererString[rendererLength - 1] == ')') {
        SkString innerString;
        innerString.set(rendererString + kHeaderLength, rendererLength - kHeaderLength - 1);
        if (strstr(rendererString, "Direct3D11")) {
            return {GrGLANGLEBackend::kD3D11, std::move(innerString)};
        } else if (strstr(rendererString, "Direct3D9")) {
            return {GrGLANGLEBackend::kD3D9, std::move(innerString)};
        } else if (strstr(rendererString, "Metal")) {
            return {GrGLANGLEBackend::kMetal, std::move(innerString)};
        } else if (strstr(rendererString, "OpenGL")) {
            return {GrGLANGLEBackend::kOpenGL, std::move(innerString)};
        }
    }
    return {GrGLANGLEBackend::kUnknown, {}};
}

static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
get_angle_gl_vendor_and_renderer(
        const char* innerString,
        const GrGLExtensions& extensions) {
    TArray<SkString> parts;
    SkStrSplit(innerString, ",", &parts);
    // This would need some fixing if we have substrings that contain commas.
    if (parts.size() != 3) {
        return {GrGLVendor::kOther,
                GrGLRenderer::kOther,
                GrGLDriver::kUnknown,
                GR_GL_DRIVER_UNKNOWN_VER};
    }

    const char* angleVendorString   = parts[0].c_str();
    const char* angleRendererString = parts[1].c_str() + 1; // skip initial space
    const char* angleVersionString  = parts[2].c_str() + 1; // skip initial space

    GrGLVendor angleVendor = get_vendor(angleVendorString);

    auto [angleDriver, angleDriverVersion] = get_driver_and_version(kGLES_GrGLStandard,
                                                                    angleVendor,
                                                                    angleVendorString,
                                                                    angleRendererString,
                                                                    angleVersionString);

    auto angleRenderer = get_renderer(angleRendererString, extensions);

    return {angleVendor, angleRenderer, angleDriver, angleDriverVersion};
}

static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
get_angle_d3d_vendor_and_renderer(const char* innerString) {
    auto vendor   = GrGLVendor::kOther;
    auto renderer = GrGLRenderer::kOther;

    if (strstr(innerString, "Intel")) {
        vendor = GrGLVendor::kIntel;

        const char* modelStr;
        int modelNumber;
        if ((modelStr = strstr(innerString, "HD Graphics")) &&
            (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
             1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
            switch (modelNumber) {
                case 2000:
                case 3000:
                    renderer = GrGLRenderer::kIntelSandyBridge;
                    break;
                case 4000:
                case 2500:
                    renderer = GrGLRenderer::kIntelSandyBridge;
                    break;
                case 510:
                case 515:
                case 520:
                case 530:
                    renderer = GrGLRenderer::kIntelSkyLake;
                    break;
            }
        } else if ((modelStr = strstr(innerString, "Iris")) &&
                   (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
                    1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
                    1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
            switch (modelNumber) {
                case 540:
                case 550:
                case 555:
                case 580:
                    renderer = GrGLRenderer::kIntelSkyLake;
                    break;
            }
        }
    } else if (strstr(innerString, "NVIDIA")) {
        vendor = GrGLVendor::kNVIDIA;
    } else if (strstr(innerString, "Radeon")) {
        vendor = GrGLVendor::kATI;
    }
    // We haven't had a need yet to parse the D3D driver string.
    return {vendor, renderer, GrGLDriver::kUnknown, GR_GL_DRIVER_UNKNOWN_VER};
}

static std::tuple<GrGLVendor, GrGLRenderer>
get_webgl_vendor_and_renderer(
        const GrGLInterface* interface) {
    if (!interface->fExtensions.has("WEBGL_debug_renderer_info")) {
        return {GrGLVendor::kOther,
                GrGLRenderer::kOther};
    }

    auto getString = [&](GrGLenum s) {
        const GrGLubyte* bytes = interface->fFunctions.fGetString(s);
        if (!bytes) {
            return "";
        }
        return reinterpret_cast<const char*>(bytes);
    };

    const char* webglVendorString = getString(GR_UNMASKED_VENDOR_WEBGL);
    const char* webglRendererString = getString(GR_UNMASKED_RENDERER_WEBGL);

    GrGLVendor webglVendor = get_vendor(webglVendorString);
    GrGLRenderer webglRenderer = get_renderer(webglRendererString, interface->fExtensions);

    return {webglVendor, webglRenderer};
}

GrGLDriverInfo GrGLGetDriverInfo(const GrGLInterface* interface) {
    if (!interface) {
        return {};
    }
    SkASSERT(interface->fStandard != kNone_GrGLStandard);
    GrGLDriverInfo info;
    info.fStandard = interface->fStandard;

    auto getString = [&](GrGLenum s) {
        const GrGLubyte* bytes = interface->fFunctions.fGetString(s);
        if (!bytes) {
            return "";
        }
        return reinterpret_cast<const char*>(bytes);
    };

    const char* const version   = getString(GR_GL_VERSION);
    const char* const slversion = getString(GR_GL_SHADING_LANGUAGE_VERSION);
    const char* const renderer  = getString(GR_GL_RENDERER);
    const char* const vendor    = getString(GR_GL_VENDOR);

    info.fVersion     = GrGLGetVersionFromString(version);
    info.fGLSLVersion = get_glsl_version(slversion);
    info.fVendor      = get_vendor(vendor);
    info.fRenderer    = get_renderer(renderer, interface->fExtensions);

    std::tie(info.fDriver, info.fDriverVersion) = get_driver_and_version(interface->fStandard,
                                                                         info.fVendor,
                                                                         vendor,
                                                                         renderer,
                                                                         version);

    SkString innerAngleRendererString;
    std::tie(info.fANGLEBackend, innerAngleRendererString) = get_angle_backend(renderer);

    if (info.fANGLEBackend == GrGLANGLEBackend::kD3D9 ||
        info.fANGLEBackend == GrGLANGLEBackend::kD3D11) {
        std::tie(info.fANGLEVendor,
                 info.fANGLERenderer,
                 info.fANGLEDriver,
                 info.fANGLEDriverVersion) =
                get_angle_d3d_vendor_and_renderer(innerAngleRendererString.c_str());
    } else if (info.fANGLEBackend == GrGLANGLEBackend::kOpenGL) {
        std::tie(info.fANGLEVendor,
                 info.fANGLERenderer,
                 info.fANGLEDriver,
                 info.fANGLEDriverVersion) =
                get_angle_gl_vendor_and_renderer(innerAngleRendererString.c_str(),
                                                 interface->fExtensions);
    }

    if (info.fRenderer == GrGLRenderer::kWebGL) {
        std::tie(info.fWebGLVendor,
                 info.fWebGLRenderer) =
                get_webgl_vendor_and_renderer(interface);

    }

    info.fIsOverCommandBuffer = is_commamd_buffer(renderer, version);

    info.fIsRunningOverVirgl = is_virgl(renderer);

    return info;
}

GrGLenum GrToGLStencilFunc(GrStencilTest test) {
    static const GrGLenum gTable[kGrStencilTestCount] = {
        GR_GL_ALWAYS,           // kAlways
        GR_GL_NEVER,            // kNever
        GR_GL_GREATER,          // kGreater
        GR_GL_GEQUAL,           // kGEqual
        GR_GL_LESS,             // kLess
        GR_GL_LEQUAL,           // kLEqual
        GR_GL_EQUAL,            // kEqual
        GR_GL_NOTEQUAL,         // kNotEqual
    };
    static_assert(0 == (int)GrStencilTest::kAlways);
    static_assert(1 == (int)GrStencilTest::kNever);
    static_assert(2 == (int)GrStencilTest::kGreater);
    static_assert(3 == (int)GrStencilTest::kGEqual);
    static_assert(4 == (int)GrStencilTest::kLess);
    static_assert(5 == (int)GrStencilTest::kLEqual);
    static_assert(6 == (int)GrStencilTest::kEqual);
    static_assert(7 == (int)GrStencilTest::kNotEqual);
    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);

    return gTable[(int)test];
}

bool GrGLFormatIsCompressed(GrGLFormat format) {
    switch (format) {
        case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
        case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
        case GrGLFormat::kCOMPRESSED_RGB8_BC1:
        case GrGLFormat::kCOMPRESSED_RGBA8_BC1:
            return true;

        case GrGLFormat::kRGBA8:
        case GrGLFormat::kR8:
        case GrGLFormat::kALPHA8:
        case GrGLFormat::kLUMINANCE8:
        case GrGLFormat::kLUMINANCE8_ALPHA8:
        case GrGLFormat::kBGRA8:
        case GrGLFormat::kRGB565:
        case GrGLFormat::kRGBA16F:
        case GrGLFormat::kR16F:
        case GrGLFormat::kLUMINANCE16F:
        case GrGLFormat::kRGB8:
        case GrGLFormat::kRGBX8:
        case GrGLFormat::kRG8:
        case GrGLFormat::kRGB10_A2:
        case GrGLFormat::kRGBA4:
        case GrGLFormat::kSRGB8_ALPHA8:
        case GrGLFormat::kR16:
        case GrGLFormat::kRG16:
        case GrGLFormat::kRGBA16:
        case GrGLFormat::kRG16F:
        case GrGLFormat::kSTENCIL_INDEX8:
        case GrGLFormat::kSTENCIL_INDEX16:
        case GrGLFormat::kDEPTH24_STENCIL8:
        case GrGLFormat::kUnknown:
            return false;
    }
    SkUNREACHABLE;
}
