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 106 if (0 == strcmp(rendererString, "Chromium")) { 107 *outDriver = kChromium_GrGLDriver; 108 return; 109 } 110 111 if (standard == kGL_GrGLStandard) { 112 if (kNVIDIA_GrGLVendor == vendor) { 113 *outDriver = kNVIDIA_GrGLDriver; 114 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d", 115 &major, &minor, &rev, &driverMajor, &driverMinor); 116 // Some older NVIDIA drivers don't report the driver version. 117 if (5 == n) { 118 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 119 } 120 return; 121 } 122 123 int n = sscanf(versionString, "%d.%d Mesa %d.%d", 124 &major, &minor, &driverMajor, &driverMinor); 125 if (4 == n) { 126 *outDriver = kMesa_GrGLDriver; 127 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 128 return; 129 } 130 } 131 else { 132 if (kNVIDIA_GrGLVendor == vendor) { 133 *outDriver = kNVIDIA_GrGLDriver; 134 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d", 135 &major, &minor, &driverMajor, &driverMinor); 136 // Some older NVIDIA drivers don't report the driver version. 137 if (4 == n) { 138 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 139 } 140 return; 141 } 142 143 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", 144 &major, &minor, &driverMajor, &driverMinor); 145 if (4 == n) { 146 *outDriver = kMesa_GrGLDriver; 147 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 148 return; 149 } 150 if (0 == strncmp("ANGLE", rendererString, 5)) { 151 *outDriver = kANGLE_GrGLDriver; 152 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor, 153 &driverMinor); 154 if (4 == n) { 155 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor); 156 } 157 return; 158 } 159 } 160 161 if (kIntel_GrGLVendor == vendor) { 162 // We presume we're on the Intel driver since it hasn't identified itself as Mesa. 163 *outDriver = kIntel_GrGLDriver; 164 } 165 } 166 167 GrGLVersion GrGLGetVersionFromString(const char* versionString) { 168 if (nullptr == versionString) { 169 SkDebugf("nullptr GL version string."); 170 return GR_GL_INVALID_VER; 171 } 172 173 int major, minor; 174 175 // check for mesa 176 int mesaMajor, mesaMinor; 177 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor); 178 if (4 == n) { 179 return GR_GL_VER(major, minor); 180 } 181 182 n = sscanf(versionString, "%d.%d", &major, &minor); 183 if (2 == n) { 184 return GR_GL_VER(major, minor); 185 } 186 187 char profile[2]; 188 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, 189 &major, &minor); 190 if (4 == n) { 191 return GR_GL_VER(major, minor); 192 } 193 194 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor); 195 if (2 == n) { 196 return GR_GL_VER(major, minor); 197 } 198 199 return GR_GL_INVALID_VER; 200 } 201 202 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) { 203 if (nullptr == versionString) { 204 SkDebugf("nullptr GLSL version string."); 205 return GR_GLSL_INVALID_VER; 206 } 207 208 int major, minor; 209 210 int n = sscanf(versionString, "%d.%d", &major, &minor); 211 if (2 == n) { 212 return GR_GLSL_VER(major, minor); 213 } 214 215 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor); 216 if (2 == n) { 217 return GR_GLSL_VER(major, minor); 218 } 219 220 #ifdef SK_BUILD_FOR_ANDROID 221 // android hack until the gpu vender updates their drivers 222 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor); 223 if (2 == n) { 224 return GR_GLSL_VER(major, minor); 225 } 226 #endif 227 228 return GR_GLSL_INVALID_VER; 229 } 230 231 GrGLVendor GrGLGetVendorFromString(const char* vendorString) { 232 if (vendorString) { 233 if (0 == strcmp(vendorString, "ARM")) { 234 return kARM_GrGLVendor; 235 } 236 if (0 == strcmp(vendorString, "Imagination Technologies")) { 237 return kImagination_GrGLVendor; 238 } 239 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) { 240 return kIntel_GrGLVendor; 241 } 242 if (0 == strcmp(vendorString, "Qualcomm")) { 243 return kQualcomm_GrGLVendor; 244 } 245 if (0 == strcmp(vendorString, "NVIDIA Corporation")) { 246 return kNVIDIA_GrGLVendor; 247 } 248 } 249 return kOther_GrGLVendor; 250 } 251 252 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { 253 if (rendererString) { 254 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) { 255 return kTegra3_GrGLRenderer; 256 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { 257 return kTegra2_GrGLRenderer; 258 } 259 int lastDigit; 260 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit); 261 if (1 == n && lastDigit >= 0 && lastDigit <= 9) { 262 return kPowerVR54x_GrGLRenderer; 263 } 264 // certain iOS devices also use PowerVR54x GPUs 265 static const char kAppleA4Str[] = "Apple A4"; 266 static const char kAppleA5Str[] = "Apple A5"; 267 static const char kAppleA6Str[] = "Apple A6"; 268 if (0 == strncmp(rendererString, kAppleA4Str, 269 SK_ARRAY_COUNT(kAppleA4Str)-1) || 270 0 == strncmp(rendererString, kAppleA5Str, 271 SK_ARRAY_COUNT(kAppleA5Str)-1) || 272 0 == strncmp(rendererString, kAppleA6Str, 273 SK_ARRAY_COUNT(kAppleA6Str)-1)) { 274 return kPowerVR54x_GrGLRenderer; 275 } 276 static const char kPowerVRRogueStr[] = "PowerVR Rogue"; 277 static const char kAppleA7Str[] = "Apple A7"; 278 static const char kAppleA8Str[] = "Apple A8"; 279 if (0 == strncmp(rendererString, kPowerVRRogueStr, 280 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) || 281 0 == strncmp(rendererString, kAppleA7Str, 282 SK_ARRAY_COUNT(kAppleA7Str)-1) || 283 0 == strncmp(rendererString, kAppleA8Str, 284 SK_ARRAY_COUNT(kAppleA8Str)-1)) { 285 return kPowerVRRogue_GrGLRenderer; 286 } 287 int adrenoNumber; 288 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber); 289 if (1 == n) { 290 if (adrenoNumber >= 300) { 291 if (adrenoNumber < 400) { 292 return kAdreno3xx_GrGLRenderer; 293 } 294 if (adrenoNumber < 500) { 295 return kAdreno4xx_GrGLRenderer; 296 } 297 } 298 } 299 } 300 return kOther_GrGLRenderer; 301 } 302 303 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) { 304 const GrGLubyte* v; 305 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION)); 306 return GrGLGetVersionFromString((const char*) v); 307 } 308 309 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) { 310 const GrGLubyte* v; 311 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 312 return GrGLGetGLSLVersionFromString((const char*) v); 313 } 314 315 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) { 316 const GrGLubyte* v; 317 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR)); 318 return GrGLGetVendorFromString((const char*) v); 319 } 320 321 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) { 322 const GrGLubyte* v; 323 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER)); 324 return GrGLGetRendererFromString((const char*) v); 325 } 326 327 GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) { 328 static const GrGLenum gTable[] = { 329 GR_GL_ALWAYS, // kAlways_StencilFunc 330 GR_GL_NEVER, // kNever_StencilFunc 331 GR_GL_GREATER, // kGreater_StencilFunc 332 GR_GL_GEQUAL, // kGEqual_StencilFunc 333 GR_GL_LESS, // kLess_StencilFunc 334 GR_GL_LEQUAL, // kLEqual_StencilFunc, 335 GR_GL_EQUAL, // kEqual_StencilFunc, 336 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc, 337 }; 338 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount); 339 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); 340 GR_STATIC_ASSERT(1 == kNever_StencilFunc); 341 GR_STATIC_ASSERT(2 == kGreater_StencilFunc); 342 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc); 343 GR_STATIC_ASSERT(4 == kLess_StencilFunc); 344 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc); 345 GR_STATIC_ASSERT(6 == kEqual_StencilFunc); 346 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc); 347 SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount); 348 349 return gTable[basicFunc]; 350 } 351