blob: 3f6766387afa6f317969f61568fd44518bdfced3 [file] [log] [blame]
/*
* 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"
///////////////////////////////////////////////////////////////////////////////
#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
///////////////////////////////////////////////////////////////////////////////
#if defined(STARBOARD)
#include "starboard/common/string.h"
#include "starboard/configuration.h"
#define sscanf SbStringScanF
#else
#include <stdio.h>
#endif
#if defined(STARBOARD)
#include "starboard/egl.h"
#define EGLint SbEglInt32
#define EGLBoolean SbEglBoolean
#define EGL_CONTEXT_CLIENT_TYPE SB_EGL_CONTEXT_CLIENT_TYPE
#define EGL_OPENGL_ES_API SB_EGL_OPENGL_ES_API
#define EGL_CONTEXT_CLIENT_VERSION SB_EGL_CONTEXT_CLIENT_VERSION
#define EGL_CALL_PREFIX ::SkiaGetEglInterface().
#else // !defined(STARBOARD)
#include <EGL/egl.h>
#define EGL_CALL_PREFIX
#endif // defined(STARBOARD)
#define EGL_CALL_SIMPLE(x) (EGL_CALL_PREFIX x)
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";
}
#if defined(STARBOARD)
const SbEglInterface& SkiaGetEglInterface() {
static const SbEglInterface* egl_interface = SbGetEglInterface();
return *egl_interface;
}
#endif // defined(STARBOARD)
} // namespace
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");
}
}
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;
}
static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
*outDriver = kAndroidEmulator_GrGLDriver;
}
}
GrGLVersion GrGLGetVersionFromString(const char* versionString) {
if (nullptr == versionString) {
SkDebugf("nullptr GL version string.");
return GR_GL_INVALID_VER;
}
#if defined(STARBOARD) && !defined(GLES3_SUPPORTED)
// If we are in a build that does not support GLES3 (or it is explicitly
// disabled), ensure that Skia returns GLES2 as the version being used by
// performing the check before attempting to parse the string below.
if (strstr(versionString, "OpenGL ES")) {
return GR_GL_VER(2, 0);
}
#endif
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);
}
#if defined(STARBOARD)
// Use API calls to find out the version for OpenGL ES
// over using string parsing to determine the correct version.
//
// This is useful when a OpenGL 2.0 context is requested and received, but
// the version string still shows version 3.0
if (strstr(versionString, "OpenGL ES")) {
EGLint client_type = -1;
EGLBoolean success = false;
do {
success = EGL_CALL_SIMPLE(eglQueryContext(EGL_CALL_SIMPLE(eglGetCurrentDisplay()),
EGL_CALL_SIMPLE(eglGetCurrentContext()),
EGL_CONTEXT_CLIENT_TYPE, &client_type));
if (!success || (client_type != EGL_OPENGL_ES_API)) {
break;
}
EGLint client_version = -1;
success = EGL_CALL_SIMPLE(eglQueryContext(EGL_CALL_SIMPLE(eglGetCurrentDisplay()),
EGL_CALL_SIMPLE(eglGetCurrentContext()),
EGL_CONTEXT_CLIENT_VERSION,
&client_version));
if (!success) {
break;
}
#if defined(COBALT)
if (strstr(versionString, "Mesa")) {
// Some Mesa implementations, e.g. OpenGL ES 3.0 Mesa 11.2.0,
// will claim GL version 3.0, but do not adhere to the spec.
// E.g. it still requires internal and external formats for
// 2D textures to be the same.
client_version = SkTMin(client_version, 2);
}
#endif
return GR_GL_VER(client_version, 0);
} while (0);
}
#endif // defined(STARBOARD)
// 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 (strstr(rendererString, "llvmpipe")) {
return kGalliumLLVM_GrGLRenderer;
}
if (strstr(rendererString, "llvmpipe") || strstr(rendererString, "Gallium ")) {
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(GrGLFormat format) {
switch (format) {
case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
return true;
case GrGLFormat::kRGBA8:
case GrGLFormat::kR8:
case GrGLFormat::kALPHA8:
case GrGLFormat::kLUMINANCE8:
case GrGLFormat::kBGRA8:
case GrGLFormat::kRGB565:
case GrGLFormat::kRGBA16F:
case GrGLFormat::kR16F:
case GrGLFormat::kLUMINANCE16F:
case GrGLFormat::kRGB8:
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::kUnknown:
return false;
}
SkUNREACHABLE;
}
bool GrGLFormatToCompressionType(GrGLFormat format, SkImage::CompressionType* compressionType) {
switch (format) {
case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
*compressionType = SkImage::kETC1_CompressionType;
return true;
case GrGLFormat::kRGBA8:
case GrGLFormat::kR8:
case GrGLFormat::kALPHA8:
case GrGLFormat::kLUMINANCE8:
case GrGLFormat::kBGRA8:
case GrGLFormat::kRGB565:
case GrGLFormat::kRGBA16F:
case GrGLFormat::kR16F:
case GrGLFormat::kLUMINANCE16F:
case GrGLFormat::kRGB8:
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::kUnknown:
return false;
}
SkUNREACHABLE;
}