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
GrGLClearErr(const GrGLInterface * gl)14 void GrGLClearErr(const GrGLInterface* gl) {
15 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
16 }
17
18 namespace {
get_error_string(uint32_t err)19 const 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
GrGLCheckErr(const GrGLInterface * gl,const char * location,const char * call)38 void 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
GrGLGetStandardInUseFromString(const char * versionString)66 GrGLStandard 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
GrGLGetDriverInfo(GrGLStandard standard,GrGLVendor vendor,const char * rendererString,const char * versionString,GrGLDriver * outDriver,GrGLDriverVersion * outVersion)96 void 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, driverPoint;
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, 0);
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, 0);
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, 0);
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, 0);
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, 0);
172 }
173 return;
174 }
175 }
176
177 if (kGoogle_GrGLVendor == vendor) {
178 // Swiftshader is the only Google vendor at the moment
179 *outDriver = kSwiftShader_GrGLDriver;
180
181 // Swiftshader has a strange version string: w.x.y.z Going to arbitrarily ignore
182 // y and assume w,x and z are major, minor, point.
183 // As of writing, version is 4.0.0.6
184 int n = sscanf(versionString, "OpenGL ES %d.%d SwiftShader %d.%d.0.%d", &major, &minor,
185 &driverMajor, &driverMinor, &driverPoint);
186 if (5 == n) {
187 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
188 }
189 return;
190 }
191
192 if (kIntel_GrGLVendor == vendor) {
193 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
194 *outDriver = kIntel_GrGLDriver;
195
196 //This is how the macOS version strings are structured. This might be different on different
197 // OSes.
198 int n = sscanf(versionString, "%d.%d INTEL-%d.%d.%d", &major, &minor, &driverMajor,
199 &driverMinor, &driverPoint);
200 if (5 == n) {
201 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
202 }
203 }
204
205 if (kQualcomm_GrGLVendor == vendor) {
206 *outDriver = kQualcomm_GrGLDriver;
207 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
208 &driverMinor);
209 if (4 == n) {
210 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
211 }
212 return;
213 }
214 }
215
GrGLGetVersionFromString(const char * versionString)216 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
217 if (nullptr == versionString) {
218 SkDebugf("nullptr GL version string.");
219 return GR_GL_INVALID_VER;
220 }
221
222 int major, minor;
223
224 // check for mesa
225 int mesaMajor, mesaMinor;
226 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
227 if (4 == n) {
228 return GR_GL_VER(major, minor);
229 }
230
231 n = sscanf(versionString, "%d.%d", &major, &minor);
232 if (2 == n) {
233 return GR_GL_VER(major, minor);
234 }
235
236 char profile[2];
237 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
238 &major, &minor);
239 if (4 == n) {
240 return GR_GL_VER(major, minor);
241 }
242
243 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
244 if (2 == n) {
245 return GR_GL_VER(major, minor);
246 }
247
248 return GR_GL_INVALID_VER;
249 }
250
GrGLGetGLSLVersionFromString(const char * versionString)251 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
252 if (nullptr == versionString) {
253 SkDebugf("nullptr GLSL version string.");
254 return GR_GLSL_INVALID_VER;
255 }
256
257 int major, minor;
258
259 int n = sscanf(versionString, "%d.%d", &major, &minor);
260 if (2 == n) {
261 return GR_GLSL_VER(major, minor);
262 }
263
264 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
265 if (2 == n) {
266 return GR_GLSL_VER(major, minor);
267 }
268
269 #ifdef SK_BUILD_FOR_ANDROID
270 // android hack until the gpu vender updates their drivers
271 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
272 if (2 == n) {
273 return GR_GLSL_VER(major, minor);
274 }
275 #endif
276
277 return GR_GLSL_INVALID_VER;
278 }
279
GrGLGetVendorFromString(const char * vendorString)280 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
281 if (vendorString) {
282 if (0 == strcmp(vendorString, "ARM")) {
283 return kARM_GrGLVendor;
284 }
285 if (0 == strcmp(vendorString, "Google Inc.")) {
286 return kGoogle_GrGLVendor;
287 }
288 if (0 == strcmp(vendorString, "Imagination Technologies")) {
289 return kImagination_GrGLVendor;
290 }
291 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
292 return kIntel_GrGLVendor;
293 }
294 if (0 == strcmp(vendorString, "Qualcomm")) {
295 return kQualcomm_GrGLVendor;
296 }
297 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
298 return kNVIDIA_GrGLVendor;
299 }
300 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
301 return kATI_GrGLVendor;
302 }
303 }
304 return kOther_GrGLVendor;
305 }
306
is_renderer_angle(const char * rendererString)307 static bool is_renderer_angle(const char* rendererString) {
308 static constexpr char kHeader[] = "ANGLE ";
309 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
310 return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
311 }
312
GrGLGetRendererFromStrings(const char * rendererString,const GrGLExtensions & extensions)313 GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
314 const GrGLExtensions& extensions) {
315 if (rendererString) {
316 static const char kTegraStr[] = "NVIDIA Tegra";
317 if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
318 // Tegra strings are not very descriptive. We distinguish between the modern and legacy
319 // architectures by the presence of NV_path_rendering.
320 return extensions.has("GL_NV_path_rendering") ? kTegra_GrGLRenderer
321 : kTegra_PreK1_GrGLRenderer;
322 }
323 int lastDigit;
324 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
325 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
326 return kPowerVR54x_GrGLRenderer;
327 }
328 // certain iOS devices also use PowerVR54x GPUs
329 static const char kAppleA4Str[] = "Apple A4";
330 static const char kAppleA5Str[] = "Apple A5";
331 static const char kAppleA6Str[] = "Apple A6";
332 if (0 == strncmp(rendererString, kAppleA4Str,
333 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
334 0 == strncmp(rendererString, kAppleA5Str,
335 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
336 0 == strncmp(rendererString, kAppleA6Str,
337 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
338 return kPowerVR54x_GrGLRenderer;
339 }
340 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
341 static const char kAppleA7Str[] = "Apple A7";
342 static const char kAppleA8Str[] = "Apple A8";
343 if (0 == strncmp(rendererString, kPowerVRRogueStr,
344 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
345 0 == strncmp(rendererString, kAppleA7Str,
346 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
347 0 == strncmp(rendererString, kAppleA8Str,
348 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
349 return kPowerVRRogue_GrGLRenderer;
350 }
351 int adrenoNumber;
352 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
353 if (1 == n) {
354 if (adrenoNumber >= 300) {
355 if (adrenoNumber < 400) {
356 return kAdreno3xx_GrGLRenderer;
357 }
358 if (adrenoNumber < 500) {
359 return adrenoNumber >= 430
360 ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
361 }
362 if (adrenoNumber < 600) {
363 return kAdreno5xx_GrGLRenderer;
364 }
365 }
366 }
367 if (0 == strcmp("Google SwiftShader", rendererString)) {
368 return kGoogleSwiftShader_GrGLRenderer;
369 }
370
371 if (const char* intelString = strstr(rendererString, "Intel")) {
372 if (0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
373 return kIntelIrisPro_GrGLRenderer;
374 }
375 if (strstr(intelString, "Sandybridge")) {
376 return kIntelSandyBridge_GrGLRenderer;
377 }
378 if (strstr(intelString, "Bay Trail")) {
379 return kIntelBayTrail_GrGLRenderer;
380 }
381 int intelNumber;
382 if (sscanf(intelString, "Intel(R) Iris(TM) Graphics %d", &intelNumber) ||
383 sscanf(intelString, "Intel(R) Iris(TM) Pro Graphics %d", &intelNumber) ||
384 sscanf(intelString, "Intel(R) Iris(TM) Pro Graphics P%d", &intelNumber) ||
385 sscanf(intelString, "Intel(R) Iris(R) Graphics %d", &intelNumber) ||
386 sscanf(intelString, "Intel(R) Iris(R) Pro Graphics %d", &intelNumber) ||
387 sscanf(intelString, "Intel(R) Iris(R) Pro Graphics P%d", &intelNumber) ||
388 sscanf(intelString, "Intel(R) HD Graphics %d", &intelNumber) ||
389 sscanf(intelString, "Intel(R) HD Graphics P%d", &intelNumber)) {
390
391 if (intelNumber >= 4000 && intelNumber < 5000) {
392 return kIntel4xxx_GrGLRenderer;
393 }
394 if (intelNumber >= 6000 && intelNumber < 7000) {
395 return kIntel6xxx_GrGLRenderer;
396 }
397 if (intelNumber >= 2000 && intelNumber < 4000) {
398 return kIntelSandyBridge_GrGLRenderer;
399 }
400 if (intelNumber >= 500 && intelNumber < 600) {
401 return kIntelSkylake_GrGLRenderer;
402 }
403 }
404 }
405
406 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
407 if (const char* amdString = strstr(rendererString, "Radeon")) {
408 char amdGeneration, amdTier, amdRevision;
409 n = sscanf(amdString, "Radeon (TM) R9 M%c%c%c",
410 &amdGeneration, &amdTier, &amdRevision);
411 if (3 == n) {
412 if ('4' == amdGeneration) {
413 return kAMDRadeonR9M4xx_GrGLRenderer;
414 }
415 }
416
417 char amd0, amd1, amd2;
418 n = sscanf(amdString, "Radeon HD 7%c%c%c Series", &amd0, &amd1, &amd2);
419 if (3 == n) {
420 return kAMDRadeonHD7xxx_GrGLRenderer;
421 }
422 }
423
424 if (0 == strcmp("Mesa Offscreen", rendererString)) {
425 return kOSMesa_GrGLRenderer;
426 }
427 if (strstr(rendererString, "llvmpipe")) {
428 return kGalliumLLVM_GrGLRenderer;
429 }
430 static const char kMaliTStr[] = "Mali-T";
431 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
432 return kMaliT_GrGLRenderer;
433 }
434 int mali400Num;
435 if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
436 mali400Num < 500) {
437 return kMali4xx_GrGLRenderer;
438 }
439 if (is_renderer_angle(rendererString)) {
440 return kANGLE_GrGLRenderer;
441 }
442 }
443 return kOther_GrGLRenderer;
444 }
445
GrGLGetANGLEInfoFromString(const char * rendererString,GrGLANGLEBackend * backend,GrGLANGLEVendor * vendor,GrGLANGLERenderer * renderer)446 void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend* backend,
447 GrGLANGLEVendor* vendor, GrGLANGLERenderer* renderer) {
448 *backend = GrGLANGLEBackend::kUnknown;
449 *vendor = GrGLANGLEVendor::kUnknown;
450 *renderer = GrGLANGLERenderer::kUnknown;
451 if (!is_renderer_angle(rendererString)) {
452 return;
453 }
454 if (strstr(rendererString, "Intel")) {
455 *vendor = GrGLANGLEVendor::kIntel;
456
457 const char* modelStr;
458 int modelNumber;
459 if ((modelStr = strstr(rendererString, "HD Graphics")) &&
460 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
461 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
462 switch (modelNumber) {
463 case 2000:
464 case 3000:
465 *renderer = GrGLANGLERenderer::kSandyBridge;
466 break;
467 case 4000:
468 case 2500:
469 *renderer = GrGLANGLERenderer::kIvyBridge;
470 break;
471 case 510:
472 case 515:
473 case 520:
474 case 530:
475 *renderer = GrGLANGLERenderer::kSkylake;
476 break;
477 }
478 } else if ((modelStr = strstr(rendererString, "Iris")) &&
479 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
480 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
481 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
482 switch (modelNumber) {
483 case 540:
484 case 550:
485 case 555:
486 case 580:
487 *renderer = GrGLANGLERenderer::kSkylake;
488 break;
489 }
490 }
491 }
492 if (strstr(rendererString, "Direct3D11")) {
493 *backend = GrGLANGLEBackend::kD3D11;
494 } else if (strstr(rendererString, "Direct3D9")) {
495 *backend = GrGLANGLEBackend::kD3D9;
496 } else if (strstr(rendererString, "OpenGL")) {
497 *backend = GrGLANGLEBackend::kOpenGL;
498 }
499 }
500
GrGLGetVersion(const GrGLInterface * gl)501 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
502 const GrGLubyte* v;
503 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
504 return GrGLGetVersionFromString((const char*) v);
505 }
506
GrGLGetGLSLVersion(const GrGLInterface * gl)507 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
508 const GrGLubyte* v;
509 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
510 return GrGLGetGLSLVersionFromString((const char*) v);
511 }
512
GrGLGetVendor(const GrGLInterface * gl)513 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
514 const GrGLubyte* v;
515 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
516 return GrGLGetVendorFromString((const char*) v);
517 }
518
GrGLGetRenderer(const GrGLInterface * gl)519 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
520 const GrGLubyte* rendererString;
521 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
522
523 return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
524 }
525
GrToGLStencilFunc(GrStencilTest test)526 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
527 static const GrGLenum gTable[kGrStencilTestCount] = {
528 GR_GL_ALWAYS, // kAlways
529 GR_GL_NEVER, // kNever
530 GR_GL_GREATER, // kGreater
531 GR_GL_GEQUAL, // kGEqual
532 GR_GL_LESS, // kLess
533 GR_GL_LEQUAL, // kLEqual
534 GR_GL_EQUAL, // kEqual
535 GR_GL_NOTEQUAL, // kNotEqual
536 };
537 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
538 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
539 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
540 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
541 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
542 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
543 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
544 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
545 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
546
547 return gTable[(int)test];
548 }
549
550