/*
 * 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/private/GrTypesPriv.h"
#include "src/gpu/GrDataUtils.h"
#include "src/gpu/gl/GrGLUtil.h"
#include <stdio.h>

void GrGLClearErr(const GrGLInterface* gl) {
    while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
}

namespace {
const char *get_error_string(uint32_t err) {
    switch (err) {
    case GR_GL_NO_ERROR:
        return "";
    case GR_GL_INVALID_ENUM:
        return "Invalid Enum";
    case GR_GL_INVALID_VALUE:
        return "Invalid Value";
    case GR_GL_INVALID_OPERATION:
        return "Invalid Operation";
    case GR_GL_OUT_OF_MEMORY:
        return "Out of Memory";
    case GR_GL_CONTEXT_LOST:
        return "Context Lost";
    }
    return "Unknown";
}
}

void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
        if (location) {
            SkDebugf(" at\n\t%s", location);
        }
        if (call) {
            SkDebugf("\n\t\t%s", call);
        }
        SkDebugf("\n");
    }
}

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

#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 (nullptr == 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;
}

void GrGLGetDriverInfo(GrGLStandard standard,
                       GrGLVendor vendor,
                       const char* rendererString,
                       const char* versionString,
                       GrGLDriver* outDriver,
                       GrGLDriverVersion* outVersion) {
    int major, minor, rev, driverMajor, driverMinor, driverPoint;

    *outDriver = kUnknown_GrGLDriver;
    *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
    // These null checks are for test GL contexts that return nullptr in their
    // glGetString implementation.
    if (!rendererString) {
        rendererString = "";
    }
    if (!versionString) {
        versionString = "";
    }

    static const char kChromium[] = "Chromium";
    char suffix[SK_ARRAY_COUNT(kChromium)];
    if (0 == strcmp(rendererString, kChromium) ||
        (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
         0 == strcmp(kChromium, suffix))) {
        *outDriver = kChromium_GrGLDriver;
        return;
    }

    if (GR_IS_GR_GL(standard)) {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            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 (5 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
            return;
        }
        int n = sscanf(versionString, "%d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 != n) {
            n = sscanf(versionString, "%d.%d (Core Profile) Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        }
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            return;
        }
    } else if (GR_IS_GR_GL_ES(standard)) {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            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 (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
            return;
        }

        int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            return;
        }
        if (0 == strncmp("ANGLE", rendererString, 5)) {
            *outDriver = kANGLE_GrGLDriver;
            n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
                                                                      &driverMinor);
            if (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
            }
            return;
        }
    }

    if (kGoogle_GrGLVendor == vendor) {
        // Swiftshader is the only Google vendor at the moment
        *outDriver = kSwiftShader_GrGLDriver;

        // Swiftshader has a strange version string: w.x.y.z  Going to arbitrarily ignore
        // y and assume w,x and z are major, minor, point.
        // As of writing, version is 4.0.0.6
        int n = sscanf(versionString, "OpenGL ES %d.%d SwiftShader %d.%d.0.%d", &major, &minor,
                       &driverMajor, &driverMinor, &driverPoint);
        if (5 == n) {
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
        }
        return;
    }

    if (kIntel_GrGLVendor == vendor) {
        // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
        *outDriver = kIntel_GrGLDriver;

        //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 (5 == n) {
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
        }
    }

    if (kQualcomm_GrGLVendor == vendor) {
        *outDriver = kQualcomm_GrGLDriver;
        int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
                       &driverMinor);
        if (4 == n) {
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
        }
        return;
    }
}

GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    if (nullptr == 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;
}

GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GLSL version string.");
        return GR_GLSL_INVALID_VER;
    }

    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;
}

GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    if (vendorString) {
        if (0 == strcmp(vendorString, "ARM")) {
            return kARM_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Google Inc.")) {
            return kGoogle_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Imagination Technologies")) {
            return kImagination_GrGLVendor;
        }
        if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
            return kIntel_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Qualcomm")) {
            return kQualcomm_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
            return kNVIDIA_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
            return kATI_GrGLVendor;
        }
    }
    return kOther_GrGLVendor;
}

static bool is_renderer_angle(const char* rendererString) {
    static constexpr char kHeader[] = "ANGLE ";
    static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
    return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
}

GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
                                        const GrGLExtensions& extensions) {
    if (rendererString) {
        static const char kTegraStr[] = "NVIDIA Tegra";
        if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(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") ? kTegra_GrGLRenderer
                                                          : kTegra_PreK1_GrGLRenderer;
        }
        int lastDigit;
        int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
        if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
            return kPowerVR54x_GrGLRenderer;
        }
        // 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,
                         SK_ARRAY_COUNT(kAppleA4Str)-1) ||
            0 == strncmp(rendererString, kAppleA5Str,
                         SK_ARRAY_COUNT(kAppleA5Str)-1) ||
            0 == strncmp(rendererString, kAppleA6Str,
                         SK_ARRAY_COUNT(kAppleA6Str)-1)) {
            return kPowerVR54x_GrGLRenderer;
        }
        static const char kPowerVRRogueStr[] = "PowerVR Rogue";
        static const char kAppleA7Str[] = "Apple A7";
        static const char kAppleA8Str[] = "Apple A8";
        if (0 == strncmp(rendererString, kPowerVRRogueStr,
                         SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
            0 == strncmp(rendererString, kAppleA7Str,
                         SK_ARRAY_COUNT(kAppleA7Str)-1) ||
            0 == strncmp(rendererString, kAppleA8Str,
                         SK_ARRAY_COUNT(kAppleA8Str)-1)) {
            return kPowerVRRogue_GrGLRenderer;
        }
        int adrenoNumber;
        n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
        if (1 == n) {
            if (adrenoNumber >= 300) {
                if (adrenoNumber < 400) {
                    return kAdreno3xx_GrGLRenderer;
                }
                if (adrenoNumber < 500) {
                    return adrenoNumber >= 430
                            ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
                }
                if (adrenoNumber < 600) {
                    return kAdreno5xx_GrGLRenderer;
                }
            }
        }
        if (0 == strcmp("Google SwiftShader", rendererString)) {
            return kGoogleSwiftShader_GrGLRenderer;
        }

        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 kIntelHaswell_GrGLRenderer;
            }
            if (strstr(intelString, "Sandybridge")) {
                return kIntelSandyBridge_GrGLRenderer;
            }
            if (strstr(intelString, "Bay Trail")) {
                return kIntelValleyView_GrGLRenderer;
            }
            // 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 kIntelSandyBridge_GrGLRenderer;
                    }
                    if (intelNumber == 2500 || intelNumber == 4000) {
                        return kIntelIvyBridge_GrGLRenderer;
                    }
                    if (intelNumber >= 4200 && intelNumber <= 5200) {
                        return kIntelHaswell_GrGLRenderer;
                    }
                    if (intelNumber >= 400 && intelNumber <= 405) {
                        return kIntelCherryView_GrGLRenderer;
                    }
                    if (intelNumber >= 5300 && intelNumber <= 6300) {
                        return kIntelBroadwell_GrGLRenderer;
                    }
                    if (intelNumber >= 500 && intelNumber <= 505) {
                        return kIntelApolloLake_GrGLRenderer;
                    }
                    if (intelNumber >= 510 && intelNumber <= 580) {
                        return kIntelSkyLake_GrGLRenderer;
                    }
                    if (intelNumber >= 600 && intelNumber <= 605) {
                        return kIntelGeminiLake_GrGLRenderer;
                    }
                    // 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") ? kIntelCoffeeLake_GrGLRenderer
                                                          : kIntelKabyLake_GrGLRenderer;
                    }
                    if (intelNumber >= 610 && intelNumber <= 650) {
                        return kIntelKabyLake_GrGLRenderer;
                    }
                    if (intelNumber == 655) {
                        return kIntelCoffeeLake_GrGLRenderer;
                    }
                    if (intelNumber >= 910 && intelNumber <= 950) {
                        return kIntelIceLake_GrGLRenderer;
                    }
                }
            }
        }

        // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
        if (const char* amdString = strstr(rendererString, "Radeon")) {
            char amdGeneration, amdTier, amdRevision;
            n = sscanf(amdString, "Radeon (TM) R9 M%c%c%c",
                                       &amdGeneration, &amdTier, &amdRevision);
            if (3 == n) {
                if ('4' == amdGeneration) {
                    return kAMDRadeonR9M4xx_GrGLRenderer;
                }
            }

            char amd0, amd1, amd2;
            n = sscanf(amdString, "Radeon HD 7%c%c%c Series", &amd0, &amd1, &amd2);
            if (3 == n) {
                return kAMDRadeonHD7xxx_GrGLRenderer;
            }
        }

        if (0 == strcmp("Mesa Offscreen", rendererString)) {
            return kOSMesa_GrGLRenderer;
        }
        if (strstr(rendererString, "llvmpipe")) {
            return kGalliumLLVM_GrGLRenderer;
        }
        static const char kMaliTStr[] = "Mali-T";
        if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
            return kMaliT_GrGLRenderer;
        }
        int mali400Num;
        if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
            mali400Num < 500) {
            return kMali4xx_GrGLRenderer;
        }
        if (is_renderer_angle(rendererString)) {
            return kANGLE_GrGLRenderer;
        }
    }
    return kOther_GrGLRenderer;
}

void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend* backend,
                                GrGLANGLEVendor* vendor, GrGLANGLERenderer* renderer) {
    *backend = GrGLANGLEBackend::kUnknown;
    *vendor = GrGLANGLEVendor::kUnknown;
    *renderer = GrGLANGLERenderer::kUnknown;
    if (!is_renderer_angle(rendererString)) {
        return;
    }
    if (strstr(rendererString, "Intel")) {
        *vendor = GrGLANGLEVendor::kIntel;

        const char* modelStr;
        int modelNumber;
        if ((modelStr = strstr(rendererString, "HD Graphics")) &&
            (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
             1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
            switch (modelNumber) {
                case 2000:
                case 3000:
                    *renderer = GrGLANGLERenderer::kSandyBridge;
                    break;
                case 4000:
                case 2500:
                    *renderer = GrGLANGLERenderer::kIvyBridge;
                    break;
                case 510:
                case 515:
                case 520:
                case 530:
                    *renderer = GrGLANGLERenderer::kSkylake;
                    break;
            }
        } else if ((modelStr = strstr(rendererString, "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 = GrGLANGLERenderer::kSkylake;
                    break;
            }
        }
    }
    if (strstr(rendererString, "Direct3D11")) {
        *backend = GrGLANGLEBackend::kD3D11;
    } else if (strstr(rendererString, "Direct3D9")) {
        *backend = GrGLANGLEBackend::kD3D9;
    } else if (strstr(rendererString, "OpenGL")) {
        *backend = GrGLANGLEBackend::kOpenGL;
    }
}

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

GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    return GrGLGetGLSLVersionFromString((const char*) v);
}

GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    return GrGLGetVendorFromString((const char*) v);
}

GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    const GrGLubyte* rendererString;
    GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));

    return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
}

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
    };
    GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
    GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
    GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
    GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
    GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
    GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
    GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
    GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);

    return gTable[(int)test];
}

bool GrGLFormatIsCompressed(GrGLenum glFormat) {
    switch (glFormat) {
        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
        case GR_GL_COMPRESSED_ETC1_RGB8:
            return true;
        default:
            return false;
    }
    SK_ABORT("Invalid format");
    return false;
}

GrCompression GrGLFormat2Compression(GrGLenum glFormat) {
    switch (glFormat) {
        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
        case GR_GL_COMPRESSED_ETC1_RGB8:
            return GrCompression::kETC1;
        default:
            return GrCompression::kNone;
    }
    SK_ABORT("Invalid format");
    return GrCompression::kNone;
}

size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height) {
    SkASSERT(GrGLFormatIsCompressed(glFormat));

    switch (glFormat) {
        case GR_GL_COMPRESSED_RGB8_ETC2:  // fall through
        case GR_GL_COMPRESSED_ETC1_RGB8:
            return GrETC1CompressedDataSize(width, height);
        default:
            SK_ABORT("Unknown compressed format");
            return 4 * width * height;
    }

    SK_ABORT("Unknown compressed format");
    return 4 * width * height;
}

size_t GrGLBytesPerFormat(GrGLenum glFormat) {
    switch (glFormat) {
        case GR_GL_LUMINANCE8:
        case GR_GL_ALPHA8:
        case GR_GL_R8:
            return 1;

        case GR_GL_RGB565:
        case GR_GL_RGBA4:
        case GR_GL_RG8:
        case GR_GL_R16F:
        case GR_GL_R16:
            return 2;

        case GR_GL_RGB8:
            return 3;

        case GR_GL_RGBA8:
        case GR_GL_SRGB8_ALPHA8:
        case GR_GL_BGRA8:
        case GR_GL_RGB10_A2:
        case GR_GL_RG16:
            return 4;

        case GR_GL_RGBA16F:
        case GR_GL_RG32F:
            return 8;

        case GR_GL_RGBA32F:
            return 16;

        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
        case GR_GL_COMPRESSED_ETC1_RGB8:
            return 0;

        // Experimental (for Y416 and mutant P016/P010)
        case GR_GL_RG16F:
            return 4;
        case GR_GL_RGBA16:
            return 8;
    }

    SK_ABORT("Invalid GL format");
    return 0;
}

bool GrGLFormatIsSupported(GrGLenum format) {
    switch (format) {
        case GR_GL_LUMINANCE8:
        case GR_GL_ALPHA8:
        case GR_GL_R8:
        case GR_GL_RGB565:
        case GR_GL_RGBA4:
        case GR_GL_RG8:
        case GR_GL_R16F:
        case GR_GL_R16:
        case GR_GL_RGB8:
        case GR_GL_RGBA8:
        case GR_GL_SRGB8_ALPHA8:
        case GR_GL_BGRA8:
        case GR_GL_RGB10_A2:
        case GR_GL_RG16:
        case GR_GL_RGBA16F:
        case GR_GL_RG32F:
        case GR_GL_RGBA32F:
        case GR_GL_COMPRESSED_RGB8_ETC2:
        case GR_GL_COMPRESSED_ETC1_RGB8:
        // Experimental (for Y416 and mutant P016/P010)
        case GR_GL_RG16F:
        case GR_GL_RGBA16:
            return true;
        default:
            return false;
    }
}
