Line data Source code
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 :
13 0 : void GrGLClearErr(const GrGLInterface* gl) {
14 0 : while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
15 0 : }
16 :
17 : namespace {
18 0 : const char *get_error_string(uint32_t err) {
19 0 : switch (err) {
20 : case GR_GL_NO_ERROR:
21 0 : return "";
22 : case GR_GL_INVALID_ENUM:
23 0 : return "Invalid Enum";
24 : case GR_GL_INVALID_VALUE:
25 0 : return "Invalid Value";
26 : case GR_GL_INVALID_OPERATION:
27 0 : return "Invalid Operation";
28 : case GR_GL_OUT_OF_MEMORY:
29 0 : return "Out of Memory";
30 : case GR_GL_CONTEXT_LOST:
31 0 : return "Context Lost";
32 : }
33 0 : return "Unknown";
34 : }
35 : }
36 :
37 0 : void GrGLCheckErr(const GrGLInterface* gl,
38 : const char* location,
39 : const char* call) {
40 0 : uint32_t err = GR_GL_GET_ERROR(gl);
41 0 : if (GR_GL_NO_ERROR != err) {
42 0 : SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
43 0 : if (location) {
44 0 : SkDebugf(" at\n\t%s", location);
45 : }
46 0 : if (call) {
47 0 : SkDebugf("\n\t\t%s", call);
48 : }
49 0 : SkDebugf("\n");
50 : }
51 0 : }
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 :
65 0 : GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
66 0 : if (nullptr == versionString) {
67 0 : SkDebugf("nullptr GL version string.");
68 0 : return kNone_GrGLStandard;
69 : }
70 :
71 : int major, minor;
72 :
73 : // check for desktop
74 0 : int n = sscanf(versionString, "%d.%d", &major, &minor);
75 0 : if (2 == n) {
76 0 : return kGL_GrGLStandard;
77 : }
78 :
79 : // check for ES 1
80 : char profile[2];
81 0 : n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
82 0 : if (4 == n) {
83 : // we no longer support ES1.
84 0 : return kNone_GrGLStandard;
85 : }
86 :
87 : // check for ES2
88 0 : n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
89 0 : if (2 == n) {
90 0 : return kGLES_GrGLStandard;
91 : }
92 0 : return kNone_GrGLStandard;
93 : }
94 :
95 0 : 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 0 : *outDriver = kUnknown_GrGLDriver;
104 0 : *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
105 : // These null checks are for test GL contexts that return nullptr in their
106 : // glGetString implementation.
107 0 : if (!rendererString) {
108 0 : rendererString = "";
109 : }
110 0 : if (!versionString) {
111 0 : versionString = "";
112 : }
113 :
114 : static const char kChromium[] = "Chromium";
115 : char suffix[SK_ARRAY_COUNT(kChromium)];
116 0 : if (0 == strcmp(rendererString, kChromium) ||
117 0 : (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
118 0 : 0 == strcmp(kChromium, suffix))) {
119 0 : *outDriver = kChromium_GrGLDriver;
120 0 : return;
121 : }
122 :
123 0 : if (standard == kGL_GrGLStandard) {
124 0 : if (kNVIDIA_GrGLVendor == vendor) {
125 0 : *outDriver = kNVIDIA_GrGLDriver;
126 : int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
127 0 : &major, &minor, &rev, &driverMajor, &driverMinor);
128 : // Some older NVIDIA drivers don't report the driver version.
129 0 : if (5 == n) {
130 0 : *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
131 : }
132 0 : return;
133 : }
134 : int n = sscanf(versionString, "%d.%d Mesa %d.%d",
135 0 : &major, &minor, &driverMajor, &driverMinor);
136 0 : if (4 == n) {
137 0 : *outDriver = kMesa_GrGLDriver;
138 0 : *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
139 0 : return;
140 : }
141 : }
142 : else {
143 0 : if (kNVIDIA_GrGLVendor == vendor) {
144 0 : *outDriver = kNVIDIA_GrGLDriver;
145 : int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
146 0 : &major, &minor, &driverMajor, &driverMinor);
147 : // Some older NVIDIA drivers don't report the driver version.
148 0 : if (4 == n) {
149 0 : *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
150 : }
151 0 : return;
152 : }
153 :
154 : int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
155 0 : &major, &minor, &driverMajor, &driverMinor);
156 0 : if (4 == n) {
157 0 : *outDriver = kMesa_GrGLDriver;
158 0 : *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
159 0 : return;
160 : }
161 0 : if (0 == strncmp("ANGLE", rendererString, 5)) {
162 0 : *outDriver = kANGLE_GrGLDriver;
163 : n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
164 0 : &driverMinor);
165 0 : if (4 == n) {
166 0 : *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
167 : }
168 0 : return;
169 : }
170 : }
171 :
172 0 : if (kIntel_GrGLVendor == vendor) {
173 : // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
174 0 : *outDriver = kIntel_GrGLDriver;
175 : }
176 : }
177 :
178 0 : GrGLVersion GrGLGetVersionFromString(const char* versionString) {
179 0 : if (nullptr == versionString) {
180 0 : SkDebugf("nullptr GL version string.");
181 0 : return GR_GL_INVALID_VER;
182 : }
183 :
184 : int major, minor;
185 :
186 : // check for mesa
187 : int mesaMajor, mesaMinor;
188 0 : int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
189 0 : if (4 == n) {
190 0 : return GR_GL_VER(major, minor);
191 : }
192 :
193 0 : n = sscanf(versionString, "%d.%d", &major, &minor);
194 0 : if (2 == n) {
195 0 : return GR_GL_VER(major, minor);
196 : }
197 :
198 : char profile[2];
199 0 : n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
200 0 : &major, &minor);
201 0 : if (4 == n) {
202 0 : return GR_GL_VER(major, minor);
203 : }
204 :
205 0 : n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
206 0 : if (2 == n) {
207 0 : return GR_GL_VER(major, minor);
208 : }
209 :
210 0 : return GR_GL_INVALID_VER;
211 : }
212 :
213 0 : GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
214 0 : if (nullptr == versionString) {
215 0 : SkDebugf("nullptr GLSL version string.");
216 0 : return GR_GLSL_INVALID_VER;
217 : }
218 :
219 : int major, minor;
220 :
221 0 : int n = sscanf(versionString, "%d.%d", &major, &minor);
222 0 : if (2 == n) {
223 0 : return GR_GLSL_VER(major, minor);
224 : }
225 :
226 0 : n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
227 0 : if (2 == n) {
228 0 : 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 0 : return GR_GLSL_INVALID_VER;
240 : }
241 :
242 0 : GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
243 0 : if (vendorString) {
244 0 : if (0 == strcmp(vendorString, "ARM")) {
245 0 : return kARM_GrGLVendor;
246 : }
247 0 : if (0 == strcmp(vendorString, "Imagination Technologies")) {
248 0 : return kImagination_GrGLVendor;
249 : }
250 0 : if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
251 0 : return kIntel_GrGLVendor;
252 : }
253 0 : if (0 == strcmp(vendorString, "Qualcomm")) {
254 0 : return kQualcomm_GrGLVendor;
255 : }
256 0 : if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
257 0 : return kNVIDIA_GrGLVendor;
258 : }
259 0 : if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
260 0 : return kATI_GrGLVendor;
261 : }
262 : }
263 0 : return kOther_GrGLVendor;
264 : }
265 :
266 0 : GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
267 0 : if (rendererString) {
268 0 : if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
269 0 : return kTegra3_GrGLRenderer;
270 0 : } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
271 0 : return kTegra2_GrGLRenderer;
272 : }
273 : int lastDigit;
274 0 : int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
275 0 : if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
276 0 : 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 0 : if (0 == strncmp(rendererString, kAppleA4Str,
283 0 : SK_ARRAY_COUNT(kAppleA4Str)-1) ||
284 0 : 0 == strncmp(rendererString, kAppleA5Str,
285 0 : SK_ARRAY_COUNT(kAppleA5Str)-1) ||
286 0 : 0 == strncmp(rendererString, kAppleA6Str,
287 : SK_ARRAY_COUNT(kAppleA6Str)-1)) {
288 0 : 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 0 : if (0 == strncmp(rendererString, kPowerVRRogueStr,
294 0 : SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
295 0 : 0 == strncmp(rendererString, kAppleA7Str,
296 0 : SK_ARRAY_COUNT(kAppleA7Str)-1) ||
297 0 : 0 == strncmp(rendererString, kAppleA8Str,
298 : SK_ARRAY_COUNT(kAppleA8Str)-1)) {
299 0 : return kPowerVRRogue_GrGLRenderer;
300 : }
301 : int adrenoNumber;
302 0 : n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
303 0 : if (1 == n) {
304 0 : if (adrenoNumber >= 300) {
305 0 : if (adrenoNumber < 400) {
306 0 : return kAdreno3xx_GrGLRenderer;
307 : }
308 0 : if (adrenoNumber < 500) {
309 0 : return kAdreno4xx_GrGLRenderer;
310 : }
311 0 : if (adrenoNumber < 600) {
312 0 : return kAdreno5xx_GrGLRenderer;
313 : }
314 : }
315 : }
316 0 : if (0 == strcmp("Mesa Offscreen", rendererString)) {
317 0 : return kOSMesa_GrGLRenderer;
318 : }
319 : }
320 0 : return kOther_GrGLRenderer;
321 : }
322 :
323 0 : GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
324 : const GrGLubyte* v;
325 0 : GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
326 0 : return GrGLGetVersionFromString((const char*) v);
327 : }
328 :
329 0 : GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
330 : const GrGLubyte* v;
331 0 : GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
332 0 : return GrGLGetGLSLVersionFromString((const char*) v);
333 : }
334 :
335 0 : GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
336 : const GrGLubyte* v;
337 0 : GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
338 0 : return GrGLGetVendorFromString((const char*) v);
339 : }
340 :
341 0 : GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
342 : const GrGLubyte* v;
343 0 : GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
344 0 : return GrGLGetRendererFromString((const char*) v);
345 : }
346 :
347 0 : 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 0 : SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
367 :
368 0 : return gTable[(int)test];
369 : }
|