1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9#include "GrGLUtil.h" 10#include "GrTypesPriv.h" 11#include "SkMatrix.h" 12#include <stdio.h> 13 14void GrGLClearErr(const GrGLInterface* gl) { 15 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {} 16} 17 18namespace { 19const char *get_error_string(uint32_t err) { 20 switch (err) { 21 case GR_GL_NO_ERROR: 22 return ""; 23 case GR_GL_INVALID_ENUM: 24 return "Invalid Enum"; 25 case GR_GL_INVALID_VALUE: 26 return "Invalid Value"; 27 case GR_GL_INVALID_OPERATION: 28 return "Invalid Operation"; 29 case GR_GL_OUT_OF_MEMORY: 30 return "Out of Memory"; 31 case GR_GL_CONTEXT_LOST: 32 return "Context Lost"; 33 } 34 return "Unknown"; 35} 36} 37 38void GrGLCheckErr(const GrGLInterface* gl, 39 const char* location, 40 const char* call) { 41 uint32_t err = GR_GL_GET_ERROR(gl); 42 if (GR_GL_NO_ERROR != err) { 43 SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err)); 44 if (location) { 45 SkDebugf(" at\n\t%s", location); 46 } 47 if (call) { 48 SkDebugf("\n\t\t%s", call); 49 } 50 SkDebugf("\n"); 51 } 52} 53 54/////////////////////////////////////////////////////////////////////////////// 55 56#if GR_GL_LOG_CALLS 57 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START); 58#endif 59 60#if GR_GL_CHECK_ERROR 61 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START); 62#endif 63 64/////////////////////////////////////////////////////////////////////////////// 65 66GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) { 67 if (nullptr == versionString) { 68 SkDebugf("nullptr GL version string."); 69 return kNone_GrGLStandard; 70 } 71 72 int major, minor; 73 74 // check for desktop 75 int n = sscanf(versionString, "%d.%d", &major, &minor); 76 if (2 == n) { 77 return kGL_GrGLStandard; 78 } 79 80 // check for ES 1 81 char profile[2]; 82 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor); 83 if (4 == n) { 84 // we no longer support ES1. 85 return kNone_GrGLStandard; 86 } 87 88 // check for ES2 89 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); 90 if (2 == n) { 91 return kGLES_GrGLStandard; 92 } 93 return kNone_GrGLStandard; 94} 95 96void GrGLGetDriverInfo(GrGLStandard standard, 97 GrGLVendor vendor, 98 const char* rendererString, 99 const char* versionString, 100 GrGLDriver* outDriver, 101 GrGLDriverVersion* outVersion) { 102 int major, minor, rev, driverMajor, driverMinor; 103 104 *outDriver = kUnknown_GrGLDriver; 105 *outVersion = GR_GL_DRIVER_UNKNOWN_VER; 106 // These null checks are for test GL contexts that return nullptr in their 107 // glGetString implementation. 108 if (!rendererString) { 109 rendererString = ""; 110 } 111 if (!versionString) { 112 versionString = ""; 113 } 114 115 static const char kChromium[] = "Chromium"; 116 char suffix[SK_ARRAY_COUNT(kChromium)]; 117 if (0 == strcmp(rendererString, kChromium) || 118 (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) && 119 0 == strcmp(kChromium, suffix))) { 120 *outDriver = kChromium_GrGLDriver; 121 return; 122 } 123 124 if (standard == kGL_GrGLStandard) { 125 if (kNVIDIA_GrGLVendor == vendor) { 126 *outDriver = kNVIDIA_GrGLDriver; 127 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d", 128 &major, &minor, &rev, &driverMajor, &driverMinor); 129 // Some older NVIDIA drivers don't report the driver version. 130 if (5 == n) { 131 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 132 } 133 return; 134 } 135 int n = sscanf(versionString, "%d.%d Mesa %d.%d", 136 &major, &minor, &driverMajor, &driverMinor); 137 if (4 != n) { 138 n = sscanf(versionString, "%d.%d (Core Profile) Mesa %d.%d", 139 &major, &minor, &driverMajor, &driverMinor); 140 } 141 if (4 == n) { 142 *outDriver = kMesa_GrGLDriver; 143 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 144 return; 145 } 146 } 147 else { 148 if (kNVIDIA_GrGLVendor == vendor) { 149 *outDriver = kNVIDIA_GrGLDriver; 150 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d", 151 &major, &minor, &driverMajor, &driverMinor); 152 // Some older NVIDIA drivers don't report the driver version. 153 if (4 == n) { 154 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 155 } 156 return; 157 } 158 159 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", 160 &major, &minor, &driverMajor, &driverMinor); 161 if (4 == n) { 162 *outDriver = kMesa_GrGLDriver; 163 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 164 return; 165 } 166 if (0 == strncmp("ANGLE", rendererString, 5)) { 167 *outDriver = kANGLE_GrGLDriver; 168 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor, 169 &driverMinor); 170 if (4 == n) { 171 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 172 } 173 return; 174 } 175 } 176 177 if (kIntel_GrGLVendor == vendor) { 178 // We presume we're on the Intel driver since it hasn't identified itself as Mesa. 179 *outDriver = kIntel_GrGLDriver; 180 } 181 182 if (kQualcomm_GrGLVendor == vendor) { 183 *outDriver = kQualcomm_GrGLDriver; 184 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor, 185 &driverMinor); 186 if (4 == n) { 187 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 188 } 189 return; 190 } 191} 192 193GrGLVersion GrGLGetVersionFromString(const char* versionString) { 194 if (nullptr == versionString) { 195 SkDebugf("nullptr GL version string."); 196 return GR_GL_INVALID_VER; 197 } 198 199 int major, minor; 200 201 // check for mesa 202 int mesaMajor, mesaMinor; 203 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor); 204 if (4 == n) { 205 return GR_GL_VER(major, minor); 206 } 207 208 n = sscanf(versionString, "%d.%d", &major, &minor); 209 if (2 == n) { 210 return GR_GL_VER(major, minor); 211 } 212 213 char profile[2]; 214 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, 215 &major, &minor); 216 if (4 == n) { 217 return GR_GL_VER(major, minor); 218 } 219 220 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); 221 if (2 == n) { 222 return GR_GL_VER(major, minor); 223 } 224 225 return GR_GL_INVALID_VER; 226} 227 228GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) { 229 if (nullptr == versionString) { 230 SkDebugf("nullptr GLSL version string."); 231 return GR_GLSL_INVALID_VER; 232 } 233 234 int major, minor; 235 236 int n = sscanf(versionString, "%d.%d", &major, &minor); 237 if (2 == n) { 238 return GR_GLSL_VER(major, minor); 239 } 240 241 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor); 242 if (2 == n) { 243 return GR_GLSL_VER(major, minor); 244 } 245 246#ifdef SK_BUILD_FOR_ANDROID 247 // android hack until the gpu vender updates their drivers 248 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor); 249 if (2 == n) { 250 return GR_GLSL_VER(major, minor); 251 } 252#endif 253 254 return GR_GLSL_INVALID_VER; 255} 256 257GrGLVendor GrGLGetVendorFromString(const char* vendorString) { 258 if (vendorString) { 259 if (0 == strcmp(vendorString, "ARM")) { 260 return kARM_GrGLVendor; 261 } 262 if (0 == strcmp(vendorString, "Imagination Technologies")) { 263 return kImagination_GrGLVendor; 264 } 265 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) { 266 return kIntel_GrGLVendor; 267 } 268 if (0 == strcmp(vendorString, "Qualcomm")) { 269 return kQualcomm_GrGLVendor; 270 } 271 if (0 == strcmp(vendorString, "NVIDIA Corporation")) { 272 return kNVIDIA_GrGLVendor; 273 } 274 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) { 275 return kATI_GrGLVendor; 276 } 277 } 278 return kOther_GrGLVendor; 279} 280 281static bool is_renderer_angle(const char* rendererString) { 282 static constexpr char kHeader[] = "ANGLE "; 283 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1; 284 return 0 == strncmp(rendererString, kHeader, kHeaderLength); 285} 286 287GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { 288 if (rendererString) { 289 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) { 290 return kTegra3_GrGLRenderer; 291 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { 292 return kTegra2_GrGLRenderer; 293 } 294 int lastDigit; 295 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit); 296 if (1 == n && lastDigit >= 0 && lastDigit <= 9) { 297 return kPowerVR54x_GrGLRenderer; 298 } 299 // certain iOS devices also use PowerVR54x GPUs 300 static const char kAppleA4Str[] = "Apple A4"; 301 static const char kAppleA5Str[] = "Apple A5"; 302 static const char kAppleA6Str[] = "Apple A6"; 303 if (0 == strncmp(rendererString, kAppleA4Str, 304 SK_ARRAY_COUNT(kAppleA4Str)-1) || 305 0 == strncmp(rendererString, kAppleA5Str, 306 SK_ARRAY_COUNT(kAppleA5Str)-1) || 307 0 == strncmp(rendererString, kAppleA6Str, 308 SK_ARRAY_COUNT(kAppleA6Str)-1)) { 309 return kPowerVR54x_GrGLRenderer; 310 } 311 static const char kPowerVRRogueStr[] = "PowerVR Rogue"; 312 static const char kAppleA7Str[] = "Apple A7"; 313 static const char kAppleA8Str[] = "Apple A8"; 314 if (0 == strncmp(rendererString, kPowerVRRogueStr, 315 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) || 316 0 == strncmp(rendererString, kAppleA7Str, 317 SK_ARRAY_COUNT(kAppleA7Str)-1) || 318 0 == strncmp(rendererString, kAppleA8Str, 319 SK_ARRAY_COUNT(kAppleA8Str)-1)) { 320 return kPowerVRRogue_GrGLRenderer; 321 } 322 int adrenoNumber; 323 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber); 324 if (1 == n) { 325 if (adrenoNumber >= 300) { 326 if (adrenoNumber < 400) { 327 return kAdreno3xx_GrGLRenderer; 328 } 329 if (adrenoNumber < 500) { 330 return kAdreno4xx_GrGLRenderer; 331 } 332 if (adrenoNumber < 600) { 333 return kAdreno5xx_GrGLRenderer; 334 } 335 } 336 } 337 if (0 == strcmp("Intel Iris Pro OpenGL Engine", rendererString)) { 338 return kIntelIrisPro_GrGLRenderer; 339 } 340 341 int intelNumber; 342 n = sscanf(rendererString, "Intel(R) Iris(TM) Graphics %d", &intelNumber); 343 if (1 != n) { 344 n = sscanf(rendererString, "Intel(R) HD Graphics %d", &intelNumber); 345 } 346 if (1 == n) { 347 if (intelNumber >= 4000 && intelNumber < 5000) { 348 return kIntel4xxx_GrGLRenderer; 349 } 350 if (intelNumber >= 6000 && intelNumber < 7000) { 351 return kIntel6xxx_GrGLRenderer; 352 } 353 } 354 355 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195) 356 if (const char* amdString = strstr(rendererString, "Radeon")) { 357 char amdGeneration, amdTier, amdRevision; 358 n = sscanf(amdString, "Radeon (TM) R9 M%c%c%c", 359 &amdGeneration, &amdTier, &amdRevision); 360 if (3 == n) { 361 if ('4' == amdGeneration) { 362 return kAMDRadeonR9M4xx_GrGLRenderer; 363 } 364 } 365 366 char amd0, amd1, amd2; 367 n = sscanf(amdString, "Radeon HD 7%c%c%c Series", &amd0, &amd1, &amd2); 368 if (3 == n) { 369 return kAMDRadeonHD7xxx_GrGLRenderer; 370 } 371 } 372 373 if (0 == strcmp("Mesa Offscreen", rendererString)) { 374 return kOSMesa_GrGLRenderer; 375 } 376 if (strstr(rendererString, "llvmpipe")) { 377 return kGalliumLLVM_GrGLRenderer; 378 } 379 static const char kMaliTStr[] = "Mali-T"; 380 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) { 381 return kMaliT_GrGLRenderer; 382 } 383 if (is_renderer_angle(rendererString)) { 384 return kANGLE_GrGLRenderer; 385 } 386 } 387 return kOther_GrGLRenderer; 388} 389 390void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend* backend, 391 GrGLANGLEVendor* vendor, GrGLANGLERenderer* renderer) { 392 *backend = GrGLANGLEBackend::kUnknown; 393 *vendor = GrGLANGLEVendor::kUnknown; 394 *renderer = GrGLANGLERenderer::kUnknown; 395 if (!is_renderer_angle(rendererString)) { 396 return; 397 } 398 if (strstr(rendererString, "Intel")) { 399 *vendor = GrGLANGLEVendor::kIntel; 400 401 const char* modelStr; 402 int modelNumber; 403 if ((modelStr = strstr(rendererString, "HD Graphics")) && 404 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) || 405 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) { 406 switch (modelNumber) { 407 case 4000: 408 case 2500: 409 *renderer = GrGLANGLERenderer::kIvyBridge; 410 break; 411 case 510: 412 case 515: 413 case 520: 414 case 530: 415 *renderer = GrGLANGLERenderer::kSkylake; 416 break; 417 } 418 } else if ((modelStr = strstr(rendererString, "Iris")) && 419 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) || 420 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) || 421 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) { 422 switch (modelNumber) { 423 case 540: 424 case 550: 425 case 555: 426 case 580: 427 *renderer = GrGLANGLERenderer::kSkylake; 428 break; 429 } 430 } 431 } 432 if (strstr(rendererString, "Direct3D11")) { 433 *backend = GrGLANGLEBackend::kD3D11; 434 } else if (strstr(rendererString, "Direct3D9")) { 435 *backend = GrGLANGLEBackend::kD3D9; 436 } else if (strstr(rendererString, "OpenGL")) { 437 *backend = GrGLANGLEBackend::kOpenGL; 438 } 439} 440 441GrGLVersion GrGLGetVersion(const GrGLInterface* gl) { 442 const GrGLubyte* v; 443 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION)); 444 return GrGLGetVersionFromString((const char*) v); 445} 446 447GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) { 448 const GrGLubyte* v; 449 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 450 return GrGLGetGLSLVersionFromString((const char*) v); 451} 452 453GrGLVendor GrGLGetVendor(const GrGLInterface* gl) { 454 const GrGLubyte* v; 455 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR)); 456 return GrGLGetVendorFromString((const char*) v); 457} 458 459GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) { 460 const GrGLubyte* v; 461 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER)); 462 return GrGLGetRendererFromString((const char*) v); 463} 464 465GrGLenum GrToGLStencilFunc(GrStencilTest test) { 466 static const GrGLenum gTable[kGrStencilTestCount] = { 467 GR_GL_ALWAYS, // kAlways 468 GR_GL_NEVER, // kNever 469 GR_GL_GREATER, // kGreater 470 GR_GL_GEQUAL, // kGEqual 471 GR_GL_LESS, // kLess 472 GR_GL_LEQUAL, // kLEqual 473 GR_GL_EQUAL, // kEqual 474 GR_GL_NOTEQUAL, // kNotEqual 475 }; 476 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways); 477 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever); 478 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater); 479 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual); 480 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess); 481 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual); 482 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual); 483 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual); 484 SkASSERT(test < (GrStencilTest)kGrStencilTestCount); 485 486 return gTable[(int)test]; 487} 488 489GrPixelConfig GrGLSizedFormatToPixelConfig(GrGLenum sizedFormat) { 490 switch (sizedFormat) { 491 case GR_GL_R8: 492 return kAlpha_8_as_Red_GrPixelConfig; 493 case GR_GL_ALPHA8: 494 return kAlpha_8_as_Alpha_GrPixelConfig; 495 case GR_GL_RGBA8: 496 return kRGBA_8888_GrPixelConfig; 497 case GR_GL_BGRA8: 498 return kBGRA_8888_GrPixelConfig; 499 case GR_GL_SRGB8_ALPHA8: 500 return kSRGBA_8888_GrPixelConfig; 501 case GR_GL_RGB565: 502 return kRGB_565_GrPixelConfig; 503 case GR_GL_RGB5: 504 return kRGB_565_GrPixelConfig; 505 case GR_GL_RGBA4: 506 return kRGBA_4444_GrPixelConfig; 507 case GR_GL_RGB10_A2: 508 return kRGBA_1010102_GrPixelConfig; 509 case GR_GL_LUMINANCE8: 510 return kGray_8_GrPixelConfig; 511 case GR_GL_RGBA32F: 512 return kRGBA_float_GrPixelConfig; 513 case GR_GL_RG32F: 514 return kRG_float_GrPixelConfig; 515 case GR_GL_R16F: 516 return kAlpha_half_as_Red_GrPixelConfig; 517 case GR_GL_RGBA16F: 518 return kRGBA_half_GrPixelConfig; 519 default: 520 return kUnknown_GrPixelConfig; 521 } 522} 523 524