blob: 9daa79b47e479e50a0edd37315561c919b880eb5 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05009#include "include/core/SkMatrix.h"
10#include "include/private/GrTypesPriv.h"
Robert Phillips8043f322019-05-31 08:11:36 -040011#include "src/gpu/GrDataUtils.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/gl/GrGLUtil.h"
bungeman@google.comfab44db2013-10-11 18:50:45 +000013#include <stdio.h>
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000014
bsalomon@google.com0b77d682011-08-19 13:28:54 +000015void GrGLClearErr(const GrGLInterface* gl) {
commit-bot@chromium.orgc72425a2014-01-21 16:09:18 +000016 while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000017}
bsalomon@google.com27847de2011-02-22 20:59:41 +000018
bsalomon@google.com845eafd2012-06-18 12:27:29 +000019namespace {
20const char *get_error_string(uint32_t err) {
21 switch (err) {
22 case GR_GL_NO_ERROR:
23 return "";
24 case GR_GL_INVALID_ENUM:
25 return "Invalid Enum";
26 case GR_GL_INVALID_VALUE:
27 return "Invalid Value";
28 case GR_GL_INVALID_OPERATION:
29 return "Invalid Operation";
30 case GR_GL_OUT_OF_MEMORY:
31 return "Out of Memory";
32 case GR_GL_CONTEXT_LOST:
33 return "Context Lost";
34 }
35 return "Unknown";
36}
37}
38
bsalomon@google.com0b77d682011-08-19 13:28:54 +000039void GrGLCheckErr(const GrGLInterface* gl,
40 const char* location,
41 const char* call) {
42 uint32_t err = GR_GL_GET_ERROR(gl);
twiz@google.com0f31ca72011-03-18 17:38:11 +000043 if (GR_GL_NO_ERROR != err) {
tfarina38406c82014-10-31 07:11:12 -070044 SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
bsalomon49f085d2014-09-05 13:34:00 -070045 if (location) {
tfarina38406c82014-10-31 07:11:12 -070046 SkDebugf(" at\n\t%s", location);
bsalomon@google.com27847de2011-02-22 20:59:41 +000047 }
bsalomon49f085d2014-09-05 13:34:00 -070048 if (call) {
tfarina38406c82014-10-31 07:11:12 -070049 SkDebugf("\n\t\t%s", call);
bsalomon@google.com27847de2011-02-22 20:59:41 +000050 }
tfarina38406c82014-10-31 07:11:12 -070051 SkDebugf("\n");
bsalomon@google.com27847de2011-02-22 20:59:41 +000052 }
53}
54
55///////////////////////////////////////////////////////////////////////////////
56
bsalomon@google.comd5d10492011-04-28 21:16:31 +000057#if GR_GL_LOG_CALLS
58 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
59#endif
bsalomon@google.com27847de2011-02-22 20:59:41 +000060
bsalomon@google.comd5d10492011-04-28 21:16:31 +000061#if GR_GL_CHECK_ERROR
62 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
63#endif
64
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000065///////////////////////////////////////////////////////////////////////////////
66
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000067GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -070068 if (nullptr == versionString) {
69 SkDebugf("nullptr GL version string.");
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000070 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000071 }
72
73 int major, minor;
74
75 // check for desktop
76 int n = sscanf(versionString, "%d.%d", &major, &minor);
77 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000078 return kGL_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000079 }
80
Kevin Lubick39026282019-03-28 12:46:40 -040081 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
82 int esMajor, esMinor;
83 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
84 if (4 == n) {
85 return kWebGL_GrGLStandard;
86 }
87
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000088 // check for ES 1
89 char profile[2];
bsalomon@google.com960d1142013-05-29 13:11:54 +000090 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000091 if (4 == n) {
92 // we no longer support ES1.
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000093 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000094 }
95
96 // check for ES2
97 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
98 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000099 return kGLES_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000100 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000101 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000102}
103
cdalton1acea862015-06-02 13:05:52 -0700104void GrGLGetDriverInfo(GrGLStandard standard,
105 GrGLVendor vendor,
106 const char* rendererString,
107 const char* versionString,
108 GrGLDriver* outDriver,
109 GrGLDriverVersion* outVersion) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400110 int major, minor, rev, driverMajor, driverMinor, driverPoint;
derekfa6ca5a02014-11-03 13:36:40 -0800111
cdalton1acea862015-06-02 13:05:52 -0700112 *outDriver = kUnknown_GrGLDriver;
113 *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
bsalomon6383ac02016-03-23 14:55:21 -0700114 // These null checks are for test GL contexts that return nullptr in their
115 // glGetString implementation.
116 if (!rendererString) {
117 rendererString = "";
118 }
119 if (!versionString) {
120 versionString = "";
121 }
cdalton1acea862015-06-02 13:05:52 -0700122
Brian Salomona392dba2017-03-16 15:38:57 -0400123 static const char kChromium[] = "Chromium";
Mike Klein313b03a2019-11-19 17:32:06 -0600124 char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
Brian Salomona392dba2017-03-16 15:38:57 -0400125 if (0 == strcmp(rendererString, kChromium) ||
126 (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
127 0 == strcmp(kChromium, suffix))) {
cdalton1acea862015-06-02 13:05:52 -0700128 *outDriver = kChromium_GrGLDriver;
129 return;
130 }
derekfa6ca5a02014-11-03 13:36:40 -0800131
Kevin Lubick8aa203c2019-03-19 13:23:10 -0400132 if (GR_IS_GR_GL(standard)) {
cdalton1acea862015-06-02 13:05:52 -0700133 if (kNVIDIA_GrGLVendor == vendor) {
134 *outDriver = kNVIDIA_GrGLDriver;
135 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
136 &major, &minor, &rev, &driverMajor, &driverMinor);
137 // Some older NVIDIA drivers don't report the driver version.
138 if (5 == n) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400139 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700140 }
141 return;
142 }
cdalton1acea862015-06-02 13:05:52 -0700143 int n = sscanf(versionString, "%d.%d Mesa %d.%d",
144 &major, &minor, &driverMajor, &driverMinor);
Chris Dalton06cd6662017-10-07 14:37:57 -0600145 if (4 != n) {
146 n = sscanf(versionString, "%d.%d (Core Profile) Mesa %d.%d",
147 &major, &minor, &driverMajor, &driverMinor);
148 }
cdalton1acea862015-06-02 13:05:52 -0700149 if (4 == n) {
150 *outDriver = kMesa_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400151 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700152 return;
153 }
Kevin Lubick8aa203c2019-03-19 13:23:10 -0400154 } else if (GR_IS_GR_GL_ES(standard)) {
cdalton1acea862015-06-02 13:05:52 -0700155 if (kNVIDIA_GrGLVendor == vendor) {
156 *outDriver = kNVIDIA_GrGLDriver;
157 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
158 &major, &minor, &driverMajor, &driverMinor);
159 // Some older NVIDIA drivers don't report the driver version.
160 if (4 == n) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400161 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700162 }
163 return;
164 }
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000165
cdalton1acea862015-06-02 13:05:52 -0700166 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
167 &major, &minor, &driverMajor, &driverMinor);
168 if (4 == n) {
169 *outDriver = kMesa_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400170 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700171 return;
172 }
bsalomon88c7b982015-07-31 11:20:16 -0700173 if (0 == strncmp("ANGLE", rendererString, 5)) {
174 *outDriver = kANGLE_GrGLDriver;
175 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
176 &driverMinor);
177 if (4 == n) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400178 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
bsalomon88c7b982015-07-31 11:20:16 -0700179 }
180 return;
181 }
cdalton1acea862015-06-02 13:05:52 -0700182 }
cdalton1dd05422015-06-12 09:01:18 -0700183
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400184 if (kGoogle_GrGLVendor == vendor) {
185 // Swiftshader is the only Google vendor at the moment
186 *outDriver = kSwiftShader_GrGLDriver;
187
188 // Swiftshader has a strange version string: w.x.y.z Going to arbitrarily ignore
189 // y and assume w,x and z are major, minor, point.
190 // As of writing, version is 4.0.0.6
191 int n = sscanf(versionString, "OpenGL ES %d.%d SwiftShader %d.%d.0.%d", &major, &minor,
192 &driverMajor, &driverMinor, &driverPoint);
193 if (5 == n) {
194 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
195 }
196 return;
197 }
198
cdalton1dd05422015-06-12 09:01:18 -0700199 if (kIntel_GrGLVendor == vendor) {
200 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
201 *outDriver = kIntel_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400202
203 //This is how the macOS version strings are structured. This might be different on different
204 // OSes.
205 int n = sscanf(versionString, "%d.%d INTEL-%d.%d.%d", &major, &minor, &driverMajor,
206 &driverMinor, &driverPoint);
207 if (5 == n) {
208 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
209 }
cdalton1dd05422015-06-12 09:01:18 -0700210 }
Brian Salomonb52fa022017-06-07 09:42:52 -0400211
212 if (kQualcomm_GrGLVendor == vendor) {
213 *outDriver = kQualcomm_GrGLDriver;
214 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
215 &driverMinor);
216 if (4 == n) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400217 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
Brian Salomonb52fa022017-06-07 09:42:52 -0400218 }
219 return;
220 }
Brian Salomon5a5f3e82019-08-16 15:05:40 -0400221 static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
222 if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
223 *outDriver = kAndroidEmulator_GrGLDriver;
224 }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +0000225}
226
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000227GrGLVersion GrGLGetVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700228 if (nullptr == versionString) {
229 SkDebugf("nullptr GL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000230 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000231 }
232
233 int major, minor;
234
bsalomon@google.com960d1142013-05-29 13:11:54 +0000235 // check for mesa
236 int mesaMajor, mesaMinor;
237 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
238 if (4 == n) {
joshualitt46821702014-07-30 11:49:12 -0700239 return GR_GL_VER(major, minor);
bsalomon@google.com960d1142013-05-29 13:11:54 +0000240 }
241
242 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000243 if (2 == n) {
244 return GR_GL_VER(major, minor);
245 }
246
Kevin Lubick39026282019-03-28 12:46:40 -0400247 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
248 int esMajor, esMinor;
249 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
250 if (4 == n) {
251 return GR_GL_VER(major, minor);
252 }
253
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000254 char profile[2];
255 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
256 &major, &minor);
257 if (4 == n) {
258 return GR_GL_VER(major, minor);
259 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000260
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000261 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
262 if (2 == n) {
263 return GR_GL_VER(major, minor);
264 }
265
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000266 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000267}
268
269GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700270 if (nullptr == versionString) {
271 SkDebugf("nullptr GLSL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000272 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000273 }
274
275 int major, minor;
276
277 int n = sscanf(versionString, "%d.%d", &major, &minor);
278 if (2 == n) {
279 return GR_GLSL_VER(major, minor);
280 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000281
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000282 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
283 if (2 == n) {
284 return GR_GLSL_VER(major, minor);
285 }
286
287#ifdef SK_BUILD_FOR_ANDROID
288 // android hack until the gpu vender updates their drivers
289 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
290 if (2 == n) {
291 return GR_GLSL_VER(major, minor);
292 }
293#endif
294
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000295 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000296}
297
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000298GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
bsalomon49f085d2014-09-05 13:34:00 -0700299 if (vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000300 if (0 == strcmp(vendorString, "ARM")) {
301 return kARM_GrGLVendor;
302 }
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400303 if (0 == strcmp(vendorString, "Google Inc.")) {
304 return kGoogle_GrGLVendor;
305 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000306 if (0 == strcmp(vendorString, "Imagination Technologies")) {
307 return kImagination_GrGLVendor;
308 }
commit-bot@chromium.org54318d32014-02-14 17:27:04 +0000309 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000310 return kIntel_GrGLVendor;
311 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000312 if (0 == strcmp(vendorString, "Qualcomm")) {
313 return kQualcomm_GrGLVendor;
314 }
bsalomone904c092014-07-17 10:50:59 -0700315 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
bsalomon63b21962014-11-05 07:05:34 -0800316 return kNVIDIA_GrGLVendor;
bsalomone904c092014-07-17 10:50:59 -0700317 }
brianosman131ff132016-06-07 14:22:44 -0700318 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
319 return kATI_GrGLVendor;
320 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000321 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000322 return kOther_GrGLVendor;
323}
324
Brian Salomon266ef6d2017-09-22 11:27:42 -0400325static bool is_renderer_angle(const char* rendererString) {
326 static constexpr char kHeader[] = "ANGLE ";
327 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
Brian Salomon2ab5e782018-12-18 09:00:36 -0500328 return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
Brian Salomon266ef6d2017-09-22 11:27:42 -0400329}
330
Brian Salomon4470e342018-04-04 14:27:48 -0400331GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
332 const GrGLExtensions& extensions) {
bsalomon49f085d2014-09-05 13:34:00 -0700333 if (rendererString) {
Chris Dalton0090ef62018-03-28 17:35:00 -0600334 static const char kTegraStr[] = "NVIDIA Tegra";
335 if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
336 // Tegra strings are not very descriptive. We distinguish between the modern and legacy
337 // architectures by the presence of NV_path_rendering.
Brian Salomon4470e342018-04-04 14:27:48 -0400338 return extensions.has("GL_NV_path_rendering") ? kTegra_GrGLRenderer
339 : kTegra_PreK1_GrGLRenderer;
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000340 }
bsalomon63b21962014-11-05 07:05:34 -0800341 int lastDigit;
342 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
343 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
344 return kPowerVR54x_GrGLRenderer;
345 }
jvanverthf10ecb72015-12-10 09:06:24 -0800346 // certain iOS devices also use PowerVR54x GPUs
347 static const char kAppleA4Str[] = "Apple A4";
348 static const char kAppleA5Str[] = "Apple A5";
349 static const char kAppleA6Str[] = "Apple A6";
350 if (0 == strncmp(rendererString, kAppleA4Str,
351 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
352 0 == strncmp(rendererString, kAppleA5Str,
353 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
354 0 == strncmp(rendererString, kAppleA6Str,
355 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
356 return kPowerVR54x_GrGLRenderer;
357 }
bsalomon63b21962014-11-05 07:05:34 -0800358 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
jvanverthf10ecb72015-12-10 09:06:24 -0800359 static const char kAppleA7Str[] = "Apple A7";
360 static const char kAppleA8Str[] = "Apple A8";
bsalomon63b21962014-11-05 07:05:34 -0800361 if (0 == strncmp(rendererString, kPowerVRRogueStr,
jvanverthf10ecb72015-12-10 09:06:24 -0800362 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
363 0 == strncmp(rendererString, kAppleA7Str,
364 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
365 0 == strncmp(rendererString, kAppleA8Str,
366 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
bsalomon63b21962014-11-05 07:05:34 -0800367 return kPowerVRRogue_GrGLRenderer;
368 }
bsalomona8fcea02015-02-13 09:00:39 -0800369 int adrenoNumber;
370 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
371 if (1 == n) {
372 if (adrenoNumber >= 300) {
373 if (adrenoNumber < 400) {
374 return kAdreno3xx_GrGLRenderer;
375 }
376 if (adrenoNumber < 500) {
Chris Dalton1214be92018-06-28 19:06:27 -0600377 return adrenoNumber >= 430
378 ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
bsalomona8fcea02015-02-13 09:00:39 -0800379 }
egdaniel7517e452016-09-20 13:00:26 -0700380 if (adrenoNumber < 600) {
381 return kAdreno5xx_GrGLRenderer;
382 }
Chris Dalton6e38ce72019-10-23 11:14:49 -0600383 if (adrenoNumber == 615) {
384 return kAdreno615_GrGLRenderer;
385 }
386 if (adrenoNumber == 630) {
387 return kAdreno630_GrGLRenderer;
388 }
bsalomona8fcea02015-02-13 09:00:39 -0800389 }
390 }
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400391 if (0 == strcmp("Google SwiftShader", rendererString)) {
392 return kGoogleSwiftShader_GrGLRenderer;
393 }
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400394
Chris Daltonb70beea2018-07-23 12:17:10 -0600395 if (const char* intelString = strstr(rendererString, "Intel")) {
Brian Osmand6b53d52019-06-25 15:37:14 -0400396 // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
397 if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
398 0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
399 return kIntelHaswell_GrGLRenderer;
Chris Dalton4a6a7322017-10-06 14:28:11 -0600400 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600401 if (strstr(intelString, "Sandybridge")) {
Chris Dalton1c1391c2018-07-20 12:21:14 -0600402 return kIntelSandyBridge_GrGLRenderer;
403 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600404 if (strstr(intelString, "Bay Trail")) {
Brian Osmand6b53d52019-06-25 15:37:14 -0400405 return kIntelValleyView_GrGLRenderer;
Chris Daltonb70beea2018-07-23 12:17:10 -0600406 }
Brian Osmand6b53d52019-06-25 15:37:14 -0400407 // There are many possible intervening strings here:
408 // 'Intel(R)' is a common prefix
409 // 'Iris' may appear, followed by '(R)' or '(TM)'
410 // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
411 // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
412 //
413 // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
414 // so just skip to that and handle two cases:
415 if (const char* intelGfxString = strstr(intelString, "Graphics")) {
416 int intelNumber;
417 if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
418 sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
Chris Daltonb70beea2018-07-23 12:17:10 -0600419
Brian Osmand6b53d52019-06-25 15:37:14 -0400420 if (intelNumber == 2000 || intelNumber == 3000) {
421 return kIntelSandyBridge_GrGLRenderer;
422 }
423 if (intelNumber == 2500 || intelNumber == 4000) {
424 return kIntelIvyBridge_GrGLRenderer;
425 }
426 if (intelNumber >= 4200 && intelNumber <= 5200) {
427 return kIntelHaswell_GrGLRenderer;
428 }
429 if (intelNumber >= 400 && intelNumber <= 405) {
430 return kIntelCherryView_GrGLRenderer;
431 }
432 if (intelNumber >= 5300 && intelNumber <= 6300) {
433 return kIntelBroadwell_GrGLRenderer;
434 }
435 if (intelNumber >= 500 && intelNumber <= 505) {
436 return kIntelApolloLake_GrGLRenderer;
437 }
438 if (intelNumber >= 510 && intelNumber <= 580) {
439 return kIntelSkyLake_GrGLRenderer;
440 }
441 if (intelNumber >= 600 && intelNumber <= 605) {
442 return kIntelGeminiLake_GrGLRenderer;
443 }
444 // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
445 // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
446 if (intelNumber == 610 || intelNumber == 630) {
447 return strstr(intelString, "UHD") ? kIntelCoffeeLake_GrGLRenderer
448 : kIntelKabyLake_GrGLRenderer;
449 }
450 if (intelNumber >= 610 && intelNumber <= 650) {
451 return kIntelKabyLake_GrGLRenderer;
452 }
453 if (intelNumber == 655) {
454 return kIntelCoffeeLake_GrGLRenderer;
455 }
456 if (intelNumber >= 910 && intelNumber <= 950) {
457 return kIntelIceLake_GrGLRenderer;
458 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600459 }
Chris Daltonda40cd22018-04-16 13:19:58 -0600460 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400461 }
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400462
463 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
Brian Salomond2c67f42019-10-24 14:58:40 -0400464 static constexpr char kRadeonStr[] = "Radeon ";
465 if (const char* amdString = strstr(rendererString, kRadeonStr)) {
466 amdString += strlen(kRadeonStr);
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400467 char amdGeneration, amdTier, amdRevision;
Brian Salomond2c67f42019-10-24 14:58:40 -0400468 // Sometimes there is a (TM) and sometimes not.
469 static constexpr char kTMStr[] = "(TM) ";
470 if (!strncmp(amdString, kTMStr, strlen(kTMStr))) {
471 amdString += strlen(kTMStr);
472 }
473 n = sscanf(amdString, "R9 M%c%c%c", &amdGeneration, &amdTier, &amdRevision);
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400474 if (3 == n) {
Brian Salomond2c67f42019-10-24 14:58:40 -0400475 if ('3' == amdGeneration) {
476 return kAMDRadeonR9M3xx_GrGLRenderer;
477 } else if ('4' == amdGeneration) {
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400478 return kAMDRadeonR9M4xx_GrGLRenderer;
479 }
480 }
481
482 char amd0, amd1, amd2;
Brian Salomond2c67f42019-10-24 14:58:40 -0400483 n = sscanf(amdString, "HD 7%c%c%c Series", &amd0, &amd1, &amd2);
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400484 if (3 == n) {
485 return kAMDRadeonHD7xxx_GrGLRenderer;
486 }
Herb Derbyff82e152019-10-25 15:18:44 -0400487
488 int amdVegaModel=0;
489 n = sscanf(amdString, "Pro Vega %i", &amdVegaModel);
490 if (1 == n) {
491 return kAMDRadeonProVegaxx_GrGLRenderer;
492 }
493
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400494 }
495
Greg Daniel25019172017-10-26 13:32:33 -0400496 if (strstr(rendererString, "llvmpipe")) {
497 return kGalliumLLVM_GrGLRenderer;
498 }
Brian Osmanac1e4962017-05-25 11:34:38 -0400499 static const char kMaliTStr[] = "Mali-T";
500 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
501 return kMaliT_GrGLRenderer;
502 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400503 int mali400Num;
504 if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
505 mali400Num < 500) {
506 return kMali4xx_GrGLRenderer;
507 }
Brian Salomon266ef6d2017-09-22 11:27:42 -0400508 if (is_renderer_angle(rendererString)) {
Robert Phillipsbc712742017-06-02 11:20:37 -0400509 return kANGLE_GrGLRenderer;
510 }
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000511 }
512 return kOther_GrGLRenderer;
513}
514
Brian Salomon266ef6d2017-09-22 11:27:42 -0400515void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend* backend,
516 GrGLANGLEVendor* vendor, GrGLANGLERenderer* renderer) {
517 *backend = GrGLANGLEBackend::kUnknown;
518 *vendor = GrGLANGLEVendor::kUnknown;
519 *renderer = GrGLANGLERenderer::kUnknown;
520 if (!is_renderer_angle(rendererString)) {
521 return;
522 }
523 if (strstr(rendererString, "Intel")) {
524 *vendor = GrGLANGLEVendor::kIntel;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700525
526 const char* modelStr;
527 int modelNumber;
528 if ((modelStr = strstr(rendererString, "HD Graphics")) &&
529 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
530 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
531 switch (modelNumber) {
Chris Dalton1c1391c2018-07-20 12:21:14 -0600532 case 2000:
533 case 3000:
534 *renderer = GrGLANGLERenderer::kSandyBridge;
535 break;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700536 case 4000:
537 case 2500:
538 *renderer = GrGLANGLERenderer::kIvyBridge;
539 break;
540 case 510:
541 case 515:
542 case 520:
543 case 530:
544 *renderer = GrGLANGLERenderer::kSkylake;
545 break;
546 }
547 } else if ((modelStr = strstr(rendererString, "Iris")) &&
548 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
549 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
550 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
551 switch (modelNumber) {
552 case 540:
553 case 550:
554 case 555:
555 case 580:
556 *renderer = GrGLANGLERenderer::kSkylake;
557 break;
558 }
559 }
Brian Salomon266ef6d2017-09-22 11:27:42 -0400560 }
561 if (strstr(rendererString, "Direct3D11")) {
562 *backend = GrGLANGLEBackend::kD3D11;
563 } else if (strstr(rendererString, "Direct3D9")) {
564 *backend = GrGLANGLEBackend::kD3D9;
565 } else if (strstr(rendererString, "OpenGL")) {
566 *backend = GrGLANGLEBackend::kOpenGL;
567 }
568}
569
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000570GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
571 const GrGLubyte* v;
572 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
573 return GrGLGetVersionFromString((const char*) v);
574}
575
576GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
577 const GrGLubyte* v;
578 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
579 return GrGLGetGLSLVersionFromString((const char*) v);
580}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000581
582GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
583 const GrGLubyte* v;
584 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
585 return GrGLGetVendorFromString((const char*) v);
586}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000587
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000588GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
Chris Dalton0090ef62018-03-28 17:35:00 -0600589 const GrGLubyte* rendererString;
590 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
591
Brian Salomon4470e342018-04-04 14:27:48 -0400592 return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000593}
594
cdalton93a379b2016-05-11 13:58:08 -0700595GrGLenum GrToGLStencilFunc(GrStencilTest test) {
596 static const GrGLenum gTable[kGrStencilTestCount] = {
597 GR_GL_ALWAYS, // kAlways
598 GR_GL_NEVER, // kNever
599 GR_GL_GREATER, // kGreater
600 GR_GL_GEQUAL, // kGEqual
601 GR_GL_LESS, // kLess
602 GR_GL_LEQUAL, // kLEqual
603 GR_GL_EQUAL, // kEqual
604 GR_GL_NOTEQUAL, // kNotEqual
kkinnunenccdaa042014-08-20 01:36:23 -0700605 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500606 static_assert(0 == (int)GrStencilTest::kAlways);
607 static_assert(1 == (int)GrStencilTest::kNever);
608 static_assert(2 == (int)GrStencilTest::kGreater);
609 static_assert(3 == (int)GrStencilTest::kGEqual);
610 static_assert(4 == (int)GrStencilTest::kLess);
611 static_assert(5 == (int)GrStencilTest::kLEqual);
612 static_assert(6 == (int)GrStencilTest::kEqual);
613 static_assert(7 == (int)GrStencilTest::kNotEqual);
cdalton93a379b2016-05-11 13:58:08 -0700614 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
kkinnunenccdaa042014-08-20 01:36:23 -0700615
cdalton93a379b2016-05-11 13:58:08 -0700616 return gTable[(int)test];
kkinnunenccdaa042014-08-20 01:36:23 -0700617}
Robert Phillips8043f322019-05-31 08:11:36 -0400618
Brian Salomon5043f1f2019-07-11 21:27:54 -0400619bool GrGLFormatIsCompressed(GrGLFormat format) {
620 switch (format) {
621 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
622 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
Robert Phillips8043f322019-05-31 08:11:36 -0400623 return true;
Brian Salomon5043f1f2019-07-11 21:27:54 -0400624
625 case GrGLFormat::kRGBA8:
626 case GrGLFormat::kR8:
627 case GrGLFormat::kALPHA8:
628 case GrGLFormat::kLUMINANCE8:
629 case GrGLFormat::kBGRA8:
630 case GrGLFormat::kRGB565:
631 case GrGLFormat::kRGBA16F:
632 case GrGLFormat::kR16F:
Robert Phillipsebab03f2019-07-22 08:48:18 -0400633 case GrGLFormat::kLUMINANCE16F:
Brian Salomon5043f1f2019-07-11 21:27:54 -0400634 case GrGLFormat::kRGB8:
635 case GrGLFormat::kRG8:
636 case GrGLFormat::kRGB10_A2:
637 case GrGLFormat::kRGBA4:
Brian Salomon5043f1f2019-07-11 21:27:54 -0400638 case GrGLFormat::kSRGB8_ALPHA8:
639 case GrGLFormat::kR16:
640 case GrGLFormat::kRG16:
641 case GrGLFormat::kRGBA16:
642 case GrGLFormat::kRG16F:
643 case GrGLFormat::kUnknown:
Robert Phillips8043f322019-05-31 08:11:36 -0400644 return false;
645 }
Brian Salomon5043f1f2019-07-11 21:27:54 -0400646 SkUNREACHABLE;
Robert Phillips8043f322019-05-31 08:11:36 -0400647}
Robert Phillipsd04ddcd2019-12-18 14:36:52 -0500648
649SkImage::CompressionType GrGLFormatToCompressionType(GrGLFormat format) {
650 switch (format) {
651 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
652 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
653 return SkImage::CompressionType::kETC1;
654
655 case GrGLFormat::kRGBA8:
656 case GrGLFormat::kR8:
657 case GrGLFormat::kALPHA8:
658 case GrGLFormat::kLUMINANCE8:
659 case GrGLFormat::kBGRA8:
660 case GrGLFormat::kRGB565:
661 case GrGLFormat::kRGBA16F:
662 case GrGLFormat::kR16F:
663 case GrGLFormat::kLUMINANCE16F:
664 case GrGLFormat::kRGB8:
665 case GrGLFormat::kRG8:
666 case GrGLFormat::kRGB10_A2:
667 case GrGLFormat::kRGBA4:
668 case GrGLFormat::kSRGB8_ALPHA8:
669 case GrGLFormat::kR16:
670 case GrGLFormat::kRG16:
671 case GrGLFormat::kRGBA16:
672 case GrGLFormat::kRG16F:
673 case GrGLFormat::kUnknown:
674 return SkImage::CompressionType::kNone;
675 }
676 SkUNREACHABLE;
677}
678