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 "SkMatrix.h" 11 #include <stdio.h> 12 13 void GrGLClearErr(const GrGLInterface* gl) { 14 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {} 15 } 16 17 namespace { 18 const char *get_error_string(uint32_t err) { 19 switch (err) { 20 case GR_GL_NO_ERROR: 21 return ""; 22 case GR_GL_INVALID_ENUM: 23 return "Invalid Enum"; 24 case GR_GL_INVALID_VALUE: 25 return "Invalid Value"; 26 case GR_GL_INVALID_OPERATION: 27 return "Invalid Operation"; 28 case GR_GL_OUT_OF_MEMORY: 29 return "Out of Memory"; 30 case GR_GL_CONTEXT_LOST: 31 return "Context Lost"; 32 } 33 return "Unknown"; 34 } 35 } 36 37 void GrGLCheckErr(const GrGLInterface* gl, 38 const char* location, 39 const char* call) { 40 uint32_t err = GR_GL_GET_ERROR(gl); 41 if (GR_GL_NO_ERROR != err) { 42 SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err)); 43 if (location) { 44 SkDebugf(" at\n\t%s", location); 45 } 46 if (call) { 47 SkDebugf("\n\t\t%s", call); 48 } 49 SkDebugf("\n"); 50 } 51 } 52 53 /////////////////////////////////////////////////////////////////////////////// 54 55 #if GR_GL_LOG_CALLS 56 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START); 57 #endif 58 59 #if GR_GL_CHECK_ERROR 60 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START); 61 #endif 62 63 /////////////////////////////////////////////////////////////////////////////// 64 65 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) { 66 if (nullptr == versionString) { 67 SkDebugf("nullptr GL version string."); 68 return kNone_GrGLStandard; 69 } 70 71 int major, minor; 72 73 // check for desktop 74 int n = sscanf(versionString, "%d.%d", &major, &minor); 75 if (2 == n) { 76 return kGL_GrGLStandard; 77 } 78 79 // check for ES 1 80 char profile[2]; 81 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor); 82 if (4 == n) { 83 // we no longer support ES1. 84 return kNone_GrGLStandard; 85 } 86 87 // check for ES2 88 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); 89 if (2 == n) { 90 return kGLES_GrGLStandard; 91 } 92 return kNone_GrGLStandard; 93 } 94 95 void GrGLGetDriverInfo(GrGLStandard standard, 96 GrGLVendor vendor, 97 const char* rendererString, 98 const char* versionString, 99 GrGLDriver* outDriver, 100 GrGLDriverVersion* outVersion) { 101 int major, minor, rev, driverMajor, driverMinor; 102 103 *outDriver = kUnknown_GrGLDriver; 104 *outVersion = GR_GL_DRIVER_UNKNOWN_VER; 105 // These null checks are for test GL contexts that return nullptr in their 106 // glGetString implementation. 107 if (!rendererString) { 108 rendererString = ""; 109 } 110 if (!versionString) { 111 versionString = ""; 112 } 113 114 static const char kChromium[] = "Chromium"; 115 char suffix[SK_ARRAY_COUNT(kChromium)]; 116 if (0 == strcmp(rendererString, kChromium) || 117 (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) && 118 0 == strcmp(kChromium, suffix))) { 119 *outDriver = kChromium_GrGLDriver; 120 return; 121 } 122 123 if (standard == kGL_GrGLStandard) { 124 if (kNVIDIA_GrGLVendor == vendor) { 125 *outDriver = kNVIDIA_GrGLDriver; 126 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d", 127 &major, &minor, &rev, &driverMajor, &driverMinor); 128 // Some older NVIDIA drivers don't report the driver version. 129 if (5 == n) { 130 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 131 } 132 return; 133 } 134 int n = sscanf(versionString, "%d.%d Mesa %d.%d", 135 &major, &minor, &driverMajor, &driverMinor); 136 if (4 == n) { 137 *outDriver = kMesa_GrGLDriver; 138 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 139 return; 140 } 141 } 142 else { 143 if (kNVIDIA_GrGLVendor == vendor) { 144 *outDriver = kNVIDIA_GrGLDriver; 145 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d", 146 &major, &minor, &driverMajor, &driverMinor); 147 // Some older NVIDIA drivers don't report the driver version. 148 if (4 == n) { 149 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 150 } 151 return; 152 } 153 154 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", 155 &major, &minor, &driverMajor, &driverMinor); 156 if (4 == n) { 157 *outDriver = kMesa_GrGLDriver; 158 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 159 return; 160 } 161 if (0 == strncmp("ANGLE", rendererString, 5)) { 162 *outDriver = kANGLE_GrGLDriver; 163 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor, 164 &driverMinor); 165 if (4 == n) { 166 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 167 } 168 return; 169 } 170 } 171 172 if (kIntel_GrGLVendor == vendor) { 173 // We presume we're on the Intel driver since it hasn't identified itself as Mesa. 174 *outDriver = kIntel_GrGLDriver; 175 } 176 177 if (kQualcomm_GrGLVendor == vendor) { 178 *outDriver = kQualcomm_GrGLDriver; 179 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor, 180 &driverMinor); 181 if (4 == n) { 182 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 183 } 184 return; 185 } 186 } 187 188 GrGLVersion GrGLGetVersionFromString(const char* versionString) { 189 if (nullptr == versionString) { 190 SkDebugf("nullptr GL version string."); 191 return GR_GL_INVALID_VER; 192 } 193 194 int major, minor; 195 196 // check for mesa 197 int mesaMajor, mesaMinor; 198 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor); 199 if (4 == n) { 200 return GR_GL_VER(major, minor); 201 } 202 203 n = sscanf(versionString, "%d.%d", &major, &minor); 204 if (2 == n) { 205 return GR_GL_VER(major, minor); 206 } 207 208 char profile[2]; 209 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, 210 &major, &minor); 211 if (4 == n) { 212 return GR_GL_VER(major, minor); 213 } 214 215 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); 216 if (2 == n) { 217 return GR_GL_VER(major, minor); 218 } 219 220 return GR_GL_INVALID_VER; 221 } 222 223 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) { 224 if (nullptr == versionString) { 225 SkDebugf("nullptr GLSL version string."); 226 return GR_GLSL_INVALID_VER; 227 } 228 229 int major, minor; 230 231 int n = sscanf(versionString, "%d.%d", &major, &minor); 232 if (2 == n) { 233 return GR_GLSL_VER(major, minor); 234 } 235 236 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor); 237 if (2 == n) { 238 return GR_GLSL_VER(major, minor); 239 } 240 241 #ifdef SK_BUILD_FOR_ANDROID 242 // android hack until the gpu vender updates their drivers 243 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor); 244 if (2 == n) { 245 return GR_GLSL_VER(major, minor); 246 } 247 #endif 248 249 return GR_GLSL_INVALID_VER; 250 } 251 252 GrGLVendor GrGLGetVendorFromString(const char* vendorString) { 253 if (vendorString) { 254 if (0 == strcmp(vendorString, "ARM")) { 255 return kARM_GrGLVendor; 256 } 257 if (0 == strcmp(vendorString, "Imagination Technologies")) { 258 return kImagination_GrGLVendor; 259 } 260 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) { 261 return kIntel_GrGLVendor; 262 } 263 if (0 == strcmp(vendorString, "Qualcomm")) { 264 return kQualcomm_GrGLVendor; 265 } 266 if (0 == strcmp(vendorString, "NVIDIA Corporation")) { 267 return kNVIDIA_GrGLVendor; 268 } 269 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) { 270 return kATI_GrGLVendor; 271 } 272 } 273 return kOther_GrGLVendor; 274 } 275 276 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { 277 if (rendererString) { 278 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) { 279 return kTegra3_GrGLRenderer; 280 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { 281 return kTegra2_GrGLRenderer; 282 } 283 int lastDigit; 284 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit); 285 if (1 == n && lastDigit >= 0 && lastDigit <= 9) { 286 return kPowerVR54x_GrGLRenderer; 287 } 288 // certain iOS devices also use PowerVR54x GPUs 289 static const char kAppleA4Str[] = "Apple A4"; 290 static const char kAppleA5Str[] = "Apple A5"; 291 static const char kAppleA6Str[] = "Apple A6"; 292 if (0 == strncmp(rendererString, kAppleA4Str, 293 SK_ARRAY_COUNT(kAppleA4Str)-1) || 294 0 == strncmp(rendererString, kAppleA5Str, 295 SK_ARRAY_COUNT(kAppleA5Str)-1) || 296 0 == strncmp(rendererString, kAppleA6Str, 297 SK_ARRAY_COUNT(kAppleA6Str)-1)) { 298 return kPowerVR54x_GrGLRenderer; 299 } 300 static const char kPowerVRRogueStr[] = "PowerVR Rogue"; 301 static const char kAppleA7Str[] = "Apple A7"; 302 static const char kAppleA8Str[] = "Apple A8"; 303 if (0 == strncmp(rendererString, kPowerVRRogueStr, 304 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) || 305 0 == strncmp(rendererString, kAppleA7Str, 306 SK_ARRAY_COUNT(kAppleA7Str)-1) || 307 0 == strncmp(rendererString, kAppleA8Str, 308 SK_ARRAY_COUNT(kAppleA8Str)-1)) { 309 return kPowerVRRogue_GrGLRenderer; 310 } 311 int adrenoNumber; 312 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber); 313 if (1 == n) { 314 if (adrenoNumber >= 300) { 315 if (adrenoNumber < 400) { 316 return kAdreno3xx_GrGLRenderer; 317 } 318 if (adrenoNumber < 500) { 319 return kAdreno4xx_GrGLRenderer; 320 } 321 if (adrenoNumber < 600) { 322 return kAdreno5xx_GrGLRenderer; 323 } 324 } 325 } 326 int intelNumber; 327 n = sscanf(rendererString, "Intel(R) Iris(TM) Graphics %d", &intelNumber); 328 if (1 != n) { 329 n = sscanf(rendererString, "Intel(R) HD Graphics %d", &intelNumber); 330 } 331 if (1 == n) { 332 if (intelNumber >= 6000 && intelNumber < 7000) { 333 return kIntel6xxx_GrGLRenderer; 334 } 335 } 336 if (0 == strcmp("Mesa Offscreen", rendererString)) { 337 return kOSMesa_GrGLRenderer; 338 } 339 static const char kMaliTStr[] = "Mali-T"; 340 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) { 341 return kMaliT_GrGLRenderer; 342 } 343 static const char kANGLEStr[] = "ANGLE"; 344 if (0 == strncmp(rendererString, kANGLEStr, SK_ARRAY_COUNT(kANGLEStr) - 1)) { 345 return kANGLE_GrGLRenderer; 346 } 347 } 348 return kOther_GrGLRenderer; 349 } 350 351 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) { 352 const GrGLubyte* v; 353 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION)); 354 return GrGLGetVersionFromString((const char*) v); 355 } 356 357 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) { 358 const GrGLubyte* v; 359 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 360 return GrGLGetGLSLVersionFromString((const char*) v); 361 } 362 363 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) { 364 const GrGLubyte* v; 365 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR)); 366 return GrGLGetVendorFromString((const char*) v); 367 } 368 369 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) { 370 const GrGLubyte* v; 371 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER)); 372 return GrGLGetRendererFromString((const char*) v); 373 } 374 375 GrGLenum GrToGLStencilFunc(GrStencilTest test) { 376 static const GrGLenum gTable[kGrStencilTestCount] = { 377 GR_GL_ALWAYS, // kAlways 378 GR_GL_NEVER, // kNever 379 GR_GL_GREATER, // kGreater 380 GR_GL_GEQUAL, // kGEqual 381 GR_GL_LESS, // kLess 382 GR_GL_LEQUAL, // kLEqual 383 GR_GL_EQUAL, // kEqual 384 GR_GL_NOTEQUAL, // kNotEqual 385 }; 386 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways); 387 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever); 388 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater); 389 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual); 390 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess); 391 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual); 392 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual); 393 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual); 394 SkASSERT(test < (GrStencilTest)kGrStencilTestCount); 395 396 return gTable[(int)test]; 397 } 398