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