Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/gpu/gl/GrGLUtil.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * 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.
6
 */
7
8
9
#include "include/core/SkMatrix.h"
10
#include "include/private/GrTypesPriv.h"
11
#include "src/gpu/GrDataUtils.h"
12
#include "src/gpu/gl/GrGLUtil.h"
13
#include <stdio.h>
14
15
///////////////////////////////////////////////////////////////////////////////
16
17
#if GR_GL_LOG_CALLS
18
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
19
#endif
20
21
#if GR_GL_CHECK_ERROR
22
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
23
#endif
24
25
///////////////////////////////////////////////////////////////////////////////
26
27
0
GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
28
0
    if (!versionString) {
29
0
        SkDebugf("nullptr GL version string.");
30
0
        return kNone_GrGLStandard;
31
0
    }
32
33
0
    int major, minor;
34
35
    // check for desktop
36
0
    int n = sscanf(versionString, "%d.%d", &major, &minor);
37
0
    if (2 == n) {
38
0
        return kGL_GrGLStandard;
39
0
    }
40
41
    // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
42
0
    int esMajor, esMinor;
43
0
    n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
44
0
    if (4 == n) {
45
0
        return kWebGL_GrGLStandard;
46
0
    }
47
48
    // check for ES 1
49
0
    char profile[2];
50
0
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
51
0
    if (4 == n) {
52
        // we no longer support ES1.
53
0
        return kNone_GrGLStandard;
54
0
    }
55
56
    // check for ES2
57
0
    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
58
0
    if (2 == n) {
59
0
        return kGLES_GrGLStandard;
60
0
    }
61
0
    return kNone_GrGLStandard;
62
0
}
63
64
0
GrGLVersion GrGLGetVersionFromString(const char* versionString) {
65
0
    if (!versionString) {
66
0
        SkDebugf("nullptr GL version string.");
67
0
        return GR_GL_INVALID_VER;
68
0
    }
69
70
0
    int major, minor;
71
72
    // check for mesa
73
0
    int mesaMajor, mesaMinor;
74
0
    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
75
0
    if (4 == n) {
76
0
        return GR_GL_VER(major, minor);
77
0
    }
78
79
0
    n = sscanf(versionString, "%d.%d", &major, &minor);
80
0
    if (2 == n) {
81
0
        return GR_GL_VER(major, minor);
82
0
    }
83
84
    // WebGL might look like "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))"
85
0
    int esMajor, esMinor;
86
0
    n = sscanf(versionString, "OpenGL ES %d.%d (WebGL %d.%d", &esMajor, &esMinor, &major, &minor);
87
0
    if (4 == n) {
88
0
        return GR_GL_VER(major, minor);
89
0
    }
90
91
0
    char profile[2];
92
0
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile + 1, &major, &minor);
93
0
    if (4 == n) {
94
0
        return GR_GL_VER(major, minor);
95
0
    }
96
97
0
    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
98
0
    if (2 == n) {
99
0
        return GR_GL_VER(major, minor);
100
0
    }
101
102
0
    return GR_GL_INVALID_VER;
103
0
}
104
105
0
GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
106
0
    SkASSERT(gl);
107
0
    const GrGLubyte* v;
108
0
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
109
0
    return GrGLGetVersionFromString((const char*)v);
110
0
}
Unexecuted instantiation: GrGLGetVersion(GrGLInterface const*)
Unexecuted instantiation: GrGLGetVersion(GrGLInterface const*)
111
112
0
static GrGLSLVersion get_glsl_version(const char* versionString) {
113
0
    SkASSERT(versionString);
114
0
    int major, minor;
115
116
0
    int n = sscanf(versionString, "%d.%d", &major, &minor);
117
0
    if (2 == n) {
118
0
        return GR_GLSL_VER(major, minor);
119
0
    }
120
121
0
    n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
122
0
    if (2 == n) {
123
0
        return GR_GLSL_VER(major, minor);
124
0
    }
125
126
#ifdef SK_BUILD_FOR_ANDROID
127
    // android hack until the gpu vender updates their drivers
128
    n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
129
    if (2 == n) {
130
        return GR_GLSL_VER(major, minor);
131
    }
132
#endif
133
134
0
    return GR_GLSL_INVALID_VER;
135
0
}
Unexecuted instantiation: GrGLUtil.cpp:get_glsl_version(char const*)
Unexecuted instantiation: GrGLUtil.cpp:get_glsl_version(char const*)
136
137
0
static GrGLVendor get_vendor(const char* vendorString) {
138
0
    SkASSERT(vendorString);
139
0
    if (0 == strcmp(vendorString, "ARM")) {
140
0
        return GrGLVendor::kARM;
141
0
    }
142
0
    if (0 == strcmp(vendorString, "Google Inc.")) {
143
0
        return GrGLVendor::kGoogle;
144
0
    }
145
0
    if (0 == strcmp(vendorString, "Imagination Technologies")) {
146
0
        return GrGLVendor::kImagination;
147
0
    }
148
0
    if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
149
0
        return GrGLVendor::kIntel;
150
0
    }
