• 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 
GrGLGetVersionFromString(const char * versionString)178 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
179     if (nullptr == versionString) {
180         SkDebugf("nullptr GL version string.");
181         return GR_GL_INVALID_VER;
182     }
183 
184     int major, minor;
185 
186     // check for mesa
187     int mesaMajor, mesaMinor;
188     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
189     if (4 == n) {
190         return GR_GL_VER(major, minor);
191     }
192 
193     n = sscanf(versionString, "%d.%d", &major, &minor);
194     if (2 == n) {
195         return GR_GL_VER(major, minor);
196     }
197 
198     char profile[2];
199     n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
200                &major, &minor);
201     if (4 == n) {
202         return GR_GL_VER(major, minor);
203     }
204 
205     n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
206     if (2 == n) {
207         return GR_GL_VER(major, minor);
208     }
209 
210     return GR_GL_INVALID_VER;
211 }
212 
GrGLGetGLSLVersionFromString(const char * versionString)213 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
214     if (nullptr == versionString) {
215         SkDebugf("nullptr GLSL version string.");
216         return GR_GLSL_INVALID_VER;
217     }
218 
219     int major, minor;
220 
221     int n = sscanf(versionString, "%d.%d", &major, &minor);
222     if (2 == n) {
223         return GR_GLSL_VER(major, minor);
224     }
225 
226     n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
227     if (2 == n) {
228         return GR_GLSL_VER(major, minor);
229     }
230 
231 #ifdef SK_BUILD_FOR_ANDROID
232     // android hack until the gpu vender updates their drivers
233     n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
234     if (2 == n) {
235         return GR_GLSL_VER(major, minor);
236     }
237 #endif
238 
239     return GR_GLSL_INVALID_VER;
240 }
241 
GrGLGetVendorFromString(const char * vendorString)242 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
243     if (vendorString) {
244         if (0 == strcmp(vendorString, "ARM")) {
245             return kARM_GrGLVendor;
246         }
247         if (0 == strcmp(vendorString, "Imagination Technologies")) {
248             return kImagination_GrGLVendor;
249         }
250         if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
251             return kIntel_GrGLVendor;
252         }
253         if (0 == strcmp(vendorString, "Qualcomm")) {
254             return kQualcomm_GrGLVendor;
255         }
256         if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
257             return kNVIDIA_GrGLVendor;
258         }
259         if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
260             return kATI_GrGLVendor;
261         }
262     }
263     return kOther_GrGLVendor;
264 }
265 
GrGLGetRendererFromString(const char * rendererString)266 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
267     if (rendererString) {
268         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
269             return kTegra3_GrGLRenderer;
270         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
271             return kTegra2_GrGLRenderer;
272         }
273         int lastDigit;
274         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
275         if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
276             return kPowerVR54x_GrGLRenderer;
277         }
278         // certain iOS devices also use PowerVR54x GPUs
279         static const char kAppleA4Str[] = "Apple A4";
280         static const char kAppleA5Str[] = "Apple A5";
281         static const char kAppleA6Str[] = "Apple A6";
282         if (0 == strncmp(rendererString, kAppleA4Str,
283                          SK_ARRAY_COUNT(kAppleA4Str)-1) ||
284             0 == strncmp(rendererString, kAppleA5Str,
285                          SK_ARRAY_COUNT(kAppleA5Str)-1) ||
286             0 == strncmp(rendererString, kAppleA6Str,
287                          SK_ARRAY_COUNT(kAppleA6Str)-1)) {
288             return kPowerVR54x_GrGLRenderer;
289         }
290         static const char kPowerVRRogueStr[] = "PowerVR Rogue";
291         static const char kAppleA7Str[] = "Apple A7";
292         static const char kAppleA8Str[] = "Apple A8";
293         if (0 == strncmp(rendererString, kPowerVRRogueStr,
294                          SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
295             0 == strncmp(rendererString, kAppleA7Str,
296                          SK_ARRAY_COUNT(kAppleA7Str)-1) ||
297             0 == strncmp(rendererString, kAppleA8Str,
298                          SK_ARRAY_COUNT(kAppleA8Str)-1)) {
299             return kPowerVRRogue_GrGLRenderer;
300         }
301         int adrenoNumber;
302         n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
303         if (1 == n) {
304             if (adrenoNumber >= 300) {
305                 if (adrenoNumber < 400) {
306                     return kAdreno3xx_GrGLRenderer;
307                 }
308                 if (adrenoNumber < 500) {
309                     return kAdreno4xx_GrGLRenderer;
310                 }
311                 if (adrenoNumber < 600) {
312                     return kAdreno5xx_GrGLRenderer;
313                 }
314             }
315         }
316         if (0 == strcmp("Mesa Offscreen", rendererString)) {
317             return kOSMesa_GrGLRenderer;
318         }
319     }
320     return kOther_GrGLRenderer;
321 }
322 
GrGLGetVersion(const GrGLInterface * gl)323 GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
324     const GrGLubyte* v;
325     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
326     return GrGLGetVersionFromString((const char*) v);
327 }
328 
GrGLGetGLSLVersion(const GrGLInterface * gl)329 GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
330     const GrGLubyte* v;
331     GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
332     return GrGLGetGLSLVersionFromString((const char*) v);
333 }
334 
GrGLGetVendor(const GrGLInterface * gl)335 GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
336     const GrGLubyte* v;
337     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
338     return GrGLGetVendorFromString((const char*) v);
339 }
340 
GrGLGetRenderer(const GrGLInterface * gl)341 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
342     const GrGLubyte* v;
343     GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
344     return GrGLGetRendererFromString((const char*) v);
345 }
346 
GrToGLStencilFunc(GrStencilTest test)347 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
348     static const GrGLenum gTable[kGrStencilTestCount] = {
349         GR_GL_ALWAYS,           // kAlways
350         GR_GL_NEVER,            // kNever
351         GR_GL_GREATER,          // kGreater
352         GR_GL_GEQUAL,           // kGEqual
353         GR_GL_LESS,             // kLess
354         GR_GL_LEQUAL,           // kLEqual
355         GR_GL_EQUAL,            // kEqual
356         GR_GL_NOTEQUAL,         // kNotEqual
357     };
358     GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
359     GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
360     GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
361     GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
362     GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
363     GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
364     GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
365     GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
366     SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
367 
368     return gTable[(int)test];
369 }
370