blob: b5e58554018c0560fa9fe176eb296c06f8e7bfb6 [file] [log] [blame]
bsalomon@google.com27847de2011-02-22 20:59:41 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00006 */
7
epoger@google.comec3ed6a2011-07-28 14:26:00 +00008
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +00009#include "GrGLUtil.h"
commit-bot@chromium.org215a6822013-09-05 18:28:42 +000010#include "SkMatrix.h"
bungeman@google.comfab44db2013-10-11 18:50:45 +000011#include <stdio.h>
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000012
bsalomon@google.com0b77d682011-08-19 13:28:54 +000013void GrGLClearErr(const GrGLInterface* gl) {
commit-bot@chromium.orgc72425a2014-01-21 16:09:18 +000014 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000015}
bsalomon@google.com27847de2011-02-22 20:59:41 +000016
bsalomon@google.com845eafd2012-06-18 12:27:29 +000017namespace {
18const 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
bsalomon@google.com0b77d682011-08-19 13:28:54 +000037void GrGLCheckErr(const GrGLInterface* gl,
38 const char* location,
39 const char* call) {
40 uint32_t err = GR_GL_GET_ERROR(gl);
twiz@google.com0f31ca72011-03-18 17:38:11 +000041 if (GR_GL_NO_ERROR != err) {
tfarina38406c82014-10-31 07:11:12 -070042 SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
bsalomon49f085d2014-09-05 13:34:00 -070043 if (location) {
tfarina38406c82014-10-31 07:11:12 -070044 SkDebugf(" at\n\t%s", location);
bsalomon@google.com27847de2011-02-22 20:59:41 +000045 }
bsalomon49f085d2014-09-05 13:34:00 -070046 if (call) {
tfarina38406c82014-10-31 07:11:12 -070047 SkDebugf("\n\t\t%s", call);
bsalomon@google.com27847de2011-02-22 20:59:41 +000048 }
tfarina38406c82014-10-31 07:11:12 -070049 SkDebugf("\n");
bsalomon@google.com27847de2011-02-22 20:59:41 +000050 }
51}
52
53///////////////////////////////////////////////////////////////////////////////
54
bsalomon@google.comd5d10492011-04-28 21:16:31 +000055#if GR_GL_LOG_CALLS
56 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
57#endif
bsalomon@google.com27847de2011-02-22 20:59:41 +000058
bsalomon@google.comd5d10492011-04-28 21:16:31 +000059#if GR_GL_CHECK_ERROR
60 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
61#endif
62
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000063///////////////////////////////////////////////////////////////////////////////
64
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000065GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -070066 if (nullptr == versionString) {
67 SkDebugf("nullptr GL version string.");
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000068 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000069 }
70
71 int major, minor;
72
73 // check for desktop
74 int n = sscanf(versionString, "%d.%d", &major, &minor);
75 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000076 return kGL_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000077 }
78
79 // check for ES 1
80 char profile[2];
bsalomon@google.com960d1142013-05-29 13:11:54 +000081 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000082 if (4 == n) {
83 // we no longer support ES1.
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000084 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000085 }
86
87 // check for ES2
88 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
89 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000090 return kGLES_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000091 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000092 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000093}
94
cdalton1acea862015-06-02 13:05:52 -070095void 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;
derekfa6ca5a02014-11-03 13:36:40 -0800102
cdalton1acea862015-06-02 13:05:52 -0700103 *outDriver = kUnknown_GrGLDriver;
104 *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
105
106 if (0 == strcmp(rendererString, "Chromium")) {
107 *outDriver = kChromium_GrGLDriver;
108 return;
109 }
derekfa6ca5a02014-11-03 13:36:40 -0800110
111 if (standard == kGL_GrGLStandard) {
cdalton1acea862015-06-02 13:05:52 -0700112 if (kNVIDIA_GrGLVendor == vendor) {
113 *outDriver = kNVIDIA_GrGLDriver;
114 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
115 &major, &minor, &rev, &driverMajor, &driverMinor);
116 // Some older NVIDIA drivers don't report the driver version.
117 if (5 == n) {
118 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
119 }
120 return;
121 }
122
123 int n = sscanf(versionString, "%d.%d Mesa %d.%d",
124 &major, &minor, &driverMajor, &driverMinor);
125 if (4 == n) {
126 *outDriver = kMesa_GrGLDriver;
127 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
128 return;
129 }
derekfa6ca5a02014-11-03 13:36:40 -0800130 }
131 else {
cdalton1acea862015-06-02 13:05:52 -0700132 if (kNVIDIA_GrGLVendor == vendor) {
133 *outDriver = kNVIDIA_GrGLDriver;
134 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
135 &major, &minor, &driverMajor, &driverMinor);
136 // Some older NVIDIA drivers don't report the driver version.
137 if (4 == n) {
138 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
139 }
140 return;
141 }
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000142
cdalton1acea862015-06-02 13:05:52 -0700143 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
144 &major, &minor, &driverMajor, &driverMinor);
145 if (4 == n) {
146 *outDriver = kMesa_GrGLDriver;
147 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
148 return;
149 }
bsalomon88c7b982015-07-31 11:20:16 -0700150 if (0 == strncmp("ANGLE", rendererString, 5)) {
151 *outDriver = kANGLE_GrGLDriver;
152 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
153 &driverMinor);
154 if (4 == n) {
155 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
156 }
157 return;
158 }
cdalton1acea862015-06-02 13:05:52 -0700159 }
cdalton1dd05422015-06-12 09:01:18 -0700160
161 if (kIntel_GrGLVendor == vendor) {
162 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
163 *outDriver = kIntel_GrGLDriver;
164 }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +0000165}
166
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000167GrGLVersion GrGLGetVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700168 if (nullptr == versionString) {
169 SkDebugf("nullptr GL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000170 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000171 }
172
173 int major, minor;
174
bsalomon@google.com960d1142013-05-29 13:11:54 +0000175 // check for mesa
176 int mesaMajor, mesaMinor;
177 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
178 if (4 == n) {
joshualitt46821702014-07-30 11:49:12 -0700179 return GR_GL_VER(major, minor);
bsalomon@google.com960d1142013-05-29 13:11:54 +0000180 }
181
182 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000183 if (2 == n) {
184 return GR_GL_VER(major, minor);
185 }
186
187 char profile[2];
188 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
189 &major, &minor);
190 if (4 == n) {
191 return GR_GL_VER(major, minor);
192 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000193
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000194 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
195 if (2 == n) {
196 return GR_GL_VER(major, minor);
197 }
198
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000199 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000200}
201
202GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700203 if (nullptr == versionString) {
204 SkDebugf("nullptr GLSL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000205 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000206 }
207
208 int major, minor;
209
210 int n = sscanf(versionString, "%d.%d", &major, &minor);
211 if (2 == n) {
212 return GR_GLSL_VER(major, minor);
213 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000214
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000215 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
216 if (2 == n) {
217 return GR_GLSL_VER(major, minor);
218 }
219
220#ifdef SK_BUILD_FOR_ANDROID
221 // android hack until the gpu vender updates their drivers
222 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
223 if (2 == n) {
224 return GR_GLSL_VER(major, minor);
225 }
226#endif
227
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000228 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000229}
230
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000231GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
bsalomon49f085d2014-09-05 13:34:00 -0700232 if (vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000233 if (0 == strcmp(vendorString, "ARM")) {
234 return kARM_GrGLVendor;
235 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000236 if (0 == strcmp(vendorString, "Imagination Technologies")) {
237 return kImagination_GrGLVendor;
238 }
commit-bot@chromium.org54318d32014-02-14 17:27:04 +0000239 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000240 return kIntel_GrGLVendor;
241 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000242 if (0 == strcmp(vendorString, "Qualcomm")) {
243 return kQualcomm_GrGLVendor;
244 }
bsalomone904c092014-07-17 10:50:59 -0700245 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
bsalomon63b21962014-11-05 07:05:34 -0800246 return kNVIDIA_GrGLVendor;
bsalomone904c092014-07-17 10:50:59 -0700247 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000248 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000249 return kOther_GrGLVendor;
250}
251
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000252GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
bsalomon49f085d2014-09-05 13:34:00 -0700253 if (rendererString) {
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000254 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
255 return kTegra3_GrGLRenderer;
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000256 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
257 return kTegra2_GrGLRenderer;
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000258 }
bsalomon63b21962014-11-05 07:05:34 -0800259 int lastDigit;
260 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
261 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
262 return kPowerVR54x_GrGLRenderer;
263 }
jvanverthf10ecb72015-12-10 09:06:24 -0800264 // certain iOS devices also use PowerVR54x GPUs
265 static const char kAppleA4Str[] = "Apple A4";
266 static const char kAppleA5Str[] = "Apple A5";
267 static const char kAppleA6Str[] = "Apple A6";
268 if (0 == strncmp(rendererString, kAppleA4Str,
269 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
270 0 == strncmp(rendererString, kAppleA5Str,
271 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
272 0 == strncmp(rendererString, kAppleA6Str,
273 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
274 return kPowerVR54x_GrGLRenderer;
275 }
bsalomon63b21962014-11-05 07:05:34 -0800276 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
jvanverthf10ecb72015-12-10 09:06:24 -0800277 static const char kAppleA7Str[] = "Apple A7";
278 static const char kAppleA8Str[] = "Apple A8";
bsalomon63b21962014-11-05 07:05:34 -0800279 if (0 == strncmp(rendererString, kPowerVRRogueStr,
jvanverthf10ecb72015-12-10 09:06:24 -0800280 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
281 0 == strncmp(rendererString, kAppleA7Str,
282 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
283 0 == strncmp(rendererString, kAppleA8Str,
284 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
bsalomon63b21962014-11-05 07:05:34 -0800285 return kPowerVRRogue_GrGLRenderer;
286 }
bsalomona8fcea02015-02-13 09:00:39 -0800287 int adrenoNumber;
288 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
289 if (1 == n) {
290 if (adrenoNumber >= 300) {
291 if (adrenoNumber < 400) {
292 return kAdreno3xx_GrGLRenderer;
293 }
294 if (adrenoNumber < 500) {
295 return kAdreno4xx_GrGLRenderer;
296 }
297 }
298 }
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000299 }
300 return kOther_GrGLRenderer;
301}
302
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000303GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
304 const GrGLubyte* v;
305 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
306 return GrGLGetVersionFromString((const char*) v);
307}
308
309GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
310 const GrGLubyte* v;
311 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
312 return GrGLGetGLSLVersionFromString((const char*) v);
313}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000314
315GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
316 const GrGLubyte* v;
317 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
318 return GrGLGetVendorFromString((const char*) v);
319}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000320
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000321GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
322 const GrGLubyte* v;
323 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
324 return GrGLGetRendererFromString((const char*) v);
325}
326
kkinnunenccdaa042014-08-20 01:36:23 -0700327GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) {
328 static const GrGLenum gTable[] = {
329 GR_GL_ALWAYS, // kAlways_StencilFunc
330 GR_GL_NEVER, // kNever_StencilFunc
331 GR_GL_GREATER, // kGreater_StencilFunc
332 GR_GL_GEQUAL, // kGEqual_StencilFunc
333 GR_GL_LESS, // kLess_StencilFunc
334 GR_GL_LEQUAL, // kLEqual_StencilFunc,
335 GR_GL_EQUAL, // kEqual_StencilFunc,
336 GR_GL_NOTEQUAL, // kNotEqual_StencilFunc,
337 };
338 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
339 GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
340 GR_STATIC_ASSERT(1 == kNever_StencilFunc);
341 GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
342 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
343 GR_STATIC_ASSERT(4 == kLess_StencilFunc);
344 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
345 GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
346 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
347 SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
348
349 return gTable[basicFunc];
350}