151
0
    if (0 == strcmp(vendorString, "Qualcomm") || 0 == strcmp(vendorString, "freedreno")) {
152
0
        return GrGLVendor::kQualcomm;
153
0
    }
154
0
    if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
155
0
        return GrGLVendor::kNVIDIA;
156
0
    }
157
0
    if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
158
0
        return GrGLVendor::kATI;
159
0
    }
160
0
    return GrGLVendor::kOther;
161
0
}
Unexecuted instantiation: GrGLUtil.cpp:get_vendor(char const*)
Unexecuted instantiation: GrGLUtil.cpp:get_vendor(char const*)
162
163
0
static GrGLRenderer get_renderer(const char* rendererString, const GrGLExtensions& extensions) {
164
0
    SkASSERT(rendererString);
165
0
    static const char kTegraStr[] = "NVIDIA Tegra";
166
0
    if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
167
        // Tegra strings are not very descriptive. We distinguish between the modern and legacy
168
        // architectures by the presence of NV_path_rendering.
169
0
        return extensions.has("GL_NV_path_rendering") ? GrGLRenderer::kTegra
170
0
                                                      : GrGLRenderer::kTegra_PreK1;
171
0
    }
172
0
    int lastDigit;
173
0
    int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
174
0
    if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
175
0
        return GrGLRenderer::kPowerVR54x;
176
0
    }
177
    // certain iOS devices also use PowerVR54x GPUs
178
0
    static const char kAppleA4Str[] = "Apple A4";
179
0
    static const char kAppleA5Str[] = "Apple A5";
180
0
    static const char kAppleA6Str[] = "Apple A6";
181
0
    if (0 == strncmp(rendererString, kAppleA4Str, SK_ARRAY_COUNT(kAppleA4Str) - 1) ||
182
0
        0 == strncmp(rendererString, kAppleA5Str, SK_ARRAY_COUNT(kAppleA5Str) - 1) ||
183
0
        0 == strncmp(rendererString, kAppleA6Str, SK_ARRAY_COUNT(kAppleA6Str) - 1)) {
184
0
        return GrGLRenderer::kPowerVR54x;
185
0
    }
186
0
    static const char kPowerVRRogueStr[] = "PowerVR Rogue";
187
0
    static const char kAppleA7Str[] = "Apple A7";
188
0
    static const char kAppleA8Str[] = "Apple A8";
189
0
    if (0 == strncmp(rendererString, kPowerVRRogueStr, SK_ARRAY_COUNT(kPowerVRRogueStr) - 1) ||
190
0
        0 == strncmp(rendererString, kAppleA7Str, SK_ARRAY_COUNT(kAppleA7Str) - 1) ||
191
0
        0 == strncmp(rendererString, kAppleA8Str, SK_ARRAY_COUNT(kAppleA8Str) - 1)) {
192
0
        return GrGLRenderer::kPowerVRRogue;
193
0
    }
194
0
    int adrenoNumber;
195
0
    n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
196
0
    if (n < 1) {
197
        // retry with freedreno driver
198
0
        n = sscanf(rendererString, "FD%d", &adrenoNumber);
199
0
    }
200
0
    if (1 == n) {
201
0
        if (adrenoNumber >= 300) {
202
0
            if (adrenoNumber < 400) {
203
0
                return GrGLRenderer::kAdreno3xx;
204
0
            }
205
0
            if (adrenoNumber < 500) {
206
0
                return adrenoNumber >= 430 ? GrGLRenderer::kAdreno430
207
0
                                           : GrGLRenderer::kAdreno4xx_other;
208
0
            }
209
0
            if (adrenoNumber < 600) {
210
0
                return adrenoNumber == 530 ? GrGLRenderer::kAdreno530
211
0
                                           : GrGLRenderer::kAdreno5xx_other;
212
0
            }
213
0
            if (adrenoNumber < 700) {
214
0
                if (adrenoNumber == 615) {
215
0
                    return GrGLRenderer::kAdreno615;
216
0
                }
217
0
                if (adrenoNumber == 620) {
218
0
                    return GrGLRenderer::kAdreno620;
219
0
                }
220
0
                if (adrenoNumber == 630) {
221
0
                    return GrGLRenderer::kAdreno630;
222
0
                }
223
0
                if (adrenoNumber == 640) {
224
0
                    return GrGLRenderer::kAdreno640;
225
0
                }
226
0
                return GrGLRenderer::kAdreno6xx_other;
227
0
            }
228
0
        }
229
0
    }
