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 "include/core/SkMatrix.h"
10#include "include/private/GrTypesPriv.h"
11#include "src/gpu/GrDataUtils.h"
12#include "src/gpu/gl/GrGLUtil.h"
13#include <stdio.h>
14
15///////////////////////////////////////////////////////////////////////////////
16
17#if GR_GL_LOG_CALLS
18 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
19#endif
20
21#if GR_GL_CHECK_ERROR
22 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
23#endif
24
25///////////////////////////////////////////////////////////////////////////////
26
27GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
28 if (nullptr == versionString) {
29 SkDebugf("nullptr GL version string.");
30 return kNone_GrGLStandard;
31 }
32
33 int major, minor;
34
35 // check for desktop
36 int n = sscanf(versionString, "%d.%d", &major, &minor);
37 if (2 == n) {
38 return kGL_GrGLStandard;
39 }
40
41 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
42 int esMajor, esMinor;
43 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
44 if (4 == n) {
45 return kWebGL_GrGLStandard;
46 }
47
48 // check for ES 1
49 char profile[2];
50 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
51 if (4 == n) {
52 // we no longer support ES1.
53 return kNone_GrGLStandard;
54 }
55
56 // check for ES2
57 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
58 if (2 == n) {
59 return kGLES_GrGLStandard;
60 }
61 return kNone_GrGLStandard;
62}
63
64void GrGLGetDriverInfo(GrGLStandard standard,
65 GrGLVendor vendor,
66 const char* rendererString,
67 const char* versionString,
68 GrGLDriver* outDriver,
69 GrGLDriverVersion* outVersion) {
70 int major, minor, rev, driverMajor, driverMinor, driverPoint;
71
72 *outDriver = kUnknown_GrGLDriver;
73 *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
74 // These null checks are for test GL contexts that return nullptr in their
75 // glGetString implementation.
76 if (!rendererString) {
77 rendererString = "";
78 }
79 if (!versionString) {
80 versionString = "";
81 }
82
83 static const char kChromium[] = "Chromium";
84 char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
85 if (0 == strcmp(rendererString, kChromium) ||
86 (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
87 0 == strcmp(kChromium, suffix))) {
88 *outDriver = kChromium_GrGLDriver;
89 return;
90 }
91
92 if (GR_IS_GR_GL(standard)) {
93 if (vendor == kNVIDIA_GrGLVendor) {
94 *outDriver = kNVIDIA_GrGLDriver;
95 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
96 &major, &minor, &rev, &driverMajor, &driverMinor);
97 // Some older NVIDIA drivers don't report the driver version.
98 if (n == 5) {
99 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
100 }
101 return;
102 }
103 int n = sscanf(versionString, "%d.%d Mesa %d.%d",
104 &major, &minor, &driverMajor, &driverMinor);
105 if (4 != n) {
106 n = sscanf(versionString, "%d.%d (Core Profile) Mesa %d.%d",
107 &major, &minor, &driverMajor, &driverMinor);
108 }
109 if (n == 4) {
110 *outDriver = kMesa_GrGLDriver;
111 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
112 return;
113 }
114 } else if (GR_IS_GR_GL_ES(standard)) {
115 if (vendor == kNVIDIA_GrGLVendor) {
116 *outDriver = kNVIDIA_GrGLDriver;
117 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
118 &major, &minor, &driverMajor, &driverMinor);
119 // Some older NVIDIA drivers don't report the driver version.
120 if (n == 4) {
121 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
122 }
123 return;
124 }
125
126 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
127 &major, &minor, &driverMajor, &driverMinor);
128 if (n == 4) {
129 *outDriver = kMesa_GrGLDriver;
130 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
131 return;
132 }
133 if (0 == strncmp("ANGLE", rendererString, 5)) {
134 *outDriver = kANGLE_GrGLDriver;
135 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
136 &driverMinor);
137 if (n == 4) {
138 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
139 }
140 return;
141 }
142 }
143
144 if (vendor == kGoogle_GrGLVendor) {
145 // Swiftshader is the only Google vendor at the moment
146 *outDriver = kSwiftShader_GrGLDriver;
147
148 // Swiftshader has a strange version string: w.x.y.z Going to arbitrarily ignore
149 // y and assume w,x and z are major, minor, point.
150 // As of writing, version is 4.0.0.6
151 int n = sscanf(versionString, "OpenGL ES %d.%d SwiftShader %d.%d.0.%d", &major, &minor,
152 &driverMajor, &driverMinor, &driverPoint);
153 if (n == 5) {
154 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
155 }
156 return;
157 }
158
159 if (vendor == kIntel_GrGLVendor) {
160 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
161 *outDriver = kIntel_GrGLDriver;
162
163 //This is how the macOS version strings are structured. This might be different on different
164 // OSes.
165 int n = sscanf(versionString, "%d.%d INTEL-%d.%d.%d", &major, &minor, &driverMajor,
166 &driverMinor, &driverPoint);
167 if (n == 5) {
168 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
169 }
170 }
171
172 if (vendor == kQualcomm_GrGLVendor) {
173 *outDriver = kQualcomm_GrGLDriver;
174 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
175 &driverMinor);
176 if (n == 4) {
177 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
178 }
179 return;
180 }
181
182 if (vendor == kImagination_GrGLVendor) {
183 int revision;
184 int n = sscanf(versionString, "OpenGL ES %d.%d build %d.%d@%d", &major, &minor,
185 &driverMajor, &driverMinor, &revision);
186 if (n == 5) {
187 // Revision is a large number (looks like a source control revision number) that
188 // doesn't fit into the 'patch' bits, so omit it until we need it.
189 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
190 }
191 return;
192 }
193
194 static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
195 if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
196 *outDriver = kAndroidEmulator_GrGLDriver;
197 }
198}
199
200GrGLVersion GrGLGetVersionFromString(const char* versionString) {
201 if (nullptr == versionString) {
202 SkDebugf("nullptr GL version string.");
203 return GR_GL_INVALID_VER;
204 }
205
206 int major, minor;
207
208 // check for mesa
209 int mesaMajor, mesaMinor;
210 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
211 if (4 == n) {
212 return GR_GL_VER(major, minor);
213 }
214
215 n = sscanf(versionString, "%d.%d", &major, &minor);
216 if (2 == n) {
217 return GR_GL_VER(major, minor);
218 }
219
220 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
221 int esMajor, esMinor;
222 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
223 if (4 == n) {
224 return GR_GL_VER(major, minor);
225 }
226
227 char profile[2];
228 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
229 &major, &minor);
230 if (4 == n) {
231 return GR_GL_VER(major, minor);
232 }
233
234 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
235 if (2 == n) {
236 return GR_GL_VER(major, minor);
237 }
238
239 return GR_GL_INVALID_VER;
240}
241
242GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
243 if (nullptr == versionString) {
244 SkDebugf("nullptr GLSL version string.");
245 return GR_GLSL_INVALID_VER;
246 }
247
248 int major, minor;
249
250 int n = sscanf(versionString, "%d.%d", &major, &minor);
251 if (2 == n) {
252 return GR_GLSL_VER(major, minor);
253 }
254
255 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
256 if (2 == n) {
257 return GR_GLSL_VER(major, minor);
258 }
259
260#ifdef SK_BUILD_FOR_ANDROID
261 // android hack until the gpu vender updates their drivers
262 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
263 if (2 == n) {
264 return GR_GLSL_VER(major, minor);
265 }
266#endif
267
268 return GR_GLSL_INVALID_VER;
269}
270
271GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
272 if (vendorString) {
273 if (0 == strcmp(vendorString, "ARM")) {
274 return kARM_GrGLVendor;
275 }
276 if (0 == strcmp(vendorString, "Google Inc.")) {
277 return kGoogle_GrGLVendor;
278 }
279 if (0 == strcmp(vendorString, "Imagination Technologies")) {
280 return kImagination_GrGLVendor;
281 }
282 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
283 return kIntel_GrGLVendor;
284 }
285 if (0 == strcmp(vendorString, "Qualcomm") || 0 == strcmp(vendorString, "freedreno")) {
286 return kQualcomm_GrGLVendor;
287 }
288 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
289 return kNVIDIA_GrGLVendor;
290 }
291 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
292 return kATI_GrGLVendor;
293 }
294 }
295 return kOther_GrGLVendor;
296}
297
298static bool is_renderer_angle(const char* rendererString) {
299 static constexpr char kHeader[] = "ANGLE ";
300 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
301 return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
302}
303
304GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
305 const GrGLExtensions& extensions) {
306 if (rendererString) {
307 static const char kTegraStr[] = "NVIDIA Tegra";
308 if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
309 // Tegra strings are not very descriptive. We distinguish between the modern and legacy
310 // architectures by the presence of NV_path_rendering.
311 return extensions.has("GL_NV_path_rendering") ? kTegra_GrGLRenderer
312 : kTegra_PreK1_GrGLRenderer;
313 }
314 int lastDigit;
315 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
316 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
317 return kPowerVR54x_GrGLRenderer;
318 }
319 // certain iOS devices also use PowerVR54x GPUs
320 static const char kAppleA4Str[] = "Apple A4";
321 static const char kAppleA5Str[] = "Apple A5";
322 static const char kAppleA6Str[] = "Apple A6";
323 if (0 == strncmp(rendererString, kAppleA4Str,
324 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
325 0 == strncmp(rendererString, kAppleA5Str,
326 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
327 0 == strncmp(rendererString, kAppleA6Str,
328 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
329 return kPowerVR54x_GrGLRenderer;
330 }
331 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
332 static const char kAppleA7Str[] = "Apple A7";
333 static const char kAppleA8Str[] = "Apple A8";
334 if (0 == strncmp(rendererString, kPowerVRRogueStr,
335 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
336 0 == strncmp(rendererString, kAppleA7Str,
337 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
338 0 == strncmp(rendererString, kAppleA8Str,
339 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
340 return kPowerVRRogue_GrGLRenderer;
341 }
342 int adrenoNumber;
343 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
344 if (n < 1) {
345 // retry with freedreno driver
346 n = sscanf(rendererString, "FD%d", &adrenoNumber);
347 }
348 if (1 == n) {
349 if (adrenoNumber >= 300) {
350 if (adrenoNumber < 400) {
351 return kAdreno3xx_GrGLRenderer;
352 }
353 if (adrenoNumber < 500) {
354 return adrenoNumber >= 430
355 ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
356 }
357 if (adrenoNumber < 600) {
358 return kAdreno5xx_GrGLRenderer;
359 }
360 if (adrenoNumber == 615) {
361 return kAdreno615_GrGLRenderer;
362 }
363 if (adrenoNumber == 630) {
364 return kAdreno630_GrGLRenderer;
365 }
366 if (adrenoNumber == 640) {
367 return kAdreno640_GrGLRenderer;
368 }
369 }
370 }
371 if (0 == strcmp("Google SwiftShader", rendererString)) {
372 return kGoogleSwiftShader_GrGLRenderer;
373 }
374
375 if (const char* intelString = strstr(rendererString, "Intel")) {
376 // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
377 if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
378 0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
379 return kIntelHaswell_GrGLRenderer;
380 }
381 if (strstr(intelString, "Sandybridge")) {
382 return kIntelSandyBridge_GrGLRenderer;
383 }
384 if (strstr(intelString, "Bay Trail")) {
385 return kIntelValleyView_GrGLRenderer;
386 }
387 // There are many possible intervening strings here:
388 // 'Intel(R)' is a common prefix
389 // 'Iris' may appear, followed by '(R)' or '(TM)'
390 // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
391 // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
392 //
393 // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
394 // so just skip to that and handle two cases:
395 if (const char* intelGfxString = strstr(intelString, "Graphics")) {
396 int intelNumber;
397 if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
398 sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
399
400 if (intelNumber == 2000 || intelNumber == 3000) {
401 return kIntelSandyBridge_GrGLRenderer;
402 }
403 if (intelNumber == 2500 || intelNumber == 4000) {
404 return kIntelIvyBridge_GrGLRenderer;
405 }
406 if (intelNumber >= 4200 && intelNumber <= 5200) {
407 return kIntelHaswell_GrGLRenderer;
408 }
409 if (intelNumber >= 400 && intelNumber <= 405) {
410 return kIntelCherryView_GrGLRenderer;
411 }
412 if (intelNumber >= 5300 && intelNumber <= 6300) {
413 return kIntelBroadwell_GrGLRenderer;
414 }
415 if (intelNumber >= 500 && intelNumber <= 505) {
416 return kIntelApolloLake_GrGLRenderer;
417 }
418 if (intelNumber >= 510 && intelNumber <= 580) {
419 return kIntelSkyLake_GrGLRenderer;
420 }
421 if (intelNumber >= 600 && intelNumber <= 605) {
422 return kIntelGeminiLake_GrGLRenderer;
423 }
424 // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
425 // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
426 if (intelNumber == 610 || intelNumber == 630) {
427 return strstr(intelString, "UHD") ? kIntelCoffeeLake_GrGLRenderer
428 : kIntelKabyLake_GrGLRenderer;
429 }
430 if (intelNumber >= 610 && intelNumber <= 650) {
431 return kIntelKabyLake_GrGLRenderer;
432 }
433 if (intelNumber == 655) {
434 return kIntelCoffeeLake_GrGLRenderer;
435 }
436 if (intelNumber >= 910 && intelNumber <= 950) {
437 return kIntelIceLake_GrGLRenderer;
438 }
439 }
440 }
441 }
442
443 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
444 static constexpr char kRadeonStr[] = "Radeon ";
445 if (const char* amdString = strstr(rendererString, kRadeonStr)) {
446 amdString += strlen(kRadeonStr);
447 // Sometimes there is a (TM) and sometimes not.
448 static constexpr char kTMStr[] = "(TM) ";
449 if (!strncmp(amdString, kTMStr, strlen(kTMStr))) {
450 amdString += strlen(kTMStr);
451 }
452
453 char amd0, amd1, amd2;
454 int amdModel;
455 n = sscanf(amdString, "R9 M3%c%c", &amd0, &amd1);
456 if (2 == n && isdigit(amd0) && isdigit(amd1)) {
457 return kAMDRadeonR9M3xx_GrGLRenderer;
458 }
459
460 n = sscanf(amdString, "R9 M4%c%c", &amd0, &amd1);
461 if (2 == n && isdigit(amd0) && isdigit(amd1)) {
462 return kAMDRadeonR9M4xx_GrGLRenderer;
463 }
464
465 n = sscanf(amdString, "HD 7%c%c%c Series", &amd0, &amd1, &amd2);
466 if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
467 return kAMDRadeonHD7xxx_GrGLRenderer;
468 }
469
470 n = sscanf(amdString, "Pro 5%c%c%c", &amd0, &amd1, &amd2);
471 if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
472 return kAMDRadeonPro5xxx_GrGLRenderer;
473 }
474
475 n = sscanf(amdString, "Pro Vega %i", &amdModel);
476 if (1 == n) {
477 return kAMDRadeonProVegaxx_GrGLRenderer;
478 }
479 }
480
481 if (strstr(rendererString, "llvmpipe")) {
482 return kGalliumLLVM_GrGLRenderer;
483 }
484 static const char kMaliGStr[] = "Mali-G";
485 if (0 == strncmp(rendererString, kMaliGStr, SK_ARRAY_COUNT(kMaliGStr) - 1)) {
486 return kMaliG_GrGLRenderer;
487 }
488 static const char kMaliTStr[] = "Mali-T";
489 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
490 return kMaliT_GrGLRenderer;
491 }
492 int mali400Num;
493 if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
494 mali400Num < 500) {
495 return kMali4xx_GrGLRenderer;
496 }
497 if (is_renderer_angle(rendererString)) {
498 return kANGLE_GrGLRenderer;
499 }
500 }
501 return kOther_GrGLRenderer;
502}
503
504std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfoFromString(
505 const char* rendererString) {
506 auto backend = GrGLANGLEBackend::kUnknown;
507 auto vendor = GrGLANGLEVendor::kUnknown;
508 auto renderer = GrGLANGLERenderer::kUnknown;
509 if (!is_renderer_angle(rendererString)) {
510 return {backend, vendor, renderer};
511 }
512 if (strstr(rendererString, "Intel")) {
513 vendor = GrGLANGLEVendor::kIntel;
514
515 const char* modelStr;
516 int modelNumber;
517 if ((modelStr = strstr(rendererString, "HD Graphics")) &&
518 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
519 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
520 switch (modelNumber) {
521 case 2000:
522 case 3000:
523 renderer = GrGLANGLERenderer::kSandyBridge;
524 break;
525 case 4000:
526 case 2500:
527 renderer = GrGLANGLERenderer::kIvyBridge;
528 break;
529 case 510:
530 case 515:
531 case 520:
532 case 530:
533 renderer = GrGLANGLERenderer::kSkylake;
534 break;
535 }
536 } else if ((modelStr = strstr(rendererString, "Iris")) &&
537 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
538 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
539 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
540 switch (modelNumber) {
541 case 540:
542 case 550:
543 case 555:
544 case 580:
545 renderer = GrGLANGLERenderer::kSkylake;
546 break;
547 }
548 }
549 } else if (strstr(rendererString, "NVIDIA")) {
550 vendor = GrGLANGLEVendor::kNVIDIA;
551 } else if (strstr(rendererString, "Radeon")) {
552 vendor = GrGLANGLEVendor::kAMD;
553 }
554 if (strstr(rendererString, "Direct3D11")) {
555 backend = GrGLANGLEBackend::kD3D11;
556 } else if (strstr(rendererString, "Direct3D9")) {
557 backend = GrGLANGLEBackend::kD3D9;
558 } else if (strstr(rendererString, "OpenGL")) {
559 backend = GrGLANGLEBackend::kOpenGL;
560 }
561 return {backend, vendor, renderer};
562}
563
564GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
565 const GrGLubyte* v;
566 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
567 return GrGLGetVersionFromString((const char*) v);
568}
569
570GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
571 const GrGLubyte* v;
572 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
573 return GrGLGetGLSLVersionFromString((const char*) v);
574}
575
576GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
577 const GrGLubyte* v;
578 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
579 return GrGLGetVendorFromString((const char*) v);
580}
581
582GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
583 const GrGLubyte* rendererString;
584 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
585
586 return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
587}
588
589std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfo(
590 const GrGLInterface* gl) {
591 const GrGLubyte* rendererString;
592 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
593 return GrGLGetANGLEInfoFromString((const char*)rendererString);
594}
595
596GrGLenum GrToGLStencilFunc(GrStencilTest test) {
597 static const GrGLenum gTable[kGrStencilTestCount] = {
598 GR_GL_ALWAYS, // kAlways
599 GR_GL_NEVER, // kNever
600 GR_GL_GREATER, // kGreater
601 GR_GL_GEQUAL, // kGEqual
602 GR_GL_LESS, // kLess
603 GR_GL_LEQUAL, // kLEqual
604 GR_GL_EQUAL, // kEqual
605 GR_GL_NOTEQUAL, // kNotEqual
606 };
607 static_assert(0 == (int)GrStencilTest::kAlways);
608 static_assert(1 == (int)GrStencilTest::kNever);
609 static_assert(2 == (int)GrStencilTest::kGreater);
610 static_assert(3 == (int)GrStencilTest::kGEqual);
611 static_assert(4 == (int)GrStencilTest::kLess);
612 static_assert(5 == (int)GrStencilTest::kLEqual);
613 static_assert(6 == (int)GrStencilTest::kEqual);
614 static_assert(7 == (int)GrStencilTest::kNotEqual);
615 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
616
617 return gTable[(int)test];
618}
619
620bool GrGLFormatIsCompressed(GrGLFormat format) {
621 switch (format) {
622 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
623 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
624 case GrGLFormat::kCOMPRESSED_RGB8_BC1:
625 case GrGLFormat::kCOMPRESSED_RGBA8_BC1:
626 return true;
627
628 case GrGLFormat::kRGBA8:
629 case GrGLFormat::kR8:
630 case GrGLFormat::kALPHA8:
631 case GrGLFormat::kLUMINANCE8:
632 case GrGLFormat::kBGRA8:
633 case GrGLFormat::kRGB565:
634 case GrGLFormat::kRGBA16F:
635 case GrGLFormat::kR16F:
636 case GrGLFormat::kLUMINANCE16F:
637 case GrGLFormat::kRGB8:
638 case GrGLFormat::kRG8:
639 case GrGLFormat::kRGB10_A2:
640 case GrGLFormat::kRGBA4:
641 case GrGLFormat::kSRGB8_ALPHA8:
642 case GrGLFormat::kR16:
643 case GrGLFormat::kRG16:
644 case GrGLFormat::kRGBA16:
645 case GrGLFormat::kRG16F:
646 case GrGLFormat::kUnknown:
647 return false;
648 }
649 SkUNREACHABLE;
650}
651
652