blob: 0c7f8df9c7e242fcf7372d1d918db73a6b2a4fb3 [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.com27847de2011-02-22 20:59:41 +000015///////////////////////////////////////////////////////////////////////////////
16
bsalomon@google.comd5d10492011-04-28 21:16:31 +000017#if GR_GL_LOG_CALLS
18 bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
19#endif
bsalomon@google.com27847de2011-02-22 20:59:41 +000020
bsalomon@google.comd5d10492011-04-28 21:16:31 +000021#if GR_GL_CHECK_ERROR
22 bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
23#endif
24
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000025///////////////////////////////////////////////////////////////////////////////
26
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000027GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -070028 if (nullptr == versionString) {
29 SkDebugf("nullptr GL version string.");
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000030 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000031 }
32
33 int major, minor;
34
35 // check for desktop
36 int n = sscanf(versionString, "%d.%d", &major, &minor);
37 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000038 return kGL_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000039 }
40
Kevin Lubick39026282019-03-28 12:46:40 -040041 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
42 int esMajor, esMinor;
43 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
44 if (4 == n) {
45 return kWebGL_GrGLStandard;
46 }
47
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000048 // check for ES 1
49 char profile[2];
bsalomon@google.com960d1142013-05-29 13:11:54 +000050 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000051 if (4 == n) {
52 // we no longer support ES1.
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000053 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000054 }
55
56 // check for ES2
57 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
58 if (2 == n) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000059 return kGLES_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000060 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000061 return kNone_GrGLStandard;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +000062}
63
cdalton1acea862015-06-02 13:05:52 -070064void GrGLGetDriverInfo(GrGLStandard standard,
65 GrGLVendor vendor,
66 const char* rendererString,
67 const char* versionString,
68 GrGLDriver* outDriver,
69 GrGLDriverVersion* outVersion) {
Brian Salomon9a544bc2018-04-04 16:12:31 -040070 int major, minor, rev, driverMajor, driverMinor, driverPoint;
derekfa6ca5a02014-11-03 13:36:40 -080071
cdalton1acea862015-06-02 13:05:52 -070072 *outDriver = kUnknown_GrGLDriver;
73 *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
bsalomon6383ac02016-03-23 14:55:21 -070074 // These null checks are for test GL contexts that return nullptr in their
75 // glGetString implementation.
76 if (!rendererString) {
77 rendererString = "";
78 }
79 if (!versionString) {
80 versionString = "";
81 }
cdalton1acea862015-06-02 13:05:52 -070082
Brian Salomona392dba2017-03-16 15:38:57 -040083 static const char kChromium[] = "Chromium";
Mike Klein313b03a2019-11-19 17:32:06 -060084 char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
Brian Salomona392dba2017-03-16 15:38:57 -040085 if (0 == strcmp(rendererString, kChromium) ||
86 (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
87 0 == strcmp(kChromium, suffix))) {
cdalton1acea862015-06-02 13:05:52 -070088 *outDriver = kChromium_GrGLDriver;
89 return;
90 }
derekfa6ca5a02014-11-03 13:36:40 -080091
Kevin Lubick8aa203c2019-03-19 13:23:10 -040092 if (GR_IS_GR_GL(standard)) {
Brian Salomon9c4ee9c2019-12-20 16:20:54 -050093 if (vendor == kNVIDIA_GrGLVendor) {
cdalton1acea862015-06-02 13:05:52 -070094 *outDriver = kNVIDIA_GrGLDriver;
95 int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
96 &major, &minor, &rev, &driverMajor, &driverMinor);
97 // Some older NVIDIA drivers don't report the driver version.
Brian Salomon9c4ee9c2019-12-20 16:20:54 -050098 if (n == 5) {
Brian Salomon9a544bc2018-04-04 16:12:31 -040099 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700100 }
101 return;
102 }
cdalton1acea862015-06-02 13:05:52 -0700103 int n = sscanf(versionString, "%d.%d Mesa %d.%d",
104 &major, &minor, &driverMajor, &driverMinor);
Chris Dalton06cd6662017-10-07 14:37:57 -0600105 if (4 != n) {
106 n = sscanf(versionString, "%d.%d (Core Profile) Mesa %d.%d",
107 &major, &minor, &driverMajor, &driverMinor);
108 }
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500109 if (n == 4) {
cdalton1acea862015-06-02 13:05:52 -0700110 *outDriver = kMesa_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400111 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700112 return;
113 }
Kevin Lubick8aa203c2019-03-19 13:23:10 -0400114 } else if (GR_IS_GR_GL_ES(standard)) {
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500115 if (vendor == kNVIDIA_GrGLVendor) {
cdalton1acea862015-06-02 13:05:52 -0700116 *outDriver = kNVIDIA_GrGLDriver;
117 int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
118 &major, &minor, &driverMajor, &driverMinor);
119 // Some older NVIDIA drivers don't report the driver version.
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500120 if (n == 4) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400121 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700122 }
123 return;
124 }
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000125
cdalton1acea862015-06-02 13:05:52 -0700126 int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
127 &major, &minor, &driverMajor, &driverMinor);
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500128 if (n == 4) {
cdalton1acea862015-06-02 13:05:52 -0700129 *outDriver = kMesa_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400130 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
cdalton1acea862015-06-02 13:05:52 -0700131 return;
132 }
bsalomon88c7b982015-07-31 11:20:16 -0700133 if (0 == strncmp("ANGLE", rendererString, 5)) {
134 *outDriver = kANGLE_GrGLDriver;
135 n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
136 &driverMinor);
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500137 if (n == 4) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400138 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
bsalomon88c7b982015-07-31 11:20:16 -0700139 }
140 return;
141 }
cdalton1acea862015-06-02 13:05:52 -0700142 }
cdalton1dd05422015-06-12 09:01:18 -0700143
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500144 if (vendor == kGoogle_GrGLVendor) {
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400145 // Swiftshader is the only Google vendor at the moment
146 *outDriver = kSwiftShader_GrGLDriver;
147
148 // Swiftshader has a strange version string: w.x.y.z Going to arbitrarily ignore
149 // y and assume w,x and z are major, minor, point.
150 // As of writing, version is 4.0.0.6
151 int n = sscanf(versionString, "OpenGL ES %d.%d SwiftShader %d.%d.0.%d", &major, &minor,
152 &driverMajor, &driverMinor, &driverPoint);
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500153 if (n == 5) {
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400154 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
155 }
156 return;
157 }
158
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500159 if (vendor == kIntel_GrGLVendor) {
cdalton1dd05422015-06-12 09:01:18 -0700160 // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
161 *outDriver = kIntel_GrGLDriver;
Brian Salomon9a544bc2018-04-04 16:12:31 -0400162
163 //This is how the macOS version strings are structured. This might be different on different
164 // OSes.
165 int n = sscanf(versionString, "%d.%d INTEL-%d.%d.%d", &major, &minor, &driverMajor,
166 &driverMinor, &driverPoint);
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500167 if (n == 5) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400168 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
169 }
cdalton1dd05422015-06-12 09:01:18 -0700170 }
Brian Salomonb52fa022017-06-07 09:42:52 -0400171
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500172 if (vendor == kQualcomm_GrGLVendor) {
Brian Salomonb52fa022017-06-07 09:42:52 -0400173 *outDriver = kQualcomm_GrGLDriver;
174 int n = sscanf(versionString, "OpenGL ES %d.%d V@%d.%d", &major, &minor, &driverMajor,
175 &driverMinor);
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500176 if (n == 4) {
Brian Salomon9a544bc2018-04-04 16:12:31 -0400177 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
Brian Salomonb52fa022017-06-07 09:42:52 -0400178 }
179 return;
180 }
Brian Salomon9c4ee9c2019-12-20 16:20:54 -0500181
182 if (vendor == kImagination_GrGLVendor) {
183 int revision;
184 int n = sscanf(versionString, "OpenGL ES %d.%d build %d.%d@%d", &major, &minor,
185 &driverMajor, &driverMinor, &revision);
186 if (n == 5) {
187 // Revision is a large number (looks like a source control revision number) that
188 // doesn't fit into the 'patch' bits, so omit it until we need it.
189 *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
190 }
191 return;
192 }
193
Brian Salomon5a5f3e82019-08-16 15:05:40 -0400194 static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
195 if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
196 *outDriver = kAndroidEmulator_GrGLDriver;
197 }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +0000198}
199
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000200GrGLVersion GrGLGetVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700201 if (nullptr == versionString) {
202 SkDebugf("nullptr GL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000203 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000204 }
205
206 int major, minor;
207
bsalomon@google.com960d1142013-05-29 13:11:54 +0000208 // check for mesa
209 int mesaMajor, mesaMinor;
210 int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
211 if (4 == n) {
joshualitt46821702014-07-30 11:49:12 -0700212 return GR_GL_VER(major, minor);
bsalomon@google.com960d1142013-05-29 13:11:54 +0000213 }
214
215 n = sscanf(versionString, "%d.%d", &major, &minor);
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000216 if (2 == n) {
217 return GR_GL_VER(major, minor);
218 }
219
Kevin Lubick39026282019-03-28 12:46:40 -0400220 // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
221 int esMajor, esMinor;
222 n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
223 if (4 == n) {
224 return GR_GL_VER(major, minor);
225 }
226
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000227 char profile[2];
228 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
229 &major, &minor);
230 if (4 == n) {
231 return GR_GL_VER(major, minor);
232 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000233
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000234 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
235 if (2 == n) {
236 return GR_GL_VER(major, minor);
237 }
238
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000239 return GR_GL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000240}
241
242GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
halcanary96fcdcc2015-08-27 07:41:13 -0700243 if (nullptr == versionString) {
244 SkDebugf("nullptr GLSL version string.");
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000245 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000246 }
247
248 int major, minor;
249
250 int n = sscanf(versionString, "%d.%d", &major, &minor);
251 if (2 == n) {
252 return GR_GLSL_VER(major, minor);
253 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000254
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000255 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
256 if (2 == n) {
257 return GR_GLSL_VER(major, minor);
258 }
259
260#ifdef SK_BUILD_FOR_ANDROID
261 // android hack until the gpu vender updates their drivers
262 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
263 if (2 == n) {
264 return GR_GLSL_VER(major, minor);
265 }
266#endif
267
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000268 return GR_GLSL_INVALID_VER;
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000269}
270
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000271GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
bsalomon49f085d2014-09-05 13:34:00 -0700272 if (vendorString) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000273 if (0 == strcmp(vendorString, "ARM")) {
274 return kARM_GrGLVendor;
275 }
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400276 if (0 == strcmp(vendorString, "Google Inc.")) {
277 return kGoogle_GrGLVendor;
278 }
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000279 if (0 == strcmp(vendorString, "Imagination Technologies")) {
280 return kImagination_GrGLVendor;
281 }
commit-bot@chromium.org54318d32014-02-14 17:27:04 +0000282 if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000283 return kIntel_GrGLVendor;
284 }
Shawn Guo284190b2020-07-28 15:17:00 +0800285 if (0 == strcmp(vendorString, "Qualcomm") || 0 == strcmp(vendorString, "freedreno")) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000286 return kQualcomm_GrGLVendor;
287 }
bsalomone904c092014-07-17 10:50:59 -0700288 if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
bsalomon63b21962014-11-05 07:05:34 -0800289 return kNVIDIA_GrGLVendor;
bsalomone904c092014-07-17 10:50:59 -0700290 }
brianosman131ff132016-06-07 14:22:44 -0700291 if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
292 return kATI_GrGLVendor;
293 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000294 }
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000295 return kOther_GrGLVendor;
296}
297
Brian Salomon266ef6d2017-09-22 11:27:42 -0400298static bool is_renderer_angle(const char* rendererString) {
299 static constexpr char kHeader[] = "ANGLE ";
300 static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
Brian Salomon2ab5e782018-12-18 09:00:36 -0500301 return rendererString && 0 == strncmp(rendererString, kHeader, kHeaderLength);
Brian Salomon266ef6d2017-09-22 11:27:42 -0400302}
303
Brian Salomon4470e342018-04-04 14:27:48 -0400304GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString,
305 const GrGLExtensions& extensions) {
bsalomon49f085d2014-09-05 13:34:00 -0700306 if (rendererString) {
Chris Dalton0090ef62018-03-28 17:35:00 -0600307 static const char kTegraStr[] = "NVIDIA Tegra";
308 if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
309 // Tegra strings are not very descriptive. We distinguish between the modern and legacy
310 // architectures by the presence of NV_path_rendering.
Brian Salomon4470e342018-04-04 14:27:48 -0400311 return extensions.has("GL_NV_path_rendering") ? kTegra_GrGLRenderer
312 : kTegra_PreK1_GrGLRenderer;
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000313 }
bsalomon63b21962014-11-05 07:05:34 -0800314 int lastDigit;
315 int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
316 if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
317 return kPowerVR54x_GrGLRenderer;
318 }
jvanverthf10ecb72015-12-10 09:06:24 -0800319 // certain iOS devices also use PowerVR54x GPUs
320 static const char kAppleA4Str[] = "Apple A4";
321 static const char kAppleA5Str[] = "Apple A5";
322 static const char kAppleA6Str[] = "Apple A6";
323 if (0 == strncmp(rendererString, kAppleA4Str,
324 SK_ARRAY_COUNT(kAppleA4Str)-1) ||
325 0 == strncmp(rendererString, kAppleA5Str,
326 SK_ARRAY_COUNT(kAppleA5Str)-1) ||
327 0 == strncmp(rendererString, kAppleA6Str,
328 SK_ARRAY_COUNT(kAppleA6Str)-1)) {
329 return kPowerVR54x_GrGLRenderer;
330 }
bsalomon63b21962014-11-05 07:05:34 -0800331 static const char kPowerVRRogueStr[] = "PowerVR Rogue";
jvanverthf10ecb72015-12-10 09:06:24 -0800332 static const char kAppleA7Str[] = "Apple A7";
333 static const char kAppleA8Str[] = "Apple A8";
bsalomon63b21962014-11-05 07:05:34 -0800334 if (0 == strncmp(rendererString, kPowerVRRogueStr,
jvanverthf10ecb72015-12-10 09:06:24 -0800335 SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
336 0 == strncmp(rendererString, kAppleA7Str,
337 SK_ARRAY_COUNT(kAppleA7Str)-1) ||
338 0 == strncmp(rendererString, kAppleA8Str,
339 SK_ARRAY_COUNT(kAppleA8Str)-1)) {
bsalomon63b21962014-11-05 07:05:34 -0800340 return kPowerVRRogue_GrGLRenderer;
341 }
bsalomona8fcea02015-02-13 09:00:39 -0800342 int adrenoNumber;
343 n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
Shawn Guo284190b2020-07-28 15:17:00 +0800344 if (n < 1) {
345 // retry with freedreno driver
346 n = sscanf(rendererString, "FD%d", &adrenoNumber);
347 }
bsalomona8fcea02015-02-13 09:00:39 -0800348 if (1 == n) {
349 if (adrenoNumber >= 300) {
350 if (adrenoNumber < 400) {
351 return kAdreno3xx_GrGLRenderer;
352 }
353 if (adrenoNumber < 500) {
Chris Dalton1214be92018-06-28 19:06:27 -0600354 return adrenoNumber >= 430
355 ? kAdreno430_GrGLRenderer : kAdreno4xx_other_GrGLRenderer;
bsalomona8fcea02015-02-13 09:00:39 -0800356 }
egdaniel7517e452016-09-20 13:00:26 -0700357 if (adrenoNumber < 600) {
358 return kAdreno5xx_GrGLRenderer;
359 }
Chris Dalton6e38ce72019-10-23 11:14:49 -0600360 if (adrenoNumber == 615) {
361 return kAdreno615_GrGLRenderer;
362 }
363 if (adrenoNumber == 630) {
364 return kAdreno630_GrGLRenderer;
365 }
Brian Salomonf8c187c2019-12-19 14:41:57 -0500366 if (adrenoNumber == 640) {
367 return kAdreno640_GrGLRenderer;
368 }
bsalomona8fcea02015-02-13 09:00:39 -0800369 }
370 }
Kevin Lubickda2b9f32018-06-05 16:05:58 -0400371 if (0 == strcmp("Google SwiftShader", rendererString)) {
372 return kGoogleSwiftShader_GrGLRenderer;
373 }
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400374
Chris Daltonb70beea2018-07-23 12:17:10 -0600375 if (const char* intelString = strstr(rendererString, "Intel")) {
Brian Osmand6b53d52019-06-25 15:37:14 -0400376 // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
377 if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
378 0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
379 return kIntelHaswell_GrGLRenderer;
Chris Dalton4a6a7322017-10-06 14:28:11 -0600380 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600381 if (strstr(intelString, "Sandybridge")) {
Chris Dalton1c1391c2018-07-20 12:21:14 -0600382 return kIntelSandyBridge_GrGLRenderer;
383 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600384 if (strstr(intelString, "Bay Trail")) {
Brian Osmand6b53d52019-06-25 15:37:14 -0400385 return kIntelValleyView_GrGLRenderer;
Chris Daltonb70beea2018-07-23 12:17:10 -0600386 }
Brian Osmand6b53d52019-06-25 15:37:14 -0400387 // There are many possible intervening strings here:
388 // 'Intel(R)' is a common prefix
389 // 'Iris' may appear, followed by '(R)' or '(TM)'
390 // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
391 // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
392 //
393 // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
394 // so just skip to that and handle two cases:
395 if (const char* intelGfxString = strstr(intelString, "Graphics")) {
396 int intelNumber;
397 if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
398 sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
Chris Daltonb70beea2018-07-23 12:17:10 -0600399
Brian Osmand6b53d52019-06-25 15:37:14 -0400400 if (intelNumber == 2000 || intelNumber == 3000) {
401 return kIntelSandyBridge_GrGLRenderer;
402 }
403 if (intelNumber == 2500 || intelNumber == 4000) {
404 return kIntelIvyBridge_GrGLRenderer;
405 }
406 if (intelNumber >= 4200 && intelNumber <= 5200) {
407 return kIntelHaswell_GrGLRenderer;
408 }
409 if (intelNumber >= 400 && intelNumber <= 405) {
410 return kIntelCherryView_GrGLRenderer;
411 }
412 if (intelNumber >= 5300 && intelNumber <= 6300) {
413 return kIntelBroadwell_GrGLRenderer;
414 }
415 if (intelNumber >= 500 && intelNumber <= 505) {
416 return kIntelApolloLake_GrGLRenderer;
417 }
418 if (intelNumber >= 510 && intelNumber <= 580) {
419 return kIntelSkyLake_GrGLRenderer;
420 }
421 if (intelNumber >= 600 && intelNumber <= 605) {
422 return kIntelGeminiLake_GrGLRenderer;
423 }
424 // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
425 // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
426 if (intelNumber == 610 || intelNumber == 630) {
427 return strstr(intelString, "UHD") ? kIntelCoffeeLake_GrGLRenderer
428 : kIntelKabyLake_GrGLRenderer;
429 }
430 if (intelNumber >= 610 && intelNumber <= 650) {
431 return kIntelKabyLake_GrGLRenderer;
432 }
433 if (intelNumber == 655) {
434 return kIntelCoffeeLake_GrGLRenderer;
435 }
436 if (intelNumber >= 910 && intelNumber <= 950) {
437 return kIntelIceLake_GrGLRenderer;
438 }
Chris Daltonb70beea2018-07-23 12:17:10 -0600439 }
Chris Daltonda40cd22018-04-16 13:19:58 -0600440 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400441 }
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400442
443 // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
Brian Salomond2c67f42019-10-24 14:58:40 -0400444 static constexpr char kRadeonStr[] = "Radeon ";
445 if (const char* amdString = strstr(rendererString, kRadeonStr)) {
446 amdString += strlen(kRadeonStr);
Brian Salomond2c67f42019-10-24 14:58:40 -0400447 // Sometimes there is a (TM) and sometimes not.
448 static constexpr char kTMStr[] = "(TM) ";
449 if (!strncmp(amdString, kTMStr, strlen(kTMStr))) {
450 amdString += strlen(kTMStr);
451 }
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400452
453 char amd0, amd1, amd2;
John Stilesa321dd92020-05-20 10:56:03 -0400454 int amdModel;
455 n = sscanf(amdString, "R9 M3%c%c", &amd0, &amd1);
456 if (2 == n && isdigit(amd0) && isdigit(amd1)) {
457 return kAMDRadeonR9M3xx_GrGLRenderer;
458 }
459
460 n = sscanf(amdString, "R9 M4%c%c", &amd0, &amd1);
461 if (2 == n && isdigit(amd0) && isdigit(amd1)) {
462 return kAMDRadeonR9M4xx_GrGLRenderer;
463 }
464
Brian Salomond2c67f42019-10-24 14:58:40 -0400465 n = sscanf(amdString, "HD 7%c%c%c Series", &amd0, &amd1, &amd2);
John Stilesa321dd92020-05-20 10:56:03 -0400466 if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400467 return kAMDRadeonHD7xxx_GrGLRenderer;
468 }
Herb Derbyff82e152019-10-25 15:18:44 -0400469
John Stilesa321dd92020-05-20 10:56:03 -0400470 n = sscanf(amdString, "Pro 5%c%c%c", &amd0, &amd1, &amd2);
471 if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
472 return kAMDRadeonPro5xxx_GrGLRenderer;
473 }
474
475 n = sscanf(amdString, "Pro Vega %i", &amdModel);
Herb Derbyff82e152019-10-25 15:18:44 -0400476 if (1 == n) {
477 return kAMDRadeonProVegaxx_GrGLRenderer;
478 }
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400479 }
480
Greg Daniel25019172017-10-26 13:32:33 -0400481 if (strstr(rendererString, "llvmpipe")) {
482 return kGalliumLLVM_GrGLRenderer;
483 }
Brian Osman76f635c2020-03-25 16:23:11 -0400484 static const char kMaliGStr[] = "Mali-G";
485 if (0 == strncmp(rendererString, kMaliGStr, SK_ARRAY_COUNT(kMaliGStr) - 1)) {
486 return kMaliG_GrGLRenderer;
487 }
Brian Osmanac1e4962017-05-25 11:34:38 -0400488 static const char kMaliTStr[] = "Mali-T";
489 if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
490 return kMaliT_GrGLRenderer;
491 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400492 int mali400Num;
493 if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
494 mali400Num < 500) {
495 return kMali4xx_GrGLRenderer;
496 }
Brian Salomon266ef6d2017-09-22 11:27:42 -0400497 if (is_renderer_angle(rendererString)) {
Robert Phillipsbc712742017-06-02 11:20:37 -0400498 return kANGLE_GrGLRenderer;
499 }
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000500 }
501 return kOther_GrGLRenderer;
502}
503
Brian Salomon414782d2020-04-17 09:34:17 -0400504std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfoFromString(
505 const char* rendererString) {
506 auto backend = GrGLANGLEBackend::kUnknown;
507 auto vendor = GrGLANGLEVendor::kUnknown;
508 auto renderer = GrGLANGLERenderer::kUnknown;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400509 if (!is_renderer_angle(rendererString)) {
Brian Salomon414782d2020-04-17 09:34:17 -0400510 return {backend, vendor, renderer};
Brian Salomon266ef6d2017-09-22 11:27:42 -0400511 }
512 if (strstr(rendererString, "Intel")) {
Brian Salomon414782d2020-04-17 09:34:17 -0400513 vendor = GrGLANGLEVendor::kIntel;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700514
515 const char* modelStr;
516 int modelNumber;
517 if ((modelStr = strstr(rendererString, "HD Graphics")) &&
518 (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
519 1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
520 switch (modelNumber) {
Chris Dalton1c1391c2018-07-20 12:21:14 -0600521 case 2000:
522 case 3000:
Brian Salomon414782d2020-04-17 09:34:17 -0400523 renderer = GrGLANGLERenderer::kSandyBridge;
Chris Dalton1c1391c2018-07-20 12:21:14 -0600524 break;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700525 case 4000:
526 case 2500:
Brian Salomon414782d2020-04-17 09:34:17 -0400527 renderer = GrGLANGLERenderer::kIvyBridge;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700528 break;
529 case 510:
530 case 515:
531 case 520:
532 case 530:
Brian Salomon414782d2020-04-17 09:34:17 -0400533 renderer = GrGLANGLERenderer::kSkylake;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700534 break;
535 }
536 } else if ((modelStr = strstr(rendererString, "Iris")) &&
537 (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
538 1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
539 1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
540 switch (modelNumber) {
541 case 540:
542 case 550:
543 case 555:
544 case 580:
Brian Salomon414782d2020-04-17 09:34:17 -0400545 renderer = GrGLANGLERenderer::kSkylake;
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700546 break;
547 }
548 }
Brian Salomon414782d2020-04-17 09:34:17 -0400549 } else if (strstr(rendererString, "NVIDIA")) {
550 vendor = GrGLANGLEVendor::kNVIDIA;
Brian Osman15207b82020-06-17 10:37:16 -0400551 } else if (strstr(rendererString, "Radeon")) {
552 vendor = GrGLANGLEVendor::kAMD;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400553 }
554 if (strstr(rendererString, "Direct3D11")) {
Brian Salomon414782d2020-04-17 09:34:17 -0400555 backend = GrGLANGLEBackend::kD3D11;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400556 } else if (strstr(rendererString, "Direct3D9")) {
Brian Salomon414782d2020-04-17 09:34:17 -0400557 backend = GrGLANGLEBackend::kD3D9;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400558 } else if (strstr(rendererString, "OpenGL")) {
Brian Salomon414782d2020-04-17 09:34:17 -0400559 backend = GrGLANGLEBackend::kOpenGL;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400560 }
Brian Salomon414782d2020-04-17 09:34:17 -0400561 return {backend, vendor, renderer};
Brian Salomon266ef6d2017-09-22 11:27:42 -0400562}
563
bsalomon@google.com9c1f1ac2012-05-07 17:09:37 +0000564GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
565 const GrGLubyte* v;
566 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
567 return GrGLGetVersionFromString((const char*) v);
568}
569
570GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
571 const GrGLubyte* v;
572 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
573 return GrGLGetGLSLVersionFromString((const char*) v);
574}
bsalomon@google.com0b1e4812012-10-23 13:52:43 +0000575
576GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
577 const GrGLubyte* v;
578 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
579 return GrGLGetVendorFromString((const char*) v);
580}
commit-bot@chromium.org215a6822013-09-05 18:28:42 +0000581
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000582GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
Chris Dalton0090ef62018-03-28 17:35:00 -0600583 const GrGLubyte* rendererString;
584 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
585
Brian Salomon4470e342018-04-04 14:27:48 -0400586 return GrGLGetRendererFromStrings((const char*)rendererString, gl->fExtensions);
commit-bot@chromium.org0694ea72013-09-18 13:00:28 +0000587}
588
Brian Salomon414782d2020-04-17 09:34:17 -0400589std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfo(
590 const GrGLInterface* gl) {
591 const GrGLubyte* rendererString;
592 GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
593 return GrGLGetANGLEInfoFromString((const char*)rendererString);
594}
595
cdalton93a379b2016-05-11 13:58:08 -0700596GrGLenum GrToGLStencilFunc(GrStencilTest test) {
597 static const GrGLenum gTable[kGrStencilTestCount] = {
598 GR_GL_ALWAYS, // kAlways
599 GR_GL_NEVER, // kNever
600 GR_GL_GREATER, // kGreater
601 GR_GL_GEQUAL, // kGEqual
602 GR_GL_LESS, // kLess
603 GR_GL_LEQUAL, // kLEqual
604 GR_GL_EQUAL, // kEqual
605 GR_GL_NOTEQUAL, // kNotEqual
kkinnunenccdaa042014-08-20 01:36:23 -0700606 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500607 static_assert(0 == (int)GrStencilTest::kAlways);
608 static_assert(1 == (int)GrStencilTest::kNever);
609 static_assert(2 == (int)GrStencilTest::kGreater);
610 static_assert(3 == (int)GrStencilTest::kGEqual);
611 static_assert(4 == (int)GrStencilTest::kLess);
612 static_assert(5 == (int)GrStencilTest::kLEqual);
613 static_assert(6 == (int)GrStencilTest::kEqual);
614 static_assert(7 == (int)GrStencilTest::kNotEqual);
cdalton93a379b2016-05-11 13:58:08 -0700615 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
kkinnunenccdaa042014-08-20 01:36:23 -0700616
cdalton93a379b2016-05-11 13:58:08 -0700617 return gTable[(int)test];
kkinnunenccdaa042014-08-20 01:36:23 -0700618}
Robert Phillips8043f322019-05-31 08:11:36 -0400619
Brian Salomon5043f1f2019-07-11 21:27:54 -0400620bool GrGLFormatIsCompressed(GrGLFormat format) {
621 switch (format) {
Brian Salomon5043f1f2019-07-11 21:27:54 -0400622 case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
Robert Phillipsb0855272020-01-15 12:56:52 -0500623 case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
Robert Phillips8f259a02019-12-20 11:32:27 -0500624 case GrGLFormat::kCOMPRESSED_RGB8_BC1:
Robert Phillipsb0855272020-01-15 12:56:52 -0500625 case GrGLFormat::kCOMPRESSED_RGBA8_BC1:
Robert Phillips8043f322019-05-31 08:11:36 -0400626 return true;
Brian Salomon5043f1f2019-07-11 21:27:54 -0400627
628 case GrGLFormat::kRGBA8:
629 case GrGLFormat::kR8:
630 case GrGLFormat::kALPHA8:
631 case GrGLFormat::kLUMINANCE8:
632 case GrGLFormat::kBGRA8:
633 case GrGLFormat::kRGB565:
634 case GrGLFormat::kRGBA16F:
635 case GrGLFormat::kR16F:
Robert Phillipsebab03f2019-07-22 08:48:18 -0400636 case GrGLFormat::kLUMINANCE16F:
Brian Salomon5043f1f2019-07-11 21:27:54 -0400637 case GrGLFormat::kRGB8:
638 case GrGLFormat::kRG8:
639 case GrGLFormat::kRGB10_A2:
640 case GrGLFormat::kRGBA4:
Brian Salomon5043f1f2019-07-11 21:27:54 -0400641 case GrGLFormat::kSRGB8_ALPHA8:
642 case GrGLFormat::kR16:
643 case GrGLFormat::kRG16:
644 case GrGLFormat::kRGBA16:
645 case GrGLFormat::kRG16F:
646 case GrGLFormat::kUnknown:
Robert Phillips8043f322019-05-31 08:11:36 -0400647 return false;
648 }
Brian Salomon5043f1f2019-07-11 21:27:54 -0400649 SkUNREACHABLE;
Robert Phillips8043f322019-05-31 08:11:36 -0400650}
Robert Phillipsd04ddcd2019-12-18 14:36:52 -0500651