230
0
    if (0 == strcmp("Google SwiftShader", rendererString)) {
231
0
        return GrGLRenderer::kGoogleSwiftShader;
232
0
    }
233
234
0
    if (const char* intelString = strstr(rendererString, "Intel")) {
235
        // These generic strings seem to always come from Haswell: Iris 5100 or Iris Pro 5200
236
0
        if (0 == strcmp("Intel Iris OpenGL Engine", intelString) ||
237
0
            0 == strcmp("Intel Iris Pro OpenGL Engine", intelString)) {
238
0
            return GrGLRenderer::kIntelHaswell;
239
0
        }
240
0
        if (strstr(intelString, "Sandybridge")) {
241
0
            return GrGLRenderer::kIntelSandyBridge;
242
0
        }
243
0
        if (strstr(intelString, "Bay Trail")) {
244
0
            return GrGLRenderer::kIntelValleyView;
245
0
        }
246
        // There are many possible intervening strings here:
247
        // 'Intel(R)' is a common prefix
248
        // 'Iris' may appear, followed by '(R)' or '(TM)'
249
        // 'Iris' can then be followed by 'Graphics', 'Pro Graphics', or 'Plus Graphics'
250
        // If 'Iris' isn't there, we might have 'HD Graphics' or 'UHD Graphics'
251
        //
252
        // In all cases, though, we end with 'Graphics ', an optional 'P', and a number,
253
        // so just skip to that and handle two cases:
254
0
        if (const char* intelGfxString = strstr(intelString, "Graphics")) {
255
0
            int intelNumber;
256
0
            if (sscanf(intelGfxString, "Graphics %d", &intelNumber) ||
257
0
                sscanf(intelGfxString, "Graphics P%d", &intelNumber)) {
258
0
                if (intelNumber == 2000 || intelNumber == 3000) {
259
0
                    return GrGLRenderer::kIntelSandyBridge;
260
0
                }
261
0
                if (intelNumber == 2500 || intelNumber == 4000) {
262
0
                    return GrGLRenderer::kIntelIvyBridge;
263
0
                }
264
0
                if (intelNumber >= 4200 && intelNumber <= 5200) {
265
0
                    return GrGLRenderer::kIntelHaswell;
266
0
                }
267
0
                if (intelNumber >= 400 && intelNumber <= 405) {
268
0
                    return GrGLRenderer::kIntelCherryView;
269
0
                }
270
0
                if (intelNumber >= 5300 && intelNumber <= 6300) {
271
0
                    return GrGLRenderer::kIntelBroadwell;
272
0
                }
273
0
                if (intelNumber >= 500 && intelNumber <= 505) {
274
0
                    return GrGLRenderer::kIntelApolloLake;
275
0
                }
276
0
                if (intelNumber >= 510 && intelNumber <= 580) {
277
0
                    return GrGLRenderer::kIntelSkyLake;
278
0
                }
279
0
                if (intelNumber >= 600 && intelNumber <= 605) {
280
0
                    return GrGLRenderer::kIntelGeminiLake;
281
0
                }
282
                // 610 and 630 are reused from KabyLake to CoffeeLake. The CoffeeLake variants
283
                // are "UHD Graphics", while the KabyLake ones are "HD Graphics"
284
0
                if (intelNumber == 610 || intelNumber == 630) {
285
0
                    return strstr(intelString, "UHD") ? GrGLRenderer::kIntelCoffeeLake
286
0
                                                      : GrGLRenderer::kIntelKabyLake;
287
0
                }
288
0
                if (intelNumber >= 610 && intelNumber <= 650) {
289
0
                    return GrGLRenderer::kIntelKabyLake;
290
0
                }
291
0
                if (intelNumber == 655) {
292
0
                    return GrGLRenderer::kIntelCoffeeLake;
293
0
                }
294
0
                if (intelNumber >= 910 && intelNumber <= 950) {
295
0
                    return GrGLRenderer::kIntelIceLake;
296
0
                }
297
0
            }
298
0
        }
299
0
    }
300
301
    // The AMD string can have a somewhat arbitrary preamble (see skbug.com/7195)
