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;
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
GrGLGetVersionFromString(const char * versionString)193 GrGLVersion 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
GrGLGetGLSLVersionFromString(const char * versionString)228 GrGLSLVersion 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
GrGLGetVendorFromString(const char * vendorString)257 GrGLVendor 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
is_renderer_angle(const char * rendererString)281 static 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
GrGLGetRendererFromString(const char * rendererString)287 GrGLRenderer 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
GrGLGetANGLEInfoFromString(const char * rendererString,GrGLANGLEBackend * backend,GrGLANGLEVendor * vendor,GrGLANGLERenderer * renderer)390 void 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
GrGLGetVersion(const GrGLInterface * gl)441 GrGLVersion 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
GrGLGetGLSLVersion(const GrGLInterface * gl)447 GrGLSLVersion 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
GrGLGetVendor(const GrGLInterface * gl)453 GrGLVendor 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
GrGLGetRenderer(const GrGLInterface * gl)459 GrGLRenderer 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
GrToGLStencilFunc(GrStencilTest test)465 GrGLenum 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
GrGLSizedFormatToPixelConfig(GrGLenum sizedFormat)489 GrPixelConfig 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