1/*
2 * Copyright 2012 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#ifndef GrGLUtil_DEFINED
9#define GrGLUtil_DEFINED
10
11#include "include/gpu/gl/GrGLInterface.h"
12#include "include/private/GrTypesPriv.h"
13#include "include/private/SkImageInfoPriv.h"
14#include "src/gpu/GrDataUtils.h"
15#include "src/gpu/GrStencilSettings.h"
16#include "src/gpu/gl/GrGLDefines.h"
17
18class SkMatrix;
19
20////////////////////////////////////////////////////////////////////////////////
21
22typedef uint32_t GrGLVersion;
23typedef uint32_t GrGLSLVersion;
24typedef uint64_t GrGLDriverVersion;
25
26#define GR_GL_VER(major, minor) ((static_cast<uint32_t>(major) << 16) | \
27 static_cast<uint32_t>(minor))
28#define GR_GLSL_VER(major, minor) ((static_cast<uint32_t>(major) << 16) | \
29 static_cast<uint32_t>(minor))
30#define GR_GL_DRIVER_VER(major, minor, point) ((static_cast<uint64_t>(major) << 32) | \
31 (static_cast<uint64_t>(minor) << 16) | \
32 static_cast<uint64_t>(point))
33
34#define GR_GL_MAJOR_VER(version) (static_cast<uint32_t>(version) >> 16)
35#define GR_GL_MINOR_VER(version) (static_cast<uint32_t>(version) & 0xFFFF)
36
37#define GR_GL_INVALID_VER GR_GL_VER(0, 0)
38#define GR_GLSL_INVALID_VER GR_GLSL_VER(0, 0)
39#define GR_GL_DRIVER_UNKNOWN_VER GR_GL_DRIVER_VER(0, 0, 0)
40
41static constexpr uint32_t GrGLFormatChannels(GrGLFormat format) {
42 switch (format) {
43 case GrGLFormat::kUnknown: return 0;
44 case GrGLFormat::kRGBA8: return kRGBA_SkColorChannelFlags;
45 case GrGLFormat::kR8: return kRed_SkColorChannelFlag;
46 case GrGLFormat::kALPHA8: return kAlpha_SkColorChannelFlag;
47 case GrGLFormat::kLUMINANCE8: return kGray_SkColorChannelFlag;
48 case GrGLFormat::kBGRA8: return kRGBA_SkColorChannelFlags;
49 case GrGLFormat::kRGB565: return kRGB_SkColorChannelFlags;
50 case GrGLFormat::kRGBA16F: return kRGBA_SkColorChannelFlags;
51 case GrGLFormat::kR16F: return kRed_SkColorChannelFlag;
52 case GrGLFormat::kRGB8: return kRGB_SkColorChannelFlags;
53 case GrGLFormat::kRG8: return kRG_SkColorChannelFlags;
54 case GrGLFormat::kRGB10_A2: return kRGBA_SkColorChannelFlags;
55 case GrGLFormat::kRGBA4: return kRGBA_SkColorChannelFlags;
56 case GrGLFormat::kSRGB8_ALPHA8: return kRGBA_SkColorChannelFlags;
57 case GrGLFormat::kCOMPRESSED_ETC1_RGB8: return kRGB_SkColorChannelFlags;
58 case GrGLFormat::kCOMPRESSED_RGB8_ETC2: return kRGB_SkColorChannelFlags;
59 case GrGLFormat::kCOMPRESSED_RGB8_BC1: return kRGB_SkColorChannelFlags;
60 case GrGLFormat::kCOMPRESSED_RGBA8_BC1: return kRGBA_SkColorChannelFlags;
61 case GrGLFormat::kR16: return kRed_SkColorChannelFlag;
62 case GrGLFormat::kRG16: return kRG_SkColorChannelFlags;
63 case GrGLFormat::kRGBA16: return kRGBA_SkColorChannelFlags;
64 case GrGLFormat::kRG16F: return kRG_SkColorChannelFlags;
65 case GrGLFormat::kLUMINANCE16F: return kGray_SkColorChannelFlag;
66 }
67 SkUNREACHABLE;
68}
69
70/**
71 * The Vendor and Renderer enum values are lazily updated as required.
72 */
73enum GrGLVendor {
74 kARM_GrGLVendor,
75 kGoogle_GrGLVendor,
76 kImagination_GrGLVendor,
77 kIntel_GrGLVendor,
78 kQualcomm_GrGLVendor,
79 kNVIDIA_GrGLVendor,
80 kATI_GrGLVendor,
81
82 kOther_GrGLVendor
83};
84
85enum GrGLRenderer {
86 kTegra_PreK1_GrGLRenderer, // Legacy Tegra architecture (pre-K1).
87 kTegra_GrGLRenderer, // Tegra with the same architecture as NVIDIA desktop GPUs (K1+).
88 kPowerVR54x_GrGLRenderer,
89 kPowerVRRogue_GrGLRenderer,
90 kAdreno3xx_GrGLRenderer,
91 kAdreno430_GrGLRenderer,
92 kAdreno4xx_other_GrGLRenderer,
93 kAdreno5xx_GrGLRenderer,
94 kAdreno615_GrGLRenderer, // Pixel3a
95 kAdreno630_GrGLRenderer, // Pixel3
96 kAdreno640_GrGLRenderer, // Pixel4
97 kGoogleSwiftShader_GrGLRenderer,
98
99 /** Intel GPU families, ordered by generation **/
100 // 6th gen
101 kIntelSandyBridge_GrGLRenderer,
102
103 // 7th gen
104 kIntelIvyBridge_GrGLRenderer,
105 kIntelValleyView_GrGLRenderer, // aka BayTrail
106 kIntelHaswell_GrGLRenderer,
107
108 // 8th gen
109 kIntelCherryView_GrGLRenderer, // aka Braswell
110 kIntelBroadwell_GrGLRenderer,
111
112 // 9th gen
113 kIntelApolloLake_GrGLRenderer,
114 kIntelSkyLake_GrGLRenderer,
115 kIntelGeminiLake_GrGLRenderer,
116 kIntelKabyLake_GrGLRenderer,
117 kIntelCoffeeLake_GrGLRenderer,
118
119 // 11th gen
120 kIntelIceLake_GrGLRenderer,
121
122 kGalliumLLVM_GrGLRenderer,
123 kMali4xx_GrGLRenderer,
124 /** G-3x, G-5x, or G-7x */
125 kMaliG_GrGLRenderer,
126 /** T-6xx, T-7xx, or T-8xx */
127 kMaliT_GrGLRenderer,
128 kANGLE_GrGLRenderer,
129
130 kAMDRadeonHD7xxx_GrGLRenderer, // AMD Radeon HD 7000 Series
131 kAMDRadeonR9M3xx_GrGLRenderer, // AMD Radeon R9 M300 Series
132 kAMDRadeonR9M4xx_GrGLRenderer, // AMD Radeon R9 M400 Series
133 kAMDRadeonPro5xxx_GrGLRenderer, // AMD Radeon Pro 5000 Series
134 kAMDRadeonProVegaxx_GrGLRenderer, // AMD Radeon Pro Vega
135
136 kOther_GrGLRenderer
137};
138
139enum GrGLDriver {
140 kMesa_GrGLDriver,
141 kChromium_GrGLDriver,
142 kNVIDIA_GrGLDriver,
143 kIntel_GrGLDriver,
144 kANGLE_GrGLDriver,
145 kSwiftShader_GrGLDriver,
146 kQualcomm_GrGLDriver,
147 kAndroidEmulator_GrGLDriver,
148 kUnknown_GrGLDriver
149};
150
151enum class GrGLANGLEBackend {
152 kUnknown,
153 kD3D9,
154 kD3D11,
155 kOpenGL
156};
157
158enum class GrGLANGLEVendor {
159 kUnknown,
160 kIntel,
161 kNVIDIA,
162 kAMD
163};
164
165enum class GrGLANGLERenderer {
166 kUnknown,
167 kSandyBridge,
168 kIvyBridge,
169 kSkylake
170};
171
172////////////////////////////////////////////////////////////////////////////////
173
174/**
175 * Some drivers want the var-int arg to be zero-initialized on input.
176 */
177#define GR_GL_INIT_ZERO 0
178#define GR_GL_GetIntegerv(gl, e, p) \
179 do { \
180 *(p) = GR_GL_INIT_ZERO; \
181 GR_GL_CALL(gl, GetIntegerv(e, p)); \
182 } while (0)
183
184#define GR_GL_GetFramebufferAttachmentParameteriv(gl, t, a, pname, p) \
185 do { \
186 *(p) = GR_GL_INIT_ZERO; \
187 GR_GL_CALL(gl, GetFramebufferAttachmentParameteriv(t, a, pname, p)); \
188 } while (0)
189
190#define GR_GL_GetInternalformativ(gl, t, f, n, s, p) \
191 do { \
192 *(p) = GR_GL_INIT_ZERO; \
193 GR_GL_CALL(gl, GetInternalformativ(t, f, n, s, p)); \
194 } while (0)
195
196#define GR_GL_GetNamedFramebufferAttachmentParameteriv(gl, fb, a, pname, p) \
197 do { \
198 *(p) = GR_GL_INIT_ZERO; \
199 GR_GL_CALL(gl, GetNamedFramebufferAttachmentParameteriv(fb, a, pname, p)); \
200 } while (0)
201
202#define GR_GL_GetRenderbufferParameteriv(gl, t, pname, p) \
203 do { \
204 *(p) = GR_GL_INIT_ZERO; \
205 GR_GL_CALL(gl, GetRenderbufferParameteriv(t, pname, p)); \
206 } while (0)
207
208#define GR_GL_GetTexLevelParameteriv(gl, t, l, pname, p) \
209 do { \
210 *(p) = GR_GL_INIT_ZERO; \
211 GR_GL_CALL(gl, GetTexLevelParameteriv(t, l, pname, p)); \
212 } while (0)
213
214#define GR_GL_GetShaderPrecisionFormat(gl, st, pt, range, precision) \
215 do { \
216 (range)[0] = GR_GL_INIT_ZERO; \
217 (range)[1] = GR_GL_INIT_ZERO; \
218 (*precision) = GR_GL_INIT_ZERO; \
219 GR_GL_CALL(gl, GetShaderPrecisionFormat(st, pt, range, precision)); \
220 } while (0)
221
222////////////////////////////////////////////////////////////////////////////////
223
224/**
225 * Helpers for glGetString()
226 */
227
228// these variants assume caller already has a string from glGetString()
229GrGLVersion GrGLGetVersionFromString(const char* versionString);
230GrGLStandard GrGLGetStandardInUseFromString(const char* versionString);
231GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
232GrGLVendor GrGLGetVendorFromString(const char* vendorString);
233GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString, const GrGLExtensions&);
234std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfoFromString(
235 const char* rendererString);
236
237void GrGLGetDriverInfo(GrGLStandard standard,
238 GrGLVendor vendor,
239 const char* rendererString,
240 const char* versionString,
241 GrGLDriver* outDriver,
242 GrGLDriverVersion* outVersion);
243
244// these variants call glGetString()
245GrGLVersion GrGLGetVersion(const GrGLInterface*);
246GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*);
247GrGLVendor GrGLGetVendor(const GrGLInterface*);
248GrGLRenderer GrGLGetRenderer(const GrGLInterface*);
249std::tuple<GrGLANGLEBackend, GrGLANGLEVendor, GrGLANGLERenderer> GrGLGetANGLEInfo(
250 const GrGLInterface*);
251
252/**
253 * Helpers for glGetError()
254 */
255
256void GrGLCheckErr(const GrGLInterface* gl,
257 const char* location,
258 const char* call);
259
260////////////////////////////////////////////////////////////////////////////////
261
262/**
263 * Macros for using GrGLInterface to make GL calls
264 */
265
266// Conditionally checks glGetError based on compile-time and run-time flags.
267#if GR_GL_CHECK_ERROR
268 extern bool gCheckErrorGL;
269#define GR_GL_CHECK_ERROR_IMPL(IFACE, X) \
270 do { \
271 if (gCheckErrorGL) { \
272 IFACE->checkError(GR_FILE_AND_LINE_STR, #X); \
273 } \
274 } while (false)
275#else
276#define GR_GL_CHECK_ERROR_IMPL(IFACE, X) \
277 do { \
278 } while (false)
279#endif
280
281// internal macro to conditionally log the gl call using SkDebugf based on
282// compile-time and run-time flags.
283#if GR_GL_LOG_CALLS
284 extern bool gLogCallsGL;
285 #define GR_GL_LOG_CALLS_IMPL(X) \
286 if (gLogCallsGL) \
287 SkDebugf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
288#else
289 #define GR_GL_LOG_CALLS_IMPL(X)
290#endif
291
292// makes a GL call on the interface and does any error checking and logging
293#define GR_GL_CALL(IFACE, X) \
294 do { \
295 GR_GL_CALL_NOERRCHECK(IFACE, X); \
296 GR_GL_CHECK_ERROR_IMPL(IFACE, X); \
297 } while (false)
298
299// Variant of above that always skips the error check. This is useful when
300// the caller wants to do its own glGetError() call and examine the error value.
301#define GR_GL_CALL_NOERRCHECK(IFACE, X) \
302 do { \
303 (IFACE)->fFunctions.f##X; \
304 GR_GL_LOG_CALLS_IMPL(X); \
305 } while (false)
306
307// same as GR_GL_CALL but stores the return value of the gl call in RET
308#define GR_GL_CALL_RET(IFACE, RET, X) \
309 do { \
310 GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X); \
311 GR_GL_CHECK_ERROR_IMPL(IFACE, X); \
312 } while (false)
313
314// same as GR_GL_CALL_RET but always skips the error check.
315#define GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X) \
316 do { \
317 (RET) = (IFACE)->fFunctions.f##X; \
318 GR_GL_LOG_CALLS_IMPL(X); \
319 } while (false)
320
321static constexpr GrGLFormat GrGLFormatFromGLEnum(GrGLenum glFormat) {
322 switch (glFormat) {
323 case GR_GL_RGBA8: return GrGLFormat::kRGBA8;
324 case GR_GL_R8: return GrGLFormat::kR8;
325 case GR_GL_ALPHA8: return GrGLFormat::kALPHA8;
326 case GR_GL_LUMINANCE8: return GrGLFormat::kLUMINANCE8;
327 case GR_GL_BGRA8: return GrGLFormat::kBGRA8;
328 case GR_GL_RGB565: return GrGLFormat::kRGB565;
329 case GR_GL_RGBA16F: return GrGLFormat::kRGBA16F;
330 case GR_GL_LUMINANCE16F: return GrGLFormat::kLUMINANCE16F;
331 case GR_GL_R16F: return GrGLFormat::kR16F;
332 case GR_GL_RGB8: return GrGLFormat::kRGB8;
333 case GR_GL_RG8: return GrGLFormat::kRG8;
334 case GR_GL_RGB10_A2: return GrGLFormat::kRGB10_A2;
335 case GR_GL_RGBA4: return GrGLFormat::kRGBA4;
336 case GR_GL_SRGB8_ALPHA8: return GrGLFormat::kSRGB8_ALPHA8;
337 case GR_GL_COMPRESSED_ETC1_RGB8: return GrGLFormat::kCOMPRESSED_ETC1_RGB8;
338 case GR_GL_COMPRESSED_RGB8_ETC2: return GrGLFormat::kCOMPRESSED_RGB8_ETC2;
339 case GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GrGLFormat::kCOMPRESSED_RGB8_BC1;
340 case GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GrGLFormat::kCOMPRESSED_RGBA8_BC1;
341 case GR_GL_R16: return GrGLFormat::kR16;
342 case GR_GL_RG16: return GrGLFormat::kRG16;
343 case GR_GL_RGBA16: return GrGLFormat::kRGBA16;
344 case GR_GL_RG16F: return GrGLFormat::kRG16F;
345
346 default: return GrGLFormat::kUnknown;
347 }
348}
349
350/** Returns either the sized internal format or compressed internal format of the GrGLFormat. */
351static constexpr GrGLenum GrGLFormatToEnum(GrGLFormat format) {
352 switch (format) {
353 case GrGLFormat::kRGBA8: return GR_GL_RGBA8;
354 case GrGLFormat::kR8: return GR_GL_R8;
355 case GrGLFormat::kALPHA8: return GR_GL_ALPHA8;
356 case GrGLFormat::kLUMINANCE8: return GR_GL_LUMINANCE8;
357 case GrGLFormat::kBGRA8: return GR_GL_BGRA8;
358 case GrGLFormat::kRGB565: return GR_GL_RGB565;
359 case GrGLFormat::kRGBA16F: return GR_GL_RGBA16F;
360 case GrGLFormat::kLUMINANCE16F: return GR_GL_LUMINANCE16F;
361 case GrGLFormat::kR16F: return GR_GL_R16F;
362 case GrGLFormat::kRGB8: return GR_GL_RGB8;
363 case GrGLFormat::kRG8: return GR_GL_RG8;
364 case GrGLFormat::kRGB10_A2: return GR_GL_RGB10_A2;
365 case GrGLFormat::kRGBA4: return GR_GL_RGBA4;
366 case GrGLFormat::kSRGB8_ALPHA8: return GR_GL_SRGB8_ALPHA8;
367 case GrGLFormat::kCOMPRESSED_ETC1_RGB8: return GR_GL_COMPRESSED_ETC1_RGB8;
368 case GrGLFormat::kCOMPRESSED_RGB8_ETC2: return GR_GL_COMPRESSED_RGB8_ETC2;
369 case GrGLFormat::kCOMPRESSED_RGB8_BC1: return GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
370 case GrGLFormat::kCOMPRESSED_RGBA8_BC1: return GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
371 case GrGLFormat::kR16: return GR_GL_R16;
372 case GrGLFormat::kRG16: return GR_GL_RG16;
373 case GrGLFormat::kRGBA16: return GR_GL_RGBA16;
374 case GrGLFormat::kRG16F: return GR_GL_RG16F;
375 case GrGLFormat::kUnknown: return 0;
376 }
377 SkUNREACHABLE;
378}
379
380#if GR_TEST_UTILS
381static constexpr const char* GrGLFormatToStr(GrGLenum glFormat) {
382 switch (glFormat) {
383 case GR_GL_RGBA8: return "RGBA8";
384 case GR_GL_R8: return "R8";
385 case GR_GL_ALPHA8: return "ALPHA8";
386 case GR_GL_LUMINANCE8: return "LUMINANCE8";
387 case GR_GL_BGRA8: return "BGRA8";
388 case GR_GL_RGB565: return "RGB565";
389 case GR_GL_RGBA16F: return "RGBA16F";
390 case GR_GL_LUMINANCE16F: return "LUMINANCE16F";
391 case GR_GL_R16F: return "R16F";
392 case GR_GL_RGB8: return "RGB8";
393 case GR_GL_RG8: return "RG8";
394 case GR_GL_RGB10_A2: return "RGB10_A2";
395 case GR_GL_RGBA4: return "RGBA4";
396 case GR_GL_RGBA32F: return "RGBA32F";
397 case GR_GL_SRGB8_ALPHA8: return "SRGB8_ALPHA8";
398 case GR_GL_COMPRESSED_ETC1_RGB8: return "ETC1";
399 case GR_GL_COMPRESSED_RGB8_ETC2: return "ETC2";
400 case GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return "RGB8_BC1";
401 case GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return "RGBA8_BC1";
402 case GR_GL_R16: return "R16";
403 case GR_GL_RG16: return "RG16";
404 case GR_GL_RGBA16: return "RGBA16";
405 case GR_GL_RG16F: return "RG16F";
406
407 default: return "Unknown";
408 }
409}
410#endif
411
412GrGLenum GrToGLStencilFunc(GrStencilTest test);
413
414/**
415 * Returns true if the format is compressed.
416 */
417bool GrGLFormatIsCompressed(GrGLFormat);
418
419#endif
420