302
0
    static constexpr char kRadeonStr[] = "Radeon ";
303
0
    if (const char* amdString = strstr(rendererString, kRadeonStr)) {
304
0
        amdString += strlen(kRadeonStr);
305
        // Sometimes there is a (TM) and sometimes not.
306
0
        static constexpr char kTMStr[] = "(TM) ";
307
0
        if (!strncmp(amdString, kTMStr, strlen(kTMStr))) {
308
0
            amdString += strlen(kTMStr);
309
0
        }
310
311
0
        char amd0, amd1, amd2;
312
0
        int amdModel;
313
0
        n = sscanf(amdString, "R9 M3%c%c", &amd0, &amd1);
314
0
        if (2 == n && isdigit(amd0) && isdigit(amd1)) {
315
0
            return GrGLRenderer::kAMDRadeonR9M3xx;
316
0
        }
317
318
0
        n = sscanf(amdString, "R9 M4%c%c", &amd0, &amd1);
319
0
        if (2 == n && isdigit(amd0) && isdigit(amd1)) {
320
0
            return GrGLRenderer::kAMDRadeonR9M4xx;
321
0
        }
322
323
0
        n = sscanf(amdString, "HD 7%c%c%c Series", &amd0, &amd1, &amd2);
324
0
        if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
325
0
            return GrGLRenderer::kAMDRadeonHD7xxx;
326
0
        }
327
328
0
        n = sscanf(amdString, "Pro 5%c%c%c", &amd0, &amd1, &amd2);
329
0
        if (3 == n && isdigit(amd0) && isdigit(amd1) && isdigit(amd2)) {
330
0
            return GrGLRenderer::kAMDRadeonPro5xxx;
331
0
        }
332
333
0
        n = sscanf(amdString, "Pro Vega %i", &amdModel);
334
0
        if (1 == n) {
335
0
            return GrGLRenderer::kAMDRadeonProVegaxx;
336
0
        }
337
0
    }
338
339
0
    if (strstr(rendererString, "llvmpipe")) {
340
0
        return GrGLRenderer::kGalliumLLVM;
341
0
    }
342
0
    if (strstr(rendererString, "virgl")) {
343
0
        return GrGLRenderer::kVirgl;
344
0
    }
345
0
    static const char kMaliGStr[] = "Mali-G";
346
0
    if (0 == strncmp(rendererString, kMaliGStr, SK_ARRAY_COUNT(kMaliGStr) - 1)) {
347
0
        return GrGLRenderer::kMaliG;
348
0
    }
349
0
    static const char kMaliTStr[] = "Mali-T";
350
0
    if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
351
0
        return GrGLRenderer::kMaliT;
352
0
    }
353
0
    int mali400Num;
354
0
    if (1 == sscanf(rendererString, "Mali-%d", &mali400Num) && mali400Num >= 400 &&
355
0
        mali400Num < 500) {
356
0
        return GrGLRenderer::kMali4xx;
357
0
    }
358
0
    return GrGLRenderer::kOther;
359
0
}
Unexecuted instantiation: GrGLUtil.cpp:get_renderer(char const*, GrGLExtensions const&)
Unexecuted instantiation: GrGLUtil.cpp:get_renderer(char const*, GrGLExtensions const&)
360
361
0
static bool is_commamd_buffer(const char* rendererString, const char* versionString) {
362
0
    SkASSERT(rendererString);
363
0
    SkASSERT(versionString);
364
365
0
    int major, minor;
366
0
    static const char kChromium[] = "Chromium";
367
0
    char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
368
0
    return (0 == strcmp(rendererString, kChromium) ||
369
0
           (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
370
0
            0 == strcmp(kChromium, suffix)));
371
0
}
Unexecuted instantiation: GrGLUtil.cpp:is_commamd_buffer(char const*, char const*)
Unexecuted instantiation: GrGLUtil.cpp:is_commamd_buffer(char const*, char const*)
372
373
static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStandard standard,
374
                                                                        GrGLVendor vendor,
375
                                                                        const char* vendorString,
376
                                                                        const char* rendererString,
