• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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