blob: 6d8337ecfdfb8aa764aca07cb8ba49efd7694994 [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;
bsalomon6383ac02016-03-23 14:55:21 -0700105 // 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 }
cdalton1acea862015-06-02 13:05:52 -0700113
114 if (0 == strcmp(rendererString, "Chromium")) {
115 *outDriver = kChromium_GrGLDriver;
116 return;
117 }
derekfa6ca5a02014-11-03 13:36:40 -0800118
119 if (standard == kGL_GrGLStandard) {
cdalton1acea862015-06-02 13:05:52 -0700120 if (kNVIDIA_GrGLVendor == vendor) {
121 *outDriver = kNVIDIA_GrGLDriver;
122 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
123 &major, &minor, &rev, &driverMajor, &driverMinor);
124 // Some older NVIDIA drivers don't report the driver version.
125 if (5 == n) {
126 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
127 }
128 return;
129 }
cdalton1acea862015-06-02 13:05:52 -0700130 int n = sscanf(versionString, "%d.%d Mesa %d.%d",
131 &major, &minor, &driverMajor, &driverMinor);
132 if (4 == n) {
133 *outDriver = kMesa_GrGLDriver;
134 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
135 return;
136 }
derekfa6ca5a02014-11-03 13:36:40 -0800137 }
138 else {
cdalton1acea862015-06-02 13:05:52 -0700139 if (kNVIDIA_GrGLVendor == vendor) {
140 *outDriver = kNVIDIA_GrGLDriver;
141 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
142 &major, &minor, &driverMajor, &driverMinor);
143 // Some older NVIDIA drivers don't report the driver version.
144 if (4 == n) {
145 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
146 }
147 return;
148 }
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000149
cdalton1acea862015-06-02 13:05:52 -0700150 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
151 &major, &minor, &driverMajor, &driverMinor);
152 if (4 == n) {
153 *outDriver = kMesa_GrGLDriver;
154 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
155 return;
156 }
bsalomon88c7b982015-07-31 11:20:16 -0700157 if (0 == strncmp("ANGLE", rendererString, 5)) {
158 *outDriver = kANGLE_GrGLDriver;
159 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
160 &driverMinor);
161 if (4 == n) {
162 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
163 }
164 return;
165 }
cdalton1acea862015-06-02 13:05:52 -0700166 }
cdalton1dd05422015-06-12 09:01:18 -0700167
168 if (kIntel_GrGLVendor == vendor) {
169 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
170 *outDriver = kIntel_GrGLDriver;
171 }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +0000172}
173
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000174GrGLVersion GrGLGetVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700175 if (nullptr == versionString) {
176 SkDebugf("nullptr GL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000177 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000178 }
179
180 int major, minor;
181
bsalomon@google.com960d1142013-05-29 13:11:54 +0000182 // check for mesa
183 int mesaMajor, mesaMinor;
184 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
185 if (4 == n) {
joshualitt46821702014-07-30 11:49:12 -0700186 return GR_GL_VER(major, minor);
bsalomon@google.com960d1142013-05-29 13:11:54 +0000187 }
188
189 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000190 if (2 == n) {
191 return GR_GL_VER(major, minor);
192 }
193
194 char profile[2];
195 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
196 &major, &minor);
197 if (4 == n) {
198 return GR_GL_VER(major, minor);
199 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000200
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000201 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
202 if (2 == n) {
203 return GR_GL_VER(major, minor);
204 }
205
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000206 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000207}
208
209GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700210 if (nullptr == versionString) {
211 SkDebugf("nullptr GLSL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000212 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000213 }
214
215 int major, minor;
216
217 int n = sscanf(versionString, "%d.%d", &major, &minor);
218 if (2 == n) {
219 return GR_GLSL_VER(major, minor);
220 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000221
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000222 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
223 if (2 == n) {
224 return GR_GLSL_VER(major, minor);
225 }
226
227#ifdef SK_BUILD_FOR_ANDROID
228 // android hack until the gpu vender updates their drivers
229 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
230 if (2 == n) {
231 return GR_GLSL_VER(major, minor);
232 }
233#endif
234
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000235 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000236}
237
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000238GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
bsalomon49f085d2014-09-05 13:34:00 -0700239 if (vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000240 if (0 == strcmp(vendorString, "ARM")) {
241 return kARM_GrGLVendor;
242 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000243 if (0 == strcmp(vendorString, "Imagination Technologies")) {
244 return kImagination_GrGLVendor;
245 }
commit-bot@chromium.org54318d32014-02-14 17:27:04 +0000246 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000247 return kIntel_GrGLVendor;
248 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000249 if (0 == strcmp(vendorString, "Qualcomm")) {
250 return kQualcomm_GrGLVendor;
251 }
bsalomone904c092014-07-17 10:50:59 -0700252 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
bsalomon63b21962014-11-05 07:05:34 -0800253 return kNVIDIA_GrGLVendor;
bsalomone904c092014-07-17 10:50:59 -0700254 }
brianosman131ff132016-06-07 14:22:44 -0700255 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
256 return kATI_GrGLVendor;
257 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000258 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000259 return kOther_GrGLVendor;
260}
261
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000262GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
bsalomon49f085d2014-09-05 13:34:00 -0700263 if (rendererString) {
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000264 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
265 return kTegra3_GrGLRenderer;
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000266 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
267 return kTegra2_GrGLRenderer;
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000268 }
bsalomon63b21962014-11-05 07:05:34 -0800269 int lastDigit;
270 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
271 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
272 return kPowerVR54x_GrGLRenderer;
273 }
jvanverthf10ecb72015-12-10 09:06:24 -0800274 // certain iOS devices also use PowerVR54x GPUs
275 static const char kAppleA4Str[] = "Apple A4";
276 static const char kAppleA5Str[] = "Apple A5";
277 static const char kAppleA6Str[] = "Apple A6";
278 if (0 == strncmp(rendererString, kAppleA4Str,
279 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
280 0 == strncmp(rendererString, kAppleA5Str,
281 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
282 0 == strncmp(rendererString, kAppleA6Str,
283 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
284 return kPowerVR54x_GrGLRenderer;
285 }
bsalomon63b21962014-11-05 07:05:34 -0800286 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
jvanverthf10ecb72015-12-10 09:06:24 -0800287 static const char kAppleA7Str[] = "Apple A7";
288 static const char kAppleA8Str[] = "Apple A8";
bsalomon63b21962014-11-05 07:05:34 -0800289 if (0 == strncmp(rendererString, kPowerVRRogueStr,
jvanverthf10ecb72015-12-10 09:06:24 -0800290 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
291 0 == strncmp(rendererString, kAppleA7Str,
292 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
293 0 == strncmp(rendererString, kAppleA8Str,
294 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
bsalomon63b21962014-11-05 07:05:34 -0800295 return kPowerVRRogue_GrGLRenderer;
296 }
bsalomona8fcea02015-02-13 09:00:39 -0800297 int adrenoNumber;
298 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
299 if (1 == n) {
300 if (adrenoNumber >= 300) {
301 if (adrenoNumber < 400) {
302 return kAdreno3xx_GrGLRenderer;
303 }
304 if (adrenoNumber < 500) {
305 return kAdreno4xx_GrGLRenderer;
306 }
egdaniel7517e452016-09-20 13:00:26 -0700307 if (adrenoNumber < 600) {
308 return kAdreno5xx_GrGLRenderer;
309 }
bsalomona8fcea02015-02-13 09:00:39 -0800310 }
311 }
Brian Salomon0ee6f952017-01-19 15:52:24 -0500312 if (0 == strcmp("Mesa Offscreen", rendererString)) {
bsalomon40170072016-05-05 14:40:03 -0700313 return kOSMesa_GrGLRenderer;
314 }
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000315 }
316 return kOther_GrGLRenderer;
317}
318
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000319GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
320 const GrGLubyte* v;
321 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
322 return GrGLGetVersionFromString((const char*) v);
323}
324
325GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
326 const GrGLubyte* v;
327 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
328 return GrGLGetGLSLVersionFromString((const char*) v);
329}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000330
331GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
332 const GrGLubyte* v;
333 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
334 return GrGLGetVendorFromString((const char*) v);
335}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000336
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000337GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
338 const GrGLubyte* v;
339 GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
340 return GrGLGetRendererFromString((const char*) v);
341}
342
cdalton93a379b2016-05-11 13:58:08 -0700343GrGLenum GrToGLStencilFunc(GrStencilTest test) {
344 static const GrGLenum gTable[kGrStencilTestCount] = {
345 GR_GL_ALWAYS, // kAlways
346 GR_GL_NEVER, // kNever
347 GR_GL_GREATER, // kGreater
348 GR_GL_GEQUAL, // kGEqual
349 GR_GL_LESS, // kLess
350 GR_GL_LEQUAL, // kLEqual
351 GR_GL_EQUAL, // kEqual
352 GR_GL_NOTEQUAL, // kNotEqual
kkinnunenccdaa042014-08-20 01:36:23 -0700353 };
cdalton93a379b2016-05-11 13:58:08 -0700354 GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
355 GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
356 GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
357 GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
358 GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
359 GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
360 GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
361 GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
362 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
kkinnunenccdaa042014-08-20 01:36:23 -0700363
cdalton93a379b2016-05-11 13:58:08 -0700364 return gTable[(int)test];
kkinnunenccdaa042014-08-20 01:36:23 -0700365}