377
0
                                                                        const char* versionString) {
378
0
    SkASSERT(rendererString);
379
0
    SkASSERT(versionString);
380
381
0
    GrGLDriver driver               = GrGLDriver::kUnknown;
382
0
    GrGLDriverVersion driverVersion = GR_GL_DRIVER_UNKNOWN_VER;
383
384
0
    int major, minor, rev, driverMajor, driverMinor, driverPoint;
385
    // This is the same on ES and regular GL.
386
0
    if (!strcmp(vendorString, "freedreno")) {
387
0
        driver = GrGLDriver::kFreedreno;
388
0
    } else if (GR_IS_GR_GL(standard)) {
389
0
        if (vendor == GrGLVendor::kNVIDIA) {
390
0
            driver = GrGLDriver::kNVIDIA;
391
0
            int n = sscanf(versionString,
392
0
                           "%d.%d.%d NVIDIA %d.%d",
393
0
                           &major,
394
0
                           &minor,
395
0
                           &rev,
396
0
                           &driverMajor,
397
0
                           &driverMinor);
398
            // Some older NVIDIA drivers don't report the driver version.
399
0
            if (n == 5) {
400
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
401
0
            }
402
0
        } else {
403
0
            int n = sscanf(versionString,
404
0
                           "%d.%d Mesa %d.%d",
405
0
                           &major,
406
0
                           &minor,
407
0
                           &driverMajor,
408
0
                           &driverMinor);
409
0
            if (n != 4) {
410
0
                n = sscanf(versionString,
411
0
                           "%d.%d (Core Profile) Mesa %d.%d",
412
0
                           &major,
413
0
                           &minor,
414
0
                           &driverMajor,
415
0
                           &driverMinor);
416
0
            }
417
0
            if (n == 4) {
418
0
                driver = GrGLDriver::kMesa;
419
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
420
0
            }
421
0
        }
422
0
    } else if (standard == kGLES_GrGLStandard) {
423
0
        if (vendor == GrGLVendor::kNVIDIA) {
424
0
            driver = GrGLDriver::kNVIDIA;
425
0
            int n = sscanf(versionString,
426
0
                           "OpenGL ES %d.%d NVIDIA %d.%d",
427
0
                           &major,
428
0
                           &minor,
429
0
                           &driverMajor,
430
0
                           &driverMinor);
431
            // Some older NVIDIA drivers don't report the driver version.
432
0
            if (n == 4) {
433
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
434
0
            }
435
0
        } else if (vendor == GrGLVendor::kImagination) {
436
0
            int revision;
437
0
            int n = sscanf(versionString,
438
0
                           "OpenGL ES %d.%d build %d.%d@%d",
439
0
                           &major,
440
0
                           &minor,
441
0
                           &driverMajor,
442
0
                           &driverMinor,
443
0
                           &revision);
444
0
            if (n == 5) {
445
0
                driver = GrGLDriver::kImagination;
446
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
447
0
            }
448
0
        } else {
449
0
            int n = sscanf(versionString,
450
0
                           "OpenGL ES %d.%d Mesa %d.%d",
451
0
                           &major,
452
0
                           &minor,
453
0
                           &driverMajor,
454
0
                           &driverMinor);
455
0
            if (n == 4) {
456
0
                driver = GrGLDriver::kMesa;
457
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
458
0
            }
459
0
        }
460
0
    }
461
462
0
    if (driver == GrGLDriver::kUnknown) {
463
0
        if (vendor == GrGLVendor::kGoogle) {
464
            // Swiftshader is the only Google vendor at the moment
465
0
            driver = GrGLDriver::kSwiftShader;
466
467
            // Swiftshader has a strange version string: w.x.y.z  Going to arbitrarily ignore
468
            // y and assume w,x and z are major, minor, point.
469
            // As of writing, version is 4.0.0.6
470
0
            int n = sscanf(versionString,
471
0
                           "OpenGL ES %d.%d SwiftShader %d.%d.0.%d",
472
0
                           &major,
473
0
                           &minor,
474
0
                           &driverMajor,
475
0
                           &driverMinor,
476
0
                           &driverPoint);
477
0
            if (n == 5) {
478
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
479
0
            }
480
0
        } else if (vendor == GrGLVendor::kIntel) {
481
            // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
482
0
            driver = GrGLDriver::kIntel;
483
484
            // This is how the macOS version strings are structured. This might be different on
485
            // different
486
            //  OSes.
487
0
            int n = sscanf(versionString,
488
0
                           "%d.%d INTEL-%d.%d.%d",
489
0
                           &major,
490
0
                           &minor,
491
0
                           &driverMajor,
492
0
                           &driverMinor,
493
0
                           &driverPoint);
494
0
            if (n == 5) {
495
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, driverPoint);
496
0
            }
497
0
        } else if (vendor == GrGLVendor::kQualcomm) {
498
0
            driver = GrGLDriver::kQualcomm;
499
0
            int n = sscanf(versionString,
500
0
                           "OpenGL ES %d.%d V@%d.%d",
501
0
                           &major,
502
0
                           &minor,
503
0
                           &driverMajor,
504
0
                           &driverMinor);
505
0
            if (n == 4) {
506
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
507
0
            }
508
0
        } else if (vendor == GrGLVendor::kImagination) {
509
0
            int revision;
510
0
            int n = sscanf(versionString,
511
0
                           "OpenGL ES %d.%d build %d.%d@%d",
512
0
                           &major,
513
0
                           &minor,
514
0
                           &driverMajor,
515
0
                           &driverMinor,
516
0
                           &revision);
517
0
            if (n == 5) {
518
                // Revision is a large number (looks like a source control revision number) that
519
                // doesn't fit into the 'patch' bits, so omit it until we need it.
520
0
                driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
521
0
            }
522
0
        } else {
523
0
            static constexpr char kEmulatorPrefix[] = "Android Emulator OpenGL ES Translator";
524
0
            if (0 == strncmp(kEmulatorPrefix, rendererString, strlen(kEmulatorPrefix))) {
525
0
                driver = GrGLDriver::kAndroidEmulator;
526
0
            }
527
0
        }
528
0
    }
