• 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 "SkMatrix.h"
11 #include <stdio.h>
12 
GrGLClearErr(const GrGLInterface * gl)13 void GrGLClearErr(const GrGLInterface* gl) {
14     while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
15 }
16 
17 namespace {
get_error_string(uint32_t err)18 const char *get_error_string(uint32_t err) {
19     switch (err) {
20     case GR_GL_NO_ERROR:
21         return "";
22     case GR_GL_INVALID_ENUM:
23         return "Invalid Enum";
24     case GR_GL_INVALID_VALUE:
25         return "Invalid Value";
26     case GR_GL_INVALID_OPERATION:
27         return "Invalid Operation";
28     case GR_GL_OUT_OF_MEMORY:
29         return "Out of Memory";
30     case GR_GL_CONTEXT_LOST:
31         return "Context Lost";
32     }
33     return "Unknown";
34 }
35 }
36 
GrGLCheckErr(const GrGLInterface * gl,const char * location,const char * call)37 void GrGLCheckErr(const GrGLInterface* gl,
38                   const char* location,
39                   const char* call) {
40     uint32_t err = GR_GL_GET_ERROR(gl);
41     if (GR_GL_NO_ERROR != err) {
42         SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
43         if (location) {
44             SkDebugf(" at\n\t%s", location);
45         }
46         if (call) {
47             SkDebugf("\n\t\t%s", call);
48         }
49         SkDebugf("\n");
50     }
51 }
52 
53 ///////////////////////////////////////////////////////////////////////////////
54 
55 #if GR_GL_LOG_CALLS
56     bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
57 #endif
58 
59 #if GR_GL_CHECK_ERROR
60     bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
61 #endif
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 
GrGLGetStandardInUseFromString(const char * versionString)65 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
66     if (nullptr == versionString) {
67         SkDebugf("nullptr GL version string.");
68         return kNone_GrGLStandard;
69     }
70 
71     int major, minor;
72 
73     // check for desktop
74     int n = sscanf(versionString, "%d.%d", &major, &minor);
75     if (2 == n) {
76         return kGL_GrGLStandard;
77     }
78 
79     // check for ES 1
80     char profile[2];
81     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
82     if (4 == n) {
83         // we no longer support ES1.
84         return kNone_GrGLStandard;
85     }
86 
87     // check for ES2
88     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
89     if (2 == n) {
90         return kGLES_GrGLStandard;
91     }
92     return kNone_GrGLStandard;
93 }
94 
GrGLGetDriverInfo(GrGLStandard standard,GrGLVendor vendor,const char * rendererString,const char * versionString,GrGLDriver * outDriver,GrGLDriverVersion * outVersion)95 void GrGLGetDriverInfo(GrGLStandard standard,
96                        GrGLVendor vendor,
97                        const char* rendererString,
98                        const char* versionString,
99                        GrGLDriver* outDriver,
100                        GrGLDriverVersion* outVersion) {
101     int major, minor, rev, driverMajor, driverMinor;
102 
103     *outDriver = kUnknown_GrGLDriver;
104     *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
105     // These null checks are for test GL contexts that return nullptr in their
106     // glGetString implementation.
107     if (!rendererString) {
108         rendererString = "";
109     }
110     if (!versionString) {
111         versionString = "";
112     }
113 
114     static const char kChromium[] = "Chromium";
115     char suffix[SK_ARRAY_COUNT(kChromium)];
116     if (0 == strcmp(rendererString, kChromium) ||
117         (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
118          0 == strcmp(kChromium, suffix))) {
119         *outDriver = kChromium_GrGLDriver;
120         return;
121     }
122 
123     if (standard == kGL_GrGLStandard) {
124         if (kNVIDIA_GrGLVendor == vendor) {
125             *outDriver = kNVIDIA_GrGLDriver;
126             int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
127                            &major, &minor, &rev, &driverMajor, &driverMinor);
128             // Some older NVIDIA drivers don't report the driver version.
129             if (5 == n) {
130                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
131             }
132             return;
133         }
134         int n = sscanf(versionString, "%d.%d Mesa %d.%d",
135                        &major, &minor, &driverMajor, &driverMinor);
136         if (4 == n) {
137             *outDriver = kMesa_GrGLDriver;
138             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
139             return;
140         }
141     }
142     else {
143         if (kNVIDIA_GrGLVendor == vendor) {
144             *outDriver = kNVIDIA_GrGLDriver;
145             int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
146                            &major, &minor, &driverMajor, &driverMinor);
147             // Some older NVIDIA drivers don't report the driver version.
148             if (4 == n) {
149                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
150             }
151             return;
152         }
153 
154         int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
155                        &major, &minor, &driverMajor, &driverMinor);
156         if (4 == n) {
157             *outDriver = kMesa_GrGLDriver;
158             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
159             return;
160         }
161         if (0 == strncmp("ANGLE", rendererString, 5)) {
162             *outDriver = kANGLE_GrGLDriver;
163             n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
164                                                                       &driverMinor);
165             if (4 == n) {
166                 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
167             }
168             return;
169         }
170     }
171 
172     if (kIntel_GrGLVendor == vendor) {
173         // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
174         *outDriver = kIntel_GrGLDriver;
175     }
176 
177     if (kQualcomm_GrGLVendor == vendor) {
178         *outDriver = kQualcomm_GrGLDriver;
179         int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
180                        &driverMinor);
181         if (4 == n) {
182             *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
183         }
184         return;
185     }
186 }
187 
GrGLGetVersionFromString(const char * versionString)188 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
189     if (nullptr == versionString) {
190         SkDebugf("nullptr GL version string.");
191         return GR_GL_INVALID_VER;
192     }
193 
194     int major, minor;
195 
196     // check for mesa
197     int mesaMajor, mesaMinor;
198     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
199     if (4 == n) {
200         return GR_GL_VER(major, minor);
201     }
202 
203     n = sscanf(versionString, "%d.%d", &major, &minor);
204     if (2 == n) {
205         return GR_GL_VER(major, minor);
206     }
207 
208     char profile[2];
209     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
210                &major, &minor);
211     if (4 == n) {
212         return GR_GL_VER(major, minor);
213     }
214 
215     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
216     if (2 == n) {
217         return GR_GL_VER(major, minor);
218     }
219 
220     return GR_GL_INVALID_VER;
221 }
222 
GrGLGetGLSLVersionFromString(const char * versionString)223 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
224     if (nullptr == versionString) {
225         SkDebugf("nullptr GLSL version string.");
226         return GR_GLSL_INVALID_VER;
227     }
228 
229     int major, minor;
230 
231     int n = sscanf(versionString, "%d.%d", &major, &minor);
232     if (2 == n) {
233         return GR_GLSL_VER(major, minor);
234     }
235 
236     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
237     if (2 == n) {
238         return GR_GLSL_VER(major, minor);
239     }
240 
241 #ifdef SK_BUILD_FOR_ANDROID
242     // android hack until the gpu vender updates their drivers
243     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
244     if (2 == n) {
245         return GR_GLSL_VER(major, minor);
246     }
247 #endif
248 
249     return GR_GLSL_INVALID_VER;
250 }
251 
GrGLGetVendorFromString(const char * vendorString)252 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
253     if (vendorString) {
254         if (0 == strcmp(vendorString, "ARM")) {
255             return kARM_GrGLVendor;
256         }
257         if (0 == strcmp(vendorString, "Imagination Technologies")) {
258             return kImagination_GrGLVendor;
259         }
260         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
261             return kIntel_GrGLVendor;
262         }
263         if (0 == strcmp(vendorString, "Qualcomm")) {
264             return kQualcomm_GrGLVendor;
265         }
266         if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
267             return kNVIDIA_GrGLVendor;
268         }
269         if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
270             return kATI_GrGLVendor;
271         }
272     }
273     return kOther_GrGLVendor;
274 }
275 
GrGLGetRendererFromString(const char * rendererString)276 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
277     if (rendererString) {
278         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
279             return kTegra3_GrGLRenderer;
280         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
281             return kTegra2_GrGLRenderer;
282         }
283         int lastDigit;
284         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
285         if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
286             return kPowerVR54x_GrGLRenderer;
287         }
288         // certain iOS devices also use PowerVR54x GPUs
289         static const char kAppleA4Str[] = "Apple A4";
290         static const char kAppleA5Str[] = "Apple A5";
291         static const char kAppleA6Str[] = "Apple A6";
292         if (0 == strncmp(rendererString, kAppleA4Str,
293                          SK_ARRAY_COUNT(kAppleA4Str)-1) ||
294             0 == strncmp(rendererString, kAppleA5Str,
295                          SK_ARRAY_COUNT(kAppleA5Str)-1) ||
296             0 == strncmp(rendererString, kAppleA6Str,
297                          SK_ARRAY_COUNT(kAppleA6Str)-1)) {
298             return kPowerVR54x_GrGLRenderer;
299         }
300         static const char kPowerVRRogueStr[] = "PowerVR Rogue";
301         static const char kAppleA7Str[] = "Apple A7";
302         static const char kAppleA8Str[] = "Apple A8";
303         if (0 == strncmp(rendererString, kPowerVRRogueStr,
304                          SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
305             0 == strncmp(rendererString, kAppleA7Str,
306                          SK_ARRAY_COUNT(kAppleA7Str)-1) ||
307             0 == strncmp(rendererString, kAppleA8Str,
308                          SK_ARRAY_COUNT(kAppleA8Str)-1)) {
309             return kPowerVRRogue_GrGLRenderer;
310         }
311         int adrenoNumber;
312         n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
313         if (1 == n) {
314             if (adrenoNumber >= 300) {
315                 if (adrenoNumber < 400) {
316                     return kAdreno3xx_GrGLRenderer;
317                 }
318                 if (adrenoNumber < 500) {
319                     return kAdreno4xx_GrGLRenderer;
320                 }
321                 if (adrenoNumber < 600) {
322                     return kAdreno5xx_GrGLRenderer;
323                 }
324             }
325         }
326         int intelNumber;
327         n = sscanf(rendererString, "Intel(R) Iris(TM) Graphics %d", &intelNumber);
328         if (1 != n) {
329             n = sscanf(rendererString, "Intel(R) HD Graphics %d", &intelNumber);
330         }
331         if (1 == n) {
332             if (intelNumber >= 6000 && intelNumber < 7000) {
333                 return kIntel6xxx_GrGLRenderer;
334             }
335         }
336         if (0 == strcmp("Mesa Offscreen", rendererString)) {
337             return kOSMesa_GrGLRenderer;
338         }
339         static const char kMaliTStr[] = "Mali-T";
340         if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
341             return kMaliT_GrGLRenderer;
342         }
343         static const char kANGLEStr[] = "ANGLE";
344         if (0 == strncmp(rendererString, kANGLEStr, SK_ARRAY_COUNT(kANGLEStr) - 1)) {
345             return kANGLE_GrGLRenderer;
346         }
347     }
348     return kOther_GrGLRenderer;
349 }
350 
GrGLGetVersion(const GrGLInterface * gl)351 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
352     const GrGLubyte* v;
353     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
354     return GrGLGetVersionFromString((const char*) v);
355 }
356 
GrGLGetGLSLVersion(const GrGLInterface * gl)357 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
358     const GrGLubyte* v;
359     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
360     return GrGLGetGLSLVersionFromString((const char*) v);
361 }
362 
GrGLGetVendor(const GrGLInterface * gl)363 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
364     const GrGLubyte* v;
365     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
366     return GrGLGetVendorFromString((const char*) v);
367 }
368 
GrGLGetRenderer(const GrGLInterface * gl)369 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
370     const GrGLubyte* v;
371     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
372     return GrGLGetRendererFromString((const char*) v);
373 }
374 
GrToGLStencilFunc(GrStencilTest test)375 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
376     static const GrGLenum gTable[kGrStencilTestCount] = {
377         GR_GL_ALWAYS,           // kAlways
378         GR_GL_NEVER,            // kNever
379         GR_GL_GREATER,          // kGreater
380         GR_GL_GEQUAL,           // kGEqual
381         GR_GL_LESS,             // kLess
382         GR_GL_LEQUAL,           // kLEqual
383         GR_GL_EQUAL,            // kEqual
384         GR_GL_NOTEQUAL,         // kNotEqual
385     };
386     GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
387     GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
388     GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
389     GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
390     GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
391     GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
392     GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
393     GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
394     SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
395 
396     return gTable[(int)test];
397 }
398