blob: 6da7c20aec8c18a1fe0ec3e517b12a3fe6c99d43 [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
Brian Salomona392dba2017-03-16 15:38:57 -0400114 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))) {
cdalton1acea862015-06-02 13:05:52 -0700119 *outDriver = kChromium_GrGLDriver;
120 return;
121 }
derekfa6ca5a02014-11-03 13:36:40 -0800122
123 if (standard == kGL_GrGLStandard) {
cdalton1acea862015-06-02 13:05:52 -0700124 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 }
cdalton1acea862015-06-02 13:05:52 -0700134 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 }
derekfa6ca5a02014-11-03 13:36:40 -0800141 }
142 else {
cdalton1acea862015-06-02 13:05:52 -0700143 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 }
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000153
cdalton1acea862015-06-02 13:05:52 -0700154 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 }
bsalomon88c7b982015-07-31 11:20:16 -0700161 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 }
cdalton1acea862015-06-02 13:05:52 -0700170 }
cdalton1dd05422015-06-12 09:01:18 -0700171
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 }
Brian Salomonb52fa022017-06-07 09:42:52 -0400176
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 }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +0000186}
187
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000188GrGLVersion GrGLGetVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700189 if (nullptr == versionString) {
190 SkDebugf("nullptr GL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000191 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000192 }
193
194 int major, minor;
195
bsalomon@google.com960d1142013-05-29 13:11:54 +0000196 // 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) {
joshualitt46821702014-07-30 11:49:12 -0700200 return GR_GL_VER(major, minor);
bsalomon@google.com960d1142013-05-29 13:11:54 +0000201 }
202
203 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000204 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 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000214
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000215 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
216 if (2 == n) {
217 return GR_GL_VER(major, minor);
218 }
219
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000220 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000221}
222
223GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700224 if (nullptr == versionString) {
225 SkDebugf("nullptr GLSL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000226 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000227 }
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 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000235
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000236 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
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000249 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000250}
251
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000252GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
bsalomon49f085d2014-09-05 13:34:00 -0700253 if (vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000254 if (0 == strcmp(vendorString, "ARM")) {
255 return kARM_GrGLVendor;
256 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000257 if (0 == strcmp(vendorString, "Imagination Technologies")) {
258 return kImagination_GrGLVendor;
259 }
commit-bot@chromium.org54318d32014-02-14 17:27:04 +0000260 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000261 return kIntel_GrGLVendor;
262 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000263 if (0 == strcmp(vendorString, "Qualcomm")) {
264 return kQualcomm_GrGLVendor;
265 }
bsalomone904c092014-07-17 10:50:59 -0700266 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
bsalomon63b21962014-11-05 07:05:34 -0800267 return kNVIDIA_GrGLVendor;
bsalomone904c092014-07-17 10:50:59 -0700268 }
brianosman131ff132016-06-07 14:22:44 -0700269 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
270 return kATI_GrGLVendor;
271 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000272 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000273 return kOther_GrGLVendor;
274}
275
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000276GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
bsalomon49f085d2014-09-05 13:34:00 -0700277 if (rendererString) {
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000278 if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
279 return kTegra3_GrGLRenderer;
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000280 } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
281 return kTegra2_GrGLRenderer;
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000282 }
bsalomon63b21962014-11-05 07:05:34 -0800283 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 }
jvanverthf10ecb72015-12-10 09:06:24 -0800288 // 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 }
bsalomon63b21962014-11-05 07:05:34 -0800300 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
jvanverthf10ecb72015-12-10 09:06:24 -0800301 static const char kAppleA7Str[] = "Apple A7";
302 static const char kAppleA8Str[] = "Apple A8";
bsalomon63b21962014-11-05 07:05:34 -0800303 if (0 == strncmp(rendererString, kPowerVRRogueStr,
jvanverthf10ecb72015-12-10 09:06:24 -0800304 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)) {
bsalomon63b21962014-11-05 07:05:34 -0800309 return kPowerVRRogue_GrGLRenderer;
310 }
bsalomona8fcea02015-02-13 09:00:39 -0800311 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 }
egdaniel7517e452016-09-20 13:00:26 -0700321 if (adrenoNumber < 600) {
322 return kAdreno5xx_GrGLRenderer;
323 }
bsalomona8fcea02015-02-13 09:00:39 -0800324 }
325 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400326 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 }
Brian Salomon0ee6f952017-01-19 15:52:24 -0500336 if (0 == strcmp("Mesa Offscreen", rendererString)) {
bsalomon40170072016-05-05 14:40:03 -0700337 return kOSMesa_GrGLRenderer;
338 }
Brian Osmanac1e4962017-05-25 11:34:38 -0400339 static const char kMaliTStr[] = "Mali-T";
340 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
341 return kMaliT_GrGLRenderer;
342 }
Robert Phillipsbc712742017-06-02 11:20:37 -0400343 static const char kANGLEStr[] = "ANGLE";
344 if (0 == strncmp(rendererString, kANGLEStr, SK_ARRAY_COUNT(kANGLEStr) - 1)) {
345 return kANGLE_GrGLRenderer;
346 }
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000347 }
348 return kOther_GrGLRenderer;
349}
350
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000351GrGLVersion 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
357GrGLSLVersion 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}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000362
363GrGLVendor 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}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000368
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000369GrGLRenderer 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
cdalton93a379b2016-05-11 13:58:08 -0700375GrGLenum 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
kkinnunenccdaa042014-08-20 01:36:23 -0700385 };
cdalton93a379b2016-05-11 13:58:08 -0700386 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);
kkinnunenccdaa042014-08-20 01:36:23 -0700395
cdalton93a379b2016-05-11 13:58:08 -0700396 return gTable[(int)test];
kkinnunenccdaa042014-08-20 01:36:23 -0700397}