529
0
    return {driver, driverVersion};
530
0
}
Unexecuted instantiation: GrGLUtil.cpp:get_driver_and_version(GrGLStandard, GrGLVendor, char const*, char const*, char const*)
Unexecuted instantiation: GrGLUtil.cpp:get_driver_and_version(GrGLStandard, GrGLVendor, char const*, char const*, char const*)
531
532
// If this is detected as ANGLE then the ANGLE backend is returned along with rendererString
533
// stripped of "ANGLE(" and ")" at the start and end, respectively.
534
0
static std::tuple<GrGLANGLEBackend, SkString> get_angle_backend(const char* rendererString) {
535
    // crbug.com/1203705 ANGLE renderer will be "ANGLE (<gl-vendor>, <gl-renderer>, <gl-version>)"
536
    // on ANGLE's GL backend with related substitutions for the inner strings on other backends.
537
0
    static constexpr char kHeader[] = "ANGLE (";
538
0
    static constexpr size_t kHeaderLength = SK_ARRAY_COUNT(kHeader) - 1;
539
0
    int rendererLength = strlen(rendererString);
540
0
    if (!strncmp(rendererString, kHeader, kHeaderLength) &&
541
0
        rendererString[rendererLength - 1] == ')') {
542
0
        SkString innerString;
543
0
        innerString.set(rendererString + kHeaderLength, rendererLength - kHeaderLength - 1);
544
0
        if (strstr(rendererString, "Direct3D11")) {
545
0
            return {GrGLANGLEBackend::kD3D11, std::move(innerString)};
546
0
        } else if (strstr(rendererString, "Direct3D9")) {
547
0
            return {GrGLANGLEBackend::kD3D9, std::move(innerString)};
548
0
        } else if (strstr(rendererString, "OpenGL")) {
549
0
            return {GrGLANGLEBackend::kOpenGL, std::move(innerString)};
550
0
        }
551
0
    }
552
0
    return {GrGLANGLEBackend::kUnknown, {}};
553
0
}
554
555
static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
556
get_angle_gl_vendor_and_renderer(
557
        const char* innerString,
558
0
        const GrGLExtensions& extensions) {
559
0
    SkTArray<SkString> parts;
560
0
    SkStrSplit(innerString, ",", &parts);
561
    // This would need some fixing if we have substrings that contain commas.
562
0
    if (parts.size() != 3) {
563
0
        return {GrGLVendor::kOther,
564
0
                GrGLRenderer::kOther,
565
0
                GrGLDriver::kUnknown,
566
0
                GR_GL_DRIVER_UNKNOWN_VER};
567
0
    }
568
569
0
    const char* angleVendorString   = parts[0].c_str();
570
0
    const char* angleRendererString = parts[1].c_str() + 1; // skip initial space
571
0
    const char* angleVersionString  = parts[2].c_str() + 1; // skip initial space
572
573
0
    GrGLVendor angleVendor = get_vendor(angleVendorString);
574
575
0
    auto [angleDriver, angleDriverVersion] = get_driver_and_version(kGLES_GrGLStandard,
576
0
                                                                    angleVendor,
577
0
                                                                    angleVendorString,
578
0
                                                                    angleRendererString,
579
0
                                                                    angleVersionString);
580
581
0
    auto angleRenderer = get_renderer(angleRendererString, extensions);
582
583
0
    return {angleVendor, angleRenderer, angleDriver, angleDriverVersion};
584
0
}
585
586
static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
587
0
get_angle_d3d_vendor_and_renderer(const char* innerString) {
588
0
    auto vendor   = GrGLVendor::kOther;
589
0
    auto renderer = GrGLRenderer::kOther;
590
591
0
    if (strstr(innerString, "Intel")) {
592
0
        vendor = GrGLVendor::kIntel;
593
594
0
        const char* modelStr;
595
0
        int modelNumber;
596
0
        if ((modelStr = strstr(innerString, "HD Graphics")) &&
597
0
            (1 == sscanf(modelStr, "HD Graphics %i", &modelNumber) ||
598
0
             1 == sscanf(modelStr, "HD Graphics P%i", &modelNumber))) {
599
0
            switch (modelNumber) {
600
0
                case 2000:
601
0
                case 3000:
602
0
                    renderer = GrGLRenderer::kIntelSandyBridge;
603
0
                    break;
604
0
                case 4000:
605
0
                case 2500:
606
0
                    renderer = GrGLRenderer::kIntelSandyBridge;
607
0
                    break;
608
0
                case 510:
609
0
                case 515:
610
0
                case 520:
611
0
                case 530:
612
0
                    renderer = GrGLRenderer::kIntelSkyLake;
613
0
                    break;
614
0
            }
615
0
        } else if ((modelStr = strstr(innerString, "Iris")) &&
616
0
                   (1 == sscanf(modelStr, "Iris(TM) Graphics %i", &modelNumber) ||
617
0
                    1 == sscanf(modelStr, "Iris(TM) Pro Graphics %i", &modelNumber) ||
618
0
                    1 == sscanf(modelStr, "Iris(TM) Pro Graphics P%i", &modelNumber))) {
619
0
            switch (modelNumber) {
620
0
                case 540:
621
0
                case 550:
622
0
                case 555:
623
0
                case 580:
624
0
                    renderer = GrGLRenderer::kIntelSkyLake;
625
0
                    break;
626
0
            }
627
0
        }
628
0
    } else if (strstr(innerString, "NVIDIA")) {
629
0
        vendor = GrGLVendor::kNVIDIA;
630
0
    } else if (strstr(innerString, "Radeon")) {
631
0
        vendor = GrGLVendor::kATI;
632
0
    }
633
    // We haven't had a need yet to parse the D3D driver string.
634
0
    return {vendor, renderer, GrGLDriver::kUnknown, GR_GL_DRIVER_UNKNOWN_VER};
635
0
}
636
637
0
GrGLDriverInfo GrGLGetDriverInfo(const GrGLInterface* interface) {
638
0
    if (!interface) {
639
0
        return {};
640
0
    }
641
0
    SkASSERT(interface->fStandard != kNone_GrGLStandard);
642
0
    GrGLDriverInfo info;
643
0
    info.fStandard = interface->fStandard;
644
645
0
    auto getString = [&](GrGLenum s) {
646
0
        const GrGLubyte* bytes = interface->fFunctions.fGetString(s);
647
0
        if (!bytes) {
648
0
            return "";
649
0
        }
650
0
        return reinterpret_cast<const char*>(bytes);
651
0
    };
Unexecuted instantiation: GrGLUtil.cpp:GrGLGetDriverInfo(GrGLInterface const*)::$_0::operator()(unsigned int) const
Unexecuted instantiation: GrGLUtil.cpp:GrGLGetDriverInfo(GrGLInterface const*)::$_2::operator()(unsigned int) const
652
653
0
    const char* const version   = getString(GR_GL_VERSION);
654
0
    const char* const slversion = getString(GR_GL_SHADING_LANGUAGE_VERSION);
655
0
    const char* const renderer  = getString(GR_GL_RENDERER);
656
0
    const char* const vendor    = getString(GR_GL_VENDOR);
657
658
0
    info.fVersion     = GrGLGetVersionFromString(version);
659
0
    info.fGLSLVersion = get_glsl_version(slversion);
660
0
    info.fVendor      = get_vendor(vendor);
661
0
    info.fRenderer    = get_renderer(renderer, interface->fExtensions);
662
663
0
    std::tie(info.fDriver, info.fDriverVersion) = get_driver_and_version(interface->fStandard,
664
0
                                                                         info.fVendor,
665
0
                                                                         vendor,
666
0
                                                                         renderer,
667
0
                                                                         version);
668
669
0
    SkString innerAngleRendererString;
670
0
    std::tie(info.fANGLEBackend, innerAngleRendererString) = get_angle_backend(renderer);
671
672
0
    if (info.fANGLEBackend == GrGLANGLEBackend::kD3D9 ||
673
0
        info.fANGLEBackend == GrGLANGLEBackend::kD3D11) {
674
0
        std::tie(info.fANGLEVendor,
675
0
                 info.fANGLERenderer,
676
0
                 info.fANGLEDriver,
677
0
                 info.fANGLEDriverVersion) =
678
0
                get_angle_d3d_vendor_and_renderer(innerAngleRendererString.c_str());
679
0
    } else if (info.fANGLEBackend == GrGLANGLEBackend::kOpenGL) {
680
0
        std::tie(info.fANGLEVendor,
681
0
                 info.fANGLERenderer,
682
0
                 info.fANGLEDriver,
683
0
                 info.fANGLEDriverVersion) =
684
0
                get_angle_gl_vendor_and_renderer(innerAngleRendererString.c_str(),
685
0
                                                 interface->fExtensions);
686
0
    }
687
688
0
    info.fIsOverCommandBuffer = is_commamd_buffer(renderer, version);
689
690
0
    return info;
691
0
}
Unexecuted instantiation: GrGLGetDriverInfo(GrGLInterface const*)
Unexecuted instantiation: GrGLGetDriverInfo(GrGLInterface const*)
692
693
0
GrGLenum GrToGLStencilFunc(GrStencilTest test) {
694
0
    static const GrGLenum gTable[kGrStencilTestCount] = {
695
0
        GR_GL_ALWAYS,           // kAlways
696
0
        GR_GL_NEVER,            // kNever
697
0
        GR_GL_GREATER,          // kGreater
698
0
        GR_GL_GEQUAL,           // kGEqual
699
0
        GR_GL_LESS,             // kLess
700
0
        GR_GL_LEQUAL,           // kLEqual
701
0
        GR_GL_EQUAL,            // kEqual
702
0
        GR_GL_NOTEQUAL,         // kNotEqual
703
0
    };
704
0
    static_assert(0 == (int)GrStencilTest::kAlways);
705
0
    static_assert(1 == (int)GrStencilTest::kNever);
706
0
    static_assert(2 == (int)GrStencilTest::kGreater);
707
0
    static_assert(3 == (int)GrStencilTest::kGEqual);
708
0
    static_assert(4 == (int)GrStencilTest::kLess);
709
0
    static_assert(5 == (int)GrStencilTest::kLEqual);
710
0
    static_assert(6 == (int)GrStencilTest::kEqual);
711
0
    static_assert(7 == (int)GrStencilTest::kNotEqual);
712
0
    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
713
714
0
    return gTable[(int)test];
715
0
}
Unexecuted instantiation: GrToGLStencilFunc(GrStencilTest)
Unexecuted instantiation: GrToGLStencilFunc(GrStencilTest)
716
717
0
bool GrGLFormatIsCompressed(GrGLFormat format) {
718
0
    switch (format) {
719
0
        case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
720
0
        case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
721
0
        case GrGLFormat::kCOMPRESSED_RGB8_BC1:
722
0
        case GrGLFormat::kCOMPRESSED_RGBA8_BC1:
723
0
            return true;
724
725
0
        case GrGLFormat::kRGBA8:
726
0
        case GrGLFormat::kR8:
727
0
        case GrGLFormat::kALPHA8:
728
0
        case GrGLFormat::kLUMINANCE8:
729
0
        case GrGLFormat::kLUMINANCE8_ALPHA8:
730
0
        case GrGLFormat::kBGRA8:
731
0
        case GrGLFormat::kRGB565:
732
0
        case GrGLFormat::kRGBA16F:
733
0
        case GrGLFormat::kR16F:
734
0
        case GrGLFormat::kLUMINANCE16F:
735
0
        case GrGLFormat::kRGB8:
736
0
        case GrGLFormat::kRG8:
737
0
        case GrGLFormat::kRGB10_A2:
738
0
        case GrGLFormat::kRGBA4:
739
0
        case GrGLFormat::kSRGB8_ALPHA8:
740
0
        case GrGLFormat::kR16:
741
0
        case GrGLFormat::kRG16:
742
0
        case GrGLFormat::kRGBA16:
743
0
        case GrGLFormat::kRG16F:
744
0
        case GrGLFormat::kSTENCIL_INDEX8:
745
0
        case GrGLFormat::kSTENCIL_INDEX16:
746
0
        case GrGLFormat::kDEPTH24_STENCIL8:
747
0
        case GrGLFormat::kUnknown:
748
0
            return false;
749
0
    }
750
0
    SkUNREACHABLE;
751
0
}
752