xref: /aosp_15_r20/external/skia/src/gpu/ganesh/gl/GrGLCaps.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #include "src/gpu/ganesh/gl/GrGLCaps.h"
9 
10 #include "include/core/SkColor.h"
11 #include "include/core/SkRect.h"
12 #include "include/core/SkSize.h"
13 #include "include/core/SkTextureCompressionType.h"
14 #include "include/gpu/GpuTypes.h"
15 #include "include/gpu/ganesh/GrContextOptions.h"
16 #include "include/gpu/ganesh/GrDriverBugWorkarounds.h"
17 #include "include/gpu/ganesh/GrTypes.h"
18 #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
19 #include "include/gpu/ganesh/gl/GrGLFunctions.h"
20 #include "include/gpu/ganesh/gl/GrGLInterface.h"
21 #include "include/private/base/SkDebug.h"
22 #include "include/private/base/SkMath.h"
23 #include "include/private/base/SkTemplates.h"
24 #include "include/private/base/SkTo.h"
25 #include "src/core/SkCompressedDataUtils.h"
26 #include "src/gpu/Blend.h"
27 #include "src/gpu/GpuTypesPriv.h"
28 #include "src/gpu/ganesh/GrBackendUtils.h"
29 #include "src/gpu/ganesh/GrProgramDesc.h"
30 #include "src/gpu/ganesh/GrRenderTarget.h"
31 #include "src/gpu/ganesh/GrRenderTargetProxy.h"
32 #include "src/gpu/ganesh/GrShaderCaps.h"
33 #include "src/gpu/ganesh/GrSurface.h"
34 #include "src/gpu/ganesh/GrSurfaceProxy.h"
35 #include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
36 #include "src/gpu/ganesh/GrTextureProxy.h"
37 #include "src/gpu/ganesh/TestFormatColorTypeCombination.h"
38 #include "src/gpu/ganesh/gl/GrGLContext.h"
39 #include "src/gpu/ganesh/gl/GrGLDefines.h"
40 #include "src/gpu/ganesh/gl/GrGLRenderTarget.h"
41 #include "src/gpu/ganesh/gl/GrGLTexture.h"
42 #include "src/gpu/ganesh/gl/GrGLUtil.h"
43 #include "src/sksl/SkSLGLSL.h"
44 
45 #include <algorithm>
46 #include <cstddef>
47 #include <initializer_list>
48 #include <memory>
49 
50 class GrProgramInfo;
51 class SkJSONWriter;
52 
53 #if defined(SK_BUILD_FOR_IOS)
54 #include <TargetConditionals.h>
55 #endif
56 
GrGLCaps(const GrContextOptions & contextOptions,const GrGLContextInfo & ctxInfo,const GrGLInterface * glInterface)57 GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
58                    const GrGLContextInfo& ctxInfo,
59                    const GrGLInterface* glInterface) : INHERITED(contextOptions) {
60     fStandard = ctxInfo.standard();
61 
62     fPackFlipYSupport = false;
63     fTextureUsageSupport = false;
64     fImagingSupport = false;
65     fVertexArrayObjectSupport = false;
66     fDebugSupport = false;
67     fES2CompatibilitySupport = false;
68     fStrictProtectedness = false;
69     fDrawRangeElementsSupport = false;
70     fBaseVertexBaseInstanceSupport = false;
71     fIsCoreProfile = false;
72     fBindFragDataLocationSupport = false;
73     fRectangleTextureSupport = false;
74     fBindUniformLocationSupport = false;
75     fMipmapLevelControlSupport = false;
76     fMipmapLodControlSupport = false;
77     fDoManualMipmapping = false;
78     fClearToBoundaryValuesIsBroken = false;
79     fClearTextureSupport = false;
80     fDrawArraysBaseVertexIsBroken = false;
81     fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
82     fUseDrawInsteadOfAllRenderTargetWrites = false;
83     fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
84     fDontSetBaseOrMaxLevelForExternalTextures = false;
85     fNeverDisableColorWrites = false;
86     fMustSetAnyTexParameterToEnableMipmapping = false;
87     fAllowBGRA8CopyTexSubImage = false;
88     fAllowSRGBCopyTexSubImage = false;
89     fDisallowDynamicMSAA = false;
90     fMustResetBlendFuncBetweenDualSourceAndDisable = false;
91     fBindTexture0WhenChangingTextureFBOMultisampleCount = false;
92     fRebindColorAttachmentAfterCheckFramebufferStatus = false;
93     fFlushBeforeWritePixels = false;
94     fDisableScalingCopyAsDraws = false;
95     fPadRG88TransferAlignment = false;
96     fProgramBinarySupport = false;
97     fProgramParameterSupport = false;
98     fSamplerObjectSupport = false;
99     fUseSamplerObjects = false;
100     fTextureSwizzleSupport = false;
101     fTiledRenderingSupport = false;
102     fFenceSyncSupport = false;
103     fFBFetchRequiresEnablePerSample = false;
104     fSRGBWriteControl = false;
105     fSkipErrorChecks = false;
106 
107     fShaderCaps = std::make_unique<GrShaderCaps>();
108 
109     this->init(contextOptions, ctxInfo, glInterface);
110 }
111 
angle_backend_is_d3d(GrGLANGLEBackend backend)112 static bool angle_backend_is_d3d(GrGLANGLEBackend backend) {
113     return backend == GrGLANGLEBackend::kD3D9 || backend == GrGLANGLEBackend::kD3D11;
114 }
115 
angle_backend_is_metal(GrGLANGLEBackend backend)116 static bool angle_backend_is_metal(GrGLANGLEBackend backend) {
117     return backend == GrGLANGLEBackend::kMetal;
118 }
119 
init(const GrContextOptions & contextOptions,const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)120 void GrGLCaps::init(const GrContextOptions& contextOptions,
121                     const GrGLContextInfo& ctxInfo,
122                     const GrGLInterface* gli) {
123     GrGLStandard standard = ctxInfo.standard();
124     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
125     sk_ignore_unused_variable(standard);
126     GrGLVersion version = ctxInfo.version();
127 
128 #if defined(GPU_TEST_UTILS)
129     const GrGLubyte* deviceName;
130     GR_GL_CALL_RET(gli, deviceName, GetString(GR_GL_RENDERER));
131     this->setDeviceName(reinterpret_cast<const char*>(deviceName));
132 #endif
133 
134     if (GR_IS_GR_GL(standard)) {
135         GrGLint max;
136         GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
137         fMaxFragmentUniformVectors = max / 4;
138         if (version >= GR_GL_VER(3, 2)) {
139             GrGLint profileMask;
140             GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
141             fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
142         }
143     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
144         GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
145                           &fMaxFragmentUniformVectors);
146     }
147 
148     if (fDriverBugWorkarounds.max_fragment_uniform_vectors_32) {
149         fMaxFragmentUniformVectors = std::min(fMaxFragmentUniformVectors, 32);
150     }
151     GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
152 
153     if (GR_IS_GR_GL(standard)) {
154         fWritePixelsRowBytesSupport = true;
155         fReadPixelsRowBytesSupport = true;
156         fPackFlipYSupport = false;
157     } else if (GR_IS_GR_GL_ES(standard)) {
158         fWritePixelsRowBytesSupport =
159                 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_unpack_subimage");
160         fReadPixelsRowBytesSupport =
161                 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pack_subimage");
162         fPackFlipYSupport =
163             ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
164     } else if (GR_IS_GR_WEBGL(standard)) {
165         // WebGL 2.0 has these
166         fWritePixelsRowBytesSupport = version >= GR_GL_VER(2, 0);
167         fReadPixelsRowBytesSupport = version >= GR_GL_VER(2, 0);
168     }
169     fTransferPixelsToRowBytesSupport = fWritePixelsRowBytesSupport;
170 
171     if (fDriverBugWorkarounds.pack_parameters_workaround_with_pack_buffer) {
172         // In some cases drivers handle copying the last row incorrectly
173         // when using GL_PACK_ROW_LENGTH.  Chromium handles this by iterating
174         // through every row and conditionally clobbering that value, but
175         // Skia already has a scratch buffer workaround when pack row length
176         // is not supported, so just use that.
177         fReadPixelsRowBytesSupport = false;
178     }
179 
180     fTextureUsageSupport = GR_IS_GR_GL_ES(standard) &&
181                            ctxInfo.hasExtension("GL_ANGLE_texture_usage");
182 
183     if (GR_IS_GR_GL(standard)) {
184         fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
185                                  ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
186                                  ctxInfo.hasExtension("GL_NV_texture_barrier");
187     } else if (GR_IS_GR_GL_ES(standard)) {
188         fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
189     } else if (GR_IS_GR_WEBGL(standard)) {
190         fTextureBarrierSupport = false;
191     }
192 
193     if (GR_IS_GR_GL(standard)) {
194         fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
195                                   ctxInfo.hasExtension("GL_ARB_texture_multisample");
196     } else if (GR_IS_GR_GL_ES(standard)) {
197         fSampleLocationsSupport = version >= GR_GL_VER(3,1);
198     } else if (GR_IS_GR_WEBGL(standard)) {
199         fSampleLocationsSupport = false;
200     }
201 
202     fImagingSupport = GR_IS_GR_GL(standard) &&
203                       ctxInfo.hasExtension("GL_ARB_imaging");
204 
205     if (((GR_IS_GR_GL(standard) && version >= GR_GL_VER(4,3)) ||
206          (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0)) ||
207          ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
208         fInvalidateFBType = kInvalidate_InvalidateFBType;
209     } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
210         fInvalidateFBType = kDiscard_InvalidateFBType;
211     }
212 
213     // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
214     // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
215     if (GR_IS_GR_GL_ES(standard)) {
216         // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
217         // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
218         if (ctxInfo.vendor() == GrGLVendor::kARM) {
219             fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
220         }
221     }
222 
223     if (ctxInfo.vendor() == GrGLVendor::kARM         ||
224         ctxInfo.vendor() == GrGLVendor::kImagination ||
225         ctxInfo.vendor() == GrGLVendor::kQualcomm ) {
226         fPreferFullscreenClears = true;
227     }
228 
229     if (GR_IS_GR_GL(standard)) {
230         fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
231                                     ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
232                                     ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
233     } else if (GR_IS_GR_GL_ES(standard)) {
234         fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
235                                     ctxInfo.hasExtension("GL_OES_vertex_array_object");
236     } else if (GR_IS_GR_WEBGL(standard)) {
237         fVertexArrayObjectSupport = version >= GR_GL_VER(2, 0) ||
238                                     ctxInfo.hasExtension("GL_OES_vertex_array_object") ||
239                                     ctxInfo.hasExtension("OES_vertex_array_object");
240     }
241 
242     if (GR_IS_GR_GL(standard) && version >= GR_GL_VER(4,3)) {
243         fDebugSupport = true;
244     } else if (GR_IS_GR_GL_ES(standard)) {
245         fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
246     } else if (GR_IS_GR_WEBGL(standard)) {
247         fDebugSupport = false;
248     }
249 
250     if (GR_IS_GR_GL(standard)) {
251         fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
252     }
253     else if (GR_IS_GR_GL_ES(standard)) {
254         fES2CompatibilitySupport = true;
255     } else if (GR_IS_GR_WEBGL(standard)) {
256         fES2CompatibilitySupport = true;
257     }
258 
259     if (GR_IS_GR_GL(standard)) {
260         fClientCanDisableMultisample = true;
261     } else if (GR_IS_GR_GL_ES(standard)) {
262         fClientCanDisableMultisample = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
263     } else if (GR_IS_GR_WEBGL(standard)) {
264         fClientCanDisableMultisample = false;
265     }
266 
267     if (GR_IS_GR_GL(standard)) {
268         // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
269         // instanced arrays, but we could make this more granular if we wanted
270         fDrawInstancedSupport =
271                 version >= GR_GL_VER(3, 2) ||
272                 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
273                  ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
274     } else if (GR_IS_GR_GL_ES(standard)) {
275         fDrawInstancedSupport =
276                 version >= GR_GL_VER(3, 0) ||
277                 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
278                  ctxInfo.hasExtension("GL_EXT_instanced_arrays")) ||
279                 ctxInfo.hasExtension("GL_ANGLE_instanced_arrays");
280     }  else if (GR_IS_GR_WEBGL(standard)) {
281         // WebGL 2.0 has DrawArraysInstanced and drawElementsInstanced
282         fDrawInstancedSupport = version >= GR_GL_VER(2, 0);
283     }
284 
285     if (GR_IS_GR_GL(standard)) {
286         if (version >= GR_GL_VER(3, 0)) {
287             fBindFragDataLocationSupport = true;
288         }
289     } else if (GR_IS_GR_GL_ES(standard)) {
290         if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
291             fBindFragDataLocationSupport = true;
292         }
293     } else if (GR_IS_GR_WEBGL(standard)) {
294         fBindFragDataLocationSupport = false;
295     }
296 
297     fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
298 
299     if (GR_IS_GR_GL(standard)) {
300         if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle") ||
301             ctxInfo.hasExtension("GL_ANGLE_texture_rectangle")) {
302             fRectangleTextureSupport = true;
303         }
304     } else if (GR_IS_GR_GL_ES(standard)) {
305         fRectangleTextureSupport = ctxInfo.hasExtension("GL_ARB_texture_rectangle") ||
306                                    ctxInfo.hasExtension("GL_ANGLE_texture_rectangle");
307     } else if (GR_IS_GR_WEBGL(standard)) {
308         fRectangleTextureSupport = false;
309     }
310 
311     // GrCaps defaults fClampToBorderSupport to true, so disable when unsupported
312     if (GR_IS_GR_GL(standard)) {
313         // Clamp to border added in 1.3
314         if (version < GR_GL_VER(1, 3) && !ctxInfo.hasExtension("GL_ARB_texture_border_clamp")) {
315             fClampToBorderSupport = false;
316         }
317     } else if (GR_IS_GR_GL_ES(standard)) {
318         // GLES didn't have clamp to border until 3.2, but provides several alternative extensions
319         if (version < GR_GL_VER(3, 2) && !ctxInfo.hasExtension("GL_EXT_texture_border_clamp") &&
320             !ctxInfo.hasExtension("GL_NV_texture_border_clamp") &&
321             !ctxInfo.hasExtension("GL_OES_texture_border_clamp")) {
322             fClampToBorderSupport = false;
323         }
324     } else if (GR_IS_GR_WEBGL(standard)) {
325         // WebGL appears to only have REPEAT, CLAMP_TO_EDGE and MIRRORED_REPEAT
326         fClampToBorderSupport = false;
327     }
328 
329     if (GR_IS_GR_GL(standard)) {
330         if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
331             fTextureSwizzleSupport = true;
332         }
333     } else if (GR_IS_GR_GL_ES(standard)) {
334         if (version >= GR_GL_VER(3,0)) {
335             fTextureSwizzleSupport = true;
336         }
337     } else if (GR_IS_GR_WEBGL(standard)) {
338         fTextureSwizzleSupport = false;
339     }
340 
341     if (GR_IS_GR_GL(standard)) {
342         fMipmapLevelControlSupport = true;
343         fMipmapLodControlSupport = true;
344     } else if (GR_IS_GR_GL_ES(standard)) {
345         if (version >= GR_GL_VER(3,0)) {
346             fMipmapLevelControlSupport = true;
347             fMipmapLodControlSupport = true;
348         }
349     } else if (GR_IS_GR_WEBGL(standard)) {
350         fMipmapLevelControlSupport = false;
351         fMipmapLodControlSupport = false;
352     }
353 
354     if ((GR_IS_GR_GL_ES(standard) || GR_IS_GR_GL(standard)) &&
355         ctxInfo.hasExtension("GL_ARB_invalidate_subdata")) {
356         fInvalidateBufferType = InvalidateBufferType::kInvalidate;
357     } else if (!GR_IS_GR_WEBGL(standard) && !ctxInfo.isOverCommandBuffer()) {
358         // Chrome's command buffer will push an array of zeros to a buffer if null is passed to
359         // glBufferData (to avoid letting an application see uninitialized memory). This is
360         // expensive so we avoid it. WebGL spec explicitly disallows null values.
361         fInvalidateBufferType = InvalidateBufferType::kNullData;
362     }
363 
364     if (GR_IS_GR_GL(standard)) {
365         fClearTextureSupport = (version >= GR_GL_VER(4,4) ||
366                                 ctxInfo.hasExtension("GL_ARB_clear_texture"));
367     } else if (GR_IS_GR_GL_ES(standard)) {
368         fClearTextureSupport = ctxInfo.hasExtension("GL_EXT_clear_texture");
369     } else if (GR_IS_GR_WEBGL(standard)) {
370         fClearTextureSupport = false;
371     }
372 
373 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
374     fSupportsAHardwareBufferImages = true;
375 #endif
376 
377     if (GR_IS_GR_GL(standard)) {
378         fSRGBWriteControl = version >= GR_GL_VER(3, 0) ||
379                             ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
380                             ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB");
381     } else if (GR_IS_GR_GL_ES(standard)) {
382         // ES through 3.2 requires EXT_srgb_write_control to support toggling
383         // sRGB writing for destinations.
384         fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
385     }  // No WebGL support
386 
387     fSkipErrorChecks = ctxInfo.isOverCommandBuffer();
388     if (GR_IS_GR_WEBGL(standard)) {
389         // Error checks are quite costly in webgl, especially in Chrome.
390         fSkipErrorChecks = true;
391     }
392 
393     // When we are abandoning the context we cannot call into GL thus we should skip any sync work.
394     fMustSyncGpuDuringAbandon = false;
395 
396     fSupportsProtectedContent = [&]() {
397         if (!ctxInfo.hasExtension("GL_EXT_protected_textures")) {
398             return false;
399         }
400 
401         GrGLint contextFlags;
402         GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_FLAGS, &contextFlags);
403         return SkToBool(contextFlags & GR_GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT);
404     }();
405 
406     /**
407      * When Ganesh is backed by ANGLE mapping to Vulkan, the Protectedness handling has to be
408      * more like the Vulkan case (i.e., all internally allocated objects that will be written to
409      * in a Protected Context must be Protected). ANGLE just forwards any work to the
410      * active Vulkan Context. If that Vulkan Context is Protected that would mean, without
411      * using strict Protectedness, writes to unProtected objects would be submitted to a
412      * Protected Queue - which is not allowed in Vulkan.
413      */
414     fStrictProtectedness = fSupportsProtectedContent &&
415                            ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown;
416 
417     /**************************************************************************
418     * GrShaderCaps fields
419     **************************************************************************/
420 
421     // This must be called after fCoreProfile is set on the GrGLCaps
422     this->initGLSL(ctxInfo, gli);
423     GrShaderCaps* shaderCaps = fShaderCaps.get();
424 
425     // Enable supported shader-related caps
426     if (GR_IS_GR_GL(standard)) {
427         shaderCaps->fDualSourceBlendingSupport =
428                 (version >= GR_GL_VER(3, 3) ||
429                  ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
430                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
431 
432         shaderCaps->fShaderDerivativeSupport = true;
433         shaderCaps->fExplicitTextureLodSupport =
434                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
435 
436         shaderCaps->fIntegerSupport = version >= GR_GL_VER(3, 0) &&
437             ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
438 
439         shaderCaps->fNonsquareMatrixSupport =
440                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
441         shaderCaps->fInverseHyperbolicSupport =
442                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
443     } else if (GR_IS_GR_GL_ES(standard)) {
444         shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
445 
446         shaderCaps->fShaderDerivativeSupport =
447                 // We use this value for GLSL ES 3.0.
448                 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_standard_derivatives");
449         shaderCaps->fExplicitTextureLodSupport =
450                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
451 
452         shaderCaps->fIntegerSupport = version >= GR_GL_VER(3, 0) &&
453                                       ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
454         shaderCaps->fNonsquareMatrixSupport =
455                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
456         shaderCaps->fInverseHyperbolicSupport =
457                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
458     } else if (GR_IS_GR_WEBGL(standard)) {
459         shaderCaps->fShaderDerivativeSupport = version >= GR_GL_VER(2, 0) ||
460                                                ctxInfo.hasExtension("GL_OES_standard_derivatives") ||
461                                                ctxInfo.hasExtension("OES_standard_derivatives");
462         shaderCaps->fExplicitTextureLodSupport =
463                 version >= GR_GL_VER(2, 0) &&
464                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
465         shaderCaps->fIntegerSupport = (version >= GR_GL_VER(2, 0));
466         shaderCaps->fNonsquareMatrixSupport =
467                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
468         shaderCaps->fInverseHyperbolicSupport =
469                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
470     }
471 
472     if (ctxInfo.hasExtension("GL_NV_conservative_raster")) {
473         fConservativeRasterSupport = true;
474     }
475 
476     if (GR_IS_GR_GL(standard)) {
477         fWireframeSupport = true;
478     }
479 
480     if (GR_IS_GR_GL(standard)) {
481         shaderCaps->fRewriteSwitchStatements =
482                 ctxInfo.glslGeneration() < SkSL::GLSLGeneration::k130;  // introduced in GLSL 1.3
483     } else if (GR_IS_GR_GL_ES(standard)) {
484         shaderCaps->fRewriteSwitchStatements =
485                 ctxInfo.glslGeneration() < SkSL::GLSLGeneration::k300es;  // introduced in GLSL ES3
486     } else if (GR_IS_GR_WEBGL(standard)) {
487         shaderCaps->fRewriteSwitchStatements = version < GR_GL_VER(2, 0);  // introduced in WebGL 2
488         shaderCaps->fCanUseVoidInSequenceExpressions =
489                 false;  // removed in WebGL 2, use workaround in all versions for safety
490     }
491 
492     // Protect ourselves against tracking huge amounts of texture state.
493     static const uint8_t kMaxSaneSamplers = 32;
494     GrGLint maxSamplers;
495     GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
496     shaderCaps->fMaxFragmentSamplers = std::min<GrGLint>(kMaxSaneSamplers, maxSamplers);
497 
498     // SGX and Mali GPUs have tiled architectures that have trouble with frequently changing VBOs.
499     // We've measured a performance increase using non-VBO vertex data for dynamic content on these
500     // GPUs. Perhaps we should read the renderer string and limit this decision to specific GPU
501     // families rather than basing it on the vendor alone.
502     // Angle can be initialized with client arrays disabled and needs to be queried. The Chrome
503     // command buffer blocks the use of client side buffers (but may emulate VBOs with them). Client
504     // side buffers are not allowed in core profiles.
505     if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
506         GrGLint clientArraysEnabled = GR_GL_TRUE;
507         if (ctxInfo.hasExtension("GL_ANGLE_client_arrays")) {
508             GR_GL_GetIntegerv(gli, GR_GL_CLIENT_ARRAYS_ANGLE, &clientArraysEnabled);
509         }
510 
511         if (clientArraysEnabled && !ctxInfo.isOverCommandBuffer() && !fIsCoreProfile &&
512             (ctxInfo.vendor() == GrGLVendor::kARM || ctxInfo.vendor() == GrGLVendor::kImagination ||
513              ctxInfo.vendor() == GrGLVendor::kQualcomm)) {
514             fPreferClientSideDynamicBuffers = true;
515         }
516     } // No client side arrays in WebGL https://www.khronos.org/registry/webgl/specs/1.0/#6.2
517 
518     if (!contextOptions.fAvoidStencilBuffers && !fSupportsProtectedContent) {
519         // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
520         // We also avoid both for Protected Contexts due to their use of RenderBuffers (which
521         // cannot be correctly created as Protected).
522         this->initFSAASupport(contextOptions, ctxInfo, gli);
523         this->initStencilSupport(ctxInfo);
524     }
525 
526     // Setup blit framebuffer
527     if (GR_IS_GR_GL(standard)) {
528         if (version >= GR_GL_VER(3,0) ||
529             ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
530             ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
531             fBlitFramebufferFlags = 0;
532         }
533     } else if (GR_IS_GR_GL_ES(standard)) {
534         if (version >= GR_GL_VER(3, 0) ||
535             ctxInfo.hasExtension("GL_NV_framebuffer_blit")) {
536             fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
537                                     kNoMSAADst_BlitFramebufferFlag |
538                                     kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
539         } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
540                    ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
541             // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
542             // limitations.
543             fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
544                                     kResolveMustBeFull_BlitFrambufferFlag |
545                                     kNoMSAADst_BlitFramebufferFlag |
546                                     kNoFormatConversion_BlitFramebufferFlag |
547                                     kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
548         }
549     } // No WebGL 1.0 support for BlitFramebuffer
550 
551     this->initBlendEqationSupport(ctxInfo);
552 
553     if (GR_IS_GR_GL(standard)) {
554         fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
555                                             // extension includes glMapBuffer.
556         if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
557             fMapBufferFlags |= kSubset_MapFlag;
558             fMapBufferType = kMapBufferRange_MapBufferType;
559         } else {
560             fMapBufferType = kMapBuffer_MapBufferType;
561         }
562     } else if (GR_IS_GR_GL_ES(standard)) {
563         // Unextended GLES2 doesn't have any buffer mapping.
564         fMapBufferFlags = kNone_MapFlags;
565         if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
566             fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
567             fMapBufferType = kChromium_MapBufferType;
568         } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
569             fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
570             fMapBufferType = kMapBufferRange_MapBufferType;
571         } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
572             fMapBufferFlags = kCanMap_MapFlag;
573             fMapBufferType = kMapBuffer_MapBufferType;
574         }
575     } else if (GR_IS_GR_WEBGL(standard)) {
576         // explicitly removed https://www.khronos.org/registry/webgl/specs/2.0/#5.14
577         fMapBufferFlags = kNone_MapFlags;
578     }
579 
580     // Buffers have more restrictions in WebGL than GLES. For example,
581     // https://www.khronos.org/registry/webgl/specs/latest/2.0/#BUFFER_OBJECT_BINDING
582     // We therefore haven't attempted to support mapping or transfers between buffers and surfaces
583     // or between buffers.
584 
585     if (GR_IS_GR_GL(standard)) {
586         if (version >= GR_GL_VER(2, 1) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object") ||
587             ctxInfo.hasExtension("GL_EXT_pixel_buffer_object")) {
588             fTransferFromBufferToTextureSupport = true;
589             fTransferFromSurfaceToBufferSupport = true;
590             fTransferBufferType = TransferBufferType::kARB_PBO;
591         }
592     } else if (GR_IS_GR_GL_ES(standard)) {
593         if (version >= GR_GL_VER(3, 0) ||
594             (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
595              // GL_EXT_unpack_subimage needed to support subtexture rectangles
596              ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
597             fTransferFromBufferToTextureSupport = true;
598             fTransferFromSurfaceToBufferSupport = true;
599             if (version < GR_GL_VER(3, 0)) {
600                 fTransferBufferType = TransferBufferType::kNV_PBO;
601             } else {
602                 fTransferBufferType = TransferBufferType::kARB_PBO;
603             }
604 // TODO: get transfer buffers working in Chrome
605 //        } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
606 //            fTransferFromBufferToTextureSupport = false;
607 //            fTransferFromSurfaceToBufferSupport = false;
608 //            fTransferBufferType = TransferBufferType::kChromium;
609         }
610     }
611 
612     if (GR_IS_GR_GL(standard) &&
613         (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_copy_buffer"))) {
614         fTransferFromBufferToBufferSupport = true;
615     } else if (GR_IS_GR_GL_ES(standard) &&
616                (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_copy_buffer"))) {
617         fTransferFromBufferToBufferSupport = true;
618     }
619 
620     // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
621     // threshold to the maximum unless the client gives us a hint that map memory is cheap.
622     if (fBufferMapThreshold < 0) {
623 #if 0
624         // We think mapping on Chromium will be cheaper once we know ahead of time how much space
625         // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
626         // using a small subset.
627         fBufferMapThreshold = ctxInfo.isOverCommandBuffer() ? 0 : SK_MaxS32;
628 #else
629         fBufferMapThreshold = SK_MaxS32;
630 #endif
631     }
632 
633     if (GR_IS_GR_GL(standard)) {
634         fNPOTTextureTileSupport = true;
635         fMipmapSupport = true;
636         fAnisoSupport = version >= GR_GL_VER(4,6)                                 ||
637                         ctxInfo.hasExtension("GL_ARB_texture_filter_anisotropic") ||
638                         ctxInfo.hasExtension("GL_EXT_texture_filter_anisotropic");
639     } else if (GR_IS_GR_GL_ES(standard)) {
640         // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
641         // ES3 has no limitations.
642         fNPOTTextureTileSupport = version >= GR_GL_VER(3,0) ||
643                                   ctxInfo.hasExtension("GL_OES_texture_npot");
644         // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
645         // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
646         // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
647         // to alllow arbitrary wrap modes, however.
648         fMipmapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
649         fAnisoSupport = ctxInfo.hasExtension("GL_EXT_texture_filter_anisotropic");
650     } else if (GR_IS_GR_WEBGL(standard)) {
651         // Texture access works in the WebGL 2.0 API as in the OpenGL ES 3.0 API
652         fNPOTTextureTileSupport = version >= GR_GL_VER(2,0);
653         // All mipmapping and all wrapping modes are supported for non-power-of-
654         // two images [in WebGL 2.0].
655         fMipmapSupport = fNPOTTextureTileSupport;
656         fAnisoSupport = ctxInfo.hasExtension("GL_EXT_texture_filter_anisotropic") ||
657                         ctxInfo.hasExtension("EXT_texture_filter_anisotropic");
658     }
659     if (fAnisoSupport) {
660         GR_GL_GetFloatv(gli, GR_GL_MAX_TEXTURE_MAX_ANISOTROPY, &fMaxTextureMaxAnisotropy);
661     }
662 
663     GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
664 
665     GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
666     fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
667 
668     if (ctxInfo.vendor() == GrGLVendor::kARM) {
669         // On Mali G71, RT's above 4k have been observed to incur a performance cost.
670         fMaxPreferredRenderTargetSize = std::min(4096, fMaxPreferredRenderTargetSize);
671     }
672 
673     fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
674 
675     // Disable scratch texture reuse on Mali and Adreno devices
676     fReuseScratchTextures = (ctxInfo.vendor() != GrGLVendor::kARM);
677 
678 #if 0
679     fReuseScratchBuffers = ctxInfo.vendor() != GrGLVendor::kARM
680                            ctxInfo.vendor() != GrGLVendor::kQualcomm;
681 #endif
682 
683     if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
684         GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
685     }
686 
687 #ifdef SK_BUILD_FOR_WIN
688     // We're assuming that on Windows Chromium we're using D3D ANGLE.
689     bool isD3DANGLE = angle_backend_is_d3d(ctxInfo.angleBackend()) ||
690                       ctxInfo.isOverCommandBuffer();
691     // On ANGLE deferring flushes can lead to GPU starvation
692     fPreferVRAMUseOverFlushes = !isD3DANGLE;
693 #endif
694 
695     if (ctxInfo.isOverCommandBuffer()) {
696         fMustClearUploadedBufferData = true;
697     }
698 
699     // In a WASM build on Firefox, we see warnings like
700     // WebGL warning: texSubImage2D: This operation requires zeroing texture data. This is slow.
701     // WebGL warning: texSubImage2D: Texture has not been initialized prior to a partial upload,
702     //                forcing the browser to clear it. This may be slow.
703     // Setting the initial clear seems to make those warnings go away and offers a substantial
704     // boost in performance in Firefox. Chrome sees a more modest increase.
705     if (GR_IS_GR_WEBGL(standard)) {
706         fShouldInitializeTextures = true;
707     }
708 
709     if (GR_IS_GR_GL(standard)) {
710         // ARB allows mixed size FBO attachments, EXT does not.
711         if (version >= GR_GL_VER(3, 0) ||
712             ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
713             fOversizedStencilSupport = true;
714         } else {
715             SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
716         }
717     } else if (GR_IS_GR_GL_ES(standard)) {
718         // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
719         fOversizedStencilSupport = version >= GR_GL_VER(3, 0);
720     } else if (GR_IS_GR_WEBGL(standard)) {
721         // WebGL 1.0 has some constraints for FBO attachments:
722         // https://www.khronos.org/registry/webgl/specs/1.0/index.html#6.6
723         // These constraints "no longer apply in WebGL 2"
724         fOversizedStencilSupport = version >= GR_GL_VER(2, 0);
725     }
726 
727     if (GR_IS_GR_GL(standard)) {
728         fBaseVertexBaseInstanceSupport = version >= GR_GL_VER(4,2) ||
729                                          ctxInfo.hasExtension("GL_ARB_base_instance");
730         if (fBaseVertexBaseInstanceSupport) {
731             fNativeDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
732                                          ctxInfo.hasExtension("GL_ARB_draw_indirect");
733             if (version >= GR_GL_VER(4,3) || ctxInfo.hasExtension("GL_ARB_multi_draw_indirect")) {
734                 fMultiDrawType = MultiDrawType::kMultiDrawIndirect;
735             }
736         }
737         fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
738     } else if (GR_IS_GR_GL_ES(standard)) {
739         if (ctxInfo.hasExtension("GL_ANGLE_base_vertex_base_instance")) {
740             fBaseVertexBaseInstanceSupport = true;
741             fNativeDrawIndirectSupport = true;
742             fMultiDrawType = MultiDrawType::kANGLEOrWebGL;
743             // The indirect structs need to reside in CPU memory for the ANGLE version.
744             fUseClientSideIndirectBuffers = true;
745         } else {
746             fBaseVertexBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance");
747             // Don't support indirect draws on ES. They don't allow VAO 0.
748             //
749             // "An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
750             // DRAW_INDIRECT_BUFFER or to any enabled vertex array."
751             //
752             // https://www.khronos.org/registry/OpenGL/specs/es/3.1/es_spec_3.1.pdf
753         }
754         fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
755     } else if (GR_IS_GR_WEBGL(standard)) {
756         fBaseVertexBaseInstanceSupport = ctxInfo.hasExtension(
757                 "WEBGL_draw_instanced_base_vertex_base_instance");
758         if (fBaseVertexBaseInstanceSupport && ctxInfo.hasExtension(
759                 "GL_WEBGL_multi_draw_instanced_base_vertex_base_instance")) {
760             fNativeDrawIndirectSupport = true;
761             fMultiDrawType = MultiDrawType::kANGLEOrWebGL;
762         }
763         // The indirect structs need to reside in CPU memory for the WebGL version.
764         fUseClientSideIndirectBuffers = true;
765         fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
766     }
767     // We used to disable this as a correctness workaround (http://anglebug.com/4536). Now it is
768     // disabled because of poor performance (http://skbug.com/11998).
769     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
770         fBaseVertexBaseInstanceSupport = false;
771         fNativeDrawIndirectSupport = false;
772         fMultiDrawType = MultiDrawType::kNone;
773     }
774 
775     // We do not support GrBackendSemaphore for GL backends because the clients cannot really make
776     // GrGLsync objects ahead of time without talking to the GPU.
777     fBackendSemaphoreSupport = false;
778     // We prefer GL sync objects but also support NV_fence_sync. The former can be
779     // used to implement GrGLsync and GrSemaphore. The latter only implements GrGLsync.
780     // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
781     if (GR_IS_GR_WEBGL(standard)) {
782         // Only in WebGL 2.0
783         fSemaphoreSupport = fFenceSyncSupport = version >= GR_GL_VER(2, 0);
784         fFenceType = FenceType::kSyncObject;
785     } else if (GR_IS_GR_GL(standard) &&
786                (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync"))) {
787         fSemaphoreSupport = fFenceSyncSupport = true;
788         fFenceType = FenceType::kSyncObject;
789     } else if (GR_IS_GR_GL_ES(standard) &&
790                (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync"))) {
791         fSemaphoreSupport = fFenceSyncSupport = true;
792         fFenceType = FenceType::kSyncObject;
793     } else if (ctxInfo.hasExtension("GL_NV_fence")) {
794         // This extension can exist in GL and GL ES. We have it last because we prefer the
795         // standard GLsync object implementation which also supports GPU semaphore semantics.
796         fFenceSyncSupport = true;
797         fFenceType = FenceType::kNVFence;
798     }
799     fFinishedProcAsyncCallbackSupport = fFenceSyncSupport;
800 
801     if (GR_IS_GR_WEBGL(standard)) {
802         if (version >= GR_GL_VER(2, 0)) {
803             if (ctxInfo.hasExtension("EXT_disjoint_timer_query_webgl2") ||
804                 ctxInfo.hasExtension("GL_EXT_disjoint_timer_query_webgl2")) {
805                 fTimerQueryType = TimerQueryType::kDisjoint;
806             }
807         } else {
808             if (ctxInfo.hasExtension("EXT_disjoint_timer_query") ||
809                 ctxInfo.hasExtension("GL_EXT_disjoint_timer_query")) {
810                 fTimerQueryType = TimerQueryType::kDisjoint;
811             }
812         }
813     } else if (GR_IS_GR_GL_ES(standard)) {
814         if (ctxInfo.hasExtension("GL_EXT_disjoint_timer_query")) {
815             fTimerQueryType = TimerQueryType::kDisjoint;
816         }
817     } else if (GR_IS_GR_GL(standard)) {
818         if (version >= GR_GL_VER(3, 3) || ctxInfo.hasExtension("GL_EXT_timer_query") ||
819             ctxInfo.hasExtension("GL_ARB_timer_query")) {
820             fTimerQueryType = TimerQueryType::kRegular;
821         }
822     }
823     if (fTimerQueryType != TimerQueryType::kNone) {
824         fSupportedGpuStats |= skgpu::GpuStatsFlags::kElapsedTime;
825     }
826 
827     // Safely moving textures between contexts requires semaphores.
828     fCrossContextTextureSupport = fSemaphoreSupport;
829 
830     // Half float vertex attributes requires GL3 or ES3
831     // It can also work with OES_VERTEX_HALF_FLOAT, but that requires a different enum.
832     if (GR_IS_GR_GL(standard)) {
833         fHalfFloatVertexAttributeSupport = (version >= GR_GL_VER(3, 0));
834     } else if (GR_IS_GR_GL_ES(standard)) {
835         fHalfFloatVertexAttributeSupport = (version >= GR_GL_VER(3, 0));
836     } else if (GR_IS_GR_WEBGL(standard)) {
837         // This appears to be supported in 2.0, looking at the spec.
838         fHalfFloatVertexAttributeSupport = (version >= GR_GL_VER(2, 0));
839     }
840 
841     fDynamicStateArrayGeometryProcessorTextureSupport = true;
842 
843     if (GR_IS_GR_GL(standard)) {
844         fProgramBinarySupport = (version >= GR_GL_VER(4, 1));
845         fProgramParameterSupport = (version >= GR_GL_VER(4, 1));
846     } else if (GR_IS_GR_GL_ES(standard)) {
847         fProgramBinarySupport =
848                 (version >= GR_GL_VER(3, 0)) || ctxInfo.hasExtension("GL_OES_get_program_binary");
849         fProgramParameterSupport = (version >= GR_GL_VER(3, 0));
850     } // Explicitly not supported in WebGL 2.0
851       // https://www.khronos.org/registry/webgl/specs/2.0/#5.4
852     if (fProgramBinarySupport) {
853         GrGLint count;
854         GR_GL_GetIntegerv(gli, GR_GL_NUM_PROGRAM_BINARY_FORMATS, &count);
855         if (count > 0) {
856             fProgramBinaryFormats.resize_back(count);
857             GR_GL_GetIntegerv(gli, GR_GL_PROGRAM_BINARY_FORMATS,
858                               reinterpret_cast<GrGLint*>(fProgramBinaryFormats.data()));
859         } else {
860             fProgramBinarySupport = false;
861         }
862     }
863     if (GR_IS_GR_GL(standard)) {
864         fSamplerObjectSupport =
865                 version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_sampler_objects");
866     } else if (GR_IS_GR_GL_ES(standard)) {
867         fSamplerObjectSupport = version >= GR_GL_VER(3,0);
868     } else if (GR_IS_GR_WEBGL(standard)) {
869         fSamplerObjectSupport = version >= GR_GL_VER(2,0);
870     }
871     // We currently use sampler objects whenever they are available.
872     fUseSamplerObjects = fSamplerObjectSupport;
873 
874     if (GR_IS_GR_GL_ES(standard)) {
875         fTiledRenderingSupport = ctxInfo.hasExtension("GL_QCOM_tiled_rendering");
876     }
877 
878     if (ctxInfo.vendor() == GrGLVendor::kARM) {
879         fShouldCollapseSrcOverToSrcWhenAble = true;
880     }
881 
882 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
883     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
884         // https://b/195281495
885         // The TecnoSpark 3 Pro with a PowerVR GE8300 seems to have a steep dithering performance
886         // cliff in the Android Framework
887         fAvoidDithering = true;
888     }
889 #endif
890 
891     FormatWorkarounds formatWorkarounds;
892 
893     if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
894         this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, gli, shaderCaps,
895                                                 &formatWorkarounds);
896     }
897 
898     // Requires msaa support, ES compatibility have already been detected.
899     this->initFormatTable(ctxInfo, gli, formatWorkarounds);
900 
901     this->finishInitialization(contextOptions);
902 
903     // For GL, besides the user-specifiable override, we also want to avoid stencil buffers
904     // in Protected mode (to avoid using RenderBuffers)
905     fAvoidStencilBuffers = contextOptions.fAvoidStencilBuffers || fSupportsProtectedContent;
906 
907     // For now these two are equivalent but we could have dst read in shader via some other method.
908     shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
909 }
910 
get_glsl_version_decl_string(GrGLStandard standard,SkSL::GLSLGeneration generation,bool isCoreProfile)911 const char* get_glsl_version_decl_string(GrGLStandard standard, SkSL::GLSLGeneration generation,
912                                          bool isCoreProfile) {
913     if (GR_IS_GR_GL(standard)) {
914         switch (generation) {
915             case SkSL::GLSLGeneration::k110:
916                 return "#version 110\n";
917             case SkSL::GLSLGeneration::k130:
918                 return "#version 130\n";
919             case SkSL::GLSLGeneration::k140:
920                 return "#version 140\n";
921             case SkSL::GLSLGeneration::k150:
922                 if (isCoreProfile) {
923                     return "#version 150\n";
924                 } else {
925                     return "#version 150 compatibility\n";
926                 }
927             case SkSL::GLSLGeneration::k330:
928                 if (isCoreProfile) {
929                     return "#version 330\n";
930                 } else {
931                     return "#version 330 compatibility\n";
932                 }
933             case SkSL::GLSLGeneration::k400:
934                 if (isCoreProfile) {
935                     return "#version 400\n";
936                 } else {
937                     return "#version 400 compatibility\n";
938                 }
939             case SkSL::GLSLGeneration::k420:
940                 if (isCoreProfile) {
941                     return "#version 420\n";
942                 } else {
943                     return "#version 420 compatibility\n";
944                 }
945             default:
946                 break;
947         }
948     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
949         switch (generation) {
950             case SkSL::GLSLGeneration::k100es:
951                 return "#version 100\n";
952             case SkSL::GLSLGeneration::k300es:
953                 return "#version 300 es\n";
954             case SkSL::GLSLGeneration::k310es:
955                 return "#version 310 es\n";
956             case SkSL::GLSLGeneration::k320es:
957                 return "#version 320 es\n";
958             default:
959                 break;
960         }
961     }
962     return "<no version>";
963 }
964 
is_float_fp32(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli,GrGLenum precision)965 bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
966     if (GR_IS_GR_GL(ctxInfo.standard()) &&
967         ctxInfo.version() < GR_GL_VER(4,1) &&
968         !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
969         // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
970         return true;
971     }
972     // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
973     // geometry shaders don't have lower precision than vertex and fragment.
974     for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
975         GrGLint range[2];
976         GrGLint bits;
977         GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
978         if (range[0] < 127 || range[1] < 127 || bits < 23) {
979             return false;
980         }
981     }
982     return true;
983 }
984 
initGLSL(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)985 void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
986     GrGLStandard standard = ctxInfo.standard();
987     GrGLVersion version = ctxInfo.version();
988 
989     /**************************************************************************
990     * Caps specific to GrShaderCaps
991     **************************************************************************/
992 
993     GrShaderCaps* shaderCaps = fShaderCaps.get();
994     shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
995     if (GR_IS_GR_GL_ES(standard)) {
996         // fFBFetchRequiresEnablePerSample is not a shader cap but is initialized below to keep it
997         // with related FB fetch logic.
998         if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
999             shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
1000             shaderCaps->fFBFetchSupport = true;
1001             shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
1002             shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
1003             fFBFetchRequiresEnablePerSample = false;
1004         } else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
1005             // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know.
1006             shaderCaps->fFBFetchNeedsCustomOutput = false;
1007             shaderCaps->fFBFetchSupport = true;
1008             shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
1009             shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
1010             fFBFetchRequiresEnablePerSample = false;
1011         } else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
1012             // The arm extension also requires an additional flag which we will set onResetContext.
1013             shaderCaps->fFBFetchNeedsCustomOutput = false;
1014             shaderCaps->fFBFetchSupport = true;
1015             shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
1016             shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
1017             fFBFetchRequiresEnablePerSample = true;
1018         }
1019         shaderCaps->fUsesPrecisionModifiers = true;
1020     } else if (GR_IS_GR_GL(standard)) {
1021         if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
1022             shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
1023             shaderCaps->fFBFetchSupport = true;
1024             shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
1025             shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
1026             fFBFetchRequiresEnablePerSample = false;
1027         }
1028     } else if (GR_IS_GR_WEBGL(standard)) {
1029         shaderCaps->fUsesPrecisionModifiers = true;
1030     }
1031 
1032     if (GR_IS_GR_GL(standard)) {
1033         shaderCaps->fFlatInterpolationSupport =
1034                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
1035     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1036         shaderCaps->fFlatInterpolationSupport =
1037                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
1038     } // not sure for WebGL
1039 
1040     // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
1041     // Avoid on ANGLE too, it inserts a geometry shader into the pipeline to implement flat interp.
1042     // Is this only true on ANGLE's D3D backends or also on the GL backend?
1043     // Flat interpolation is slow with ANGLE's Metal backend and uses memory to rewrite index
1044     // buffers to support GL's provoking vertex semantics.
1045     // Never prefer flat shading on WebGL. GPU detection isn't as robust (e.g.
1046     // WEBGL_debug_renderer_info may not be enabled and strings may be masked), the perf benefits
1047     // are minimal, and potential cost is high (e.g. on ANGLE Metal backend).
1048     shaderCaps->fPreferFlatInterpolation = !GR_IS_GR_WEBGL(standard) &&
1049                                            shaderCaps->fFlatInterpolationSupport &&
1050                                            ctxInfo.vendor() != GrGLVendor::kQualcomm &&
1051                                            !angle_backend_is_d3d(ctxInfo.angleBackend()) &&
1052                                            !angle_backend_is_metal(ctxInfo.angleBackend());
1053     if (GR_IS_GR_GL(standard)) {
1054         shaderCaps->fNoPerspectiveInterpolationSupport =
1055             ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k130;
1056     } else if (GR_IS_GR_GL_ES(standard)) {
1057         if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation") &&
1058             ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es) {
1059             shaderCaps->fNoPerspectiveInterpolationSupport = true;
1060             shaderCaps->fNoPerspectiveInterpolationExtensionString =
1061                 "GL_NV_shader_noperspective_interpolation";
1062         }
1063     }  // Not sure for WebGL
1064 
1065     if (GR_IS_GR_GL(standard)) {
1066         shaderCaps->fSampleMaskSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1067     } else if (GR_IS_GR_GL_ES(standard)) {
1068         if (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k320es) {
1069             shaderCaps->fSampleMaskSupport = true;
1070         } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
1071             shaderCaps->fSampleMaskSupport = true;
1072             shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
1073         }
1074     }
1075 
1076     shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
1077                                                                   shaderCaps->fGLSLGeneration,
1078                                                                   fIsCoreProfile);
1079 
1080     if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1081         if (SkSL::GLSLGeneration::k100es == shaderCaps->fGLSLGeneration) {
1082             shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
1083         }
1084     } // WebGL might have to check for OES_standard_derivatives
1085 
1086     if (GR_IS_GR_GL_ES(standard)) {
1087         shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
1088     }
1089 
1090     if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
1091         if (ctxInfo.glslGeneration() == SkSL::GLSLGeneration::k100es) {
1092             shaderCaps->fExternalTextureSupport = true;
1093             shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
1094         } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
1095                    ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
1096             // At least one driver has been found that has this extension without the "GL_" prefix.
1097             shaderCaps->fExternalTextureSupport = true;
1098             shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
1099         }
1100     }
1101 
1102     if (GR_IS_GR_GL(standard)) {
1103         shaderCaps->fVertexIDSupport = true;
1104     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1105         shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
1106     }
1107 
1108     // isinf() exists in GLSL 1.3 and above, but hardware without proper IEEE support is allowed to
1109     // always return false, so it's potentially meaningless. In GLSL 3.3 and GLSL ES3+, isinf() is
1110     // required to actually identify infinite values. (GPUs are not required to _produce_ infinite
1111     // values via operations like `num / 0.0` until GLSL 4.1.)
1112     shaderCaps->fInfinitySupport = (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330);
1113 
1114     // Using isinf or isnan with ANGLE will disable fast-math (which is a good thing!), but that
1115     // leads to hangs in the Metal shader compiler service for some of our tessellation shaders,
1116     // running on Intel Macs. For now, pretend that we don't have infinity support, even when we're
1117     // targeting ANGLE's ES3 to Metal.
1118     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kMetal &&
1119         ctxInfo.angleVendor() == GrGLVendor::kIntel) {
1120         shaderCaps->fInfinitySupport = false;
1121     }
1122 
1123     if (GR_IS_GR_GL(standard)) {
1124         shaderCaps->fNonconstantArrayIndexSupport = true;
1125     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1126         shaderCaps->fNonconstantArrayIndexSupport =
1127                 (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es);
1128     }
1129 
1130     if (GR_IS_GR_GL(standard)) {
1131         shaderCaps->fBitManipulationSupport =
1132                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1133     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1134         shaderCaps->fBitManipulationSupport =
1135                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k310es;
1136     }
1137 
1138     shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
1139     shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
1140     shaderCaps->fHasLowFragmentPrecision = ctxInfo.renderer() == GrGLRenderer::kMali4xx;
1141 
1142     if (GR_IS_GR_GL(standard)) {
1143         shaderCaps->fBuiltinFMASupport =
1144                  ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1145     } else if (GR_IS_GR_GL_ES(standard)) {
1146         shaderCaps->fBuiltinFMASupport =
1147                  ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k320es;
1148     } else if (GR_IS_GR_WEBGL(standard)) {
1149         shaderCaps->fBuiltinFMASupport = false;
1150     }
1151 
1152     shaderCaps->fBuiltinDeterminantSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k150;
1153 }
1154 
initFSAASupport(const GrContextOptions & contextOptions,const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)1155 void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions,
1156                                const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
1157     if (GR_IS_GR_GL(ctxInfo.standard())) {
1158         if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1159             ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
1160             fMSFBOType = kStandard_MSFBOType;
1161         } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1162                    ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
1163             fMSFBOType = kStandard_MSFBOType;
1164         }
1165     } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1166         // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
1167         // ES3 driver bugs on at least one device with a tiled GPU (N10).
1168         if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1169             fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1170             fMSAAResolvesAutomatically = true;
1171         } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1172             fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
1173             fMSAAResolvesAutomatically = true;
1174         } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1175             fMSFBOType = kStandard_MSFBOType;
1176         } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
1177             fMSFBOType = kStandard_MSFBOType;
1178         } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
1179             fMSFBOType = kStandard_MSFBOType;
1180         } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1181             fMSFBOType = kES_Apple_MSFBOType;
1182         }
1183     } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1184         // No support in WebGL 1, but there is for 2.0
1185         if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1186             fMSFBOType = kStandard_MSFBOType;
1187         } else {
1188             fMSFBOType = kNone_MSFBOType;
1189         }
1190     }
1191 }
1192 
initBlendEqationSupport(const GrGLContextInfo & ctxInfo)1193 void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
1194     GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
1195 
1196     bool layoutQualifierSupport = false;
1197     if ((GR_IS_GR_GL(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k140) ||
1198         (GR_IS_GR_GL_ES(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k300es)){
1199         layoutQualifierSupport = true;
1200     } else if (GR_IS_GR_WEBGL(fStandard)) {
1201         return;
1202     }
1203 
1204     if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1205         fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1206         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1207     } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1208                layoutQualifierSupport) {
1209         fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1210         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1211     } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1212         fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1213         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1214     } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
1215         fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1216         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1217     }
1218 }
1219 
1220 
initStencilSupport(const GrGLContextInfo & ctxInfo)1221 void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
1222 
1223     // Build up list of legal stencil formats (though perhaps not supported on
1224     // the particular gpu/driver) from most preferred to least.
1225 
1226     // We push back stencil formats onto the fStencilFormats array in order of most preferred to
1227     // least preferred.
1228 
1229     if (GR_IS_GR_GL(ctxInfo.standard())) {
1230         bool supportsPackedDS =
1231             ctxInfo.version() >= GR_GL_VER(3,0) ||
1232             ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1233             ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1234 
1235         // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1236         // require FBO support we can expect these are legal formats and don't
1237         // check.
1238         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1239         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX16;
1240         if (supportsPackedDS) {
1241             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1242         }
1243     } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1244         // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1245         // for other formats.
1246 
1247         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1248         if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1249             ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
1250             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1251         }
1252     } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1253         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1254         if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1255             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1256         }
1257     }
1258 }
1259 
1260 #ifdef SK_ENABLE_DUMP_GPU
1261 #include "src/utils/SkJSONWriter.h"
1262 
multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType)1263 static const char* multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType) {
1264     switch (multiDrawType) {
1265         case GrGLCaps::MultiDrawType::kNone : return "kNone";
1266         case GrGLCaps::MultiDrawType::kMultiDrawIndirect : return "kMultiDrawIndirect";
1267         case GrGLCaps::MultiDrawType::kANGLEOrWebGL : return "kMultiDrawIndirect";
1268     }
1269     SkUNREACHABLE;
1270 }
1271 
onDumpJSON(SkJSONWriter * writer) const1272 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
1273 
1274     // We are called by the base class, which has already called beginObject(). We choose to nest
1275     // all of our caps information in a named sub-object.
1276     writer->beginObject("GL caps");
1277 
1278     writer->beginArray("Stencil Formats");
1279 
1280     for (int i = 0; i < fStencilFormats.size(); ++i) {
1281         writer->beginObject(nullptr, false);
1282         writer->appendS32("stencil bits", GrGLFormatStencilBits(fStencilFormats[i]));
1283         writer->appendS32("total bytes", GrGLFormatBytesPerBlock(fStencilFormats[i]));
1284         writer->endObject();
1285     }
1286 
1287     writer->endArray();
1288 
1289     auto msfboStr = [&] {
1290         switch (fMSFBOType) {
1291             case kNone_MSFBOType:               return "None";
1292             case kStandard_MSFBOType:           return "Standard";
1293             case kES_Apple_MSFBOType:           return "Apple";
1294             case kES_IMG_MsToTexture_MSFBOType: return "IMG MS To Texture";
1295             case kES_EXT_MsToTexture_MSFBOType: return "EXT MS To Texture";
1296         }
1297         SkUNREACHABLE;
1298     };
1299 
1300     auto invalidateFBTypeStr = [&] {
1301         switch (fInvalidateFBType) {
1302             case kNone_InvalidateFBType:       return "None";
1303             case kDiscard_InvalidateFBType:    return "Discard";
1304             case kInvalidate_InvalidateFBType: return "Invalidate";
1305         }
1306         SkUNREACHABLE;
1307     };
1308 
1309     auto invalidateBufferTypeStr = [&] {
1310         switch (fInvalidateBufferType) {
1311             case InvalidateBufferType::kNone:       return "None";
1312             case InvalidateBufferType::kNullData:   return "Null data hint";
1313             case InvalidateBufferType::kInvalidate: return "Invalidate";
1314         }
1315         SkUNREACHABLE;
1316     };
1317 
1318     auto mapBufferTypeStr = [&] {
1319         switch (fMapBufferType) {
1320             case kNone_MapBufferType:           return "None";
1321             case kMapBuffer_MapBufferType:      return "MapBuffer";
1322             case kMapBufferRange_MapBufferType: return "MapBufferRange";
1323             case kChromium_MapBufferType:       return "Chromium";
1324         }
1325         SkUNREACHABLE;
1326     };
1327 
1328     writer->appendBool("Core Profile", fIsCoreProfile);
1329     writer->appendCString("MSAA Type", msfboStr());
1330     writer->appendCString("Invalidate FB Type", invalidateFBTypeStr());
1331     writer->appendCString("Invalidate Buffer Type", invalidateBufferTypeStr());
1332     writer->appendCString("Map Buffer Type", mapBufferTypeStr());
1333     writer->appendCString("Multi Draw Type", multi_draw_type_name(fMultiDrawType));
1334     writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1335     writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
1336 
1337     writer->appendBool("Texture Usage support", fTextureUsageSupport);
1338     writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1339     writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
1340     writer->appendBool("Debug support", fDebugSupport);
1341     writer->appendBool("ES2 compatibility support", fES2CompatibilitySupport);
1342     writer->appendBool("Strict Protectedness", fStrictProtectedness);
1343     writer->appendBool("drawRangeElements support", fDrawRangeElementsSupport);
1344     writer->appendBool("Base (vertex base) instance support", fBaseVertexBaseInstanceSupport);
1345     writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1346     writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1347     writer->appendBool("Mipmap LOD control support", fMipmapLodControlSupport);
1348     writer->appendBool("Mipmap level control support", fMipmapLevelControlSupport);
1349     writer->appendBool("Clear texture support", fClearTextureSupport);
1350     writer->appendBool("Program binary support", fProgramBinarySupport);
1351     writer->appendBool("Program parameters support", fProgramParameterSupport);
1352     writer->appendBool("Sampler object support", fSamplerObjectSupport);
1353     writer->appendBool("Using sampler objects", fUseSamplerObjects);
1354     writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1355     writer->appendBool("Tiled rendering support", fTiledRenderingSupport);
1356     writer->appendBool("Fence sync support", fFenceSyncSupport);
1357     writer->appendBool("FB fetch requires enable per sample", fFBFetchRequiresEnablePerSample);
1358     writer->appendBool("sRGB Write Control", fSRGBWriteControl);
1359 
1360     writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1361                        fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1362     writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1363                        fUseDrawInsteadOfAllRenderTargetWrites);
1364     writer->appendBool("Max instances per draw without crashing (or zero)",
1365                        fMaxInstancesPerDrawWithoutCrashing);
1366 
1367     writer->beginArray("formats");
1368 
1369     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
1370         writer->beginObject(nullptr, false);
1371         writer->appendHexU32("flags", fFormatTable[i].fFlags);
1372         writer->appendHexU32("f_type", (uint32_t)fFormatTable[i].fFormatType);
1373         writer->appendHexU32("c_internal", fFormatTable[i].fCompressedInternalFormat);
1374         writer->appendHexU32("i_for_teximage", fFormatTable[i].fInternalFormatForTexImageOrStorage);
1375         writer->appendHexU32("i_for_renderbuffer", fFormatTable[i].fInternalFormatForRenderbuffer);
1376         writer->appendHexU32("default_ex_format", fFormatTable[i].fDefaultExternalFormat);
1377         writer->appendHexU32("default_ex_type", fFormatTable[i].fDefaultExternalType);
1378         writer->appendHexU32("default_color_type", (uint32_t)fFormatTable[i].fDefaultColorType);
1379 
1380         writer->beginArray("surface color types");
1381         for (int j = 0; j < fFormatTable[i].fColorTypeInfoCount; ++j) {
1382             const auto& ctInfo = fFormatTable[i].fColorTypeInfos[j];
1383             writer->beginObject(nullptr, false);
1384             writer->appendHexU32("colorType", (uint32_t)ctInfo.fColorType);
1385             writer->appendHexU32("flags", ctInfo.fFlags);
1386 
1387             writer->beginArray("data color types");
1388             for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
1389                 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
1390                 writer->beginObject(nullptr, false);
1391                 writer->appendHexU32("colorType", (uint32_t)ioInfo.fColorType);
1392                 writer->appendHexU32("ex_type", ioInfo.fExternalType);
1393                 writer->appendHexU32("ex_teximage", ioInfo.fExternalTexImageFormat);
1394                 writer->appendHexU32("ex_read", ioInfo.fExternalReadFormat);
1395                 writer->endObject();
1396             }
1397             writer->endArray();
1398             writer->endObject();
1399         }
1400         writer->endArray();
1401         writer->endObject();
1402     }
1403 
1404     writer->endArray();
1405     writer->endObject();
1406 }
1407 #else
onDumpJSON(SkJSONWriter * writer) const1408 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const { }
1409 #endif
1410 
getTexImageExternalFormatAndType(GrGLFormat surfaceFormat,GrGLenum * externalFormat,GrGLenum * externalType) const1411 void GrGLCaps::getTexImageExternalFormatAndType(GrGLFormat surfaceFormat, GrGLenum* externalFormat,
1412                                                 GrGLenum* externalType) const {
1413     const auto& info = this->getFormatInfo(surfaceFormat);
1414     *externalType = info.fDefaultExternalType;
1415     *externalFormat = info.fDefaultExternalFormat;
1416 }
1417 
getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,GrGLenum * externalFormat,GrGLenum * externalType,GrColorType * colorType) const1418 void GrGLCaps::getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,
1419                                                            GrGLenum* externalFormat,
1420                                                            GrGLenum* externalType,
1421                                                            GrColorType* colorType) const {
1422     const auto& info = this->getFormatInfo(format);
1423     *externalType = info.fDefaultExternalType;
1424     *externalFormat = info.fDefaultExternalFormat;
1425     *colorType = info.fDefaultColorType;
1426 }
1427 
getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1428 void GrGLCaps::getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,
1429                                                    GrColorType surfaceColorType,
1430                                                    GrColorType memoryColorType,
1431                                                    GrGLenum* externalFormat,
1432                                                    GrGLenum* externalType) const {
1433     this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1434                             kTexImage_ExternalFormatUsage, externalFormat, externalType);
1435 }
1436 
getReadPixelsFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1437 void GrGLCaps::getReadPixelsFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1438                                    GrColorType memoryColorType, GrGLenum* externalFormat,
1439                                    GrGLenum* externalType) const {
1440     this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1441                             kReadPixels_ExternalFormatUsage, externalFormat, externalType);
1442 }
1443 
getExternalFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,ExternalFormatUsage usage,GrGLenum * externalFormat,GrGLenum * externalType) const1444 void GrGLCaps::getExternalFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1445                                  GrColorType memoryColorType, ExternalFormatUsage usage,
1446                                  GrGLenum* externalFormat, GrGLenum* externalType) const {
1447     SkASSERT(externalFormat && externalType);
1448     *externalFormat = this->getFormatInfo(surfaceFormat).externalFormat(
1449             surfaceColorType, memoryColorType, usage);
1450     *externalType = this->getFormatInfo(surfaceFormat).externalType(
1451             surfaceColorType, memoryColorType);
1452 }
1453 
setStencilFormatIndexForFormat(GrGLFormat format,int index)1454 void GrGLCaps::setStencilFormatIndexForFormat(GrGLFormat format, int index) {
1455     SkASSERT(!this->hasStencilFormatBeenDeterminedForFormat(format));
1456     this->getFormatInfo(format).fStencilFormatIndex =
1457             index < 0 ? FormatInfo::kUnsupported_StencilFormatIndex : index;
1458 }
1459 
setColorTypeFormat(GrColorType colorType,GrGLFormat format)1460 void GrGLCaps::setColorTypeFormat(GrColorType colorType, GrGLFormat format) {
1461     int idx = static_cast<int>(colorType);
1462     SkASSERT(fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown);
1463     fColorTypeToFormatTable[idx] = format;
1464 }
1465 
initFormatTable(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli,const FormatWorkarounds & formatWorkarounds)1466 void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1467                                const FormatWorkarounds& formatWorkarounds) {
1468     GrGLStandard standard = ctxInfo.standard();
1469     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
1470     sk_ignore_unused_variable(standard);
1471     GrGLVersion version = ctxInfo.version();
1472 
1473     uint32_t nonMSAARenderFlags = FormatInfo::kFBOColorAttachment_Flag;
1474     uint32_t msaaRenderFlags = nonMSAARenderFlags;
1475     if (kNone_MSFBOType != fMSFBOType) {
1476         msaaRenderFlags |= FormatInfo::kFBOColorAttachmentWithMSAA_Flag;
1477     }
1478 
1479     bool texStorageSupported = false;
1480     if (GR_IS_GR_GL(standard)) {
1481         // The EXT version can apply to either GL or GLES.
1482         texStorageSupported = version >= GR_GL_VER(4,2) ||
1483                               ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1484                               ctxInfo.hasExtension("GL_EXT_texture_storage");
1485     } else if (GR_IS_GR_GL_ES(standard)) {
1486         texStorageSupported = version >= GR_GL_VER(3,0) ||
1487                               ctxInfo.hasExtension("GL_EXT_texture_storage");
1488     } else if (GR_IS_GR_WEBGL(standard)) {
1489         texStorageSupported = version >= GR_GL_VER(2,0);
1490     }
1491     if (fDriverBugWorkarounds.disable_texture_storage) {
1492         texStorageSupported = false;
1493     }
1494 
1495     if (formatWorkarounds.fDisableTexStorage) {
1496         texStorageSupported = false;
1497     }
1498 
1499     // ES 2.0 requires that the internal/external formats match so we can't use sized internal
1500     // formats for glTexImage until ES 3.0. TODO: Support sized internal formats in WebGL2.
1501     bool texImageSupportsSizedInternalFormat =
1502             (GR_IS_GR_GL(standard) || (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0)));
1503 
1504     // for now we don't support floating point MSAA on ES
1505     uint32_t fpRenderFlags = (GR_IS_GR_GL(standard)) ? msaaRenderFlags : nonMSAARenderFlags;
1506 
1507     for (int i = 0; i < kGrColorTypeCnt; ++i) {
1508         fColorTypeToFormatTable[i] = GrGLFormat::kUnknown;
1509     }
1510 
1511     ///////////////////////////////////////////////////////////////////////////
1512 
1513     GrGLenum halfFloatType = GR_GL_HALF_FLOAT;
1514     if ((GR_IS_GR_GL_ES(standard) && version < GR_GL_VER(3, 0)) ||
1515         (GR_IS_GR_WEBGL(standard) && version < GR_GL_VER(2, 0))) {
1516         halfFloatType = GR_GL_HALF_FLOAT_OES;
1517     }
1518 
1519     // Format: RGBA8
1520     {
1521         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA8);
1522         info.fFormatType = FormatType::kNormalizedFixedPoint;
1523         info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
1524         info.fDefaultExternalFormat = GR_GL_RGBA;
1525         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1526         info.fDefaultColorType = GrColorType::kRGBA_8888;
1527         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1528         if (GR_IS_GR_GL(standard)) {
1529             info.fFlags |= msaaRenderFlags;
1530         } else if (GR_IS_GR_GL_ES(standard)) {
1531             if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1532                 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1533                 info.fFlags |= msaaRenderFlags;
1534             }
1535         } else if (GR_IS_GR_WEBGL(standard)) {
1536             info.fFlags |= msaaRenderFlags;
1537         }
1538 
1539         if (texStorageSupported) {
1540             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1541             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA8;
1542         } else {
1543             info.fInternalFormatForTexImageOrStorage =
1544                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA8 : GR_GL_RGBA;
1545         }
1546 
1547         bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
1548                 (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
1549         info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
1550         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1551         int ctIdx = 0;
1552         // Format: RGBA8, Surface: kRGBA_8888
1553         {
1554             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1555             ctInfo.fColorType = GrColorType::kRGBA_8888;
1556             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1557             this->setColorTypeFormat(GrColorType::kRGBA_8888, GrGLFormat::kRGBA8);
1558 
1559             // External IO ColorTypes:
1560             ctInfo.fExternalIOFormatCount = 2;
1561             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1562                     ctInfo.fExternalIOFormatCount);
1563             int ioIdx = 0;
1564             // Format: RGBA8, Surface: kRGBA_8888, Data: kRGBA_8888
1565             {
1566                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1567                 ioFormat.fColorType = GrColorType::kRGBA_8888;
1568                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1569                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1570                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1571             }
1572             // Format: RGBA8, Surface: kRGBA_8888, Data: kBGRA_8888
1573             {
1574                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1575                 ioFormat.fColorType = GrColorType::kBGRA_8888;
1576                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1577                 ioFormat.fExternalTexImageFormat = 0;  // TODO: Enable this on non-ES GL
1578                 ioFormat.fExternalReadFormat =
1579                         formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1580                 // Not guaranteed by ES/WebGL.
1581                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1582             }
1583         }
1584 
1585         // Format: RGBA8, Surface: kBGRA_8888
1586         if (supportsBGRAColorType) {
1587             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1588             ctInfo.fColorType = GrColorType::kBGRA_8888;
1589             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1590             this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kRGBA8);
1591 
1592             // External IO ColorTypes:
1593             ctInfo.fExternalIOFormatCount = 2;
1594             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1595                     ctInfo.fExternalIOFormatCount);
1596             int ioIdx = 0;
1597             // Format: RGBA8, Surface: kBGRA_8888, Data: kBGRA_8888
1598             {
1599                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1600                 ioFormat.fColorType = GrColorType::kBGRA_8888;
1601                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1602                 ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
1603                 ioFormat.fExternalReadFormat =
1604                         formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1605                 // Not guaranteed by ES/WebGL.
1606                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1607             }
1608 
1609             // Format: RGBA8, Surface: kBGRA_8888, Data: kRGBA_8888
1610             {
1611                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1612                 ioFormat.fColorType = GrColorType::kRGBA_8888;
1613                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1614                 ioFormat.fExternalTexImageFormat = 0;
1615                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1616             }
1617         }
1618 
1619         // Format: RGBA8, Surface: kRGB_888x
1620         {
1621             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1622             ctInfo.fColorType = GrColorType::kRGB_888x;
1623             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1624             ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
1625 
1626             // External IO ColorTypes:
1627             ctInfo.fExternalIOFormatCount = 1;
1628             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1629                     ctInfo.fExternalIOFormatCount);
1630             int ioIdx = 0;
1631             // Format: RGBA8, Surface: kRGB_888x, Data: kRGBA_888x
1632             {
1633                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1634                 ioFormat.fColorType = GrColorType::kRGB_888x;
1635                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1636                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1637                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1638             }
1639         }
1640     }
1641 
1642     // Format: R8
1643     {
1644         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR8);
1645         info.fFormatType = FormatType::kNormalizedFixedPoint;
1646         info.fInternalFormatForRenderbuffer = GR_GL_R8;
1647         info.fDefaultExternalFormat = GR_GL_RED;
1648         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1649         info.fDefaultColorType = GrColorType::kR_8;
1650         bool r8Support = false;
1651         if (GR_IS_GR_GL(standard)) {
1652             r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1653         } else if (GR_IS_GR_GL_ES(standard)) {
1654             r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1655         } else if (GR_IS_GR_WEBGL(standard)) {
1656             r8Support = ctxInfo.version() >= GR_GL_VER(2, 0);
1657         }
1658         if (formatWorkarounds.fDisallowR8ForPowerVRSGX54x) {
1659             r8Support = false;
1660         }
1661 
1662         if (r8Support) {
1663             info.fFlags |= FormatInfo::kTexturable_Flag
1664                         |  FormatInfo::kTransfers_Flag
1665                         |  msaaRenderFlags;
1666         }
1667 
1668         if (texStorageSupported) {
1669             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1670             info.fInternalFormatForTexImageOrStorage = GR_GL_R8;
1671         } else {
1672             info.fInternalFormatForTexImageOrStorage =
1673                     texImageSupportsSizedInternalFormat ? GR_GL_R8 : GR_GL_RED;
1674         }
1675 
1676         if (r8Support) {
1677             info.fColorTypeInfoCount = 3;
1678             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1679             int ctIdx = 0;
1680             // Format: R8, Surface: kR_8
1681             {
1682                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1683                 ctInfo.fColorType = GrColorType::kR_8;
1684                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1685                 this->setColorTypeFormat(GrColorType::kR_8, GrGLFormat::kR8);
1686 
1687                 // External IO ColorTypes:
1688                 ctInfo.fExternalIOFormatCount = 2;
1689                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1690                         ctInfo.fExternalIOFormatCount);
1691                 int ioIdx = 0;
1692                 // Format: R8, Surface: kR_8, Data: kR_8
1693                 {
1694                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1695                     ioFormat.fColorType = GrColorType::kR_8;
1696                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1697                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1698                     ioFormat.fExternalReadFormat = GR_GL_RED;
1699                     // Not guaranteed by ES/WebGL.
1700                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1701                 }
1702 
1703                 // Format: R8, Surface: kR_8, Data: kR_8xxx
1704                 {
1705                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1706                     ioFormat.fColorType = GrColorType::kR_8xxx;
1707                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1708                     ioFormat.fExternalTexImageFormat = 0;
1709                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1710                 }
1711             }
1712 
1713             // Format: R8, Surface: kAlpha_8
1714             {
1715                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1716                 ctInfo.fColorType = GrColorType::kAlpha_8;
1717                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1718                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
1719                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
1720                 this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kR8);
1721 
1722                 // External IO ColorTypes:
1723                 ctInfo.fExternalIOFormatCount = 2;
1724                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1725                         ctInfo.fExternalIOFormatCount);
1726                 int ioIdx = 0;
1727                 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8
1728                 {
1729                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1730                     ioFormat.fColorType = GrColorType::kAlpha_8;
1731                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1732                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1733                     ioFormat.fExternalReadFormat = GR_GL_RED;
1734                     // Not guaranteed by ES/WebGL.
1735                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1736                 }
1737 
1738                 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8xxx
1739                 {
1740                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1741                     ioFormat.fColorType = GrColorType::kAlpha_8xxx;
1742                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1743                     ioFormat.fExternalTexImageFormat = 0;
1744                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1745                 }
1746             }
1747 
1748             // Format: R8, Surface: kGray_8
1749             {
1750                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1751                 ctInfo.fColorType = GrColorType::kGray_8;
1752                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1753                 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
1754                 this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kR8);
1755 
1756                 // External IO ColorTypes:
1757                 ctInfo.fExternalIOFormatCount = 2;
1758                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1759                         ctInfo.fExternalIOFormatCount);
1760                 int ioIdx = 0;
1761                 // Format: R8, Surface: kGray_8, Data: kGray_8
1762                 {
1763                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1764                     ioFormat.fColorType = GrColorType::kGray_8;
1765                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1766                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1767                     ioFormat.fExternalReadFormat = GR_GL_RED;
1768                     // Not guaranteed by ES/WebGL.
1769                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1770                 }
1771 
1772                 // Format: R8, Surface: kGray_8, Data: kGray_8xxx
1773                 {
1774                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1775                     ioFormat.fColorType = GrColorType::kGray_8xxx;
1776                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1777                     ioFormat.fExternalTexImageFormat = 0;
1778                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1779                 }
1780             }
1781         }
1782     }
1783 
1784     // Format: ALPHA8
1785     {
1786         bool alpha8IsValidForGL = GR_IS_GR_GL(standard) &&
1787                 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1788         bool alpha8IsValidForGLES = GR_IS_GR_GL_ES(standard);
1789         bool alpha8IsValidForWebGL = GR_IS_GR_WEBGL(standard);
1790 
1791         FormatInfo& info = this->getFormatInfo(GrGLFormat::kALPHA8);
1792         info.fFormatType = FormatType::kNormalizedFixedPoint;
1793         // GL_EXT_texture_storage adds GL_ALPHA8 for texture storage. However, ES3 has glTexStorage
1794         // but does not have GL_ALPHA8 (and requires a sized internal format for glTexStorage).
1795         // WebGL never has GL_ALPHA8.
1796         bool alpha8SizedEnumSupported =
1797                 alpha8IsValidForGL ||
1798                 (alpha8IsValidForGLES && ctxInfo.hasExtension("GL_EXT_texture_storage"));
1799         bool alpha8TexStorageSupported = alpha8SizedEnumSupported && texStorageSupported;
1800 
1801         bool alpha8IsRenderable = false;
1802         if (alpha8IsValidForGL) {
1803             // Core profile removes ALPHA8 support.
1804             // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1805             alpha8IsRenderable = ctxInfo.version() >= GR_GL_VER(3, 0) ||
1806                                  ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1807         }
1808         info.fInternalFormatForRenderbuffer = GR_GL_ALPHA8;
1809         info.fDefaultExternalFormat = GR_GL_ALPHA;
1810         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1811         info.fDefaultColorType = GrColorType::kAlpha_8;
1812         if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1813             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1814         }
1815         if (alpha8IsRenderable && alpha8IsValidForGL) {
1816             // We will use ALPHA8 to create MSAA renderbuffers.
1817             SkASSERT(alpha8SizedEnumSupported);
1818             info.fFlags |= msaaRenderFlags;
1819         }
1820         if (alpha8TexStorageSupported) {
1821             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1822             info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1823         } else {
1824             // Even if GL_ALPHA8 is added to ES by GL_EXT_texture_storage it doesn't become legal
1825             // for glTexImage2D.
1826             if (!GR_IS_GR_GL_ES(standard) && texImageSupportsSizedInternalFormat &&
1827                 alpha8SizedEnumSupported) {
1828                 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1829             } else {
1830                 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA;
1831             }
1832         }
1833 
1834         if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1835             info.fColorTypeInfoCount = 1;
1836             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1837             int ctIdx = 0;
1838             // Format: ALPHA8, Surface: kAlpha_8
1839             {
1840                 if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1841                     auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1842                     ctInfo.fColorType = GrColorType::kAlpha_8;
1843                     ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
1844                                     ColorTypeInfo::kRenderable_Flag;
1845                     int idx = static_cast<int>(GrColorType::kAlpha_8);
1846                     if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1847                         this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kALPHA8);
1848                     }
1849 
1850                     // External IO ColorTypes:
1851                     ctInfo.fExternalIOFormatCount = 2;
1852                     ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1853                             ctInfo.fExternalIOFormatCount);
1854                     int ioIdx = 0;
1855                     // Format: ALPHA8, Surface: kAlpha_8, Data: kAlpha_8
1856                     {
1857                         auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1858                         ioFormat.fColorType = GrColorType::kAlpha_8;
1859                         ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1860                         ioFormat.fExternalTexImageFormat = GR_GL_ALPHA;
1861                         ioFormat.fExternalReadFormat = GR_GL_ALPHA;
1862                         // Not guaranteed by ES/WebGL.
1863                         ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1864                     }
1865 
1866                     // Format: ALPHA8, Surface: kAlpha_8, Data: kRGBA_8888
1867                     {
1868                         auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1869                         ioFormat.fColorType = GrColorType::kRGBA_8888;
1870                         ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1871                         ioFormat.fExternalTexImageFormat = 0;
1872                         ioFormat.fExternalReadFormat = GR_GL_RGBA;
1873                     }
1874                 }
1875             }
1876         }
1877     }
1878 
1879     // Do we support the lumincance and luminance_alpha formats
1880     bool lum8Supported = false;
1881     bool lum8SizedFormatSupported = false;
1882     if (GR_IS_GR_GL(standard) && !fIsCoreProfile) {
1883         lum8Supported = true;
1884         lum8SizedFormatSupported = true;
1885     } else if (GR_IS_GR_GL_ES(standard)) {
1886         lum8Supported = true;
1887         // Even on ES3 this extension is required to define LUMINANCE8. GL_LUMINANCE8 is not a
1888         // valid internal format for TexImage2D so we need to be using texture storage to use
1889         // it. Even though we check the extension for texture storage here, we also check to see
1890         // if texStorageSupported may have been disabled for a workaround.
1891         lum8SizedFormatSupported =
1892                 texStorageSupported && ctxInfo.hasExtension("GL_EXT_texture_storage");
1893     } else if (GR_IS_GR_WEBGL(standard)) {
1894         lum8Supported = true;
1895     }
1896 
1897     // Format: LUMINANCE8
1898     {
1899         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8);
1900         info.fFormatType = FormatType::kNormalizedFixedPoint;
1901         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8;
1902         info.fDefaultExternalFormat = GR_GL_LUMINANCE;
1903         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1904         info.fDefaultColorType = GrColorType::kGray_8;
1905 
1906         if (lum8Supported) {
1907             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1908         }
1909         if (texStorageSupported && lum8SizedFormatSupported) {
1910             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1911             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1912         } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1913             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1914         } else {
1915             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
1916         }
1917         // We are not enabling attaching to an FBO for LUMINANCE8 mostly because of confusion in the
1918         // spec. For GLES it does not seem to ever support LUMINANCE8 being color-renderable. For GL
1919         // versions less than 3.0 it is provided by GL_ARB_framebuffer_object. However, the original
1920         // version of that extension did not add LUMINANCE8, but was added in a later revsion. So
1921         // even the presence of that extension does not guarantee support. GL 3.0 and higher (core
1922         // or compatibility) do not list LUMINANCE8 as color-renderable (which is strange since the
1923         // GL_ARB_framebuffer_object extension was meant to bring 3.0 functionality to lower
1924         // versions).
1925 
1926         if (lum8Supported) {
1927             info.fColorTypeInfoCount = 1;
1928             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1929             int ctIdx = 0;
1930             // Format: LUMINANCE8, Surface: kGray_8
1931             {
1932                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1933                 ctInfo.fColorType = GrColorType::kGray_8;
1934                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1935                 int idx = static_cast<int>(GrColorType::kGray_8);
1936                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1937                     this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kLUMINANCE8);
1938                 }
1939 
1940                 // External IO ColorTypes:
1941                 ctInfo.fExternalIOFormatCount = 2;
1942                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1943                         ctInfo.fExternalIOFormatCount);
1944                 int ioIdx = 0;
1945                 // Format: LUMINANCE8, Surface: kGray_8, Data: kGray_8
1946                 {
1947                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1948                     ioFormat.fColorType = GrColorType::kGray_8;
1949                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1950                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
1951                     ioFormat.fExternalReadFormat = 0;
1952                 }
1953 
1954                 // Format: LUMINANCE8, Surface: kGray_8, Data: kRGBA_8888
1955                 {
1956                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1957                     ioFormat.fColorType = GrColorType::kRGBA_8888;
1958                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1959                     ioFormat.fExternalTexImageFormat = 0;
1960                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1961                 }
1962             }
1963         }
1964     }
1965 
1966     // Format: LUMINANCE8_ALPHA8
1967     {
1968         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8_ALPHA8);
1969         info.fFormatType = FormatType::kNormalizedFixedPoint;
1970         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8_ALPHA8;
1971         info.fDefaultExternalFormat = GR_GL_LUMINANCE_ALPHA;
1972         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1973         info.fDefaultColorType = GrColorType::kGrayAlpha_88;
1974         if (lum8Supported) {
1975             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1976         }
1977         if (texStorageSupported && lum8SizedFormatSupported) {
1978             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1979             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1980         } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1981             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1982         } else {
1983             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE_ALPHA;
1984         }
1985         // See note in LUMINANCE8 section about not attaching to framebuffers.
1986 
1987         if (lum8Supported) {
1988             info.fColorTypeInfoCount = 1;
1989             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1990             int ctIdx = 0;
1991             // Format: LUMINANCE8_ALPHA8, Surface: kGrayAlpha_88
1992             {
1993                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1994                 ctInfo.fColorType = GrColorType::kGrayAlpha_88;
1995                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1996                 int idx = static_cast<int>(GrColorType::kGrayAlpha_88);
1997                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1998                     this->setColorTypeFormat(GrColorType::kGrayAlpha_88,
1999                                              GrGLFormat::kLUMINANCE8_ALPHA8);
2000                 }
2001 
2002                 // External IO ColorTypes:
2003                 ctInfo.fExternalIOFormatCount = 2;
2004                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2005                         ctInfo.fExternalIOFormatCount);
2006                 int ioIdx = 0;
2007                 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kGrayAlpha_88
2008                 {
2009                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2010                     ioFormat.fColorType = GrColorType::kGrayAlpha_88;
2011                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2012                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE_ALPHA;
2013                     ioFormat.fExternalReadFormat = 0;
2014                 }
2015 
2016                 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kRGBA_8888
2017                 {
2018                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2019                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2020                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2021                     ioFormat.fExternalTexImageFormat = 0;
2022                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2023                 }
2024             }
2025         }
2026     }
2027     // Format: BGRA8
2028     {
2029         FormatInfo& info = this->getFormatInfo(GrGLFormat::kBGRA8);
2030         info.fFormatType = FormatType::kNormalizedFixedPoint;
2031 
2032         info.fDefaultExternalFormat = GR_GL_BGRA;
2033         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2034         info.fDefaultColorType = GrColorType::kBGRA_8888;
2035 
2036         GrGLenum bgraTexImageFormat;
2037         // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2038         // as a base format. Which base format depends on which extension is used.
2039         if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2040             // GL_EXT_texture_format_BGRA8888:
2041             //      This extension adds GL_BGRA as an unsized internal format. However, it is
2042             //      written against ES 2.0 and therefore doesn't define a GL_BGRA8 as ES 2.0 doesn't
2043             //      have sized internal formats. See later where we check for tex storage BGRA8
2044             //      support.
2045             bgraTexImageFormat = GR_GL_BGRA;
2046         } else {
2047             // GL_APPLE_texture_format_BGRA8888:
2048             //     ES 2.0: the extension makes BGRA an external format but not an internal format.
2049             //     ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format
2050             //             for glTexImage (just for glTexStorage).
2051             bgraTexImageFormat = GR_GL_RGBA;
2052         }
2053 
2054         // TexStorage requires using a sized internal format and BGRA8 is only supported if we have
2055         // the GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texture_storage and
2056         // GL_EXT_texture_format_BGRA8888.
2057         bool supportsBGRATexStorage = false;
2058 
2059         if (GR_IS_GR_GL_ES(standard)) {
2060             if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2061                 // The GL_EXT_texture_format_BGRA8888 extension adds BGRA color renderbuffer support
2062                 // for ES 2.0. The extension adds BGRA to the supported renerable formats in table
2063                 // 4.5. In ES 2.0. All the extensions that add multisample support, all reference
2064                 // table 4.5 as the formats that are supported. Thus we can use msaaRenderFlags.
2065                 // Additionally, the renderable support was added in a later revision of the
2066                 // extension. So it is possible for older drivers to support the extension but only
2067                 // an early revision of it without renderable support. We have no way of
2068                 // distinguishing between the two and assume renderable.
2069 
2070 
2071                 info.fFlags = FormatInfo::kTexturable_Flag
2072                             | FormatInfo::kTransfers_Flag;
2073                 // Only enable BGRA msaa if we know we're going through Angle. The spec for
2074                 // GL_EXT_texture_format_BGRA8888 was updated in 2016 to add support for GL_BGRA_EXT
2075                 // as a sized, renderable format. But we may end up running on old drivers written
2076                 // against earlier version of the spec. Also the interactions between all these
2077                 // extensions are very suibtle and it wouldn't be hard for a driver to mess them up.
2078                 // We are confident that Angle does it as we expect. Our non-angle test bots do seem
2079                 // to pass and draw correctly so we could consider enabling this more broadly in the
2080                 // future.
2081                 // In addition, we also need to disable BGRA MSAA on Mesa. When a client attempts
2082                 // to wrap a GPU-backed texture into an SkSurface with MSAA, Ganesh will create
2083                 // a MSAA renderbuffer to first render to before resolving to the single-sampled
2084                 // texture. Mesa claims to support EXT_texture_format_BGRA8888, and according to
2085                 // the spec, this should imply support for both BGRA textures and renderbuffers.
2086                 // In practice, however, Mesa only supports BGRA textures and will error on
2087                 // glRenderbufferStorage* if the internalformat is BGRA.
2088                 if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown &&
2089                     ctxInfo.angleDriver() != GrGLDriver::kMesa) {
2090                     // Angle incorrectly requires GL_BGRA8_EXT for the interalFormat for both ES2
2091                     // and ES3 even though this extension does not define that value. The extension
2092                     // only defines GL_BGRA_EXT as an internal format.
2093                     info.fInternalFormatForRenderbuffer = GR_GL_BGRA8;
2094                     info.fFlags |= msaaRenderFlags;
2095                 } else {
2096                     // It is not clear what the correct format to use on ES3 is. This extension only
2097                     // defines GL_BGRA_EXT. That is definitely the correct thing to use on ES2, but
2098                     // its unclear whether that is valid in ES3 or if it wants something like
2099                     // GL_BGRA8_EXT (which is only defined in the apple extenstion). For now we set
2100                     // everything to use BGRA since its the only explicitly defined value. Until we
2101                     // enable MSAA for non-angle this is a moot point.
2102                     info.fInternalFormatForRenderbuffer = GR_GL_BGRA;
2103                     info.fFlags |= nonMSAARenderFlags;
2104                 }
2105                 // GL_EXT_texture storage has defined interactions with
2106                 // GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but
2107                 // without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format.
2108                 if (ctxInfo.hasExtension("GL_EXT_texture_storage") &&
2109                     !formatWorkarounds.fDisableBGRATextureStorageForIntelWindowsES) {
2110                     supportsBGRATexStorage = true;
2111                 }
2112             } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
2113                 // This APPLE extension introduces complexity on ES2. It leaves the internal format
2114                 // as RGBA, but allows BGRA as the external format. From testing, it appears that
2115                 // the driver remembers the external format when the texture is created (with
2116                 // TexImage). If you then try to upload data in the other swizzle (with
2117                 // TexSubImage), it fails. We could work around this, but it adds even more state
2118                 // tracking to code that is already too tricky. Instead, we opt not to support BGRA
2119                 // on ES2 with this extension. This also side-steps some ambiguous interactions with
2120                 // the texture storage extension.
2121                 if (version >= GR_GL_VER(3,0)) {
2122                     // The APPLE extension doesn't explicitly make this renderable, but
2123                     // internally it appears to use RGBA8, which we'll patch up below.
2124                     info.fFlags = FormatInfo::kTexturable_Flag
2125                                 | FormatInfo::kTransfers_Flag
2126                                 | msaaRenderFlags;
2127                     // The GL_APPLE_texture_format_BGRA8888 does not add support for BGRA color
2128                     // renderbuffers at all so we use RGBA here.
2129                     info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
2130                     supportsBGRATexStorage = true;
2131                 }
2132             }
2133         }
2134         if (texStorageSupported && supportsBGRATexStorage) {
2135             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2136             info.fInternalFormatForTexImageOrStorage = GR_GL_BGRA8;
2137         } else {
2138             info.fInternalFormatForTexImageOrStorage = bgraTexImageFormat;
2139         }
2140 
2141         if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2142             info.fColorTypeInfoCount = 2;
2143             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2144             int ctIdx = 0;
2145             // Format: BGRA8, Surface: kBGRA_8888
2146             {
2147                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2148                 ctInfo.fColorType = GrColorType::kBGRA_8888;
2149                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2150                 this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kBGRA8);
2151 
2152                 // External IO ColorTypes:
2153                 ctInfo.fExternalIOFormatCount = 2;
2154                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2155                         ctInfo.fExternalIOFormatCount);
2156                 int ioIdx = 0;
2157                 // Format: BGRA8, Surface: kBGRA_8888, Data: kBGRA_8888
2158                 {
2159                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2160                     ioFormat.fColorType = GrColorType::kBGRA_8888;
2161                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2162                     ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2163                     ioFormat.fExternalReadFormat = 0;
2164                     ioFormat.fExternalReadFormat =
2165                             formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2166                     // Not guaranteed by ES/WebGL.
2167                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2168                 }
2169 
2170                 // Format: BGRA8, Surface: kBGRA_8888, Data: kRGBA_8888
2171                 {
2172                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2173                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2174                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2175                     ioFormat.fExternalTexImageFormat = 0;
2176                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2177                 }
2178             }
2179 
2180             // Format: BGRA8, Surface: kRGB_888x
2181             {
2182                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2183                 ctInfo.fColorType = GrColorType::kRGB_888x;
2184                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2185                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2186 
2187                 // External IO ColorTypes:
2188                 ctInfo.fExternalIOFormatCount = 1;
2189                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2190                         ctInfo.fExternalIOFormatCount);
2191                 int ioIdx = 0;
2192                 // Format: BGRA8, Surface: kRGB_888x, Data: kRGBA_888x
2193                 {
2194                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2195                     ioFormat.fColorType = GrColorType::kRGB_888x;
2196                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2197                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2198                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2199                 }
2200             }
2201         }
2202     }
2203 
2204     // Format: RGB565
2205     {
2206         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB565);
2207         info.fFormatType = FormatType::kNormalizedFixedPoint;
2208         info.fInternalFormatForRenderbuffer = GR_GL_RGB565;
2209         info.fDefaultExternalFormat = GR_GL_RGB;
2210         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2211         info.fDefaultColorType = GrColorType::kBGR_565;
2212         if (GR_IS_GR_GL(standard)) {
2213             if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
2214                 info.fFlags = FormatInfo::kTexturable_Flag
2215                             | FormatInfo::kTransfers_Flag
2216                             | msaaRenderFlags;
2217             }
2218         } else if (GR_IS_GR_GL_ES(standard)) {
2219             info.fFlags = FormatInfo::kTexturable_Flag
2220                         | FormatInfo::kTransfers_Flag
2221                         | msaaRenderFlags;
2222         } else if (GR_IS_GR_WEBGL(standard)) {
2223             info.fFlags = FormatInfo::kTexturable_Flag
2224                         | FormatInfo::kTransfers_Flag
2225                         | msaaRenderFlags;
2226         }
2227         // 565 is not a sized internal format on desktop GL. So on desktop with
2228         // 565 we always use an unsized internal format to let the system pick
2229         // the best sized format to convert the 565 data to. Since TexStorage
2230         // only allows sized internal formats we disallow it.
2231         //
2232         // TODO: As of 4.2, regular GL supports 565. This logic is due for an
2233         // update.
2234         if (texStorageSupported && GR_IS_GR_GL_ES(standard)) {
2235             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2236             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB565;
2237         } else {
2238             info.fInternalFormatForTexImageOrStorage =
2239                     texImageSupportsSizedInternalFormat ? GR_GL_RGB565 : GR_GL_RGB;
2240         }
2241 
2242         if (SkToBool(info.fFlags &FormatInfo::kTexturable_Flag)) {
2243             info.fColorTypeInfoCount = 1;
2244             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2245             int ctIdx = 0;
2246             // Format: RGB565, Surface: kBGR_565
2247             {
2248                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2249                 ctInfo.fColorType = GrColorType::kBGR_565;
2250                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2251                 this->setColorTypeFormat(GrColorType::kBGR_565, GrGLFormat::kRGB565);
2252 
2253                 // External IO ColorTypes:
2254                 ctInfo.fExternalIOFormatCount = 2;
2255                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2256                         ctInfo.fExternalIOFormatCount);
2257                 int ioIdx = 0;
2258                 // Format: RGB565, Surface: kBGR_565, Data: kBGR_565
2259                 {
2260                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2261                     ioFormat.fColorType = GrColorType::kBGR_565;
2262                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2263                     ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2264                     ioFormat.fExternalReadFormat = GR_GL_RGB;
2265                     // Not guaranteed by ES/WebGL.
2266                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2267                 }
2268 
2269                 // Format: RGB565, Surface: kBGR_565, Data: kRGBA_8888
2270                 {
2271                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2272                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2273                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2274                     ioFormat.fExternalTexImageFormat = 0;
2275                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2276                 }
2277             }
2278         }
2279     }
2280 
2281     // Format: RGBA16F
2282     {
2283         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16F);
2284         info.fFormatType = FormatType::kFloat;
2285         info.fInternalFormatForRenderbuffer = GR_GL_RGBA16F;
2286         info.fDefaultExternalFormat = GR_GL_RGBA;
2287         info.fDefaultExternalType = halfFloatType;
2288         info.fDefaultColorType = GrColorType::kRGBA_F16;
2289         bool rgba16FTextureSupport = false;
2290         bool rgba16FRenderTargetSupport = false;
2291 
2292         if (GR_IS_GR_GL(standard)) {
2293             if (version >= GR_GL_VER(3, 0)) {
2294                 rgba16FTextureSupport = true;
2295                 rgba16FRenderTargetSupport = true;
2296             } else if (ctxInfo.hasExtension("GL_ARB_texture_float")) {
2297                 rgba16FTextureSupport = true;
2298             }
2299         } else if (GR_IS_GR_GL_ES(standard)) {
2300             if (version >= GR_GL_VER(3, 0)) {
2301                 rgba16FTextureSupport = true;
2302                 rgba16FRenderTargetSupport =
2303                         version >= GR_GL_VER(3, 2) ||
2304                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2305                         ctxInfo.hasExtension("GL_EXT_color_buffer_float");
2306             } else if (ctxInfo.hasExtension("GL_OES_texture_half_float") &&
2307                        ctxInfo.hasExtension("GL_OES_texture_half_float_linear")) {
2308                 rgba16FTextureSupport = true;
2309                 rgba16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2310             }
2311         } else if (GR_IS_GR_WEBGL(standard)) {
2312             if (version >= GR_GL_VER(2, 0)) {
2313                 rgba16FTextureSupport = true;
2314                 rgba16FRenderTargetSupport =
2315                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2316                         ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
2317                         ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2318                         ctxInfo.hasExtension("EXT_color_buffer_float");
2319             } else if ((ctxInfo.hasExtension("GL_OES_texture_half_float") ||
2320                         ctxInfo.hasExtension("OES_texture_half_float")) &&
2321                        (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") ||
2322                         ctxInfo.hasExtension("OES_texture_half_float_linear"))) {
2323                 rgba16FTextureSupport = true;
2324                 // We don't check for EXT_color_buffer_float as it's only defined for WebGL 2.
2325                 rgba16FRenderTargetSupport =
2326                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2327                         ctxInfo.hasExtension("EXT_color_buffer_half_float");
2328             }
2329         }
2330 
2331         if (rgba16FTextureSupport) {
2332             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2333             if (rgba16FRenderTargetSupport) {
2334                 info.fFlags |= fpRenderFlags;
2335             }
2336         }
2337         if (texStorageSupported && !formatWorkarounds.fDisableRGBA16FTexStorageForCrBug1008003) {
2338             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2339             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16F;
2340         } else {
2341             info.fInternalFormatForTexImageOrStorage =
2342                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA16F : GR_GL_RGBA;
2343         }
2344 
2345         if (rgba16FTextureSupport) {
2346             uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2347 
2348             info.fColorTypeInfoCount = 3;
2349             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2350             int ctIdx = 0;
2351             // Format: RGBA16F, Surface: kRGBA_F16
2352             {
2353                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2354                 ctInfo.fColorType = GrColorType::kRGBA_F16;
2355                 ctInfo.fFlags = flags;
2356                 this->setColorTypeFormat(GrColorType::kRGBA_F16, GrGLFormat::kRGBA16F);
2357 
2358                 // External IO ColorTypes:
2359                 ctInfo.fExternalIOFormatCount = 2;
2360                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2361                         ctInfo.fExternalIOFormatCount);
2362                 int ioIdx = 0;
2363                 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F16
2364                 {
2365                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2366                     ioFormat.fColorType = GrColorType::kRGBA_F16;
2367                     ioFormat.fExternalType = halfFloatType;
2368                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2369                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2370                     // Not guaranteed by ES/WebGL.
2371                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2372                 }
2373 
2374                 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F32
2375                 {
2376                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2377                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2378                     ioFormat.fExternalType = GR_GL_FLOAT;
2379                     ioFormat.fExternalTexImageFormat = 0;
2380                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2381                 }
2382             }
2383 
2384             // Format: RGBA16F, Surface: kRGBA_F16_Clamped
2385             {
2386                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2387                 ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
2388                 ctInfo.fFlags = flags;
2389                 this->setColorTypeFormat(GrColorType::kRGBA_F16_Clamped, GrGLFormat::kRGBA16F);
2390 
2391                 // External IO ColorTypes:
2392                 ctInfo.fExternalIOFormatCount = 2;
2393                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2394                         ctInfo.fExternalIOFormatCount);
2395                 int ioIdx = 0;
2396                 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F16_Clamped
2397                 {
2398                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2399                     ioFormat.fColorType = GrColorType::kRGBA_F16_Clamped;
2400                     ioFormat.fExternalType = halfFloatType;
2401                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2402                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2403                     // Not guaranteed by ES/WebGL.
2404                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2405                 }
2406 
2407                 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F32
2408                 {
2409                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2410                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2411                     ioFormat.fExternalType = GR_GL_FLOAT;
2412                     ioFormat.fExternalTexImageFormat = 0;
2413                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2414                 }
2415             }
2416             // Format: RGBA16F, Surface: kRGB_F16F16F16x
2417             {
2418                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2419                 ctInfo.fColorType = GrColorType::kRGB_F16F16F16x;
2420                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2421                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2422                 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2423                 this->setColorTypeFormat(GrColorType::kRGB_F16F16F16x, GrGLFormat::kRGBA16F);
2424 
2425                 // External IO ColorTypes:
2426                 ctInfo.fExternalIOFormatCount = 2;
2427                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2428                         ctInfo.fExternalIOFormatCount);
2429                 int ioIdx = 0;
2430                 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGB_F16F16F16x
2431                 {
2432                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2433                     ioFormat.fColorType = GrColorType::kRGB_F16F16F16x;
2434                     ioFormat.fExternalType = halfFloatType;
2435                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2436                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2437                     // Not guaranteed by ES/WebGL.
2438                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2439                 }
2440                 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGBA_F32
2441                 {
2442                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2443                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2444                     ioFormat.fExternalType = GR_GL_FLOAT;
2445                     ioFormat.fExternalTexImageFormat = 0;
2446                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2447                 }
2448             }
2449         }
2450     }
2451 
2452     // Format: R16F
2453     {
2454         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16F);
2455         info.fFormatType = FormatType::kFloat;
2456         info.fInternalFormatForRenderbuffer = GR_GL_R16F;
2457         info.fDefaultExternalFormat = GR_GL_RED;
2458         info.fDefaultExternalType = halfFloatType;
2459         info.fDefaultColorType = GrColorType::kR_F16;
2460         bool r16FTextureSupport = false;
2461         bool r16FRenderTargetSupport = false;
2462 
2463         if (GR_IS_GR_GL(standard)) {
2464             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg")) {
2465                 r16FTextureSupport = true;
2466                 r16FRenderTargetSupport = true;
2467             }
2468         } else if (GR_IS_GR_GL_ES(standard)) {
2469             // It seems possible that a combination of GL_EXT_texture_rg and
2470             // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
2471             // clear. The latter mentions interaction but that may only be for renderbuffers as
2472             // neither adds the texture format explicitly.
2473             // GL_OES_texture_format_half_float makes no reference to RED formats.
2474             if (version >= GR_GL_VER(3, 0)) {
2475                 r16FTextureSupport = true;
2476                 r16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
2477                                           ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2478                                           ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2479             }
2480         } else if (GR_IS_GR_WEBGL(standard)) {
2481             if (version >= GR_GL_VER(2, 0)) {
2482                 r16FTextureSupport = true;
2483                 r16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2484                                           ctxInfo.hasExtension("EXT_color_buffer_float");
2485             }
2486         }
2487 
2488         if (r16FTextureSupport) {
2489             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2490             if (r16FRenderTargetSupport) {
2491                 info.fFlags |= fpRenderFlags;
2492             }
2493         }
2494         if (texStorageSupported) {
2495             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2496             info.fInternalFormatForTexImageOrStorage = GR_GL_R16F;
2497         } else {
2498             info.fInternalFormatForTexImageOrStorage =
2499                     texImageSupportsSizedInternalFormat ? GR_GL_R16F : GR_GL_RED;
2500         }
2501 
2502         if (r16FTextureSupport) {
2503             // Format: R16F, Surface: kAlpha_F16
2504             info.fColorTypeInfoCount = 1;
2505             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2506             int ctIdx = 0;
2507             {
2508                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2509                 ctInfo.fColorType = GrColorType::kAlpha_F16;
2510                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2511                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2512                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
2513                 this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kR16F);
2514 
2515                 // External IO ColorTypes:
2516                 ctInfo.fExternalIOFormatCount = 2;
2517                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2518                         ctInfo.fExternalIOFormatCount);
2519                 int ioIdx = 0;
2520                 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F16
2521                 {
2522                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2523                     ioFormat.fColorType = GrColorType::kAlpha_F16;
2524                     ioFormat.fExternalType = halfFloatType;
2525                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
2526                     ioFormat.fExternalReadFormat = GR_GL_RED;
2527                     // Not guaranteed by ES/WebGL.
2528                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2529                 }
2530 
2531                 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F32xxx
2532                 {
2533                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2534                     ioFormat.fColorType = GrColorType::kAlpha_F32xxx;
2535                     ioFormat.fExternalType = GR_GL_FLOAT;
2536                     ioFormat.fExternalTexImageFormat = 0;
2537                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2538                 }
2539             }
2540         }
2541     }
2542 
2543     // Format: LUMINANCE16F
2544     {
2545         // NOTE: We disallow lum16f on ES devices if linear filtering modes are not
2546         // supported. This is for simplicity, but a more granular approach is possible.
2547         bool lum16FSupported = false;
2548         bool lum16FSizedFormatSupported = false;
2549         GrGLenum lumHalfFloatType = halfFloatType;
2550         if (GR_IS_GR_GL(standard)) {
2551             if (!fIsCoreProfile && ctxInfo.hasExtension("GL_ARB_texture_float")) {
2552                 lum16FSupported = true;
2553                 lum16FSizedFormatSupported = true;
2554             }
2555         } else if (GR_IS_GR_GL_ES(standard)) {
2556             if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
2557                 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
2558                 lum16FSupported = true;
2559                 // Even in ES 3.0+ LUMINANCE and GL_HALF_FLOAT are not listed as a valid
2560                 // combination. Thus we must use GL_HALF_FLOAT_OES provided by the extension
2561                 // GL_OES_texture_half_float. Note: these two types are not defined to be the same
2562                 // value.
2563                 lumHalfFloatType = GR_GL_HALF_FLOAT_OES;
2564                 // Even on ES3 this extension is required to define LUMINANCE16F.
2565                 lum16FSizedFormatSupported = ctxInfo.hasExtension("GL_EXT_texture_storage");
2566             }
2567         } // No WebGL support
2568 
2569         if (formatWorkarounds.fDisableLuminance16F) {
2570             lum16FSupported = false;
2571         }
2572 
2573         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE16F);
2574         info.fFormatType = FormatType::kFloat;
2575         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE16F;
2576         info.fDefaultExternalFormat = GR_GL_LUMINANCE;
2577         info.fDefaultExternalType = lumHalfFloatType;
2578         info.fDefaultColorType = GrColorType::kGray_F16;
2579 
2580         if (lum16FSupported) {
2581             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2582 
2583             if (texStorageSupported && lum16FSizedFormatSupported) {
2584                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2585                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2586             } else if (texImageSupportsSizedInternalFormat && lum16FSizedFormatSupported) {
2587                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2588             } else {
2589                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
2590             }
2591 
2592             info.fColorTypeInfoCount = 1;
2593             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2594             int ctIdx = 0;
2595             // Format: LUMINANCE16F, Surface: kAlpha_F16
2596             {
2597                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2598                 ctInfo.fColorType = GrColorType::kAlpha_F16;
2599                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2600                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2601                 ctInfo.fWriteSwizzle = skgpu::Swizzle("aaa0");
2602 
2603                 int idx = static_cast<int>(GrColorType::kAlpha_F16);
2604                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2605                     this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kLUMINANCE16F);
2606                 }
2607 
2608                 // External IO ColorTypes:
2609                 ctInfo.fExternalIOFormatCount = 2;
2610                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2611                         ctInfo.fExternalIOFormatCount);
2612                 int ioIdx = 0;
2613                 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kAlpha_F16
2614                 {
2615                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2616                     ioFormat.fColorType = GrColorType::kAlpha_F16;
2617                     ioFormat.fExternalType = lumHalfFloatType;
2618                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
2619                     ioFormat.fExternalReadFormat = 0;
2620                 }
2621 
2622                 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kRGBA_F32
2623                 {
2624                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2625                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2626                     ioFormat.fExternalType = GR_GL_FLOAT;
2627                     ioFormat.fExternalTexImageFormat = 0;
2628                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2629                 }
2630             }
2631         }
2632     }
2633 
2634     // Format: RGBx8
2635     {
2636         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBX8);
2637         info.fFormatType = FormatType::kNormalizedFixedPoint;
2638         info.fInternalFormatForRenderbuffer = GR_GL_RGBX8;
2639         info.fDefaultExternalFormat = GR_GL_RGB;
2640         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2641         info.fDefaultColorType = GrColorType::kRGB_888;
2642 
2643         bool supportsSizedRGBX = false;
2644         // The GL_ANGLE_rgbx_internal_format extension only adds the sized GL_RGBX8 type and does
2645         // not have a way to create a texture of that format with texImage using an unsized type. So
2646         // we require that we either have texture storage support or that tex image supports sized
2647         // formats to say that this format is supported.
2648         if (GR_IS_GR_GL_ES(standard) && ctxInfo.hasExtension("GL_ANGLE_rgbx_internal_format") &&
2649             (texStorageSupported || texImageSupportsSizedInternalFormat)) {
2650             supportsSizedRGBX = true;
2651         }
2652 
2653         if (supportsSizedRGBX) {
2654             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBX8;
2655             info.fFlags = FormatInfo::kTexturable_Flag |
2656                           FormatInfo::kTransfers_Flag |
2657                           msaaRenderFlags;
2658             if (texStorageSupported) {
2659                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2660             }
2661             info.fColorTypeInfoCount = 1;
2662             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2663             int ctIdx = 0;
2664             // Format: RGBX8, Surface: kRGB_888x
2665             {
2666                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2667                 ctInfo.fColorType = GrColorType::kRGB_888x;
2668                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2669                 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGBX8);
2670 
2671                 // External IO ColorTypes:
2672                 ctInfo.fExternalIOFormatCount = 2;
2673                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2674                         ctInfo.fExternalIOFormatCount);
2675                 int ioIdx = 0;
2676                 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888
2677                 {
2678                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2679                     ioFormat.fColorType = GrColorType::kRGB_888;
2680                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2681                     ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2682                     ioFormat.fExternalReadFormat = 0;
2683                 }
2684 
2685                 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888x
2686                 {
2687                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2688                     ioFormat.fColorType = GrColorType::kRGB_888x;
2689                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2690                     ioFormat.fExternalTexImageFormat = 0;
2691                     ioFormat.fExternalReadFormat = GR_GL_RGBX8;
2692                 }
2693             }
2694         }
2695     }
2696 
2697     // Format: RGB8
2698     {
2699         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB8);
2700         info.fFormatType = FormatType::kNormalizedFixedPoint;
2701         info.fInternalFormatForRenderbuffer = GR_GL_RGB8;
2702         info.fDefaultExternalFormat = GR_GL_RGB;
2703         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2704         info.fDefaultColorType = GrColorType::kRGB_888;
2705         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2706         if (GR_IS_GR_GL(standard)) {
2707             // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be
2708             // a supported render buffer format. Since we usually use render buffers for MSAA on
2709             // non-ES GL we don't support MSAA for GL_RGB8. On 4.2+ we could check using
2710             // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if
2711             // this becomes an issue.
2712             info.fFlags |= nonMSAARenderFlags;
2713         } else if (GR_IS_GR_GL_ES(standard)) {
2714             // 3.0 and the extension support this as a render buffer format.
2715             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
2716                 info.fFlags |= msaaRenderFlags;
2717             }
2718         } else if (GR_IS_GR_WEBGL(standard)) {
2719             // WebGL seems to support RBG8
2720             info.fFlags |= msaaRenderFlags;
2721         }
2722         if (texStorageSupported) {
2723             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2724             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB8;
2725         } else {
2726             info.fInternalFormatForTexImageOrStorage =
2727                     texImageSupportsSizedInternalFormat ? GR_GL_RGB8 : GR_GL_RGB;
2728         }
2729 
2730         info.fColorTypeInfoCount = 1;
2731         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2732         int ctIdx = 0;
2733         // Format: RGB8, Surface: kRGB_888x
2734         {
2735             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2736             ctInfo.fColorType = GrColorType::kRGB_888x;
2737             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2738 
2739             int idx = static_cast<int>(GrColorType::kRGB_888x);
2740             if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2741                 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGB8);
2742             }
2743 
2744             // External IO ColorTypes:
2745             ctInfo.fExternalIOFormatCount = 2;
2746             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2747                     ctInfo.fExternalIOFormatCount);
2748             int ioIdx = 0;
2749             // Format: RGB8, Surface: kRGB_888x, Data: kRGB_888
2750             {
2751                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2752                 ioFormat.fColorType = GrColorType::kRGB_888;
2753                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2754                 ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2755                 ioFormat.fExternalReadFormat = 0;
2756             }
2757 
2758             // Format: RGB8, Surface: kRGB_888x, Data: kRGBA_8888
2759             {
2760                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2761                 ioFormat.fColorType = GrColorType::kRGBA_8888;
2762                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2763                 ioFormat.fExternalTexImageFormat = 0;
2764                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2765             }
2766         }
2767     }
2768 
2769     // Format: RG8
2770     {
2771         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG8);
2772         info.fFormatType = FormatType::kNormalizedFixedPoint;
2773         info.fInternalFormatForRenderbuffer = GR_GL_RG8;
2774         info.fDefaultExternalFormat = GR_GL_RG;
2775         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2776         info.fDefaultColorType = GrColorType::kRG_88;
2777         bool rg8Support = false;
2778         if (GR_IS_GR_GL(standard)) {
2779             rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
2780         } else if (GR_IS_GR_GL_ES(standard)) {
2781             rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
2782         } else if (GR_IS_GR_WEBGL(standard)) {
2783             rg8Support = version >= GR_GL_VER(2, 0);
2784         }
2785         if (rg8Support) {
2786             info.fFlags |= FormatInfo::kTexturable_Flag
2787                         |  FormatInfo::kTransfers_Flag
2788                         |  msaaRenderFlags;
2789             if (texStorageSupported) {
2790                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2791                 info.fInternalFormatForTexImageOrStorage = GR_GL_RG8;
2792             }
2793         }
2794         if (!(info.fFlags & FormatInfo::kUseTexStorage_Flag)) {
2795             info.fInternalFormatForTexImageOrStorage =
2796                     texImageSupportsSizedInternalFormat ? GR_GL_RG8 : GR_GL_RG;
2797         }
2798         if (rg8Support) {
2799             info.fColorTypeInfoCount = 1;
2800             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2801             int ctIdx = 0;
2802             // Format: RG8, Surface: kRG_88
2803             {
2804                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2805                 ctInfo.fColorType = GrColorType::kRG_88;
2806                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2807                 this->setColorTypeFormat(GrColorType::kRG_88, GrGLFormat::kRG8);
2808 
2809                 // External IO ColorTypes:
2810                 ctInfo.fExternalIOFormatCount = 2;
2811                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2812                         ctInfo.fExternalIOFormatCount);
2813                 int ioIdx = 0;
2814                 // Format: RG8, Surface: kRG_88, Data: kRG_88
2815                 {
2816                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2817                     ioFormat.fColorType = GrColorType::kRG_88;
2818                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2819                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
2820                     ioFormat.fExternalReadFormat = 0;
2821                     if (GR_IS_GR_GL(standard) && !formatWorkarounds.fDisallowDirectRG8ReadPixels) {
2822                         ioFormat.fExternalReadFormat = GR_GL_RG;
2823                     }
2824                 }
2825 
2826                 // Format: RG8, Surface: kRG_88, Data: kRGBA_8888
2827                 {
2828                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2829                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2830                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2831                     ioFormat.fExternalTexImageFormat = 0;
2832                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2833                 }
2834             }
2835         }
2836     }
2837 
2838     // Format: RGB10_A2
2839     {
2840         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB10_A2);
2841         info.fFormatType = FormatType::kNormalizedFixedPoint;
2842         info.fInternalFormatForRenderbuffer = GR_GL_RGB10_A2;
2843         info.fDefaultExternalFormat = GR_GL_RGBA;
2844         info.fDefaultExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2845         info.fDefaultColorType = GrColorType::kRGBA_1010102;
2846         if (GR_IS_GR_GL(standard) ||
2847            (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
2848             info.fFlags = FormatInfo::kTexturable_Flag
2849                         | FormatInfo::kTransfers_Flag
2850                         | msaaRenderFlags;
2851         } else if (GR_IS_GR_GL_ES(standard) &&
2852                    ctxInfo.hasExtension("GL_EXT_texture_type_2_10_10_10_REV")) {
2853             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2854         } // No WebGL support
2855 
2856         if (texStorageSupported) {
2857             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2858             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB10_A2;
2859         } else {
2860             info.fInternalFormatForTexImageOrStorage =
2861                     texImageSupportsSizedInternalFormat ? GR_GL_RGB10_A2 : GR_GL_RGBA;
2862         }
2863 
2864         if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2865             bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
2866                     (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
2867 
2868             info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
2869             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2870             int ctIdx = 0;
2871             // Format: RGB10_A2, Surface: kRGBA_1010102
2872             {
2873                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2874                 ctInfo.fColorType = GrColorType::kRGBA_1010102;
2875                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2876                 this->setColorTypeFormat(GrColorType::kRGBA_1010102, GrGLFormat::kRGB10_A2);
2877 
2878                 // External IO ColorTypes:
2879                 ctInfo.fExternalIOFormatCount = 2;
2880                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2881                         ctInfo.fExternalIOFormatCount);
2882                 int ioIdx = 0;
2883                 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_1010102
2884                 {
2885                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2886                     ioFormat.fColorType = GrColorType::kRGBA_1010102;
2887                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2888                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2889                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2890                     // Not guaranteed by ES/WebGL.
2891                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2892                 }
2893 
2894                 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_8888
2895                 {
2896                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2897                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2898                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2899                     ioFormat.fExternalTexImageFormat = 0;
2900                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2901                 }
2902             }
2903             //------------------------------------------------------------------
2904             // Format: RGB10_A2, Surface: kBGRA_1010102
2905             if (supportsBGRAColorType) {
2906                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2907                 ctInfo.fColorType = GrColorType::kBGRA_1010102;
2908                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2909                 this->setColorTypeFormat(GrColorType::kBGRA_1010102, GrGLFormat::kRGB10_A2);
2910 
2911                 // External IO ColorTypes:
2912                 ctInfo.fExternalIOFormatCount = 2;
2913                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2914                         ctInfo.fExternalIOFormatCount);
2915                 int ioIdx = 0;
2916                 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kBGRA_1010102
2917                 {
2918                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2919                     ioFormat.fColorType = GrColorType::kBGRA_1010102;
2920                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2921                     ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2922                     ioFormat.fExternalReadFormat =
2923                             formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2924                     // Not guaranteed by ES/WebGL.
2925                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2926                 }
2927 
2928                 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kRGBA_8888
2929                 {
2930                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2931                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2932                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2933                     ioFormat.fExternalTexImageFormat = 0;
2934                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2935                 }
2936             }
2937             // Format: RGB10_A2, Surface: kRGB_101010x
2938             {
2939                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2940                 ctInfo.fColorType = GrColorType::kRGB_101010x;
2941                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2942                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2943                 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2944                 this->setColorTypeFormat(GrColorType::kRGB_101010x, GrGLFormat::kRGB10_A2);
2945 
2946                 // External IO ColorTypes:
2947                 ctInfo.fExternalIOFormatCount = 2;
2948                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2949                         ctInfo.fExternalIOFormatCount);
2950                 int ioIdx = 0;
2951                 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGB_101010x
2952                 {
2953                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2954                     ioFormat.fColorType = GrColorType::kRGB_101010x;
2955                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2956                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2957                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2958                     // Not guaranteed by ES/WebGL.
2959                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2960                 }
2961                 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGBA_8888
2962                 {
2963                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2964                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2965                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2966                     ioFormat.fExternalTexImageFormat = 0;
2967                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2968                 }
2969             }
2970 
2971         }
2972     }
2973 
2974     // Format: RGBA4
2975     {
2976         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA4);
2977         info.fFormatType = FormatType::kNormalizedFixedPoint;
2978         info.fInternalFormatForRenderbuffer = GR_GL_RGBA4;
2979         info.fDefaultExternalFormat = GR_GL_RGBA;
2980         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
2981         info.fDefaultColorType = GrColorType::kABGR_4444;
2982         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2983         if (GR_IS_GR_GL(standard)) {
2984             if (version >= GR_GL_VER(4, 2)) {
2985                 info.fFlags |= msaaRenderFlags;
2986             }
2987         } else if (GR_IS_GR_GL_ES(standard)) {
2988             info.fFlags |= msaaRenderFlags;
2989         } else if (GR_IS_GR_WEBGL(standard)) {
2990             info.fFlags |= msaaRenderFlags;
2991         }
2992         if (texStorageSupported) {
2993             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2994             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA4;
2995         } else {
2996             info.fInternalFormatForTexImageOrStorage =
2997                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA4 : GR_GL_RGBA;
2998         }
2999 
3000         info.fColorTypeInfoCount = 1;
3001         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3002         int ctIdx = 0;
3003         // Format: RGBA4, Surface: kABGR_4444
3004         {
3005             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3006             ctInfo.fColorType = GrColorType::kABGR_4444;
3007             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3008             this->setColorTypeFormat(GrColorType::kABGR_4444, GrGLFormat::kRGBA4);
3009 
3010             // External IO ColorTypes:
3011             ctInfo.fExternalIOFormatCount = 2;
3012             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3013                     ctInfo.fExternalIOFormatCount);
3014             int ioIdx = 0;
3015             // Format: RGBA4, Surface: kABGR_4444, Data: kABGR_4444
3016             {
3017                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3018                 ioFormat.fColorType = GrColorType::kABGR_4444;
3019                 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
3020                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3021                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3022                 // Not guaranteed by ES/WebGL.
3023                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3024             }
3025 
3026             // Format: RGBA4, Surface: kABGR_4444, Data: kRGBA_8888
3027             {
3028                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3029                 ioFormat.fColorType = GrColorType::kRGBA_8888;
3030                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3031                 ioFormat.fExternalTexImageFormat = 0;
3032                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3033             }
3034         }
3035     }
3036 
3037     // Format: SRGB8_ALPHA8
3038     {
3039         FormatInfo& info = this->getFormatInfo(GrGLFormat::kSRGB8_ALPHA8);
3040         info.fFormatType = FormatType::kNormalizedFixedPoint;
3041         info.fInternalFormatForRenderbuffer = GR_GL_SRGB8_ALPHA8;
3042         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
3043         info.fDefaultColorType = GrColorType::kRGBA_8888_SRGB;
3044 
3045         // We may modify the default external format below.
3046         info.fDefaultExternalFormat = GR_GL_RGBA;
3047         bool srgb8Alpha8TexStorageSupported = texStorageSupported;
3048         bool srgb8Alpha8TextureSupport = false;
3049         bool srgb8Alpha8RenderTargetSupport = false;
3050         if (GR_IS_GR_GL(standard)) {
3051             if (version >= GR_GL_VER(3, 0)) {
3052                 srgb8Alpha8TextureSupport = true;
3053                 srgb8Alpha8RenderTargetSupport = true;
3054             } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
3055                 srgb8Alpha8TextureSupport = true;
3056                 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
3057                     ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
3058                     srgb8Alpha8RenderTargetSupport = true;
3059                 }
3060             }
3061         } else if (GR_IS_GR_GL_ES(standard)) {
3062             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_sRGB")) {
3063                 srgb8Alpha8TextureSupport = true;
3064                 srgb8Alpha8RenderTargetSupport = true;
3065             }
3066             if (version < GR_GL_VER(3, 0)) {
3067                 // ES 2.0 requires that the external format matches the internal format.
3068                 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3069                 // There is no defined interaction between GL_EXT_sRGB and GL_EXT_texture_storage.
3070                 srgb8Alpha8TexStorageSupported = false;
3071             }
3072         } else if (GR_IS_GR_WEBGL(standard)) {
3073             // sRGB extension should be on most WebGL 1.0 contexts, although sometimes under 2
3074             // names.
3075             if (version >= GR_GL_VER(2, 0) || ctxInfo.hasExtension("GL_EXT_sRGB") ||
3076                 ctxInfo.hasExtension("EXT_sRGB")) {
3077                 srgb8Alpha8TextureSupport = true;
3078                 srgb8Alpha8RenderTargetSupport = true;
3079             }
3080             if (version < GR_GL_VER(2, 0)) {
3081                 // WebGL 1.0 requires that the external format matches the internal format.
3082                 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3083                 // There is no extension to WebGL 1 that adds glTexStorage.
3084                 SkASSERT(!srgb8Alpha8TexStorageSupported);
3085             }
3086         }
3087 
3088         if (srgb8Alpha8TextureSupport) {
3089             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3090             if (srgb8Alpha8RenderTargetSupport) {
3091                 info.fFlags |= formatWorkarounds.fDisableSRGBRenderWithMSAAForMacAMD
3092                                        ? nonMSAARenderFlags
3093                                        : msaaRenderFlags;
3094             }
3095         }
3096         if (srgb8Alpha8TexStorageSupported) {
3097             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3098             info.fInternalFormatForTexImageOrStorage = GR_GL_SRGB8_ALPHA8;
3099         } else {
3100             info.fInternalFormatForTexImageOrStorage =
3101                     texImageSupportsSizedInternalFormat ? GR_GL_SRGB8_ALPHA8 : GR_GL_SRGB_ALPHA;
3102         }
3103 
3104         if (srgb8Alpha8TextureSupport) {
3105             info.fColorTypeInfoCount = 1;
3106             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3107             int ctIdx = 0;
3108             // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB
3109             {
3110                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3111                 ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
3112                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3113                 this->setColorTypeFormat(GrColorType::kRGBA_8888_SRGB, GrGLFormat::kSRGB8_ALPHA8);
3114 
3115                 // External IO ColorTypes:
3116                 ctInfo.fExternalIOFormatCount = 1;
3117                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3118                         ctInfo.fExternalIOFormatCount);
3119                 int ioIdx = 0;
3120 
3121                 // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB, Data: kRGBA_8888_SRGB
3122                 {
3123                     // GL does not do srgb<->rgb conversions when transferring between cpu and gpu.
3124                     // Thus, the external format is GL_RGBA. See below for note about ES2.0 and
3125                     // glTex[Sub]Image.
3126                     GrGLenum texImageExternalFormat = GR_GL_RGBA;
3127 
3128                     // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the
3129                     // <format> param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and
3130                     // <format> params to match. Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the
3131                     // <format> param. On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the
3132                     // <format> param to glTexImage.
3133                     if (GR_IS_GR_GL_ES(standard) && version == GR_GL_VER(2,0)) {
3134                         texImageExternalFormat = GR_GL_SRGB_ALPHA;
3135                     }
3136                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3137                     ioFormat.fColorType = GrColorType::kRGBA_8888_SRGB;
3138                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3139                     ioFormat.fExternalTexImageFormat = texImageExternalFormat;
3140                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3141                 }
3142             }
3143         }
3144     }
3145 
3146     // Format: COMPRESSED_RGB8_BC1
3147     {
3148         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_BC1);
3149         info.fFormatType = FormatType::kNormalizedFixedPoint;
3150         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
3151         if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3152             if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3153                 info.fFlags = FormatInfo::kTexturable_Flag;
3154             }
3155         } else if (GR_IS_GR_WEBGL(standard)) {
3156             if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3157                 info.fFlags = FormatInfo::kTexturable_Flag;
3158             }
3159         }
3160 
3161         // There are no support GrColorTypes for this format
3162     }
3163 
3164     // Format: COMPRESSED_RGBA8_BC1
3165     {
3166         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGBA8_BC1);
3167         info.fFormatType = FormatType::kNormalizedFixedPoint;
3168         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3169         if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3170             if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3171                 info.fFlags = FormatInfo::kTexturable_Flag;
3172             }
3173         } else if (GR_IS_GR_WEBGL(standard)) {
3174             if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3175                 info.fFlags = FormatInfo::kTexturable_Flag;
3176             }
3177         }
3178 
3179         // There are no support GrColorTypes for this format
3180     }
3181 
3182     // Format: COMPRESSED_RGB8_ETC2
3183     {
3184         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_ETC2);
3185         info.fFormatType = FormatType::kNormalizedFixedPoint;
3186         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB8_ETC2;
3187         if (!formatWorkarounds.fDisallowETC2Compression) {
3188             if (GR_IS_GR_GL(standard)) {
3189                 if (version >= GR_GL_VER(4, 3) ||
3190                     ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
3191                     info.fFlags = FormatInfo::kTexturable_Flag;
3192                 }
3193             } else if (GR_IS_GR_GL_ES(standard)) {
3194                 if (version >= GR_GL_VER(3, 0) ||
3195                     ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture")) {
3196                     info.fFlags = FormatInfo::kTexturable_Flag;
3197                 }
3198             } else if (GR_IS_GR_WEBGL(standard)) {
3199                 if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc")) {
3200                     info.fFlags = FormatInfo::kTexturable_Flag;
3201                 }
3202             }
3203         }
3204 
3205         // There are no support GrColorTypes for this format
3206     }
3207 
3208     // Format: COMPRESSED_ETC1_RGB8
3209     {
3210         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ETC1_RGB8);
3211         info.fFormatType = FormatType::kNormalizedFixedPoint;
3212         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_ETC1_RGB8;
3213         if (GR_IS_GR_GL_ES(standard)) {
3214             if (ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
3215                 info.fFlags = FormatInfo::kTexturable_Flag;
3216             }
3217         } else if (GR_IS_GR_WEBGL(standard)) {
3218             if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc1")) {
3219                 info.fFlags = FormatInfo::kTexturable_Flag;
3220             }
3221         }
3222         // No GL support
3223 
3224         // There are no support GrColorTypes for this format
3225     }
3226 
3227     // Format: R16
3228     {
3229         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16);
3230         info.fFormatType = FormatType::kNormalizedFixedPoint;
3231         info.fInternalFormatForRenderbuffer = GR_GL_R16;
3232         info.fDefaultExternalFormat = GR_GL_RED;
3233         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3234         info.fDefaultColorType = GrColorType::kR_16;
3235         bool r16Supported = false;
3236         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3237             if (GR_IS_GR_GL(standard)) {
3238                 r16Supported = version >= GR_GL_VER(3, 0) ||
3239                                ctxInfo.hasExtension("GL_ARB_texture_rg");
3240             } else if (GR_IS_GR_GL_ES(standard)) {
3241                 r16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3242             }  // No WebGL support
3243         }
3244 
3245         if (r16Supported) {
3246             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3247             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3248                 info.fFlags |= FormatInfo::kTransfers_Flag;
3249             }
3250         }
3251 
3252         if (texStorageSupported) {
3253             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3254             info.fInternalFormatForTexImageOrStorage = GR_GL_R16;
3255         } else {
3256             info.fInternalFormatForTexImageOrStorage =
3257                     texImageSupportsSizedInternalFormat ? GR_GL_R16 : GR_GL_RED;
3258         }
3259 
3260         if (r16Supported) {
3261             info.fColorTypeInfoCount = 1;
3262             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3263             int ctIdx = 0;
3264             // Format: R16, Surface: kAlpha_16
3265             {
3266                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3267                 ctInfo.fColorType = GrColorType::kAlpha_16;
3268                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3269                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
3270                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
3271                 this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
3272 
3273                 // External IO ColorTypes:
3274                 ctInfo.fExternalIOFormatCount = 2;
3275                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3276                         ctInfo.fExternalIOFormatCount);
3277                 int ioIdx = 0;
3278                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_16
3279                 {
3280                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3281                     ioFormat.fColorType = GrColorType::kAlpha_16;
3282                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3283                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
3284                     ioFormat.fExternalReadFormat = GR_GL_RED;
3285                     // Not guaranteed by ES/WebGL.
3286                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3287                 }
3288 
3289                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
3290                 {
3291                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3292                     ioFormat.fColorType = GrColorType::kAlpha_8xxx;
3293                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3294                     ioFormat.fExternalTexImageFormat = 0;
3295                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3296                 }
3297             }
3298         }
3299     }
3300 
3301     // Format: RG16
3302     {
3303         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16);
3304         info.fFormatType = FormatType::kNormalizedFixedPoint;
3305         info.fInternalFormatForTexImageOrStorage =
3306                 texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3307         info.fInternalFormatForRenderbuffer = GR_GL_RG16;
3308         info.fDefaultExternalFormat = GR_GL_RG;
3309         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3310         info.fDefaultColorType = GrColorType::kRG_1616;
3311         bool rg16Supported = false;
3312         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3313             if (GR_IS_GR_GL(standard)) {
3314                 rg16Supported = version >= GR_GL_VER(3, 0) ||
3315                                 ctxInfo.hasExtension("GL_ARB_texture_rg");
3316             } else if (GR_IS_GR_GL_ES(standard)) {
3317                 rg16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3318             }  // No WebGL support
3319         }
3320 
3321         if (rg16Supported) {
3322             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3323             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3324                 info.fFlags |= FormatInfo::kTransfers_Flag;
3325             }
3326         }
3327 
3328         if (texStorageSupported) {
3329             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3330             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16;
3331         } else {
3332             info.fInternalFormatForTexImageOrStorage =
3333                     texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3334         }
3335 
3336         if (rg16Supported) {
3337             info.fColorTypeInfoCount = 1;
3338             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3339             int ctIdx = 0;
3340             // Format: GR_GL_RG16, Surface: kRG_1616
3341             {
3342                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3343                 ctInfo.fColorType = GrColorType::kRG_1616;
3344                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3345                 this->setColorTypeFormat(GrColorType::kRG_1616, GrGLFormat::kRG16);
3346 
3347                 // External IO ColorTypes:
3348                 ctInfo.fExternalIOFormatCount = 2;
3349                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3350                         ctInfo.fExternalIOFormatCount);
3351                 int ioIdx = 0;
3352                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRG_1616
3353                 {
3354                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3355                     ioFormat.fColorType = GrColorType::kRG_1616;
3356                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3357                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3358                     ioFormat.fExternalReadFormat = GR_GL_RG;
3359                     // Not guaranteed by ES/WebGL.
3360                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3361                 }
3362 
3363                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRGBA_8888
3364                 {
3365                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3366                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3367                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3368                     ioFormat.fExternalTexImageFormat = 0;
3369                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3370                 }
3371             }
3372         }
3373     }
3374 
3375     // Format: RGBA16
3376     {
3377         bool rgba16Support = false;
3378         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3379             if (GR_IS_GR_GL(standard)) {
3380                 rgba16Support = version >= GR_GL_VER(3, 0);
3381             } else if (GR_IS_GR_GL_ES(standard)) {
3382                 rgba16Support = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3383             }  // No WebGL support
3384         }
3385 
3386         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16);
3387         info.fFormatType = FormatType::kNormalizedFixedPoint;
3388 
3389         info.fInternalFormatForRenderbuffer = GR_GL_RGBA16;
3390         info.fDefaultExternalFormat = GR_GL_RGBA;
3391         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3392         info.fDefaultColorType = GrColorType::kRGBA_16161616;
3393         if (rgba16Support) {
3394             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3395             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3396                 info.fFlags |= FormatInfo::kTransfers_Flag;
3397             }
3398         }
3399 
3400         if (texStorageSupported) {
3401             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3402             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16;
3403         } else {
3404             info.fInternalFormatForTexImageOrStorage =
3405                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA16 : GR_GL_RGBA;
3406         }
3407 
3408         if (rgba16Support) {
3409             // Format: GR_GL_RGBA16, Surface: kRGBA_16161616
3410             info.fColorTypeInfoCount = 1;
3411             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3412             int ctIdx = 0;
3413             {
3414                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3415                 ctInfo.fColorType = GrColorType::kRGBA_16161616;
3416                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3417                 this->setColorTypeFormat(GrColorType::kRGBA_16161616, GrGLFormat::kRGBA16);
3418 
3419                 // External IO ColorTypes:
3420                 ctInfo.fExternalIOFormatCount = 2;
3421                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3422                         ctInfo.fExternalIOFormatCount);
3423                 int ioIdx = 0;
3424                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_16161616
3425                 {
3426                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3427                     ioFormat.fColorType = GrColorType::kRGBA_16161616;
3428                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3429                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3430                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3431                     // Not guaranteed by ES/WebGL.
3432                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3433                 }
3434 
3435                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_8888
3436                 {
3437                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3438                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3439                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3440                     ioFormat.fExternalTexImageFormat = 0;
3441                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3442                 }
3443             }
3444         }
3445     }
3446 
3447     // Format:RG16F
3448     {
3449         bool rg16FTextureSupport = false;
3450         bool rg16FRenderTargetSupport = false;
3451         if (GR_IS_GR_GL(standard)) {
3452             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
3453                 rg16FTextureSupport = true;
3454                 rg16FRenderTargetSupport = true;
3455             }
3456         } else if (GR_IS_GR_GL_ES(standard)) {
3457             // It seems possible that a combination of GL_EXT_texture_rg and
3458             // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
3459             // clear. The latter mentions interaction but that may only be for renderbuffers as
3460             // neither adds the texture format explicitly.
3461             // GL_OES_texture_format_half_float makes no reference to RG formats.
3462             if (version >= GR_GL_VER(3, 0)) {
3463                 rg16FTextureSupport = true;
3464                 rg16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
3465                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3466                                            ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
3467             }
3468         } else if (GR_IS_GR_WEBGL(standard)) {
3469             if (version >= GR_GL_VER(2, 0)) {
3470                 rg16FTextureSupport = true;
3471                 rg16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
3472                                            ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
3473                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3474                                            ctxInfo.hasExtension("EXT_color_buffer_float");
3475             }
3476         }
3477 
3478         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16F);
3479         info.fFormatType = FormatType::kFloat;
3480         info.fInternalFormatForRenderbuffer = GR_GL_RG16F;
3481         info.fDefaultExternalFormat = GR_GL_RG;
3482         info.fDefaultExternalType = halfFloatType;
3483         info.fDefaultColorType = GrColorType::kRG_F16;
3484         if (rg16FTextureSupport) {
3485             info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3486             if (rg16FRenderTargetSupport) {
3487                 info.fFlags |= fpRenderFlags;
3488             }
3489         }
3490 
3491         if (texStorageSupported) {
3492             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3493             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16F;
3494         } else {
3495             info.fInternalFormatForTexImageOrStorage =
3496                     texImageSupportsSizedInternalFormat ? GR_GL_RG16F : GR_GL_RG;
3497         }
3498 
3499         if (rg16FTextureSupport) {
3500             info.fColorTypeInfoCount = 1;
3501             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3502             int ctIdx = 0;
3503             // Format: GR_GL_RG16F, Surface: kRG_F16
3504             {
3505                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3506                 ctInfo.fColorType = GrColorType::kRG_F16;
3507                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3508                 this->setColorTypeFormat(GrColorType::kRG_F16, GrGLFormat::kRG16F);
3509 
3510                 // External IO ColorTypes:
3511                 ctInfo.fExternalIOFormatCount = 2;
3512                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3513                         ctInfo.fExternalIOFormatCount);
3514                 int ioIdx = 0;
3515                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRG_F16
3516                 {
3517                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3518                     ioFormat.fColorType = GrColorType::kRG_F16;
3519                     ioFormat.fExternalType = halfFloatType;
3520                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3521                     ioFormat.fExternalReadFormat = GR_GL_RG;
3522                     // Not guaranteed by ES/WebGL.
3523                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3524                 }
3525 
3526                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRGBA_F32
3527                 {
3528                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3529                     ioFormat.fColorType = GrColorType::kRGBA_F32;
3530                     ioFormat.fExternalType = GR_GL_FLOAT;
3531                     ioFormat.fExternalTexImageFormat = 0;
3532                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3533                 }
3534             }
3535         }
3536     }
3537 
3538     this->setupSampleCounts(ctxInfo, gli);
3539 
3540 #ifdef SK_DEBUG
3541     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3542         if (GrGLFormat::kUnknown == static_cast<GrGLFormat>(i)) {
3543             continue;
3544         }
3545         const auto& formatInfo = fFormatTable[i];
3546         // Make sure we didn't set fbo attachable with msaa and not fbo attachable.
3547         SkASSERT(!((formatInfo.fFlags & FormatInfo::kFBOColorAttachmentWithMSAA_Flag) &&
3548                   !(formatInfo.fFlags & FormatInfo::kFBOColorAttachment_Flag)));
3549 
3550         // Make sure we set all the formats' FormatType
3551         SkASSERT(formatInfo.fFormatType != FormatType::kUnknown);
3552 
3553         // Make sure if we added a ColorTypeInfo we filled it out
3554         for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
3555             const auto& ctInfo = formatInfo.fColorTypeInfos[j];
3556             SkASSERT(ctInfo.fColorType != GrColorType::kUnknown);
3557             // Seems silly to add a color type if we don't support any flags on it.
3558             SkASSERT(ctInfo.fFlags);
3559             // Make sure if we added any ExternalIOFormats we filled it out
3560             for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
3561                 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
3562                 SkASSERT(ioInfo.fColorType != GrColorType::kUnknown);
3563             }
3564         }
3565     }
3566 #endif
3567 }
3568 
setupSampleCounts(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)3569 void GrGLCaps::setupSampleCounts(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
3570     GrGLStandard standard = ctxInfo.standard();
3571     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
3572     sk_ignore_unused_variable(standard);
3573     GrGLVersion version = ctxInfo.version();
3574 
3575     int maxSampleCnt = 1;
3576     if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
3577         GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
3578     } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
3579         GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
3580     }
3581     // Chrome has a mock GL implementation that returns 0.
3582     maxSampleCnt = std::max(1, maxSampleCnt);
3583 
3584     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3585         if (FormatInfo::kFBOColorAttachmentWithMSAA_Flag & fFormatTable[i].fFlags) {
3586             // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
3587             SkASSERT(FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags);
3588             SkASSERT(GrGLCaps::kNone_MSFBOType != fMSFBOType);
3589             if ((GR_IS_GR_GL(standard) &&
3590                   (version >= GR_GL_VER(4,2) ||
3591                    ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
3592                 (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0))) {
3593                 // Implicite resolve may have a lower max samples than the per format MSAA.
3594                 const bool multisampleIsImplicit =
3595                         GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
3596                         GrGLCaps::kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
3597                 int count;
3598                 GrGLFormat grGLFormat = static_cast<GrGLFormat>(i);
3599                 GrGLenum glFormat = this->getRenderbufferInternalFormat(grGLFormat);
3600                 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat,
3601                                           GR_GL_NUM_SAMPLE_COUNTS, 1, &count);
3602                 if (count) {
3603                     std::unique_ptr<int[]> temp(new int[count]);
3604                     GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_SAMPLES,
3605                                               count, temp.get());
3606                     // GL has a concept of MSAA rasterization with a single sample but we do not.
3607                     if (count && temp[count - 1] == 1) {
3608                         --count;
3609                         SkASSERT(!count || temp[count -1] > 1);
3610                     }
3611                     fFormatTable[i].fColorSampleCounts.reserve(count + 1);
3612                     // We initialize our supported values with 1 (no msaa) and reverse the order
3613                     // returned by GL so that the array is ascending.
3614                     fFormatTable[i].fColorSampleCounts.push_back(1);
3615                     for (int j = 0; j < count; ++j) {
3616 #if defined(SK_BUILD_FOR_IOS) && TARGET_OS_SIMULATOR
3617                         // The iOS simulator is reporting incorrect values for sample counts,
3618                         // so force them to be a power of 2.
3619                         int sampleCnt = SkPrevPow2(temp[count - j - 1]);
3620 #else
3621                         int sampleCnt = temp[count - j - 1];
3622 #endif
3623                         if (multisampleIsImplicit && sampleCnt > maxSampleCnt) {
3624                             break;
3625                         }
3626                         fFormatTable[i].fColorSampleCounts.push_back(sampleCnt);
3627                     }
3628                 }
3629             } else {
3630                 // Fake out the table using some semi-standard counts up to the max allowed sample
3631                 // count.
3632                 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
3633                 int count = std::size(kDefaultSamples);
3634                 for (; count > 0; --count) {
3635                     if (kDefaultSamples[count - 1] <= maxSampleCnt) {
3636                         break;
3637                     }
3638                 }
3639                 if (count > 0) {
3640                     fFormatTable[i].fColorSampleCounts.append(count, kDefaultSamples);
3641                 }
3642             }
3643         } else if (FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags) {
3644             fFormatTable[i].fColorSampleCounts.resize(1);
3645             fFormatTable[i].fColorSampleCounts[0] = 1;
3646         }
3647     }
3648 }
3649 
canCopyTexSubImage(GrGLFormat dstFormat,bool dstHasMSAARenderBuffer,const GrTextureType * dstTypeIfTexture,GrGLFormat srcFormat,bool srcHasMSAARenderBuffer,const GrTextureType * srcTypeIfTexture) const3650 bool GrGLCaps::canCopyTexSubImage(GrGLFormat dstFormat, bool dstHasMSAARenderBuffer,
3651                                   const GrTextureType* dstTypeIfTexture,
3652                                   GrGLFormat srcFormat, bool srcHasMSAARenderBuffer,
3653                                   const GrTextureType* srcTypeIfTexture) const {
3654     // When it comes to format types and component sizes the gl spec is fairly complex as
3655     // requirements differ depending on many properties (e.g. if the internalFormat was created with
3656     // a sized format or not). These affect the rules about which format types can be copied to
3657     // which other types. For now we are being more restrictive and requiring that the types must
3658     // match exactly.
3659     if (this->getFormatDefaultExternalType(dstFormat) !=
3660         this->getFormatDefaultExternalType(srcFormat)) {
3661         return false;
3662     }
3663 
3664     // Either both the src and dst formats need to be SRGB or both need to not be SRGB
3665     if (GrGLFormatIsSRGB(dstFormat) != GrGLFormatIsSRGB(srcFormat)) {
3666         return false;
3667     }
3668 
3669     if (GR_IS_GR_GL_ES(fStandard)) {
3670         // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3671         // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it.
3672         // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3673         // avoids bugs with using glBlitFramebuffer.
3674         if ((dstFormat == GrGLFormat::kBGRA8 || srcFormat == GrGLFormat::kBGRA8) &&
3675             !fAllowBGRA8CopyTexSubImage) {
3676             return false;
3677         }
3678 
3679         // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3680         // and SRGB isn't in the spec. There doesn't appear to be any extension that adds it.
3681         // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3682         // avoids bugs with using glBlitFramebuffer.
3683         if ((GrGLFormatIsSRGB(dstFormat) || GrGLFormatIsSRGB(srcFormat)) &&
3684             !fAllowSRGBCopyTexSubImage) {
3685             return false;
3686         }
3687 
3688         // Table 3.9 of the ES2 spec and 3.16 of ES3 spec indicates the supported internal base
3689         // formats with CopyTexSubImage. Each base format can be copied to itself or formats with
3690         // less channels.
3691         uint32_t dstChannels = GrGLFormatChannels(dstFormat);
3692         uint32_t srcChannels = GrGLFormatChannels(srcFormat);
3693         if (!dstChannels || !srcChannels) {
3694             // The formats don't represent color channels (i.e. may be depth stencil)
3695             return false;
3696         }
3697         // The dst channels have to be a subset of the srcChannels, except R, RG, or RGB, channels
3698         // can go to LUM. (See expansion of Table 3.9 in EXT_texture_rg).
3699         if ((dstChannels & srcChannels) != srcChannels) {
3700             if (dstChannels == kGray_SkColorChannelFlag ||
3701                 dstChannels == kGrayAlpha_SkColorChannelFlags) {
3702                 // The dst can't have gray if the src is alpha-only.
3703                 if (srcChannels == kAlpha_SkColorChannelFlag) {
3704                     return false;
3705                 }
3706             } else {
3707                 return false;
3708             }
3709         }
3710     }
3711 
3712     // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
3713     if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
3714         return false;
3715     }
3716 
3717     // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
3718     // texture.
3719     if (!dstTypeIfTexture) {
3720         return false;
3721     }
3722 
3723     // Check that we could wrap the source in an FBO, that the dst is not TEXTURE_EXTERNAL, that no
3724     // mirroring is required
3725     return this->canFormatBeFBOColorAttachment(srcFormat) &&
3726            (!srcTypeIfTexture || *srcTypeIfTexture != GrTextureType::kExternal) &&
3727            *dstTypeIfTexture != GrTextureType::kExternal;
3728 }
3729 
canCopyAsBlit(GrGLFormat dstFormat,int dstSampleCnt,const GrTextureType * dstTypeIfTexture,GrGLFormat srcFormat,int srcSampleCnt,const GrTextureType * srcTypeIfTexture,const SkRect & srcBounds,bool srcBoundsExact,const SkIRect & srcRect,const SkIRect & dstRect) const3730 bool GrGLCaps::canCopyAsBlit(GrGLFormat dstFormat, int dstSampleCnt,
3731                              const GrTextureType* dstTypeIfTexture,
3732                              GrGLFormat srcFormat, int srcSampleCnt,
3733                              const GrTextureType* srcTypeIfTexture,
3734                              const SkRect& srcBounds, bool srcBoundsExact,
3735                              const SkIRect& srcRect, const SkIRect& dstRect) const {
3736     auto blitFramebufferFlags = fBlitFramebufferFlags;
3737     if (!this->canFormatBeFBOColorAttachment(dstFormat) ||
3738         !this->canFormatBeFBOColorAttachment(srcFormat)) {
3739         return false;
3740     }
3741 
3742     if (dstTypeIfTexture && *dstTypeIfTexture == GrTextureType::kExternal) {
3743         return false;
3744     }
3745     if (srcTypeIfTexture && *srcTypeIfTexture == GrTextureType::kExternal) {
3746         return false;
3747     }
3748 
3749     if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3750         return false;
3751     }
3752 
3753     if (dstSampleCnt > 1 && dstSampleCnt != srcSampleCnt) {
3754         // Regardless of support-level, all blits require src and dst sample counts to match if
3755         // the dst is MSAA.
3756         return false;
3757     }
3758 
3759     if (srcRect.width() != dstRect.width() || srcRect.height() != dstRect.height()) {
3760         // If the blit would scale contents, it's only valid for non-MSAA framebuffers that we
3761         // can write directly to.
3762         if ((GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) ||
3763             this->useDrawInsteadOfAllRenderTargetWrites() || srcSampleCnt > 1) {
3764             return false;
3765         }
3766     }
3767 
3768     if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3769         if (srcSampleCnt > 1) {
3770             if (1 == dstSampleCnt) {
3771                 return false;
3772             }
3773             if (SkRect::Make(srcRect) != srcBounds || !srcBoundsExact) {
3774                 return false;
3775             }
3776         }
3777     }
3778 
3779     if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3780         if (dstSampleCnt > 1) {
3781             return false;
3782         }
3783     }
3784 
3785     if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3786         if (srcFormat != dstFormat) {
3787             return false;
3788         }
3789     } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3790         if (srcSampleCnt > 1 && srcFormat != dstFormat) {
3791             return false;
3792         }
3793     }
3794 
3795     if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3796         if (srcSampleCnt > 1) {
3797             if (dstRect != srcRect) {
3798                 return false;
3799             }
3800         }
3801     }
3802     return true;
3803 }
3804 
canCopyAsDraw(GrGLFormat dstFormat,bool srcIsTexturable,bool scalingCopy) const3805 bool GrGLCaps::canCopyAsDraw(GrGLFormat dstFormat, bool srcIsTexturable, bool scalingCopy) const {
3806     return this->isFormatRenderable(dstFormat, 1) &&
3807            srcIsTexturable &&
3808            !(fDisableScalingCopyAsDraws && scalingCopy);
3809 }
3810 
has_msaa_render_buffer(const GrSurfaceProxy * surf,const GrGLCaps & glCaps)3811 static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
3812     const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
3813     if (!rt) {
3814         return false;
3815     }
3816     // A RT has a separate MSAA renderbuffer if:
3817     // 1) It's multisampled
3818     // 2) We're using an extension with separate MSAA renderbuffers
3819     // 3) It's not FBO 0, which is special and always auto-resolves
3820     return rt->numSamples() > 1 &&
3821            glCaps.usesMSAARenderBuffers() &&
3822            !rt->glRTFBOIDIs0();
3823 }
3824 
onCanCopySurface(const GrSurfaceProxy * dst,const SkIRect & dstRect,const GrSurfaceProxy * src,const SkIRect & srcRect) const3825 bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
3826                                 const GrSurfaceProxy* src, const SkIRect& srcRect) const {
3827     if (src->isProtected() == GrProtected::kYes && dst->isProtected() != GrProtected::kYes) {
3828         return false;
3829     }
3830 
3831     int dstSampleCnt = 0;
3832     int srcSampleCnt = 0;
3833     if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
3834         dstSampleCnt = rtProxy->numSamples();
3835     }
3836     if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
3837         srcSampleCnt = rtProxy->numSamples();
3838     }
3839     SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
3840     SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
3841 
3842     const GrTextureProxy* dstTex = dst->asTextureProxy();
3843     const GrTextureProxy* srcTex = src->asTextureProxy();
3844 
3845     GrTextureType dstTexType;
3846     GrTextureType* dstTexTypePtr = nullptr;
3847     GrTextureType srcTexType;
3848     GrTextureType* srcTexTypePtr = nullptr;
3849     if (dstTex) {
3850         dstTexType = dstTex->textureType();
3851         dstTexTypePtr = &dstTexType;
3852     }
3853     if (srcTex) {
3854         srcTexType = srcTex->textureType();
3855         srcTexTypePtr = &srcTexType;
3856     }
3857 
3858     auto dstFormat = GrBackendFormats::AsGLFormat(dst->backendFormat());
3859     auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3860     // Only copyAsBlit() and copyAsDraw() can handle scaling between src and dst.
3861     const bool scalingCopy = srcRect.size() != dstRect.size();
3862     if (!scalingCopy &&
3863         this->canCopyTexSubImage(dstFormat, has_msaa_render_buffer(dst, *this), dstTexTypePtr,
3864                                  srcFormat, has_msaa_render_buffer(src, *this), srcTexTypePtr)) {
3865         return true;
3866     }
3867     return this->canCopyAsBlit(dstFormat, dstSampleCnt, dstTexTypePtr, srcFormat, srcSampleCnt,
3868                                srcTexTypePtr, src->getBoundsRect(), src->priv().isExact(), srcRect,
3869                                dstRect) ||
3870            this->canCopyAsDraw(dstFormat, SkToBool(srcTex), scalingCopy);
3871 }
3872 
getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType colorType) const3873 GrCaps::DstCopyRestrictions GrGLCaps::getDstCopyRestrictions(const GrRenderTargetProxy* src,
3874                                                              GrColorType colorType) const {
3875     // If the src is a texture, we can implement the blit as a draw assuming the config is
3876     // renderable.
3877     if (src->asTextureProxy() && !this->isFormatAsColorTypeRenderable(colorType,
3878                                                                       src->backendFormat())) {
3879         return {};
3880     }
3881 
3882     if (const auto* texProxy = src->asTextureProxy()) {
3883         if (texProxy->textureType() == GrTextureType::kExternal) {
3884             // Not supported for FBO blit or CopyTexSubImage. Caller will have to fall back to a
3885             // draw (if the source is also a texture).
3886             return {};
3887         }
3888     }
3889 
3890     // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
3891     // possible and we return false to fallback to creating a render target dst for render-to-
3892     // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
3893     // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
3894     DstCopyRestrictions blitFramebufferRestrictions = {};
3895     if (src->numSamples() > 1 &&
3896         (fBlitFramebufferFlags & kResolveMustBeFull_BlitFrambufferFlag)) {
3897         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3898         blitFramebufferRestrictions.fMustCopyWholeSrc = true;
3899         // Mirroring causes rects to mismatch later, don't allow it.
3900     } else if (src->numSamples() > 1 && (fBlitFramebufferFlags &
3901                                          kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
3902         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3903     }
3904 
3905     auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3906     // Check for format issues with glCopyTexSubImage2D
3907     if (srcFormat == GrGLFormat::kBGRA8) {
3908         // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
3909         // then we set up for that, otherwise fail.
3910         if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3911             return blitFramebufferRestrictions;
3912         }
3913         // Caller will have to use a draw.
3914         return {};
3915     }
3916 
3917     {
3918         bool srcIsMSAARenderbuffer = src->numSamples() > 1 &&
3919                                      this->usesMSAARenderBuffers();
3920         if (srcIsMSAARenderbuffer) {
3921             // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
3922             // blit or fail.
3923             if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3924                 return blitFramebufferRestrictions;
3925             }
3926             // Caller will have to use a draw.
3927             return {};
3928         }
3929     }
3930 
3931     // We'll do a CopyTexSubImage, no restrictions.
3932     return {};
3933 }
3934 
applyDriverCorrectnessWorkarounds(const GrGLContextInfo & ctxInfo,const GrContextOptions & contextOptions,const GrGLInterface * glInterface,GrShaderCaps * shaderCaps,FormatWorkarounds * formatWorkarounds)3935 void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
3936                                                  const GrContextOptions& contextOptions,
3937                                                  const GrGLInterface* glInterface,
3938                                                  GrShaderCaps* shaderCaps,
3939                                                  FormatWorkarounds* formatWorkarounds) {
3940     // A driver bug on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
3941     // Thus we are disabling this extension for now on Adreno4xx devices.
3942     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
3943         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
3944         fDriverBugWorkarounds.disable_discard_framebuffer) {
3945         fInvalidateFBType = kNone_InvalidateFBType;
3946     }
3947 
3948     if (ctxInfo.renderer() == GrGLRenderer::kIntelCherryView) {
3949         // When running DMSAA_dst_read_with_existing_barrier with DMSAA disabled on linux Intel
3950         // HD405, the test fails when using texture barriers. Oddly the gpu doing the draw which
3951         // uses the barrier correctly. It is the next draw, which does not use or need a barrier,
3952         // that is blending with a dst as if the barrier draw didn't happen. Since this GPU is not
3953         // that important to us and this driver bug could probably manifest itself in the wild, we
3954         // are just disabling texture barrier support for the gpu.
3955         fTextureBarrierSupport = false;
3956     }
3957 
3958     // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
3959     // 340.96 and 367.57.
3960     if (GR_IS_GR_GL(ctxInfo.standard()) && ctxInfo.driver() == GrGLDriver::kNVIDIA &&
3961         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
3962         fClearTextureSupport = false;
3963     }
3964 
3965     // glBlitFramebuffer seems to produce incorrect results on QC, Mali400, and Tegra3 but
3966     // glCopyTexSubImage2D works (even though there is no extension that specifically allows it).
3967     if (ctxInfo.vendor()   == GrGLVendor::kQualcomm  ||
3968         ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
3969         ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3970         fAllowBGRA8CopyTexSubImage = true;
3971     }
3972     // glCopyTexSubImage2D works for sRGB with GLES 3.0 and on some GPUs with GLES 2.0
3973     if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
3974         ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
3975         ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3976         fAllowSRGBCopyTexSubImage = true;
3977     }
3978 
3979     // http://anglebug.com/6030
3980     if (fMSFBOType == kES_EXT_MsToTexture_MSFBOType &&
3981         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
3982         // As GL_EXT_multisampled_render_to_texture supporting issue,
3983         // fall back to default dmsaa path
3984         if ((ctxInfo.vendor()  == GrGLVendor::kIntel ||
3985              ctxInfo.angleVendor() == GrGLVendor::kIntel) &&
3986              ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake) {
3987             fMSFBOType = kStandard_MSFBOType;
3988             fMSAAResolvesAutomatically = false;
3989         }
3990         else {
3991             fDisallowDynamicMSAA = true;
3992         }
3993     }
3994 
3995     // http://skbug.com/12081
3996     if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
3997         fDisallowDynamicMSAA = true;
3998     }
3999 
4000     // Below we are aggressive about turning off all mapping/transfer functionality together. This
4001     // could be finer grained if code paths and tests were adjusted to check more specific caps.
4002     // For example it might be possible to support buffer to buffer transfers even if buffer mapping
4003     // or buffer to surface transfers don't work.
4004 #if defined(__has_feature)
4005 #if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
4006     // See skbug.com/7058
4007     fMapBufferType = kNone_MapBufferType;
4008     fMapBufferFlags = kNone_MapFlags;
4009     fTransferFromBufferToTextureSupport = false;
4010     fTransferFromSurfaceToBufferSupport = false;
4011     fTransferFromBufferToBufferSupport  = false;
4012     fTransferBufferType = TransferBufferType::kNone;
4013 #endif
4014 #endif
4015 
4016     // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
4017     // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
4018     // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
4019     // unclear whether this really affects a wide range of devices.
4020     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4021         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
4022         fMapBufferType = kNone_MapBufferType;
4023         fMapBufferFlags = kNone_MapFlags;
4024         fTransferFromBufferToTextureSupport = false;
4025         fTransferFromSurfaceToBufferSupport = false;
4026         fTransferFromBufferToBufferSupport  = false;
4027         fTransferBufferType = TransferBufferType::kNone;
4028     }
4029 
4030     // The TransferPixelsToTexture test fails on ANGLE D3D9 and D3D11 if this is enabled.
4031     // https://anglebug.com/5542
4032     if (angle_backend_is_d3d(ctxInfo.angleBackend())) {
4033         fTransferPixelsToRowBytesSupport = false;
4034     }
4035 
4036     // Using MIPs on this GPU seems to be a source of trouble.
4037     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4038         fMipmapSupport = false;
4039     }
4040 
4041 #ifdef SK_BUILD_FOR_ANDROID
4042     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4043         // Flutter found glTexSubImage2D for GL_RED is much slower than GL_ALPHA on the
4044         // "MC18 PERSONAL SHOPPER"
4045         formatWorkarounds->fDisallowR8ForPowerVRSGX54x = true;
4046     }
4047 #endif
4048 
4049     // Reported on skia-discuss as occurring with these GL strings:
4050     // GL_VERSION:  3.1.0 - Build 9.17.10.4459
4051     // GL_VENDOR:   Intel
4052     // GL_RENDERER: Intel(R) HD Graphics 2000
4053     // https://groups.google.com/g/skia-discuss/c/dYV1blEAda0/m/-zuZLXQKAwAJ?utm_medium=email&utm_source=footer
4054     // See also http://skbug.com/9286
4055     if (ctxInfo.renderer() == GrGLRenderer::kIntelSandyBridge &&
4056         ctxInfo.driver() == GrGLDriver::kIntel) {
4057         fMapBufferType  = kNone_MapBufferType;
4058         fMapBufferFlags = kNone_MapFlags;
4059         // On skia-discuss it was reported that after turning off mapping there was this
4060         // shader compilation error.
4061         // ERROR: 0:18: 'assign' :  cannot convert from '3-component vector of float' to 'varying 2-component vector of float'
4062         // for this line:
4063         // vTransformedCoords_5_S0 = mat3x2(umatrix_S1_c0_c1) * vec3(_tmp_2_inPosition, 1.0);
4064         fShaderCaps->fNonsquareMatrixSupport = false;
4065     }
4066 
4067     if (ctxInfo.isOverCommandBuffer() && ctxInfo.version() >= GR_GL_VER(3,0)) {
4068         formatWorkarounds->fDisallowTextureUnorm16 = true;  // http://crbug.com/1224108
4069         formatWorkarounds->fDisallowETC2Compression = true;  // http://crbug.com/1224111
4070         fTransferFromSurfaceToBufferSupport = false;  // http://crbug.com/1224138
4071 
4072         // http://crbug.com/1224117
4073         fMapBufferFlags = kNone_MapFlags;
4074         fMapBufferType = kNone_MapBufferType;
4075     }
4076 
4077     // https://b.corp.google.com/issues/143074513
4078     // https://skbug.com/11152
4079     if (ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4080         ctxInfo.renderer() == GrGLRenderer::kAdreno620) {
4081         fMSFBOType = kNone_MSFBOType;
4082         fMSAAResolvesAutomatically = false;
4083     }
4084 
4085 #ifndef SK_BUILD_FOR_IOS
4086     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x   ||
4087         ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue ||
4088         (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx && !ctxInfo.isOverCommandBuffer())) {
4089         fPerformColorClearsAsDraws = true;
4090     }
4091 #endif
4092 
4093     // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
4094     if (ctxInfo.renderer() == GrGLRenderer::kAMDRadeonHD7xxx ||
4095         ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M4xx) {
4096         fPerformColorClearsAsDraws = true;
4097     }
4098 
4099 #ifdef SK_BUILD_FOR_MAC
4100     // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
4101     // full screen clears
4102     // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
4103     // perform full screen clears.
4104     // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
4105     // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
4106     // crbug.com/1039912 - Crash rate in glClear spiked after OS update, affecting mostly
4107     //   Broadwell on 10.13+
4108     if (ctxInfo.vendor() == GrGLVendor::kIntel &&
4109         (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12) ||
4110          ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell)) {
4111         fPerformColorClearsAsDraws = true;
4112     }
4113     // crbug.com/969609 - NVIDIA on Mac sometimes segfaults during glClear in chrome. It seems
4114     // mostly concentrated in 10.13/14, GT 650Ms, driver 12+. But there are instances of older
4115     // drivers and GTX 775s, so we'll start with a broader workaround.
4116     if (ctxInfo.vendor() == GrGLVendor::kNVIDIA) {
4117         fPerformColorClearsAsDraws = true;
4118     }
4119 #endif
4120 
4121     // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
4122     // bugs seems to involve clearing too much and not skipping the clear.
4123     // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
4124     // but only for D3D11 ANGLE.
4125     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4126         fPerformColorClearsAsDraws = true;
4127     }
4128 
4129     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4130         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4131         // This is known to be fixed sometime between driver 145.0 and 219.0
4132         if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
4133             fPerformStencilClearsAsDraws = true;
4134         }
4135         // This is known to be fixed sometime between driver 129.0 and 145.0 on Nexus 6P.
4136         // On driver 129 on Android M it fails the unit tests called WritePixelsPendingIO without
4137         // the workaround. It passes on Android N with driver 145 without the workaround.
4138         // skbug.com/11834
4139         if (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(145, 0, 0)) {
4140             fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4141         }
4142     }
4143 
4144     if (fDriverBugWorkarounds.gl_clear_broken) {
4145         fPerformColorClearsAsDraws = true;
4146         fPerformStencilClearsAsDraws = true;
4147     }
4148 
4149     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4150         // It appears that all the Adreno GPUs have less than optimal performance when
4151         // drawing w/ large index buffers.
4152         fAvoidLargeIndexBufferDraws = true;
4153     }
4154 
4155     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
4156         (ctxInfo.renderer() == GrGLRenderer::kWebGL &&
4157          ctxInfo.webglRenderer() == GrGLRenderer::kMali4xx)) {
4158         // Perspective SDF text runs significantly slower on Mali-4xx hardware
4159         fDisablePerspectiveSDFText = true;
4160     }
4161 
4162     // This was reproduced on the following configurations:
4163     // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
4164     // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
4165     // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
4166     // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
4167     // and not produced on:
4168     // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
4169     // The particular lines that get dropped from test images varies across different devices.
4170     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4171         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
4172         fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
4173     }
4174 
4175     // TODO: Don't apply this on iOS?
4176     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4177         // Our Chromebook with GrGLRenderer::kPowerVRRogue crashes on large instanced draws. The
4178         // current minimum number of instances observed to crash is somewhere between 2^14 and 2^15.
4179         // Keep the number of instances below 1000, just to be safe.
4180         fMaxInstancesPerDrawWithoutCrashing = 999;
4181     } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
4182         fMaxInstancesPerDrawWithoutCrashing = 0x4000000;
4183     }
4184 
4185 #ifndef SK_BUILD_FOR_IOS
4186     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4187         // We saw this bug on a TecnoSpark 3 Pro with a PowerVR GE8300.
4188         // GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4189         // Possibly this could be more limited by driver version or HW generation.
4190         // When using samplers, we are seeing a bug where the gpu is sometimes not sampling the
4191         // correct mip level data. A workaround to this issue is that when binding a texture we also
4192         // set some texture state, and it seems like any inividual state works (e.g. min/mag filter,
4193         // base level, max level, etc.). Currently we just set the min filter level every time we
4194         // bind a texture as the workaround.
4195         fMustSetAnyTexParameterToEnableMipmapping = true;
4196         // ColorTypeBackendAllocationTest failed for kAlpha_8 and kGray_8 when using
4197         // GL_UNPACK_ROW_LENGTH. Perhaps this could be a more limited workaround by applying
4198         // only to single channel 8 bit unorm formats but we only have a monolithic query for this
4199         // support at present.
4200         fWritePixelsRowBytesSupport = false;
4201         // TransferPixelsToTextureTest fails for all color types on
4202         // TecnoSpark 3 Pro with a PowerVR GE8300, GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4203         // if GL_UNPACK_ROW_LENGTH is used.
4204         fTransferPixelsToRowBytesSupport = false;
4205     }
4206 #endif
4207 
4208     // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
4209     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4210         fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4211         fUseDrawInsteadOfAllRenderTargetWrites = true;
4212     }
4213 
4214 #ifdef SK_BUILD_FOR_MAC
4215     static constexpr bool isMAC = true;
4216 #else
4217     static constexpr bool isMAC = false;
4218 #endif
4219 
4220 #ifdef SK_BUILD_FOR_ANDROID
4221     // Older versions of Android have problems with setting GL_TEXTURE_BASE_LEVEL or
4222     // GL_TEXTURE_MAX_LEVEL on GL_TEXTURE_EXTERTNAL_OES textures. We just leave them as is and hope
4223     // the client never changes them either.
4224     fDontSetBaseOrMaxLevelForExternalTextures = true;
4225     // PowerVR can crash setting the levels on Android up to Q for any texture?
4226     // https://crbug.com/1123874
4227     if (ctxInfo.vendor() == GrGLVendor::kImagination) {
4228         fMipmapLevelControlSupport =  false;
4229     }
4230 #endif
4231 
4232     // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
4233     // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
4234     // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
4235     // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
4236     if (fMipmapLevelControlSupport &&
4237         !ctxInfo.isOverCommandBuffer() &&  // http://crbug.com/1224110
4238         (contextOptions.fDoManualMipmapping                 ||
4239          ctxInfo.vendor()  == GrGLVendor::kIntel            ||
4240          (ctxInfo.driver() == GrGLDriver::kNVIDIA && isMAC) ||
4241          ctxInfo.vendor()  == GrGLVendor::kATI)) {
4242         fDoManualMipmapping = true;
4243     }
4244 
4245     // See http://crbug.com/710443
4246 #ifdef SK_BUILD_FOR_MAC
4247     if (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell) {
4248         fClearToBoundaryValuesIsBroken = true;
4249     }
4250 #endif
4251     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4252         fDrawArraysBaseVertexIsBroken = true;
4253     }
4254 
4255     // b/40043081, b/40045491: indirect draws in ANGLE + D3D are very slow
4256     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 ||
4257         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4258         fBaseVertexBaseInstanceSupport = false;
4259         fNativeDrawIndirectSupport = false;
4260         fMultiDrawType = MultiDrawType::kNone;
4261     }
4262 
4263     // https://b.corp.google.com/issues/188410972
4264     if (ctxInfo.isRunningOverVirgl()) {
4265         fDrawInstancedSupport = false;
4266     }
4267 
4268     // http://anglebug.com/4538
4269     if (fBaseVertexBaseInstanceSupport && !fDrawInstancedSupport) {
4270         fBaseVertexBaseInstanceSupport = false;
4271         fNativeDrawIndirectSupport = false;
4272         fMultiDrawType = MultiDrawType::kNone;
4273     }
4274 
4275     // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
4276     // Galaxy S7.
4277     // TODO: Once this is fixed we can update the check here to look at a driver version number too.
4278     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4279         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other) {
4280         shaderCaps->fFBFetchSupport = false;
4281     }
4282 
4283     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4284         // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
4285         // so we must do the abs first in a separate expression.
4286         shaderCaps->fCanUseMinAndAbsTogether = false;
4287 
4288         // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
4289         // must avoid this condition.
4290         shaderCaps->fCanUseFractForNegativeValues = false;
4291     }
4292 
4293     // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
4294     // thus must us -1.0 * %s.x to work correctly
4295     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4296         shaderCaps->fMustForceNegatedAtanParamToFloat = true;
4297     }
4298 
4299 #if defined(SK_BUILD_FOR_MAC)
4300     if (ctxInfo.vendor() == GrGLVendor::kATI) {
4301         // The Radeon GLSL compiler on Mac gets confused by ldexp(..., -x).
4302         // Convert to ldexp(..., x * -1).
4303         // http://skbug.com/12076
4304         shaderCaps->fMustForceNegatedLdexpParamToMultiply = true;
4305     }
4306 #endif
4307 
4308     // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
4309     // when floor and abs are called on the same line. Thus we must execute an Op between them to
4310     // make sure the compiler doesn't re-inline them even if we break the calls apart.
4311     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4312         shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
4313     }
4314 
4315     // On Adreno devices with framebuffer fetch support, there is a bug where they always return
4316     // the original dst color when reading the outColor even after being written to. By using a
4317     // local outColor we can work around this bug.
4318     if (shaderCaps->fFBFetchSupport && ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4319         shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
4320     }
4321 
4322     // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
4323     // color, and that uniform contains an opaque color, and the output of the shader is only based
4324     // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
4325     // that the shader always outputs opaque values. In that case, it appears to remove the shader
4326     // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
4327     // insert an extra bit of math on the uniform that confuses the compiler just enough...
4328     if (ctxInfo.renderer() == GrGLRenderer::kMaliT) {
4329         shaderCaps->fMustObfuscateUniformColor = true;
4330     }
4331 
4332 #if defined(SK_BUILD_FOR_ANDROID)
4333     // On the following GPUs, the Perlin noise code needs to aggressively snap to multiples
4334     // of 1/255 to avoid artifacts in the double table lookup:
4335     //    Tegra3, PowerVRGE8320 (Wembley), MaliG76, and Adreno308
4336     // Given the range of vendors we're just blanket enabling it on Android for OpenGL.
4337     fShaderCaps->fPerlinNoiseRoundingFix = true;
4338 #endif
4339 
4340     // On Mali 400 there is a bug using dFd* in the x direction. So we avoid using it when possible.
4341     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx) {
4342         fShaderCaps->fAvoidDfDxForGradientsWhenPossible = true;
4343     }
4344 
4345 #ifdef SK_BUILD_FOR_WIN
4346     // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
4347     //
4348     // Basically, if a shader has a construct like:
4349     //
4350     // float x = someCondition ? someValue : 0;
4351     // float2 result = (0 == x) ? float2(x, x)
4352     //                          : float2(2 * x / x, 0);
4353     //
4354     // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
4355     // we've explicitly guarded the division with a check against zero. This manifests in much
4356     // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
4357     // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
4358     if (angle_backend_is_d3d(ctxInfo.angleBackend()) || ctxInfo.isOverCommandBuffer()) {
4359         shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
4360     }
4361 #endif
4362 
4363     // The Adreno 5xx and 6xx produce incorrect results when comparing a pair of matrices.
4364     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4365         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4366         ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4367         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4368         ctxInfo.renderer() == GrGLRenderer::kAdreno630 ||
4369         ctxInfo.renderer() == GrGLRenderer::kAdreno640 ||
4370         ctxInfo.renderer() == GrGLRenderer::kAdreno6xx_other) {
4371         shaderCaps->fRewriteMatrixComparisons = true;
4372     }
4373 
4374     // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
4375     // (rare) situations. It's sporadic, and mostly on older drivers. Additionally, old Adreno
4376     // compilers (see crbug.com/skia/4078) crash when accessing .zw of gl_FragCoord, so just bypass
4377     // using gl_FragCoord at all to get around it.
4378     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4379         shaderCaps->fCanUseFragCoord = false;
4380     }
4381 
4382     // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
4383     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4384         shaderCaps->fCanUseFragCoord = false;
4385     }
4386 
4387     if (fDriverBugWorkarounds.add_and_true_to_loop_condition) {
4388         shaderCaps->fAddAndTrueToLoopCondition = true;
4389     }
4390 
4391     if (fDriverBugWorkarounds.unfold_short_circuit_as_ternary_operation) {
4392         shaderCaps->fUnfoldShortCircuitAsTernary = true;
4393     }
4394 
4395     if (fDriverBugWorkarounds.emulate_abs_int_function) {
4396         shaderCaps->fEmulateAbsIntFunction = true;
4397     }
4398 
4399     if (fDriverBugWorkarounds.rewrite_do_while_loops) {
4400         shaderCaps->fRewriteDoWhileLoops = true;
4401     }
4402 
4403     if (fDriverBugWorkarounds.remove_pow_with_constant_exponent) {
4404         shaderCaps->fRemovePowWithConstantExponent = true;
4405     }
4406 
4407     if (fDriverBugWorkarounds.disable_dual_source_blending_support) {
4408         shaderCaps->fDualSourceBlendingSupport = false;
4409     }
4410 
4411     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4412         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4413         shaderCaps->fMustWriteToFragColor = true;
4414     }
4415 
4416     // Disabling advanced blend on various platforms with major known issues. We also block Chrome
4417     // command buffer for now until its own denylists can be updated.
4418     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
4419         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
4420         ctxInfo.renderer() == GrGLRenderer::kAdreno530       ||
4421         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4422         ctxInfo.driver()   == GrGLDriver::kIntel             ||
4423         ctxInfo.angleVendor() == GrGLVendor::kIntel          ||
4424         ctxInfo.isOverCommandBuffer()                        ||
4425         ctxInfo.vendor()   == GrGLVendor::kARM /* http://skbug.com/11906 */) {
4426         fBlendEquationSupport = kBasic_BlendEquationSupport;
4427         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4428     }
4429 
4430     // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
4431     if (((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4432           ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0)) ||
4433          (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4434           ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4435           ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(337, 00, 0))) &&
4436         kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
4437         fBlendEquationSupport = kBasic_BlendEquationSupport;
4438         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4439     }
4440 
4441     if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
4442         fBlendEquationSupport = kBasic_BlendEquationSupport;
4443         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4444     }
4445 
4446     if (this->advancedBlendEquationSupport()) {
4447         if ((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4448              ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) ||
4449             (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4450              ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4451              ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(355, 00, 0))) {
4452             // Disable color-dodge and color-burn on pre-355.00 NVIDIA.
4453             fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorDodge)) |
4454                                        (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4455         }
4456         if (ctxInfo.vendor() == GrGLVendor::kARM) {
4457             // Disable color-burn on ARM until the fix is released.
4458             fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4459         }
4460     }
4461 
4462     // On Adreno 5xx devices, there is a bug where we first draw using dual source blending. Thus
4463     // the dst blend func references the dst. Then the next draw we disable blending. However, on
4464     // the second draw the driver has a bug where it tries to access the second color output again.
4465     // This is fixed by reseting the blend function to anything that does not reference src2 when we
4466     // disable blending.
4467     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4468         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4469         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4470         ctxInfo.renderer() == GrGLRenderer::kAdreno640) {
4471         fMustResetBlendFuncBetweenDualSourceAndDisable = true;
4472     }
4473 
4474     // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
4475     // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
4476     // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
4477     // skbug.com/7713
4478     if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
4479         ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330 &&
4480         !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
4481         shaderCaps->fExternalTextureSupport = true;
4482         shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
4483         shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
4484     }
4485 
4486 #ifdef SK_BUILD_FOR_IOS
4487     // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
4488     // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
4489     // is to just disable the feature.
4490     // https://github.com/flutter/flutter/issues/16718
4491     // https://bugreport.apple.com/web/?problemID=39948888
4492     fWritePixelsRowBytesSupport = false;
4493     // This affects all iOS devices for transfering from a PBO as well (presumably the issue is in
4494     // the GL->Metal layer).
4495     fTransferPixelsToRowBytesSupport = false;
4496 #endif
4497 
4498     if (ctxInfo.vendor()   == GrGLVendor::kIntel       ||  // IntelIris640 drops draws completely.
4499         ctxInfo.webglVendor() == GrGLVendor::kIntel    ||  // Disable if the webgl vendor is Intel
4500         ctxInfo.renderer() == GrGLRenderer::kMaliT     ||  // Some curves appear flat on GalaxyS6.
4501         ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4502         ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4503         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||  // We get garbage on Adreno405.
4504         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {  // D3D9 conic strokes fail.
4505         fDisableTessellationPathRenderer = true;
4506     }
4507     // We found that on Wembley devices (PowerVR GE8320) that using tessellation path renderer would
4508     // cause lots of rendering errors where it seemed like vertices were in the wrong place. This
4509     // led to lots of GMs drawing nothing (e.g. dashing4) or lots of garbage. The Wembley devices
4510     // were running Android 12 with a driver version of 1.13. We previously had TecnoSpark devices
4511     // with the same GPU running on Android P (driver 1.10) which did not have this issue. We don't
4512     // know when the bug appeared in the driver so for now we disable tessellation path renderer for
4513     // all matching gpus regardless of driver version.
4514     //
4515     // 2022-10-28 Update: Testing via Flutter found this is not a problem on driver version 1.15.
4516     // See https://github.com/flutter/flutter/issues/113596
4517     // GL_VERSION : OpenGL ES 3.1 build 1.15@6133109
4518     // GL_RENDERER: PowerVR Rogue AXE-1-16M
4519     // GL_VENDOR  : Imagination Technologies
4520     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue &&
4521         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 15, 0)) {
4522         fDisableTessellationPathRenderer = true;
4523     }
4524 
4525     // The Wembley device draws the mesh_update GM incorrectly when using transfer buffers. Buffer
4526     // to buffer transfers affect draws earlier in the GL command sequence.
4527     // Android API: 31
4528     // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4529     // GL_RENDERER: PowerVR Rogue GE8300
4530     // GL_VENDOR  : Imagination Technologies
4531     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4532         fTransferFromBufferToBufferSupport = false;
4533     }
4534 
4535     // The Wembley device fails shader compilations with no error message when there is a const
4536     // parameter. Given that we've already passed through SkSL compilation and enforced that the
4537     // parameter is never written, it is harmless to strip the const off when writing GLSL.
4538     // Android API: 31
4539     // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4540     // GL_RENDERER: PowerVR Rogue GE8300
4541     // GL_VENDOR  : Imagination Technologies
4542     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4543         fShaderCaps->fRemoveConstFromFunctionParameters = true;
4544     }
4545 #ifdef SK_BUILD_FOR_WIN
4546     // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
4547     if (ctxInfo.driver() == GrGLDriver::kIntel ||
4548         (ctxInfo.angleVendor()  == GrGLVendor::kIntel &&
4549          ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL)) {
4550         fNativeDrawIndexedIndirectIsBroken = true;
4551         fUseClientSideIndirectBuffers = true;
4552     }
4553 #endif
4554 
4555     // PowerVRGX6250 drops every pixel if we modify the sample mask while color writes are disabled.
4556     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4557         fNeverDisableColorWrites = true;
4558         shaderCaps->fMustWriteToFragColor = true;
4559     }
4560 
4561     // It appears that Qualcomm drivers don't actually support
4562     // GL_NV_shader_noperspective_interpolation in ES 3.00 or 3.10 shaders, only 3.20.
4563     // https://crbug.com/986581
4564     if (ctxInfo.vendor() == GrGLVendor::kQualcomm &&
4565         SkSL::GLSLGeneration::k320es != ctxInfo.glslGeneration()) {
4566         shaderCaps->fNoPerspectiveInterpolationSupport = false;
4567     }
4568 
4569     // We disable srgb write control for Adreno4xx devices.
4570     // see: https://bug.skia.org/5329
4571     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4572         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4573         fSRGBWriteControl = false;
4574     }
4575 
4576     // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
4577 #if defined(SK_BUILD_FOR_MAC)
4578     if (ctxInfo.vendor() == GrGLVendor::kATI) {
4579         formatWorkarounds->fDisableSRGBRenderWithMSAAForMacAMD = true;
4580     }
4581 #endif
4582 
4583     // Command buffer fails glTexSubImage2D with type == GL_HALF_FLOAT_OES if a GL_RGBA16F texture
4584     // is created with glTexStorage2D. See crbug.com/1008003.
4585     formatWorkarounds->fDisableRGBA16FTexStorageForCrBug1008003 =
4586             ctxInfo.isOverCommandBuffer() && ctxInfo.version() < GR_GL_VER(3, 0);
4587 
4588 #if defined(SK_BUILD_FOR_WIN)
4589     // On Intel Windows ES contexts it seems that using texture storage with BGRA causes
4590     // problems with cross-context SkImages.
4591     formatWorkarounds->fDisableBGRATextureStorageForIntelWindowsES =
4592             ctxInfo.driver() == GrGLDriver::kIntel && GR_IS_GR_GL_ES(ctxInfo.standard());
4593 #endif
4594 
4595     // On the Intel Iris 6100, interacting with LUM16F seems to confuse the driver. After
4596     // writing to/reading from a LUM16F texture reads from/writes to other formats behave
4597     // erratically.
4598     // All Adrenos claim to support LUM16F but don't appear to actually do so.
4599     // The failing devices/gpus were: Nexus5/Adreno330, Nexus5x/Adreno418, Pixel/Adreno530,
4600     // Pixel2XL/Adreno540 and Pixel3/Adreno630
4601     formatWorkarounds->fDisableLuminance16F =
4602             (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell ||
4603              ctxInfo.vendor() == GrGLVendor::kQualcomm) &&
4604             ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown;
4605 
4606 #ifdef SK_BUILD_FOR_MAC
4607     // On a MacBookPro 11.5 running MacOS 10.13 with a Radeon M370X the TransferPixelsFrom test
4608     // fails when transferring out from a GL_RG8 texture using GL_RG/GL_UNSIGNED_BYTE.
4609     // The same error also occurs in MacOS 10.15 with a Radeon Pro 5300M.
4610     formatWorkarounds->fDisallowDirectRG8ReadPixels =
4611             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M3xx  ||
4612             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonPro5xxx ||
4613             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonProVegaxx;
4614 #endif
4615 
4616 #ifdef SK_BUILD_FOR_ANDROID
4617     // crbug.com/945506. Telemetry reported a memory usage regression for Android Go Chrome/WebView
4618     // when using glTexStorage2D. This appears to affect OOP-R (so not just over command buffer).
4619     // Update 10/2023, it looks like this may just effect chrome Android GO devices which are
4620     // running on Mali-T720. It does not seem to impact Qualcomm devices. We have no tests to verify
4621     // if newer ARM devices are impacted, so for now we keep this disabled on all ARM by default.
4622     //
4623     // We allow the client to pass in a GrContextOption flag to say they prefer having tex storage
4624     // support regadless of memory usage impacts. This is important for supporting Protected
4625     // textures as they require tex storage support.
4626     if (ctxInfo.vendor() == GrGLVendor::kARM &&
4627         !contextOptions.fAlwaysUseTexStorageWhenAvailable &&
4628         !fSupportsProtectedContent) {
4629         formatWorkarounds->fDisableTexStorage = true;
4630     }
4631 #endif
4632 
4633     // https://github.com/flutter/flutter/issues/38700
4634     if (ctxInfo.driver() == GrGLDriver::kAndroidEmulator) {
4635         shaderCaps->fNoDefaultPrecisionForExternalSamplers = true;
4636     }
4637 
4638     // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
4639     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4640         fTiledRenderingSupport = false;
4641     }
4642     // https://github.com/flutter/flutter/issues/47164
4643     // https://github.com/flutter/flutter/issues/47804
4644     if (fTiledRenderingSupport && (!glInterface->fFunctions.fStartTiling ||
4645                                    !glInterface->fFunctions.fEndTiling)) {
4646         // Some devices expose the QCOM tiled memory extension string but don't actually provide the
4647         // start and end tiling functions (see above flutter bugs). To work around this, the funcs
4648         // are marked optional in the interface generator, but we turn off the tiled rendering cap
4649         // if they aren't provided. This disabling is in driver workarounds so that SKQP will still
4650         // fail on devices that advertise the extension w/o the functions.
4651         fTiledRenderingSupport = false;
4652     }
4653 
4654     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {
4655         formatWorkarounds->fDisallowBGRA8ReadPixels = true;
4656     }
4657 
4658     // We disable MSAA for older Intel GPUs. Before Gen9, performance was very bad. Even with Gen9,
4659     // we've seen driver crashes in the wild.
4660     // (crbug.com/527565, crbug.com/983926)
4661     if (ctxInfo.vendor() == GrGLVendor::kIntel || ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4662         // Gen11 seems mostly ok, except we avoid drawing lines with MSAA. (anglebug.com/7796)
4663         if (ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake &&
4664             contextOptions.fAllowMSAAOnNewIntel) {
4665             if (fMSFBOType != kNone_MSFBOType) {
4666                 fAvoidLineDraws = true;
4667             }
4668         } else {
4669             fMSFBOType = kNone_MSFBOType;
4670         }
4671     }
4672 
4673     // ANGLE's D3D9 backend + AMD GPUs are flaky with program binary caching (skbug.com/10395)
4674     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 &&
4675         ctxInfo.angleVendor()  == GrGLVendor::kATI) {
4676         fProgramBinarySupport = false;
4677     }
4678 
4679     // skbug.com/11204. Avoid recursion issue in SurfaceContext::writePixels.
4680     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4681         fReuseScratchTextures = false;
4682     }
4683 
4684     // skbug.com/11935. Don't reorder on these GPUs in GL on old drivers.
4685     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4686         ctxInfo.renderer() == GrGLRenderer::kAdreno640) &&
4687         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(571, 0, 0)) {
4688         fAvoidReorderingRenderTasks = true;
4689     }
4690 
4691     // http://crbug.com/1197152
4692     // http://b/187364475
4693     // We could limit this < 1.13 on ChromeOS but we don't really have a good way to detect
4694     // ChromeOS from here.
4695     if (ctxInfo.renderer()      == GrGLRenderer::kPowerVRRogue &&
4696         ctxInfo.driver()        == GrGLDriver::kImagination    &&
4697         ctxInfo.driverVersion() <  GR_GL_DRIVER_VER(1, 16, 0)) {
4698         fShaderCaps->fShaderDerivativeSupport = false;
4699     }
4700 
4701     if (ctxInfo.driver() == GrGLDriver::kFreedreno) {
4702         formatWorkarounds->fDisallowUnorm16Transfers = true;
4703     }
4704 
4705     // If we keep rebind the same texture to an FBO's color attachment but changing between MSAA and
4706     // non-MSAA we get corruption in the texture contents. Binding texture 0 and then rebinding the
4707     // original texture avoids this.
4708     // This was found on Nexus 5, Android 6.0.1, build M4B30Z
4709     // GL_VENDOR  : "Qualcomm"
4710     // GL_RENDERER: "Adreno (TM) 330"
4711     // GL_VERSION : "OpenGL ES 3.0 [email protected] AU@  (GIT@I96aee987eb)"
4712     //
4713     // We also so alpha blending issues on these GMs skbug_9819, p3_ovals, p3 on Mali-Gxx devices
4714     // The GM issues were observed on a Galaxy S9 running Android 10:
4715     // GL_VERSION : "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
4716     // GL_RENDERER: "Mali-G72"
4717     // GL_VENDOR  : "ARM"
4718     // and a P30 running Android 9:
4719     // GL_VERSION : "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
4720     // GL_RENDERER: "Mali-G76"
4721     // GL_VENDOR  : "ARM"
4722     // but *not* a Galaxy S20 running Android 10:
4723     // GL_VERSION : "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
4724     // GL_RENDERER: "Mali-G77"
4725     // GL_VENDOR  : "ARM"
4726     // It's unclear if the difference is driver version or Bifrost vs Valhall. The workaround is
4727     // fairly trivial so just applying to all Bifrost and Valhall.
4728     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4729          ctxInfo.driver()   == GrGLDriver::kQualcomm) ||
4730         (ctxInfo.renderer() == GrGLRenderer::kMaliG)) {
4731         fBindTexture0WhenChangingTextureFBOMultisampleCount = true;
4732     }
4733 
4734     // skbug.com/12640
4735     // We found that on the Galaxy S7 the TransferPixelsTo test would fail after adding
4736     // glCheckFramebufferStatus() checks when making new FBOs. Note that the returned status was
4737     // GL_FRAMEBUFFER_COMPLETE. Switching the color binding to ID 0 and back to the original
4738     // afterwards works around the issue.
4739     // GL_VENDOR  : "ARM"
4740     // GL_RENDERER: "Mali-T880"
4741     // GL_VERSION : "OpenGL ES 3.2 v1.r22p0-01rel0.f294e54ceb2cb2d81039204fa4b0402e"
4742     //
4743     // This *didn't* reproduce on a Kevin ChromeOS device:
4744     // GL_VENDOR  : "ARM"
4745     // GL_RENDERER: "Mali-T860"
4746     // GL_VERSION : "OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3"
4747     if (ctxInfo.renderer()      == GrGLRenderer::kMaliT &&
4748         ctxInfo.driver()        == GrGLDriver::kARM     &&
4749         ctxInfo.driverVersion()  < GR_GL_DRIVER_VER(1, 26, 0)) {
4750         fRebindColorAttachmentAfterCheckFramebufferStatus = true;
4751     }
4752 
4753     // skbug.com/13286
4754     // We found that the P30 produces a GL error when setting GL_TEXTURE_MAX_ANISOTROPY as a sampler
4755     // parameter but not as a texture parameter. We are disabling anisotropy on drivers that may
4756     // be affected.
4757     //
4758     // FAIL on P30
4759     // GL_VENDOR  : ARM
4760     // GL_RENDERER: Mali-G76
4761     // GL_VERSION : OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5
4762     //
4763     // PASS on Pixel6
4764     // GL_VENDOR  : ARM
4765     // GL_RENDERER: Mali-G78
4766     // GL_VERSION : OpenGL ES 3.2 v1.r32p1-00pxl0.b7e5868a59a273f4a9f58d1657ef99de
4767     //
4768     // PASS on Galaxy S30:
4769     // GL_VENDOR  : ARM
4770     // GL_RENDERER: Mali-G77
4771     // GL_VERSION : OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###
4772     //
4773     // PASS on Galaxy S9:
4774     // GL_VENDOR  : ARM
4775     // GL_RENDERER: Mali-G72
4776     // GL_VENDOR  : OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###
4777     if (ctxInfo.renderer()      == GrGLRenderer::kMaliG &&
4778         ctxInfo.driver()        == GrGLDriver::kARM     &&
4779         ctxInfo.driverVersion()  < GR_GL_DRIVER_VER(1, 19, 0)) {
4780         fAnisoSupport = false;
4781     }
4782 
4783     // b/229626353
4784     // On certain classes of Adreno running WebGL, glTexSubImage2D() occasionally fails to upload
4785     // texels on time for sampling. The solution is to call glFlush() before glTexSubImage2D().
4786     // Seen on:
4787     // * Nexus 5x (Adreno 418)
4788     // * Nexus 6 (Adreno 420)
4789     // * Pixel 3 (Adreno 630)
4790     if (ctxInfo.renderer()       == GrGLRenderer::kWebGL &&
4791         (ctxInfo.webglRenderer() == GrGLRenderer::kAdreno4xx_other ||
4792          ctxInfo.webglRenderer() == GrGLRenderer::kAdreno630)) {
4793         fFlushBeforeWritePixels = true;
4794     }
4795     // crbug.com/1395777
4796     // There appears to be a driver bug in GLSL program linking on Mali 400 and 450 devices with
4797     // driver version 2.1.199xx that causes the copy-as-draw programs in GrGLGpu to fail. The crash
4798     // rate increased when scaling copy support was added, so disallow scaling copy-as-draws on
4799     // these devices.
4800     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx &&
4801         ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(2, 1, 19900)) {
4802         fDisableScalingCopyAsDraws = true;
4803     }
4804     // skbug.com/14194
4805     // Setting the max level is technically unnecessary, but on Intel drivers it makes it
4806     // clear that a rendering feedback loop is not occurring, and avoids hitting a slow path.
4807     // When running on ANGLE, however, this triggers the validator because we can only use
4808     // levels between BASE_LEVEL and MAX_LEVEL for a framebuffer, and we're trying to use
4809     // MAX_LEVEL+1. So instead we set up sync points between each mipmap level render.
4810     if (ctxInfo.vendor() == GrGLVendor::kIntel  &&
4811         ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown) {
4812         fRegenerateMipmapType = RegenerateMipmapType::kBasePlusMaxLevel;
4813     } else if (ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4814         fRegenerateMipmapType = RegenerateMipmapType::kBasePlusSync;
4815     }
4816 #ifdef SK_BUILD_FOR_MAC
4817     // On Apple Silicon, RG88 requires 2-byte alignment for transfer buffer readback
4818     if (ctxInfo.vendor() == GrGLVendor::kApple) {
4819         fPadRG88TransferAlignment = true;
4820     }
4821 #endif
4822 }
4823 
onApplyOptionsOverrides(const GrContextOptions & options)4824 void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
4825     if (options.fDisableDriverCorrectnessWorkarounds) {
4826         SkASSERT(!fDoManualMipmapping);
4827         SkASSERT(!fClearToBoundaryValuesIsBroken);
4828         SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
4829         SkASSERT(!fDrawArraysBaseVertexIsBroken);
4830         SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
4831         SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
4832         SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
4833         SkASSERT(!fDontSetBaseOrMaxLevelForExternalTextures);
4834         SkASSERT(!fNeverDisableColorWrites);
4835     }
4836     if (options.fShaderCacheStrategy < GrContextOptions::ShaderCacheStrategy::kBackendBinary) {
4837         fProgramBinarySupport = false;
4838     }
4839 
4840     switch (options.fSkipGLErrorChecks) {
4841         case GrContextOptions::Enable::kNo:
4842             fSkipErrorChecks = false;
4843             break;
4844         case GrContextOptions::Enable::kYes:
4845             fSkipErrorChecks = true;
4846             break;
4847         case GrContextOptions::Enable::kDefault:
4848             break;
4849     }
4850 }
4851 
onSurfaceSupportsWritePixels(const GrSurface * surface) const4852 bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
4853     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4854         if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4855             if (tex->hasBaseLevelBeenBoundToFBO()) {
4856                 return false;
4857             }
4858         }
4859     }
4860     if (auto rt = surface->asRenderTarget()) {
4861         if (fUseDrawInsteadOfAllRenderTargetWrites) {
4862             return false;
4863         }
4864         if (rt->numSamples() > 1 && this->usesMSAARenderBuffers()) {
4865             return false;
4866         }
4867         return SkToBool(surface->asTexture());
4868     }
4869     return true;
4870 }
4871 
surfaceSupportsReadPixels(const GrSurface * surface) const4872 GrCaps::SurfaceReadPixelsSupport GrGLCaps::surfaceSupportsReadPixels(
4873         const GrSurface* surface) const {
4874     if (surface->isProtected()) {
4875         return SurfaceReadPixelsSupport::kUnsupported;
4876     }
4877     if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4878         // We don't support reading pixels directly from EXTERNAL textures as it would require
4879         // binding the texture to a FBO. For now we also disallow reading back directly
4880         // from compressed textures.
4881         if (tex->target() == GR_GL_TEXTURE_EXTERNAL || GrGLFormatIsCompressed(tex->format())) {
4882             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4883         }
4884     } else if (auto rt = static_cast<const GrGLRenderTarget*>(surface->asRenderTarget())) {
4885         // glReadPixels does not allow reading back from a MSAA framebuffer. If the underlying
4886         // GrSurface doesn't have a second FBO to resolve to then we must make a copy.
4887         if (rt->numSamples() > 1 && !rt->asTexture()) {
4888             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4889         }
4890     }
4891     return SurfaceReadPixelsSupport::kSupported;
4892 }
4893 
offset_alignment_for_transfer_buffer(GrGLenum externalType)4894 size_t offset_alignment_for_transfer_buffer(GrGLenum externalType) {
4895     // This switch is derived from a table titled "Pixel data type parameter values and the
4896     // corresponding GL data types" in the OpenGL spec (Table 8.2 in OpenGL 4.5).
4897     switch (externalType) {
4898         case GR_GL_UNSIGNED_BYTE:                   return sizeof(GrGLubyte);
4899         case GR_GL_BYTE:                            return sizeof(GrGLbyte);
4900         case GR_GL_UNSIGNED_SHORT:                  return sizeof(GrGLushort);
4901         case GR_GL_SHORT:                           return sizeof(GrGLshort);
4902         case GR_GL_UNSIGNED_INT:                    return sizeof(GrGLuint);
4903         case GR_GL_INT:                             return sizeof(GrGLint);
4904         case GR_GL_HALF_FLOAT:                      return sizeof(GrGLhalf);
4905         case GR_GL_HALF_FLOAT_OES:                  return sizeof(GrGLhalf);
4906         case GR_GL_FLOAT:                           return sizeof(GrGLfloat);
4907         case GR_GL_UNSIGNED_SHORT_5_6_5:            return sizeof(GrGLushort);
4908         case GR_GL_UNSIGNED_SHORT_4_4_4_4:          return sizeof(GrGLushort);
4909         case GR_GL_UNSIGNED_SHORT_5_5_5_1:          return sizeof(GrGLushort);
4910         case GR_GL_UNSIGNED_INT_2_10_10_10_REV:     return sizeof(GrGLuint);
4911 #if 0  // GL types we currently don't use. Here for future reference.
4912         case GR_GL_UNSIGNED_BYTE_3_3_2:             return sizeof(GrGLubyte);
4913         case GR_GL_UNSIGNED_BYTE_2_3_3_REV:         return sizeof(GrGLubyte);
4914         case GR_GL_UNSIGNED_SHORT_5_6_5_REV:        return sizeof(GrGLushort);
4915         case GR_GL_UNSIGNED_SHORT_4_4_4_4_REV:      return sizeof(GrGLushort);
4916         case GR_GL_UNSIGNED_SHORT_1_5_5_5_REV:      return sizeof(GrGLushort);
4917         case GR_GL_UNSIGNED_INT_8_8_8_8:            return sizeof(GrGLuint);
4918         case GR_GL_UNSIGNED_INT_8_8_8_8_REV:        return sizeof(GrGLuint);
4919         case GR_GL_UNSIGNED_INT_10_10_10_2:         return sizeof(GrGLuint);
4920         case GR_GL_UNSIGNED_INT_24_8:               return sizeof(GrGLuint);
4921         case GR_GL_UNSIGNED_INT_10F_11F_11F_REV:    return sizeof(GrGLuint);
4922         case GR_GL_UNSIGNED_INT_5_9_9_9_REV:        return sizeof(GrGLuint);
4923         // This one is not corresponding to a GL data type and the spec just says it is 4.
4924         case GR_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:  return 4;
4925 #endif
4926         default:                                    return 0;
4927     }
4928 }
4929 
onSupportedReadPixelsColorType(GrColorType srcColorType,const GrBackendFormat & srcBackendFormat,GrColorType dstColorType) const4930 GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
4931         GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
4932         GrColorType dstColorType) const {
4933 
4934     SkTextureCompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
4935     if (compression != SkTextureCompressionType::kNone) {
4936         return {SkTextureCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
4937                                                        : GrColorType::kRGBA_8888,
4938                 0};
4939     }
4940 
4941     // We first try to find a supported read pixels GrColorType that matches the requested
4942     // dstColorType. If that doesn't exists we will use any valid read pixels GrColorType.
4943     GrCaps::SupportedRead fallbackRead = {GrColorType::kUnknown, 0};
4944     const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(srcBackendFormat));
4945     bool foundSrcCT = false;
4946     for (int i = 0; !foundSrcCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4947         if (formatInfo.fColorTypeInfos[i].fColorType == srcColorType) {
4948             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4949             foundSrcCT = true;
4950             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4951                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4952                 if (ioInfo.fExternalReadFormat != 0) {
4953                     if (formatInfo.fHaveQueriedImplementationReadSupport ||
4954                         !ioInfo.fRequiresImplementationReadQuery) {
4955                         GrGLenum transferOffsetAlignment = 0;
4956                         if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4957                             transferOffsetAlignment =
4958                                     offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
4959                             if (dstColorType == GrColorType::kRG_88 && fPadRG88TransferAlignment) {
4960                                 transferOffsetAlignment = 2;
4961                             }
4962                         }
4963                         if (ioInfo.fColorType == dstColorType) {
4964                             return {dstColorType, transferOffsetAlignment};
4965                         }
4966                         // Currently we just pick the first supported format that we find as our
4967                         // fallback.
4968                         if (fallbackRead.fColorType == GrColorType::kUnknown) {
4969                             fallbackRead = {ioInfo.fColorType, transferOffsetAlignment};
4970                         }
4971                     }
4972                 }
4973             }
4974         }
4975     }
4976     return fallbackRead;
4977 }
4978 
supportedWritePixelsColorType(GrColorType surfaceColorType,const GrBackendFormat & surfaceFormat,GrColorType srcColorType) const4979 GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfaceColorType,
4980                                                                const GrBackendFormat& surfaceFormat,
4981                                                                GrColorType srcColorType) const {
4982     // We first try to find a supported write pixels GrColorType that matches the data's
4983     // srcColorType. If that doesn't exists we will use any supported GrColorType.
4984     GrColorType fallbackCT = GrColorType::kUnknown;
4985     const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(surfaceFormat));
4986     bool foundSurfaceCT = false;
4987     size_t transferOffsetAlignment = 0;
4988     if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4989         transferOffsetAlignment = 1;
4990     }
4991     for (int i = 0; !foundSurfaceCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4992         if (formatInfo.fColorTypeInfos[i].fColorType == surfaceColorType) {
4993             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4994             foundSurfaceCT = true;
4995             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4996                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4997                 if (ioInfo.fExternalTexImageFormat != 0) {
4998                     if (ioInfo.fColorType == srcColorType) {
4999                         return {srcColorType, transferOffsetAlignment};
5000                     }
5001                     // Currently we just pick the first supported format that we find as our
5002                     // fallback.
5003                     if (fallbackCT == GrColorType::kUnknown) {
5004                         fallbackCT = ioInfo.fColorType;
5005                     }
5006                 }
5007             }
5008         }
5009     }
5010     return {fallbackCT, transferOffsetAlignment};
5011 }
5012 
programBinaryFormatIsValid(GrGLenum binaryFormat) const5013 bool GrGLCaps::programBinaryFormatIsValid(GrGLenum binaryFormat) const {
5014     return std::find(fProgramBinaryFormats.begin(), fProgramBinaryFormats.end(), binaryFormat) !=
5015            fProgramBinaryFormats.end();
5016 }
5017 
onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget & backendRT) const5018 bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
5019     GrGLFramebufferInfo fbInfo;
5020     SkAssertResult(GrBackendRenderTargets::GetGLFramebufferInfo(backendRT, &fbInfo));
5021     // Window Rectangles are not supported for FBO 0;
5022     return fbInfo.fFBOID != 0;
5023 }
5024 
isFormatSRGB(const GrBackendFormat & format) const5025 bool GrGLCaps::isFormatSRGB(const GrBackendFormat& format) const {
5026     return GrBackendFormats::AsGLFormat(format) == GrGLFormat::kSRGB8_ALPHA8;
5027 }
5028 
isFormatTexturable(const GrBackendFormat & format,GrTextureType textureType) const5029 bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType textureType) const {
5030     if (textureType == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5031         return false;
5032     }
5033     return this->isFormatTexturable(GrBackendFormats::AsGLFormat(format));
5034 }
5035 
isFormatTexturable(GrGLFormat format) const5036 bool GrGLCaps::isFormatTexturable(GrGLFormat format) const {
5037     const FormatInfo& info = this->getFormatInfo(format);
5038     return SkToBool(info.fFlags & FormatInfo::kTexturable_Flag);
5039 }
5040 
isFormatAsColorTypeRenderable(GrColorType ct,const GrBackendFormat & format,int sampleCount) const5041 bool GrGLCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
5042                                              int sampleCount) const {
5043     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5044         return false;
5045     }
5046     if (format.textureType() == GrTextureType::kExternal) {
5047         return false;
5048     }
5049     auto f = GrBackendFormats::AsGLFormat(format);
5050     const FormatInfo& info = this->getFormatInfo(f);
5051     if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
5052         return false;
5053     }
5054 
5055     return this->isFormatRenderable(f, sampleCount);
5056 }
5057 
isFormatRenderable(const GrBackendFormat & format,int sampleCount) const5058 bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
5059     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5060         return false;
5061     }
5062     if (format.textureType() == GrTextureType::kExternal) {
5063         return false;
5064     }
5065     return this->isFormatRenderable(GrBackendFormats::AsGLFormat(format), sampleCount);
5066 }
5067 
getRenderTargetSampleCount(int requestedCount,GrGLFormat format) const5068 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrGLFormat format) const {
5069     const FormatInfo& info = this->getFormatInfo(format);
5070 
5071     int count = info.fColorSampleCounts.size();
5072     if (!count) {
5073         return 0;
5074     }
5075 
5076     requestedCount = std::max(1, requestedCount);
5077     if (1 == requestedCount) {
5078         return info.fColorSampleCounts[0] == 1 ? 1 : 0;
5079     }
5080 
5081     for (int sampleCount : info.fColorSampleCounts) {
5082         if (sampleCount >= requestedCount) {
5083             if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5084                 sampleCount = std::min(sampleCount, 4);
5085             }
5086             return sampleCount;
5087         }
5088     }
5089     return 0;
5090 }
5091 
maxRenderTargetSampleCount(GrGLFormat format) const5092 int GrGLCaps::maxRenderTargetSampleCount(GrGLFormat format) const {
5093     const FormatInfo& info = this->getFormatInfo(format);
5094     const auto& table = info.fColorSampleCounts;
5095     if (table.empty()) {
5096         return 0;
5097     }
5098     int count = table[table.size() - 1];
5099     if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5100         count = std::min(count, 4);
5101     }
5102     return count;
5103 }
5104 
canFormatBeFBOColorAttachment(GrGLFormat format) const5105 bool GrGLCaps::canFormatBeFBOColorAttachment(GrGLFormat format) const {
5106     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kFBOColorAttachment_Flag);
5107 }
5108 
isFormatCopyable(const GrBackendFormat & format) const5109 bool GrGLCaps::isFormatCopyable(const GrBackendFormat& format) const {
5110     // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
5111     // requires the src to be an FBO attachment, blit requires both src and dst to be FBO
5112     // attachments, and draw requires the dst to be an FBO attachment. Thus to copy from and to
5113     // the same config, we need that config to be bindable to an FBO.
5114     return this->canFormatBeFBOColorAttachment(GrBackendFormats::AsGLFormat(format));
5115 }
5116 
formatSupportsTexStorage(GrGLFormat format) const5117 bool GrGLCaps::formatSupportsTexStorage(GrGLFormat format) const {
5118     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kUseTexStorage_Flag);
5119 }
5120 
shouldQueryImplementationReadSupport(GrGLFormat format) const5121 bool GrGLCaps::shouldQueryImplementationReadSupport(GrGLFormat format) const {
5122     const auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5123     if (!formatInfo.fHaveQueriedImplementationReadSupport) {
5124         // Check whether we will actually learn anything useful.
5125         bool needQuery = false;
5126         for (int i = 0; i < formatInfo.fColorTypeInfoCount && !needQuery; ++i) {
5127             const auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5128             for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5129                 if (surfCTInfo.fExternalIOFormats[j].fRequiresImplementationReadQuery) {
5130                     needQuery = true;
5131                     break;
5132                 }
5133             }
5134         }
5135         if (!needQuery) {
5136             // Pretend we already checked it.
5137             const_cast<FormatInfo&>(formatInfo).fHaveQueriedImplementationReadSupport = true;
5138         }
5139     }
5140     return !formatInfo.fHaveQueriedImplementationReadSupport;
5141 }
5142 
didQueryImplementationReadSupport(GrGLFormat format,GrGLenum readFormat,GrGLenum readType) const5143 void GrGLCaps::didQueryImplementationReadSupport(GrGLFormat format,
5144                                                  GrGLenum readFormat,
5145                                                  GrGLenum readType) const {
5146     auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5147     for (int i = 0; i < formatInfo.fColorTypeInfoCount; ++i) {
5148         auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5149         for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5150             auto& readCTInfo = surfCTInfo.fExternalIOFormats[j];
5151             if (readCTInfo.fRequiresImplementationReadQuery) {
5152                 if (readCTInfo.fExternalReadFormat != readFormat ||
5153                     readCTInfo.fExternalType != readType) {
5154                     // Don't zero out fExternalType. It's also used for writing data to the texture!
5155                     readCTInfo.fExternalReadFormat = 0;
5156                 }
5157             }
5158         }
5159     }
5160     formatInfo.fHaveQueriedImplementationReadSupport = true;
5161 }
5162 
onAreColorTypeAndFormatCompatible(GrColorType ct,const GrBackendFormat & format) const5163 bool GrGLCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
5164                                                  const GrBackendFormat& format) const {
5165     GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5166     const auto& info = this->getFormatInfo(glFormat);
5167     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5168         if (info.fColorTypeInfos[i].fColorType == ct) {
5169             return true;
5170         }
5171     }
5172     return false;
5173 }
5174 
onGetDefaultBackendFormat(GrColorType ct) const5175 GrBackendFormat GrGLCaps::onGetDefaultBackendFormat(GrColorType ct) const {
5176     auto format = this->getFormatFromColorType(ct);
5177     if (format == GrGLFormat::kUnknown) {
5178         return {};
5179     }
5180     return GrBackendFormats::MakeGL(GrGLFormatToEnum(format), GR_GL_TEXTURE_2D);
5181 }
5182 
getBackendFormatFromCompressionType(SkTextureCompressionType compressionType) const5183 GrBackendFormat GrGLCaps::getBackendFormatFromCompressionType(
5184         SkTextureCompressionType compressionType) const {
5185     switch (compressionType) {
5186         case SkTextureCompressionType::kNone:
5187             return {};
5188         case SkTextureCompressionType::kETC2_RGB8_UNORM:
5189             // if ETC2 is available default to that format
5190             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_ETC2)) {
5191                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D);
5192             }
5193             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ETC1_RGB8)) {
5194                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D);
5195             }
5196             return {};
5197         case SkTextureCompressionType::kBC1_RGB8_UNORM:
5198             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_BC1)) {
5199                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
5200                                                 GR_GL_TEXTURE_2D);
5201             }
5202             return {};
5203         case SkTextureCompressionType::kBC1_RGBA8_UNORM:
5204             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGBA8_BC1)) {
5205                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
5206                                                 GR_GL_TEXTURE_2D);
5207             }
5208             return {};
5209     }
5210 
5211     SkUNREACHABLE;
5212 }
5213 
onGetReadSwizzle(const GrBackendFormat & format,GrColorType colorType) const5214 skgpu::Swizzle GrGLCaps::onGetReadSwizzle(const GrBackendFormat& format,
5215                                           GrColorType colorType) const {
5216     GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5217     const auto& info = this->getFormatInfo(glFormat);
5218     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5219         const auto& ctInfo = info.fColorTypeInfos[i];
5220         if (ctInfo.fColorType == colorType) {
5221             return ctInfo.fReadSwizzle;
5222         }
5223     }
5224     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5225                  (int)colorType, (int)glFormat);
5226     return {};
5227 }
5228 
getWriteSwizzle(const GrBackendFormat & format,GrColorType colorType) const5229 skgpu::Swizzle GrGLCaps::getWriteSwizzle(const GrBackendFormat& format,
5230                                          GrColorType colorType) const {
5231     const auto& info = this->getFormatInfo(GrBackendFormats::AsGLFormat(format));
5232     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5233         const auto& ctInfo = info.fColorTypeInfos[i];
5234         if (ctInfo.fColorType == colorType) {
5235             return ctInfo.fWriteSwizzle;
5236         }
5237     }
5238     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5239                  (int)colorType,
5240                  (int)GrBackendFormats::AsGLFormat(format));
5241     return {};
5242 }
5243 
onGetDstSampleFlagsForProxy(const GrRenderTargetProxy * rt) const5244 GrDstSampleFlags GrGLCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
5245     if (rt->asTextureProxy()) {
5246         return GrDstSampleFlags::kRequiresTextureBarrier;
5247     }
5248     return GrDstSampleFlags::kNone;
5249 }
5250 
onSupportsDynamicMSAA(const GrRenderTargetProxy * rtProxy) const5251 bool GrGLCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
5252     return !fDisallowDynamicMSAA;
5253 }
5254 
computeFormatKey(const GrBackendFormat & format) const5255 uint64_t GrGLCaps::computeFormatKey(const GrBackendFormat& format) const {
5256     auto glFormat = GrBackendFormats::AsGLFormat(format);
5257     return (uint64_t)(glFormat);
5258 }
5259 
makeDesc(GrRenderTarget *,const GrProgramInfo & programInfo,ProgramDescOverrideFlags overrideFlags) const5260 GrProgramDesc GrGLCaps::makeDesc(GrRenderTarget* /* rt */,
5261                                  const GrProgramInfo& programInfo,
5262                                  ProgramDescOverrideFlags overrideFlags) const {
5263     SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
5264     GrProgramDesc desc;
5265     GrProgramDesc::Build(&desc, programInfo, *this);
5266     return desc;
5267 }
5268 
5269 #if defined(GPU_TEST_UTILS)
getTestingCombinations() const5270 std::vector<GrTest::TestFormatColorTypeCombination> GrGLCaps::getTestingCombinations() const {
5271     std::vector<GrTest::TestFormatColorTypeCombination> combos = {
5272         { GrColorType::kAlpha_8,
5273           GrBackendFormats::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D) },
5274         { GrColorType::kAlpha_8,
5275           GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5276         { GrColorType::kBGR_565,
5277           GrBackendFormats::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D) },
5278         { GrColorType::kABGR_4444,
5279           GrBackendFormats::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D) },
5280         { GrColorType::kRGBA_8888,
5281           GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5282         { GrColorType::kRGBA_8888_SRGB,
5283           GrBackendFormats::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D) },
5284         { GrColorType::kRGB_888x,
5285           GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5286         { GrColorType::kRGB_888x,
5287           GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) },
5288         { GrColorType::kRGB_888x,
5289           GrBackendFormats::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D) },
5290         { GrColorType::kRGB_888x,
5291           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D) },
5292         { GrColorType::kRGB_888x,
5293           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D) },
5294         { GrColorType::kRGB_888x,
5295           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5296         { GrColorType::kRGBA_8888,
5297           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5298         { GrColorType::kRG_88,
5299           GrBackendFormats::MakeGL(GR_GL_RG8, GR_GL_TEXTURE_2D) },
5300         { GrColorType::kRGBA_1010102,
5301           GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5302         { GrColorType::kRGB_101010x,
5303           GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5304         { GrColorType::kGray_8,
5305           GrBackendFormats::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D) },
5306         { GrColorType::kGray_8,
5307           GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5308         { GrColorType::kGrayAlpha_88,
5309           GrBackendFormats::MakeGL(GR_GL_LUMINANCE8_ALPHA8, GR_GL_TEXTURE_2D) },
5310         { GrColorType::kAlpha_F16,
5311           GrBackendFormats::MakeGL(GR_GL_R16F, GR_GL_TEXTURE_2D) },
5312         { GrColorType::kAlpha_F16,
5313           GrBackendFormats::MakeGL(GR_GL_LUMINANCE16F, GR_GL_TEXTURE_2D) },
5314         { GrColorType::kRGBA_F16,
5315           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5316         { GrColorType::kRGBA_F16_Clamped,
5317           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5318         { GrColorType::kRGB_F16F16F16x,
5319           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5320         { GrColorType::kAlpha_16,
5321           GrBackendFormats::MakeGL(GR_GL_R16, GR_GL_TEXTURE_2D) },
5322         { GrColorType::kRG_1616,
5323           GrBackendFormats::MakeGL(GR_GL_RG16, GR_GL_TEXTURE_2D) },
5324         { GrColorType::kRGBA_16161616,
5325           GrBackendFormats::MakeGL(GR_GL_RGBA16, GR_GL_TEXTURE_2D) },
5326         { GrColorType::kRG_F16,
5327           GrBackendFormats::MakeGL(GR_GL_RG16F, GR_GL_TEXTURE_2D) },
5328     };
5329 
5330     if (GR_IS_GR_GL(fStandard)) {
5331         combos.push_back({ GrColorType::kBGRA_8888,
5332                            GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) });
5333         combos.push_back({ GrColorType::kBGRA_1010102,
5334                            GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) });
5335     } else {
5336         SkASSERT(GR_IS_GR_GL_ES(fStandard) || GR_IS_GR_WEBGL(fStandard));
5337 
5338         combos.push_back({ GrColorType::kBGRA_8888,
5339                            GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) });
5340     }
5341     if (this->rectangleTextureSupport()) {
5342         size_t count2D = combos.size();
5343         for (size_t i = 0; i < count2D; ++i) {
5344             auto combo2D = combos[i];
5345             GrGLenum formatEnum = GrBackendFormats::AsGLFormatEnum(combo2D.fFormat);
5346             combos.push_back({combo2D.fColorType,
5347                               GrBackendFormats::MakeGL(formatEnum, GR_GL_TEXTURE_RECTANGLE)});
5348         }
5349     }
5350     return combos;
5351 }
5352 #endif
5353