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
GrGLClearErr(const GrGLInterface * gl)15 void GrGLClearErr(const GrGLInterface* gl) {
16 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
17 }
18
19 namespace {
get_error_string(uint32_t err)20 const 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
GrGLCheckErr(const GrGLInterface * gl,const char * location,const char * call)39 void 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
GrGLGetStandardInUseFromString(const char * versionString)67 GrGLStandard 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
GrGLGetDriverInfo(GrGLStandard standard,GrGLVendor vendor,const char * rendererString,const char * versionString,GrGLDriver * outDriver,GrGLDriverVersion * outVersion)104 void 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)];
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 (kNVIDIA_GrGLVendor == vendor) {
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 (5 == n) {
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 (4 == n) {
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 (kNVIDIA_GrGLVendor == vendor) {
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 (4 == n) {
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 (4 == n) {
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 (4 == n) {
178 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
179 }
180 return;
181 }
182 }
183
184 if (kGoogle_GrGLVendor == vendor) {
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 (5 == n) {
194 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
195 }
196 return;
197 }
198
199 if (kIntel_GrGLVendor == vendor) {
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 (5 == n) {
208 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
209 }
210 }
211
212 if (kQualcomm_GrGLVendor == vendor) {
213 *outDriver = kQualcomm_GrGLDriver;
214 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
215 &driverMinor);
216 if (4 == n) {
217 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
218 }
219 return;
220 }
221 static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
222 if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
223 *outDriver = kAndroidEmulator_GrGLDriver;
224 }
225 }
226
GrGLGetVersionFromString(const char * versionString)227 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
228 if (nullptr == versionString) {
229 SkDebugf("nullptr GL version string.");
230 return GR_GL_INVALID_VER;
231 }
232
233 int major, minor;
234
235 // check for mesa
236 int mesaMajor, mesaMinor;
237 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
238 if (4 == n) {
239 return GR_GL_VER(major, minor);
240 }
241
242 n = sscanf(versionString, "%d.%d", &major, &minor);
243 if (2 == n) {
244 return GR_GL_VER(major, minor);
245 }
246
247 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
248 int esMajor, esMinor;
249 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
250 if (4 == n) {
251 return GR_GL_VER(major, minor);
252 }
253
254 char profile[2];
255 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
256 &major, &minor);
257 if (4 == n) {
258 return GR_GL_VER(major, minor);
259 }
260
261 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
262 if (2 == n) {
263 return GR_GL_VER(major, minor);
264 }
265
266 return GR_GL_INVALID_VER;
267 }
268
GrGLGetGLSLVersionFromString(const char * versionString)269 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
270 if (nullptr == versionString) {
271 SkDebugf("nullptr GLSL version string.");
272 return GR_GLSL_INVALID_VER;
273 }
274
275 int major, minor;
276
277 int n = sscanf(versionString, "%d.%d", &major, &minor);
278 if (2 == n) {
279 return GR_GLSL_VER(major, minor);
280 }
281
282 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
283 if (2 == n) {
284 return GR_GLSL_VER(major, minor);
285 }
286
287 #ifdef SK_BUILD_FOR_ANDROID
288 // android hack until the gpu vender updates their drivers
289 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
290 if (2 == n) {
291 return GR_GLSL_VER(major, minor);
292 }
293 #endif
294
295 return GR_GLSL_INVALID_VER;
296 }
297
GrGLGetVendorFromString(const char * vendorString)298 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
299 if (vendorString) {
300 if (0 == strcmp(vendorString, "ARM")) {
301 return kARM_GrGLVendor;
302 }
303 if (0 == strcmp(vendorString, "Google Inc.")) {
304 return kGoogle_GrGLVendor;
305 }
306 if (0 == strcmp(vendorString, "Imagination Technologies")) {
307 return kImagination_GrGLVendor;
308 }
309 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
310 return kIntel_GrGLVendor;
311 }
312 if (0 == strcmp(vendorString, "Qualcomm")) {
313 return kQualcomm_GrGLVendor;
314 }
315 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
316 return kNVIDIA_GrGLVendor;
317 }
318 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
319 return kATI_GrGLVendor;
320 }
321 }
322 return kOther_GrGLVendor;
323 }
324
is_renderer_angle(const char * rendererString)325 static bool is_renderer_angle(const char* rendererString) {
326 static constexpr char kHeader[] = "ANGLE ";
327 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
328 return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
329 }
330
GrGLGetRendererFromStrings(const char * rendererString,const GrGLExtensions & extensions)331 GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
332 const GrGLExtensions& extensions) {
333 if (rendererString) {
334 static const char kTegraStr[] = "NVIDIA Tegra";
335 if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
336 // Tegra strings are not very descriptive. We distinguish between the modern and legacy
337 // architectures by the presence of NV_path_rendering.
338 return extensions.has("GL_NV_path_rendering") ? kTegra_GrGLRenderer
339 : kTegra_PreK1_GrGLRenderer;
340 }
341 int lastDigit;
342 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
343 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
344 return kPowerVR54x_GrGLRenderer;
345 }
346 // certain iOS devices also use PowerVR54x GPUs
347 static const char kAppleA4Str[] = "Apple A4";
348 static const char kAppleA5Str[] = "Apple A5";
349 static const char kAppleA6Str[] = "Apple A6";
350 if (0 == strncmp(rendererString, kAppleA4Str,
351 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
352 0 == strncmp(rendererString, kAppleA5Str,
353 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
354 0 == strncmp(rendererString, kAppleA6Str,
355 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
356 return kPowerVR54x_GrGLRenderer;
357 }
358 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
359 static const char kAppleA7Str[] = "Apple A7";
360 static const char kAppleA8Str[] = "Apple A8";
361 if (0 == strncmp(rendererString, kPowerVRRogueStr,
362 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
363 0 == strncmp(rendererString, kAppleA7Str,
364 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
365 0 == strncmp(rendererString, kAppleA8Str,
366 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
367 return kPowerVRRogue_GrGLRenderer;
368 }
369 int adrenoNumber;
370 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
371 if (1 == n) {
372 if (adrenoNumber >= 300) {
373 if (adrenoNumber < 400) {
374 return kAdreno3xx_GrGLRenderer;
375 }
376 if (adrenoNumber < 500) {
377 return adrenoNumber >= 430
378 ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
379 }
380 if (adrenoNumber < 600) {
381 return kAdreno5xx_GrGLRenderer;
382 }
383 }
384 }
385 if (0 == strcmp("Google SwiftShader", rendererString)) {
386 return kGoogleSwiftShader_GrGLRenderer;
387 }
388
389 if (const char* intelString = strstr(rendererString, "Intel")) {
390 // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
391 if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
392 0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
393 return kIntelHaswell_GrGLRenderer;
394 }
395 if (strstr(intelString, "Sandybridge")) {
396 return kIntelSandyBridge_GrGLRenderer;
397 }
398 if (strstr(intelString, "Bay Trail")) {
399 return kIntelValleyView_GrGLRenderer;
400 }
401 // There are many possible intervening strings here:
402 // 'Intel(R)' is a common prefix
403 // 'Iris' may appear, followed by '(R)' or '(TM)'
404 // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
405 // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
406 //
407 // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
408 // so just skip to that and handle two cases:
409 if (const char* intelGfxString = strstr(intelString, "Graphics")) {
410 int intelNumber;
411 if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
412 sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
413
414 if (intelNumber == 2000 || intelNumber == 3000) {
415 return kIntelSandyBridge_GrGLRenderer;
416 }
417 if (intelNumber == 2500 || intelNumber == 4000) {
418 return kIntelIvyBridge_GrGLRenderer;
419 }
420 if (intelNumber >= 4200 && intelNumber <= 5200) {
421 return kIntelHaswell_GrGLRenderer;
422 }
423 if (intelNumber >= 400 && intelNumber <= 405) {
424 return kIntelCherryView_GrGLRenderer;
425 }
426 if (intelNumber >= 5300 && intelNumber <= 6300) {
427 return kIntelBroadwell_GrGLRenderer;
428 }
429 if (intelNumber >= 500 && intelNumber <= 505) {
430 return kIntelApolloLake_GrGLRenderer;
431 }
432 if (intelNumber >= 510 && intelNumber <= 580) {
433 return kIntelSkyLake_GrGLRenderer;
434 }
435 if (intelNumber >= 600 && intelNumber <= 605) {
436 return kIntelGeminiLake_GrGLRenderer;
437 }
438 // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
439 // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
440 if (intelNumber == 610 || intelNumber == 630) {
441 return strstr(intelString, "UHD") ? kIntelCoffeeLake_GrGLRenderer
442 : kIntelKabyLake_GrGLRenderer;
443 }
444 if (intelNumber >= 610 && intelNumber <= 650) {
445 return kIntelKabyLake_GrGLRenderer;
446 }
447 if (intelNumber == 655) {
448 return kIntelCoffeeLake_GrGLRenderer;
449 }
450 if (intelNumber >= 910 && intelNumber <= 950) {
451 return kIntelIceLake_GrGLRenderer;
452 }
453 }
454 }
455 }
456
457 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
458 if (const char* amdString = strstr(rendererString, "Radeon")) {
459 char amdGeneration, amdTier, amdRevision;
460 n = sscanf(amdString, "Radeon (TM) R9 M%c%c%c",
461 &amdGeneration, &amdTier, &amdRevision);
462 if (3 == n) {
463 if ('4' == amdGeneration) {
464 return kAMDRadeonR9M4xx_GrGLRenderer;
465 }
466 }
467
468 char amd0, amd1, amd2;
469 n = sscanf(amdString, "Radeon HD 7%c%c%c Series", &amd0, &amd1, &amd2);
470 if (3 == n) {
471 return kAMDRadeonHD7xxx_GrGLRenderer;
472 }
473 }
474
475 if (0 == strcmp("Mesa Offscreen", rendererString)) {
476 return kOSMesa_GrGLRenderer;
477 }
478 if (strstr(rendererString, "llvmpipe")) {
479 return kGalliumLLVM_GrGLRenderer;
480 }
481 static const char kMaliTStr[] = "Mali-T";
482 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
483 return kMaliT_GrGLRenderer;
484 }
485 int mali400Num;
486 if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
487 mali400Num < 500) {
488 return kMali4xx_GrGLRenderer;
489 }
490 if (is_renderer_angle(rendererString)) {
491 return kANGLE_GrGLRenderer;
492 }
493 }
494 return kOther_GrGLRenderer;
495 }
496
GrGLGetANGLEInfoFromString(const char * rendererString,GrGLANGLEBackend * backend,GrGLANGLEVendor * vendor,GrGLANGLERenderer * renderer)497 void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend* backend,
498 GrGLANGLEVendor* vendor, GrGLANGLERenderer* renderer) {
499 *backend = GrGLANGLEBackend::kUnknown;
500 *vendor = GrGLANGLEVendor::kUnknown;
501 *renderer = GrGLANGLERenderer::kUnknown;
502 if (!is_renderer_angle(rendererString)) {
503 return;
504 }
505 if (strstr(rendererString, "Intel")) {
506 *vendor = GrGLANGLEVendor::kIntel;
507
508 const char* modelStr;
509 int modelNumber;
510 if ((modelStr = strstr(rendererString, "HD Graphics")) &&
511 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
512 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
513 switch (modelNumber) {
514 case 2000:
515 case 3000:
516 *renderer = GrGLANGLERenderer::kSandyBridge;
517 break;
518 case 4000:
519 case 2500:
520 *renderer = GrGLANGLERenderer::kIvyBridge;
521 break;
522 case 510:
523 case 515:
524 case 520:
525 case 530:
526 *renderer = GrGLANGLERenderer::kSkylake;
527 break;
528 }
529 } else if ((modelStr = strstr(rendererString, "Iris")) &&
530 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
531 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
532 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
533 switch (modelNumber) {
534 case 540:
535 case 550:
536 case 555:
537 case 580:
538 *renderer = GrGLANGLERenderer::kSkylake;
539 break;
540 }
541 }
542 }
543 if (strstr(rendererString, "Direct3D11")) {
544 *backend = GrGLANGLEBackend::kD3D11;
545 } else if (strstr(rendererString, "Direct3D9")) {
546 *backend = GrGLANGLEBackend::kD3D9;
547 } else if (strstr(rendererString, "OpenGL")) {
548 *backend = GrGLANGLEBackend::kOpenGL;
549 }
550 }
551
GrGLGetVersion(const GrGLInterface * gl)552 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
553 const GrGLubyte* v;
554 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
555 return GrGLGetVersionFromString((const char*) v);
556 }
557
GrGLGetGLSLVersion(const GrGLInterface * gl)558 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
559 const GrGLubyte* v;
560 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
561 return GrGLGetGLSLVersionFromString((const char*) v);
562 }
563
GrGLGetVendor(const GrGLInterface * gl)564 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
565 const GrGLubyte* v;
566 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
567 return GrGLGetVendorFromString((const char*) v);
568 }
569
GrGLGetRenderer(const GrGLInterface * gl)570 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
571 const GrGLubyte* rendererString;
572 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
573
574 return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
575 }
576
GrToGLStencilFunc(GrStencilTest test)577 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
578 static const GrGLenum gTable[kGrStencilTestCount] = {
579 GR_GL_ALWAYS, // kAlways
580 GR_GL_NEVER, // kNever
581 GR_GL_GREATER, // kGreater
582 GR_GL_GEQUAL, // kGEqual
583 GR_GL_LESS, // kLess
584 GR_GL_LEQUAL, // kLEqual
585 GR_GL_EQUAL, // kEqual
586 GR_GL_NOTEQUAL, // kNotEqual
587 };
588 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
589 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
590 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
591 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
592 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
593 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
594 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
595 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
596 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
597
598 return gTable[(int)test];
599 }
600
GrGLFormatIsCompressed(GrGLFormat format)601 bool GrGLFormatIsCompressed(GrGLFormat format) {
602 switch (format) {
603 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
604 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
605 case GrGLFormat::kCOMPRESSED_ASTC_RGB8:
606 return true;
607
608 case GrGLFormat::kRGBA8:
609 case GrGLFormat::kR8:
610 case GrGLFormat::kALPHA8:
611 case GrGLFormat::kLUMINANCE8:
612 case GrGLFormat::kBGRA8:
613 case GrGLFormat::kRGB565:
614 case GrGLFormat::kRGBA16F:
615 case GrGLFormat::kR16F:
616 case GrGLFormat::kLUMINANCE16F:
617 case GrGLFormat::kRGB8:
618 case GrGLFormat::kRG8:
619 case GrGLFormat::kRGB10_A2:
620 case GrGLFormat::kRGBA4:
621 case GrGLFormat::kRGBA32F:
622 case GrGLFormat::kSRGB8_ALPHA8:
623 case GrGLFormat::kR16:
624 case GrGLFormat::kRG16:
625 case GrGLFormat::kRGBA16:
626 case GrGLFormat::kRG16F:
627 case GrGLFormat::kUnknown:
628 return false;
629 }
630 SkUNREACHABLE;
631 }
632
GrGLFormatToCompressionType(GrGLFormat format,SkImage::CompressionType * compressionType)633 bool GrGLFormatToCompressionType(GrGLFormat format, SkImage::CompressionType* compressionType) {
634 switch (format) {
635 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
636 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
637 *compressionType = SkImage::kETC1_CompressionType;
638 return true;
639 case GrGLFormat::kCOMPRESSED_ASTC_RGB8:
640 *compressionType = SkImage::kASTC_CompressionType;
641 return true;
642 case GrGLFormat::kRGBA8:
643 case GrGLFormat::kR8:
644 case GrGLFormat::kALPHA8:
645 case GrGLFormat::kLUMINANCE8:
646 case GrGLFormat::kBGRA8:
647 case GrGLFormat::kRGB565:
648 case GrGLFormat::kRGBA16F:
649 case GrGLFormat::kR16F:
650 case GrGLFormat::kLUMINANCE16F:
651 case GrGLFormat::kRGB8:
652 case GrGLFormat::kRG8:
653 case GrGLFormat::kRGB10_A2:
654 case GrGLFormat::kRGBA4:
655 case GrGLFormat::kRGBA32F:
656 case GrGLFormat::kSRGB8_ALPHA8:
657 case GrGLFormat::kR16:
658 case GrGLFormat::kRG16:
659 case GrGLFormat::kRGBA16:
660 case GrGLFormat::kRG16F:
661 case GrGLFormat::kUnknown:
662 return false;
663 }
664 SkUNREACHABLE;
665 }
666
GrGLBytesPerFormat(GrGLFormat glFormat)667 size_t GrGLBytesPerFormat(GrGLFormat glFormat) {
668 switch (glFormat) {
669 case GrGLFormat::kLUMINANCE8:
670 case GrGLFormat::kALPHA8:
671 case GrGLFormat::kR8:
672 return 1;
673
674 case GrGLFormat::kRGB565:
675 case GrGLFormat::kRGBA4:
676 case GrGLFormat::kRG8:
677 case GrGLFormat::kR16F:
678 case GrGLFormat::kLUMINANCE16F:
679 case GrGLFormat::kR16:
680 return 2;
681
682 case GrGLFormat::kRGB8:
683 return 3;
684
685 case GrGLFormat::kRGBA8:
686 case GrGLFormat::kSRGB8_ALPHA8:
687 case GrGLFormat::kBGRA8:
688 case GrGLFormat::kRGB10_A2:
689 case GrGLFormat::kRG16:
690 case GrGLFormat::kRG16F:
691 return 4;
692
693 case GrGLFormat::kRGBA16F:
694 case GrGLFormat::kRGBA16:
695 return 8;
696
697 case GrGLFormat::kRGBA32F:
698 return 16;
699
700 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
701 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
702 case GrGLFormat::kCOMPRESSED_ASTC_RGB8:
703 case GrGLFormat::kUnknown:
704 return 0;
705 }
706 SkUNREACHABLE;
707 }
708