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