• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         // GL 330 version enable VertexID and Inf in mac platform
1104 #ifdef SK_GL_ENABLE_330_MAC
1105         shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
1106 #else
1107         shaderCaps->fVertexIDSupport = true;
1108 #endif
1109     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1110         shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
1111     }
1112 
1113     // isinf() exists in GLSL 1.3 and above, but hardware without proper IEEE support is allowed to
1114     // always return false, so it's potentially meaningless. In GLSL 3.3 and GLSL ES3+, isinf() is
1115     // required to actually identify infinite values. (GPUs are not required to _produce_ infinite
1116     // values via operations like `num / 0.0` until GLSL 4.1.)
1117     shaderCaps->fInfinitySupport = (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330);
1118 
1119     // Using isinf or isnan with ANGLE will disable fast-math (which is a good thing!), but that
1120     // leads to hangs in the Metal shader compiler service for some of our tessellation shaders,
1121     // running on Intel Macs. For now, pretend that we don't have infinity support, even when we're
1122     // targeting ANGLE's ES3 to Metal.
1123     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kMetal &&
1124         ctxInfo.angleVendor() == GrGLVendor::kIntel) {
1125         shaderCaps->fInfinitySupport = false;
1126     }
1127 
1128     if (GR_IS_GR_GL(standard)) {
1129 #ifdef SK_GL_ENABLE_330_MAC
1130         shaderCaps->fInfinitySupport = (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es);
1131         shaderCaps->fNonconstantArrayIndexSupport = true;
1132 #else
1133         shaderCaps->fNonconstantArrayIndexSupport = true;
1134 #endif
1135     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1136         shaderCaps->fNonconstantArrayIndexSupport =
1137                 (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es);
1138     }
1139 
1140     if (GR_IS_GR_GL(standard)) {
1141         shaderCaps->fBitManipulationSupport =
1142                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1143     } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1144         shaderCaps->fBitManipulationSupport =
1145                 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k310es;
1146     }
1147 
1148     shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
1149     shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
1150     shaderCaps->fHasLowFragmentPrecision = ctxInfo.renderer() == GrGLRenderer::kMali4xx;
1151 
1152     if (GR_IS_GR_GL(standard)) {
1153         shaderCaps->fBuiltinFMASupport =
1154                  ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1155     } else if (GR_IS_GR_GL_ES(standard)) {
1156         shaderCaps->fBuiltinFMASupport =
1157                  ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k320es;
1158     } else if (GR_IS_GR_WEBGL(standard)) {
1159         shaderCaps->fBuiltinFMASupport = false;
1160     }
1161 
1162     shaderCaps->fBuiltinDeterminantSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k150;
1163 }
1164 
initFSAASupport(const GrContextOptions & contextOptions,const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)1165 void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions,
1166                                const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
1167     if (GR_IS_GR_GL(ctxInfo.standard())) {
1168         if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1169             ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
1170             fMSFBOType = kStandard_MSFBOType;
1171         } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1172                    ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
1173             fMSFBOType = kStandard_MSFBOType;
1174         }
1175     } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1176         // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
1177         // ES3 driver bugs on at least one device with a tiled GPU (N10).
1178         if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1179             fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1180             fMSAAResolvesAutomatically = true;
1181         } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1182             fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
1183             fMSAAResolvesAutomatically = true;
1184         } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1185             fMSFBOType = kStandard_MSFBOType;
1186         } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
1187             fMSFBOType = kStandard_MSFBOType;
1188         } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
1189             fMSFBOType = kStandard_MSFBOType;
1190         } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1191             fMSFBOType = kES_Apple_MSFBOType;
1192         }
1193     } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1194         // No support in WebGL 1, but there is for 2.0
1195         if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1196             fMSFBOType = kStandard_MSFBOType;
1197         } else {
1198             fMSFBOType = kNone_MSFBOType;
1199         }
1200     }
1201 }
1202 
initBlendEqationSupport(const GrGLContextInfo & ctxInfo)1203 void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
1204     GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
1205 
1206     bool layoutQualifierSupport = false;
1207     if ((GR_IS_GR_GL(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k140) ||
1208         (GR_IS_GR_GL_ES(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k300es)){
1209         layoutQualifierSupport = true;
1210     } else if (GR_IS_GR_WEBGL(fStandard)) {
1211         return;
1212     }
1213 
1214     if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1215         fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1216         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1217     } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1218                layoutQualifierSupport) {
1219         fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1220         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1221     } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1222         fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1223         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1224     } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
1225         fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1226         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1227     }
1228 }
1229 
1230 
initStencilSupport(const GrGLContextInfo & ctxInfo)1231 void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
1232 
1233     // Build up list of legal stencil formats (though perhaps not supported on
1234     // the particular gpu/driver) from most preferred to least.
1235 
1236     // We push back stencil formats onto the fStencilFormats array in order of most preferred to
1237     // least preferred.
1238 
1239     if (GR_IS_GR_GL(ctxInfo.standard())) {
1240         bool supportsPackedDS =
1241             ctxInfo.version() >= GR_GL_VER(3,0) ||
1242             ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1243             ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1244 
1245         // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1246         // require FBO support we can expect these are legal formats and don't
1247         // check.
1248         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1249         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX16;
1250         if (supportsPackedDS) {
1251             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1252         }
1253     } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1254         // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1255         // for other formats.
1256 
1257         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1258         if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1259             ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
1260             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1261         }
1262     } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1263         fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1264         if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1265             fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1266         }
1267     }
1268 }
1269 
1270 #ifdef SK_ENABLE_DUMP_GPU
1271 #include "src/utils/SkJSONWriter.h"
1272 
multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType)1273 static const char* multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType) {
1274     switch (multiDrawType) {
1275         case GrGLCaps::MultiDrawType::kNone : return "kNone";
1276         case GrGLCaps::MultiDrawType::kMultiDrawIndirect : return "kMultiDrawIndirect";
1277         case GrGLCaps::MultiDrawType::kANGLEOrWebGL : return "kMultiDrawIndirect";
1278     }
1279     SkUNREACHABLE;
1280 }
1281 
onDumpJSON(SkJSONWriter * writer) const1282 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
1283 
1284     // We are called by the base class, which has already called beginObject(). We choose to nest
1285     // all of our caps information in a named sub-object.
1286     writer->beginObject("GL caps");
1287 
1288     writer->beginArray("Stencil Formats");
1289 
1290     for (int i = 0; i < fStencilFormats.size(); ++i) {
1291         writer->beginObject(nullptr, false);
1292         writer->appendS32("stencil bits", GrGLFormatStencilBits(fStencilFormats[i]));
1293         writer->appendS32("total bytes", GrGLFormatBytesPerBlock(fStencilFormats[i]));
1294         writer->endObject();
1295     }
1296 
1297     writer->endArray();
1298 
1299     auto msfboStr = [&] {
1300         switch (fMSFBOType) {
1301             case kNone_MSFBOType:               return "None";
1302             case kStandard_MSFBOType:           return "Standard";
1303             case kES_Apple_MSFBOType:           return "Apple";
1304             case kES_IMG_MsToTexture_MSFBOType: return "IMG MS To Texture";
1305             case kES_EXT_MsToTexture_MSFBOType: return "EXT MS To Texture";
1306         }
1307         SkUNREACHABLE;
1308     };
1309 
1310     auto invalidateFBTypeStr = [&] {
1311         switch (fInvalidateFBType) {
1312             case kNone_InvalidateFBType:       return "None";
1313             case kDiscard_InvalidateFBType:    return "Discard";
1314             case kInvalidate_InvalidateFBType: return "Invalidate";
1315         }
1316         SkUNREACHABLE;
1317     };
1318 
1319     auto invalidateBufferTypeStr = [&] {
1320         switch (fInvalidateBufferType) {
1321             case InvalidateBufferType::kNone:       return "None";
1322             case InvalidateBufferType::kNullData:   return "Null data hint";
1323             case InvalidateBufferType::kInvalidate: return "Invalidate";
1324         }
1325         SkUNREACHABLE;
1326     };
1327 
1328     auto mapBufferTypeStr = [&] {
1329         switch (fMapBufferType) {
1330             case kNone_MapBufferType:           return "None";
1331             case kMapBuffer_MapBufferType:      return "MapBuffer";
1332             case kMapBufferRange_MapBufferType: return "MapBufferRange";
1333             case kChromium_MapBufferType:       return "Chromium";
1334         }
1335         SkUNREACHABLE;
1336     };
1337 
1338     writer->appendBool("Core Profile", fIsCoreProfile);
1339     writer->appendCString("MSAA Type", msfboStr());
1340     writer->appendCString("Invalidate FB Type", invalidateFBTypeStr());
1341     writer->appendCString("Invalidate Buffer Type", invalidateBufferTypeStr());
1342     writer->appendCString("Map Buffer Type", mapBufferTypeStr());
1343     writer->appendCString("Multi Draw Type", multi_draw_type_name(fMultiDrawType));
1344     writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1345     writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
1346 
1347     writer->appendBool("Texture Usage support", fTextureUsageSupport);
1348     writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1349     writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
1350     writer->appendBool("Debug support", fDebugSupport);
1351     writer->appendBool("ES2 compatibility support", fES2CompatibilitySupport);
1352     writer->appendBool("Strict Protectedness", fStrictProtectedness);
1353     writer->appendBool("drawRangeElements support", fDrawRangeElementsSupport);
1354     writer->appendBool("Base (vertex base) instance support", fBaseVertexBaseInstanceSupport);
1355     writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1356     writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1357     writer->appendBool("Mipmap LOD control support", fMipmapLodControlSupport);
1358     writer->appendBool("Mipmap level control support", fMipmapLevelControlSupport);
1359     writer->appendBool("Clear texture support", fClearTextureSupport);
1360     writer->appendBool("Program binary support", fProgramBinarySupport);
1361     writer->appendBool("Program parameters support", fProgramParameterSupport);
1362     writer->appendBool("Sampler object support", fSamplerObjectSupport);
1363     writer->appendBool("Using sampler objects", fUseSamplerObjects);
1364     writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1365     writer->appendBool("Tiled rendering support", fTiledRenderingSupport);
1366     writer->appendBool("Fence sync support", fFenceSyncSupport);
1367     writer->appendBool("FB fetch requires enable per sample", fFBFetchRequiresEnablePerSample);
1368     writer->appendBool("sRGB Write Control", fSRGBWriteControl);
1369 
1370     writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1371                        fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1372     writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1373                        fUseDrawInsteadOfAllRenderTargetWrites);
1374     writer->appendBool("Max instances per draw without crashing (or zero)",
1375                        fMaxInstancesPerDrawWithoutCrashing);
1376 
1377     writer->beginArray("formats");
1378 
1379     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
1380         writer->beginObject(nullptr, false);
1381         writer->appendHexU32("flags", fFormatTable[i].fFlags);
1382         writer->appendHexU32("f_type", (uint32_t)fFormatTable[i].fFormatType);
1383         writer->appendHexU32("c_internal", fFormatTable[i].fCompressedInternalFormat);
1384         writer->appendHexU32("i_for_teximage", fFormatTable[i].fInternalFormatForTexImageOrStorage);
1385         writer->appendHexU32("i_for_renderbuffer", fFormatTable[i].fInternalFormatForRenderbuffer);
1386         writer->appendHexU32("default_ex_format", fFormatTable[i].fDefaultExternalFormat);
1387         writer->appendHexU32("default_ex_type", fFormatTable[i].fDefaultExternalType);
1388         writer->appendHexU32("default_color_type", (uint32_t)fFormatTable[i].fDefaultColorType);
1389 
1390         writer->beginArray("surface color types");
1391         for (int j = 0; j < fFormatTable[i].fColorTypeInfoCount; ++j) {
1392             const auto& ctInfo = fFormatTable[i].fColorTypeInfos[j];
1393             writer->beginObject(nullptr, false);
1394             writer->appendHexU32("colorType", (uint32_t)ctInfo.fColorType);
1395             writer->appendHexU32("flags", ctInfo.fFlags);
1396 
1397             writer->beginArray("data color types");
1398             for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
1399                 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
1400                 writer->beginObject(nullptr, false);
1401                 writer->appendHexU32("colorType", (uint32_t)ioInfo.fColorType);
1402                 writer->appendHexU32("ex_type", ioInfo.fExternalType);
1403                 writer->appendHexU32("ex_teximage", ioInfo.fExternalTexImageFormat);
1404                 writer->appendHexU32("ex_read", ioInfo.fExternalReadFormat);
1405                 writer->endObject();
1406             }
1407             writer->endArray();
1408             writer->endObject();
1409         }
1410         writer->endArray();
1411         writer->endObject();
1412     }
1413 
1414     writer->endArray();
1415     writer->endObject();
1416 }
1417 #else
onDumpJSON(SkJSONWriter * writer) const1418 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const { }
1419 #endif
1420 
getTexImageExternalFormatAndType(GrGLFormat surfaceFormat,GrGLenum * externalFormat,GrGLenum * externalType) const1421 void GrGLCaps::getTexImageExternalFormatAndType(GrGLFormat surfaceFormat, GrGLenum* externalFormat,
1422                                                 GrGLenum* externalType) const {
1423     const auto& info = this->getFormatInfo(surfaceFormat);
1424     *externalType = info.fDefaultExternalType;
1425     *externalFormat = info.fDefaultExternalFormat;
1426 }
1427 
getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,GrGLenum * externalFormat,GrGLenum * externalType,GrColorType * colorType) const1428 void GrGLCaps::getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,
1429                                                            GrGLenum* externalFormat,
1430                                                            GrGLenum* externalType,
1431                                                            GrColorType* colorType) const {
1432     const auto& info = this->getFormatInfo(format);
1433     *externalType = info.fDefaultExternalType;
1434     *externalFormat = info.fDefaultExternalFormat;
1435     *colorType = info.fDefaultColorType;
1436 }
1437 
getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1438 void GrGLCaps::getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,
1439                                                    GrColorType surfaceColorType,
1440                                                    GrColorType memoryColorType,
1441                                                    GrGLenum* externalFormat,
1442                                                    GrGLenum* externalType) const {
1443     this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1444                             kTexImage_ExternalFormatUsage, externalFormat, externalType);
1445 }
1446 
getReadPixelsFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1447 void GrGLCaps::getReadPixelsFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1448                                    GrColorType memoryColorType, GrGLenum* externalFormat,
1449                                    GrGLenum* externalType) const {
1450     this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1451                             kReadPixels_ExternalFormatUsage, externalFormat, externalType);
1452 }
1453 
getExternalFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,ExternalFormatUsage usage,GrGLenum * externalFormat,GrGLenum * externalType) const1454 void GrGLCaps::getExternalFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1455                                  GrColorType memoryColorType, ExternalFormatUsage usage,
1456                                  GrGLenum* externalFormat, GrGLenum* externalType) const {
1457     SkASSERT(externalFormat && externalType);
1458     *externalFormat = this->getFormatInfo(surfaceFormat).externalFormat(
1459             surfaceColorType, memoryColorType, usage);
1460     *externalType = this->getFormatInfo(surfaceFormat).externalType(
1461             surfaceColorType, memoryColorType);
1462 }
1463 
setStencilFormatIndexForFormat(GrGLFormat format,int index)1464 void GrGLCaps::setStencilFormatIndexForFormat(GrGLFormat format, int index) {
1465     SkASSERT(!this->hasStencilFormatBeenDeterminedForFormat(format));
1466     this->getFormatInfo(format).fStencilFormatIndex =
1467             index < 0 ? FormatInfo::kUnsupported_StencilFormatIndex : index;
1468 }
1469 
setColorTypeFormat(GrColorType colorType,GrGLFormat format)1470 void GrGLCaps::setColorTypeFormat(GrColorType colorType, GrGLFormat format) {
1471     int idx = static_cast<int>(colorType);
1472     SkASSERT(fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown);
1473     fColorTypeToFormatTable[idx] = format;
1474 }
1475 
initFormatTable(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli,const FormatWorkarounds & formatWorkarounds)1476 void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1477                                const FormatWorkarounds& formatWorkarounds) {
1478     GrGLStandard standard = ctxInfo.standard();
1479     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
1480     sk_ignore_unused_variable(standard);
1481     GrGLVersion version = ctxInfo.version();
1482 
1483     uint32_t nonMSAARenderFlags = FormatInfo::kFBOColorAttachment_Flag;
1484     uint32_t msaaRenderFlags = nonMSAARenderFlags;
1485     if (kNone_MSFBOType != fMSFBOType) {
1486         msaaRenderFlags |= FormatInfo::kFBOColorAttachmentWithMSAA_Flag;
1487     }
1488 
1489     bool texStorageSupported = false;
1490     if (GR_IS_GR_GL(standard)) {
1491         // The EXT version can apply to either GL or GLES.
1492         texStorageSupported = version >= GR_GL_VER(4,2) ||
1493                               ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1494                               ctxInfo.hasExtension("GL_EXT_texture_storage");
1495     } else if (GR_IS_GR_GL_ES(standard)) {
1496         texStorageSupported = version >= GR_GL_VER(3,0) ||
1497                               ctxInfo.hasExtension("GL_EXT_texture_storage");
1498     } else if (GR_IS_GR_WEBGL(standard)) {
1499         texStorageSupported = version >= GR_GL_VER(2,0);
1500     }
1501     if (fDriverBugWorkarounds.disable_texture_storage) {
1502         texStorageSupported = false;
1503     }
1504 
1505     if (formatWorkarounds.fDisableTexStorage) {
1506         texStorageSupported = false;
1507     }
1508 
1509     // ES 2.0 requires that the internal/external formats match so we can't use sized internal
1510     // formats for glTexImage until ES 3.0. TODO: Support sized internal formats in WebGL2.
1511     bool texImageSupportsSizedInternalFormat =
1512             (GR_IS_GR_GL(standard) || (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0)));
1513 
1514     // for now we don't support floating point MSAA on ES
1515     uint32_t fpRenderFlags = (GR_IS_GR_GL(standard)) ? msaaRenderFlags : nonMSAARenderFlags;
1516 
1517     for (int i = 0; i < kGrColorTypeCnt; ++i) {
1518         fColorTypeToFormatTable[i] = GrGLFormat::kUnknown;
1519     }
1520 
1521     ///////////////////////////////////////////////////////////////////////////
1522 
1523     GrGLenum halfFloatType = GR_GL_HALF_FLOAT;
1524     if ((GR_IS_GR_GL_ES(standard) && version < GR_GL_VER(3, 0)) ||
1525         (GR_IS_GR_WEBGL(standard) && version < GR_GL_VER(2, 0))) {
1526         halfFloatType = GR_GL_HALF_FLOAT_OES;
1527     }
1528 
1529     // Format: RGBA8
1530     {
1531         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA8);
1532         info.fFormatType = FormatType::kNormalizedFixedPoint;
1533         info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
1534         info.fDefaultExternalFormat = GR_GL_RGBA;
1535         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1536         info.fDefaultColorType = GrColorType::kRGBA_8888;
1537         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1538         if (GR_IS_GR_GL(standard)) {
1539             info.fFlags |= msaaRenderFlags;
1540         } else if (GR_IS_GR_GL_ES(standard)) {
1541             if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1542                 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1543                 info.fFlags |= msaaRenderFlags;
1544             }
1545         } else if (GR_IS_GR_WEBGL(standard)) {
1546             info.fFlags |= msaaRenderFlags;
1547         }
1548 
1549         if (texStorageSupported) {
1550             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1551             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA8;
1552         } else {
1553             info.fInternalFormatForTexImageOrStorage =
1554                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA8 : GR_GL_RGBA;
1555         }
1556 
1557         bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
1558                 (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
1559         info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
1560         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1561         int ctIdx = 0;
1562         // Format: RGBA8, Surface: kRGBA_8888
1563         {
1564             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1565             ctInfo.fColorType = GrColorType::kRGBA_8888;
1566             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1567             this->setColorTypeFormat(GrColorType::kRGBA_8888, GrGLFormat::kRGBA8);
1568 
1569             // External IO ColorTypes:
1570             ctInfo.fExternalIOFormatCount = 2;
1571             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1572                     ctInfo.fExternalIOFormatCount);
1573             int ioIdx = 0;
1574             // Format: RGBA8, Surface: kRGBA_8888, Data: kRGBA_8888
1575             {
1576                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1577                 ioFormat.fColorType = GrColorType::kRGBA_8888;
1578                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1579                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1580                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1581             }
1582             // Format: RGBA8, Surface: kRGBA_8888, Data: kBGRA_8888
1583             {
1584                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1585                 ioFormat.fColorType = GrColorType::kBGRA_8888;
1586                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1587                 ioFormat.fExternalTexImageFormat = 0;  // TODO: Enable this on non-ES GL
1588                 ioFormat.fExternalReadFormat =
1589                         formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1590                 // Not guaranteed by ES/WebGL.
1591                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1592             }
1593         }
1594 
1595         // Format: RGBA8, Surface: kBGRA_8888
1596         if (supportsBGRAColorType) {
1597             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1598             ctInfo.fColorType = GrColorType::kBGRA_8888;
1599             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1600             this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kRGBA8);
1601 
1602             // External IO ColorTypes:
1603             ctInfo.fExternalIOFormatCount = 2;
1604             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1605                     ctInfo.fExternalIOFormatCount);
1606             int ioIdx = 0;
1607             // Format: RGBA8, Surface: kBGRA_8888, Data: kBGRA_8888
1608             {
1609                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1610                 ioFormat.fColorType = GrColorType::kBGRA_8888;
1611                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1612                 ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
1613                 ioFormat.fExternalReadFormat =
1614                         formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1615                 // Not guaranteed by ES/WebGL.
1616                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1617             }
1618 
1619             // Format: RGBA8, Surface: kBGRA_8888, Data: kRGBA_8888
1620             {
1621                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1622                 ioFormat.fColorType = GrColorType::kRGBA_8888;
1623                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1624                 ioFormat.fExternalTexImageFormat = 0;
1625                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1626             }
1627         }
1628 
1629         // Format: RGBA8, Surface: kRGB_888x
1630         {
1631             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1632             ctInfo.fColorType = GrColorType::kRGB_888x;
1633             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1634             ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
1635 
1636             // External IO ColorTypes:
1637             ctInfo.fExternalIOFormatCount = 1;
1638             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1639                     ctInfo.fExternalIOFormatCount);
1640             int ioIdx = 0;
1641             // Format: RGBA8, Surface: kRGB_888x, Data: kRGBA_888x
1642             {
1643                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1644                 ioFormat.fColorType = GrColorType::kRGB_888x;
1645                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1646                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1647                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1648             }
1649         }
1650     }
1651 
1652     // Format: R8
1653     {
1654         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR8);
1655         info.fFormatType = FormatType::kNormalizedFixedPoint;
1656         info.fInternalFormatForRenderbuffer = GR_GL_R8;
1657         info.fDefaultExternalFormat = GR_GL_RED;
1658         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1659         info.fDefaultColorType = GrColorType::kR_8;
1660         bool r8Support = false;
1661         if (GR_IS_GR_GL(standard)) {
1662             r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1663         } else if (GR_IS_GR_GL_ES(standard)) {
1664             r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1665         } else if (GR_IS_GR_WEBGL(standard)) {
1666             r8Support = ctxInfo.version() >= GR_GL_VER(2, 0);
1667         }
1668         if (formatWorkarounds.fDisallowR8ForPowerVRSGX54x) {
1669             r8Support = false;
1670         }
1671 
1672         if (r8Support) {
1673             info.fFlags |= FormatInfo::kTexturable_Flag
1674                         |  FormatInfo::kTransfers_Flag
1675                         |  msaaRenderFlags;
1676         }
1677 
1678         if (texStorageSupported) {
1679             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1680             info.fInternalFormatForTexImageOrStorage = GR_GL_R8;
1681         } else {
1682             info.fInternalFormatForTexImageOrStorage =
1683                     texImageSupportsSizedInternalFormat ? GR_GL_R8 : GR_GL_RED;
1684         }
1685 
1686         if (r8Support) {
1687             info.fColorTypeInfoCount = 3;
1688             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1689             int ctIdx = 0;
1690             // Format: R8, Surface: kR_8
1691             {
1692                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1693                 ctInfo.fColorType = GrColorType::kR_8;
1694                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1695                 this->setColorTypeFormat(GrColorType::kR_8, GrGLFormat::kR8);
1696 
1697                 // External IO ColorTypes:
1698                 ctInfo.fExternalIOFormatCount = 2;
1699                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1700                         ctInfo.fExternalIOFormatCount);
1701                 int ioIdx = 0;
1702                 // Format: R8, Surface: kR_8, Data: kR_8
1703                 {
1704                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1705                     ioFormat.fColorType = GrColorType::kR_8;
1706                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1707                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1708                     ioFormat.fExternalReadFormat = GR_GL_RED;
1709                     // Not guaranteed by ES/WebGL.
1710                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1711                 }
1712 
1713                 // Format: R8, Surface: kR_8, Data: kR_8xxx
1714                 {
1715                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1716                     ioFormat.fColorType = GrColorType::kR_8xxx;
1717                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1718                     ioFormat.fExternalTexImageFormat = 0;
1719                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1720                 }
1721             }
1722 
1723             // Format: R8, Surface: kAlpha_8
1724             {
1725                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1726                 ctInfo.fColorType = GrColorType::kAlpha_8;
1727                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1728                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
1729                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
1730                 this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kR8);
1731 
1732                 // External IO ColorTypes:
1733                 ctInfo.fExternalIOFormatCount = 2;
1734                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1735                         ctInfo.fExternalIOFormatCount);
1736                 int ioIdx = 0;
1737                 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8
1738                 {
1739                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1740                     ioFormat.fColorType = GrColorType::kAlpha_8;
1741                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1742                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1743                     ioFormat.fExternalReadFormat = GR_GL_RED;
1744                     // Not guaranteed by ES/WebGL.
1745                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1746                 }
1747 
1748                 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8xxx
1749                 {
1750                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1751                     ioFormat.fColorType = GrColorType::kAlpha_8xxx;
1752                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1753                     ioFormat.fExternalTexImageFormat = 0;
1754                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1755                 }
1756             }
1757 
1758             // Format: R8, Surface: kGray_8
1759             {
1760                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1761                 ctInfo.fColorType = GrColorType::kGray_8;
1762                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1763                 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
1764                 this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kR8);
1765 
1766                 // External IO ColorTypes:
1767                 ctInfo.fExternalIOFormatCount = 2;
1768                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1769                         ctInfo.fExternalIOFormatCount);
1770                 int ioIdx = 0;
1771                 // Format: R8, Surface: kGray_8, Data: kGray_8
1772                 {
1773                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1774                     ioFormat.fColorType = GrColorType::kGray_8;
1775                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1776                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
1777                     ioFormat.fExternalReadFormat = GR_GL_RED;
1778                     // Not guaranteed by ES/WebGL.
1779                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1780                 }
1781 
1782                 // Format: R8, Surface: kGray_8, Data: kGray_8xxx
1783                 {
1784                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1785                     ioFormat.fColorType = GrColorType::kGray_8xxx;
1786                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1787                     ioFormat.fExternalTexImageFormat = 0;
1788                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1789                 }
1790             }
1791         }
1792     }
1793 
1794     // Format: ALPHA8
1795     {
1796         bool alpha8IsValidForGL = GR_IS_GR_GL(standard) &&
1797                 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1798         bool alpha8IsValidForGLES = GR_IS_GR_GL_ES(standard);
1799         bool alpha8IsValidForWebGL = GR_IS_GR_WEBGL(standard);
1800 
1801         FormatInfo& info = this->getFormatInfo(GrGLFormat::kALPHA8);
1802         info.fFormatType = FormatType::kNormalizedFixedPoint;
1803         // GL_EXT_texture_storage adds GL_ALPHA8 for texture storage. However, ES3 has glTexStorage
1804         // but does not have GL_ALPHA8 (and requires a sized internal format for glTexStorage).
1805         // WebGL never has GL_ALPHA8.
1806         bool alpha8SizedEnumSupported =
1807                 alpha8IsValidForGL ||
1808                 (alpha8IsValidForGLES && ctxInfo.hasExtension("GL_EXT_texture_storage"));
1809         bool alpha8TexStorageSupported = alpha8SizedEnumSupported && texStorageSupported;
1810 
1811         bool alpha8IsRenderable = false;
1812         if (alpha8IsValidForGL) {
1813             // Core profile removes ALPHA8 support.
1814             // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1815             alpha8IsRenderable = ctxInfo.version() >= GR_GL_VER(3, 0) ||
1816                                  ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1817         }
1818         info.fInternalFormatForRenderbuffer = GR_GL_ALPHA8;
1819         info.fDefaultExternalFormat = GR_GL_ALPHA;
1820         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1821         info.fDefaultColorType = GrColorType::kAlpha_8;
1822         if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1823             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1824         }
1825         if (alpha8IsRenderable && alpha8IsValidForGL) {
1826             // We will use ALPHA8 to create MSAA renderbuffers.
1827             SkASSERT(alpha8SizedEnumSupported);
1828             info.fFlags |= msaaRenderFlags;
1829         }
1830         if (alpha8TexStorageSupported) {
1831             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1832             info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1833         } else {
1834             // Even if GL_ALPHA8 is added to ES by GL_EXT_texture_storage it doesn't become legal
1835             // for glTexImage2D.
1836             if (!GR_IS_GR_GL_ES(standard) && texImageSupportsSizedInternalFormat &&
1837                 alpha8SizedEnumSupported) {
1838                 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1839             } else {
1840                 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA;
1841             }
1842         }
1843 
1844         if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1845             info.fColorTypeInfoCount = 1;
1846             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1847             int ctIdx = 0;
1848             // Format: ALPHA8, Surface: kAlpha_8
1849             {
1850                 if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1851                     auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1852                     ctInfo.fColorType = GrColorType::kAlpha_8;
1853                     ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
1854                                     ColorTypeInfo::kRenderable_Flag;
1855                     int idx = static_cast<int>(GrColorType::kAlpha_8);
1856                     if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1857                         this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kALPHA8);
1858                     }
1859 
1860                     // External IO ColorTypes:
1861                     ctInfo.fExternalIOFormatCount = 2;
1862                     ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1863                             ctInfo.fExternalIOFormatCount);
1864                     int ioIdx = 0;
1865                     // Format: ALPHA8, Surface: kAlpha_8, Data: kAlpha_8
1866                     {
1867                         auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1868                         ioFormat.fColorType = GrColorType::kAlpha_8;
1869                         ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1870                         ioFormat.fExternalTexImageFormat = GR_GL_ALPHA;
1871                         ioFormat.fExternalReadFormat = GR_GL_ALPHA;
1872                         // Not guaranteed by ES/WebGL.
1873                         ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1874                     }
1875 
1876                     // Format: ALPHA8, Surface: kAlpha_8, Data: kRGBA_8888
1877                     {
1878                         auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1879                         ioFormat.fColorType = GrColorType::kRGBA_8888;
1880                         ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1881                         ioFormat.fExternalTexImageFormat = 0;
1882                         ioFormat.fExternalReadFormat = GR_GL_RGBA;
1883                     }
1884                 }
1885             }
1886         }
1887     }
1888 
1889     // Do we support the lumincance and luminance_alpha formats
1890     bool lum8Supported = false;
1891     bool lum8SizedFormatSupported = false;
1892     if (GR_IS_GR_GL(standard) && !fIsCoreProfile) {
1893         lum8Supported = true;
1894         lum8SizedFormatSupported = true;
1895     } else if (GR_IS_GR_GL_ES(standard)) {
1896         lum8Supported = true;
1897         // Even on ES3 this extension is required to define LUMINANCE8. GL_LUMINANCE8 is not a
1898         // valid internal format for TexImage2D so we need to be using texture storage to use
1899         // it. Even though we check the extension for texture storage here, we also check to see
1900         // if texStorageSupported may have been disabled for a workaround.
1901         lum8SizedFormatSupported =
1902                 texStorageSupported && ctxInfo.hasExtension("GL_EXT_texture_storage");
1903     } else if (GR_IS_GR_WEBGL(standard)) {
1904         lum8Supported = true;
1905     }
1906 
1907     // Format: LUMINANCE8
1908     {
1909         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8);
1910         info.fFormatType = FormatType::kNormalizedFixedPoint;
1911         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8;
1912         info.fDefaultExternalFormat = GR_GL_LUMINANCE;
1913         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1914         info.fDefaultColorType = GrColorType::kGray_8;
1915 
1916         if (lum8Supported) {
1917             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1918         }
1919         if (texStorageSupported && lum8SizedFormatSupported) {
1920             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1921             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1922         } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1923             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1924         } else {
1925             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
1926         }
1927         // We are not enabling attaching to an FBO for LUMINANCE8 mostly because of confusion in the
1928         // spec. For GLES it does not seem to ever support LUMINANCE8 being color-renderable. For GL
1929         // versions less than 3.0 it is provided by GL_ARB_framebuffer_object. However, the original
1930         // version of that extension did not add LUMINANCE8, but was added in a later revsion. So
1931         // even the presence of that extension does not guarantee support. GL 3.0 and higher (core
1932         // or compatibility) do not list LUMINANCE8 as color-renderable (which is strange since the
1933         // GL_ARB_framebuffer_object extension was meant to bring 3.0 functionality to lower
1934         // versions).
1935 
1936         if (lum8Supported) {
1937             info.fColorTypeInfoCount = 1;
1938             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1939             int ctIdx = 0;
1940             // Format: LUMINANCE8, Surface: kGray_8
1941             {
1942                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1943                 ctInfo.fColorType = GrColorType::kGray_8;
1944                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1945                 int idx = static_cast<int>(GrColorType::kGray_8);
1946                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1947                     this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kLUMINANCE8);
1948                 }
1949 
1950                 // External IO ColorTypes:
1951                 ctInfo.fExternalIOFormatCount = 2;
1952                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1953                         ctInfo.fExternalIOFormatCount);
1954                 int ioIdx = 0;
1955                 // Format: LUMINANCE8, Surface: kGray_8, Data: kGray_8
1956                 {
1957                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1958                     ioFormat.fColorType = GrColorType::kGray_8;
1959                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1960                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
1961                     ioFormat.fExternalReadFormat = 0;
1962                 }
1963 
1964                 // Format: LUMINANCE8, Surface: kGray_8, Data: kRGBA_8888
1965                 {
1966                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1967                     ioFormat.fColorType = GrColorType::kRGBA_8888;
1968                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1969                     ioFormat.fExternalTexImageFormat = 0;
1970                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
1971                 }
1972             }
1973         }
1974     }
1975 
1976     // Format: LUMINANCE8_ALPHA8
1977     {
1978         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8_ALPHA8);
1979         info.fFormatType = FormatType::kNormalizedFixedPoint;
1980         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8_ALPHA8;
1981         info.fDefaultExternalFormat = GR_GL_LUMINANCE_ALPHA;
1982         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1983         info.fDefaultColorType = GrColorType::kGrayAlpha_88;
1984         if (lum8Supported) {
1985             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1986         }
1987         if (texStorageSupported && lum8SizedFormatSupported) {
1988             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1989             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1990         } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1991             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1992         } else {
1993             info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE_ALPHA;
1994         }
1995         // See note in LUMINANCE8 section about not attaching to framebuffers.
1996 
1997         if (lum8Supported) {
1998             info.fColorTypeInfoCount = 1;
1999             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2000             int ctIdx = 0;
2001             // Format: LUMINANCE8_ALPHA8, Surface: kGrayAlpha_88
2002             {
2003                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2004                 ctInfo.fColorType = GrColorType::kGrayAlpha_88;
2005                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2006                 int idx = static_cast<int>(GrColorType::kGrayAlpha_88);
2007                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2008                     this->setColorTypeFormat(GrColorType::kGrayAlpha_88,
2009                                              GrGLFormat::kLUMINANCE8_ALPHA8);
2010                 }
2011 
2012                 // External IO ColorTypes:
2013                 ctInfo.fExternalIOFormatCount = 2;
2014                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2015                         ctInfo.fExternalIOFormatCount);
2016                 int ioIdx = 0;
2017                 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kGrayAlpha_88
2018                 {
2019                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2020                     ioFormat.fColorType = GrColorType::kGrayAlpha_88;
2021                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2022                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE_ALPHA;
2023                     ioFormat.fExternalReadFormat = 0;
2024                 }
2025 
2026                 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kRGBA_8888
2027                 {
2028                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2029                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2030                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2031                     ioFormat.fExternalTexImageFormat = 0;
2032                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2033                 }
2034             }
2035         }
2036     }
2037     // Format: BGRA8
2038     {
2039         FormatInfo& info = this->getFormatInfo(GrGLFormat::kBGRA8);
2040         info.fFormatType = FormatType::kNormalizedFixedPoint;
2041 
2042         info.fDefaultExternalFormat = GR_GL_BGRA;
2043         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2044         info.fDefaultColorType = GrColorType::kBGRA_8888;
2045 
2046         GrGLenum bgraTexImageFormat;
2047         // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2048         // as a base format. Which base format depends on which extension is used.
2049         if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2050             // GL_EXT_texture_format_BGRA8888:
2051             //      This extension adds GL_BGRA as an unsized internal format. However, it is
2052             //      written against ES 2.0 and therefore doesn't define a GL_BGRA8 as ES 2.0 doesn't
2053             //      have sized internal formats. See later where we check for tex storage BGRA8
2054             //      support.
2055             bgraTexImageFormat = GR_GL_BGRA;
2056         } else {
2057             // GL_APPLE_texture_format_BGRA8888:
2058             //     ES 2.0: the extension makes BGRA an external format but not an internal format.
2059             //     ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format
2060             //             for glTexImage (just for glTexStorage).
2061             bgraTexImageFormat = GR_GL_RGBA;
2062         }
2063 
2064         // TexStorage requires using a sized internal format and BGRA8 is only supported if we have
2065         // the GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texture_storage and
2066         // GL_EXT_texture_format_BGRA8888.
2067         bool supportsBGRATexStorage = false;
2068 
2069         if (GR_IS_GR_GL_ES(standard)) {
2070             if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2071                 // The GL_EXT_texture_format_BGRA8888 extension adds BGRA color renderbuffer support
2072                 // for ES 2.0. The extension adds BGRA to the supported renerable formats in table
2073                 // 4.5. In ES 2.0. All the extensions that add multisample support, all reference
2074                 // table 4.5 as the formats that are supported. Thus we can use msaaRenderFlags.
2075                 // Additionally, the renderable support was added in a later revision of the
2076                 // extension. So it is possible for older drivers to support the extension but only
2077                 // an early revision of it without renderable support. We have no way of
2078                 // distinguishing between the two and assume renderable.
2079 
2080 
2081                 info.fFlags = FormatInfo::kTexturable_Flag
2082                             | FormatInfo::kTransfers_Flag;
2083                 // Only enable BGRA msaa if we know we're going through Angle. The spec for
2084                 // GL_EXT_texture_format_BGRA8888 was updated in 2016 to add support for GL_BGRA_EXT
2085                 // as a sized, renderable format. But we may end up running on old drivers written
2086                 // against earlier version of the spec. Also the interactions between all these
2087                 // extensions are very suibtle and it wouldn't be hard for a driver to mess them up.
2088                 // We are confident that Angle does it as we expect. Our non-angle test bots do seem
2089                 // to pass and draw correctly so we could consider enabling this more broadly in the
2090                 // future.
2091                 // In addition, we also need to disable BGRA MSAA on Mesa. When a client attempts
2092                 // to wrap a GPU-backed texture into an SkSurface with MSAA, Ganesh will create
2093                 // a MSAA renderbuffer to first render to before resolving to the single-sampled
2094                 // texture. Mesa claims to support EXT_texture_format_BGRA8888, and according to
2095                 // the spec, this should imply support for both BGRA textures and renderbuffers.
2096                 // In practice, however, Mesa only supports BGRA textures and will error on
2097                 // glRenderbufferStorage* if the internalformat is BGRA.
2098                 if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown &&
2099                     ctxInfo.angleDriver() != GrGLDriver::kMesa) {
2100                     // Angle incorrectly requires GL_BGRA8_EXT for the interalFormat for both ES2
2101                     // and ES3 even though this extension does not define that value. The extension
2102                     // only defines GL_BGRA_EXT as an internal format.
2103                     info.fInternalFormatForRenderbuffer = GR_GL_BGRA8;
2104                     info.fFlags |= msaaRenderFlags;
2105                 } else {
2106                     // It is not clear what the correct format to use on ES3 is. This extension only
2107                     // defines GL_BGRA_EXT. That is definitely the correct thing to use on ES2, but
2108                     // its unclear whether that is valid in ES3 or if it wants something like
2109                     // GL_BGRA8_EXT (which is only defined in the apple extenstion). For now we set
2110                     // everything to use BGRA since its the only explicitly defined value. Until we
2111                     // enable MSAA for non-angle this is a moot point.
2112                     info.fInternalFormatForRenderbuffer = GR_GL_BGRA;
2113                     info.fFlags |= nonMSAARenderFlags;
2114                 }
2115                 // GL_EXT_texture storage has defined interactions with
2116                 // GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but
2117                 // without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format.
2118                 if (ctxInfo.hasExtension("GL_EXT_texture_storage") &&
2119                     !formatWorkarounds.fDisableBGRATextureStorageForIntelWindowsES) {
2120                     supportsBGRATexStorage = true;
2121                 }
2122             } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
2123                 // This APPLE extension introduces complexity on ES2. It leaves the internal format
2124                 // as RGBA, but allows BGRA as the external format. From testing, it appears that
2125                 // the driver remembers the external format when the texture is created (with
2126                 // TexImage). If you then try to upload data in the other swizzle (with
2127                 // TexSubImage), it fails. We could work around this, but it adds even more state
2128                 // tracking to code that is already too tricky. Instead, we opt not to support BGRA
2129                 // on ES2 with this extension. This also side-steps some ambiguous interactions with
2130                 // the texture storage extension.
2131                 if (version >= GR_GL_VER(3,0)) {
2132                     // The APPLE extension doesn't explicitly make this renderable, but
2133                     // internally it appears to use RGBA8, which we'll patch up below.
2134                     info.fFlags = FormatInfo::kTexturable_Flag
2135                                 | FormatInfo::kTransfers_Flag
2136                                 | msaaRenderFlags;
2137                     // The GL_APPLE_texture_format_BGRA8888 does not add support for BGRA color
2138                     // renderbuffers at all so we use RGBA here.
2139                     info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
2140                     supportsBGRATexStorage = true;
2141                 }
2142             }
2143         }
2144         if (texStorageSupported && supportsBGRATexStorage) {
2145             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2146             info.fInternalFormatForTexImageOrStorage = GR_GL_BGRA8;
2147         } else {
2148             info.fInternalFormatForTexImageOrStorage = bgraTexImageFormat;
2149         }
2150 
2151         if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2152             info.fColorTypeInfoCount = 2;
2153             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2154             int ctIdx = 0;
2155             // Format: BGRA8, Surface: kBGRA_8888
2156             {
2157                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2158                 ctInfo.fColorType = GrColorType::kBGRA_8888;
2159                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2160                 this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kBGRA8);
2161 
2162                 // External IO ColorTypes:
2163                 ctInfo.fExternalIOFormatCount = 2;
2164                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2165                         ctInfo.fExternalIOFormatCount);
2166                 int ioIdx = 0;
2167                 // Format: BGRA8, Surface: kBGRA_8888, Data: kBGRA_8888
2168                 {
2169                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2170                     ioFormat.fColorType = GrColorType::kBGRA_8888;
2171                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2172                     ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2173                     ioFormat.fExternalReadFormat = 0;
2174                     ioFormat.fExternalReadFormat =
2175                             formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2176                     // Not guaranteed by ES/WebGL.
2177                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2178                 }
2179 
2180                 // Format: BGRA8, Surface: kBGRA_8888, Data: kRGBA_8888
2181                 {
2182                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2183                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2184                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2185                     ioFormat.fExternalTexImageFormat = 0;
2186                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2187                 }
2188             }
2189 
2190             // Format: BGRA8, Surface: kRGB_888x
2191             {
2192                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2193                 ctInfo.fColorType = GrColorType::kRGB_888x;
2194                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2195                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2196 
2197                 // External IO ColorTypes:
2198                 ctInfo.fExternalIOFormatCount = 1;
2199                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2200                         ctInfo.fExternalIOFormatCount);
2201                 int ioIdx = 0;
2202                 // Format: BGRA8, Surface: kRGB_888x, Data: kRGBA_888x
2203                 {
2204                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2205                     ioFormat.fColorType = GrColorType::kRGB_888x;
2206                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2207                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2208                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2209                 }
2210             }
2211         }
2212     }
2213 
2214     // Format: RGB565
2215     {
2216         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB565);
2217         info.fFormatType = FormatType::kNormalizedFixedPoint;
2218         info.fInternalFormatForRenderbuffer = GR_GL_RGB565;
2219         info.fDefaultExternalFormat = GR_GL_RGB;
2220         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2221         info.fDefaultColorType = GrColorType::kBGR_565;
2222         if (GR_IS_GR_GL(standard)) {
2223             if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
2224                 info.fFlags = FormatInfo::kTexturable_Flag
2225                             | FormatInfo::kTransfers_Flag
2226                             | msaaRenderFlags;
2227             }
2228         } else if (GR_IS_GR_GL_ES(standard)) {
2229             info.fFlags = FormatInfo::kTexturable_Flag
2230                         | FormatInfo::kTransfers_Flag
2231                         | msaaRenderFlags;
2232         } else if (GR_IS_GR_WEBGL(standard)) {
2233             info.fFlags = FormatInfo::kTexturable_Flag
2234                         | FormatInfo::kTransfers_Flag
2235                         | msaaRenderFlags;
2236         }
2237         // 565 is not a sized internal format on desktop GL. So on desktop with
2238         // 565 we always use an unsized internal format to let the system pick
2239         // the best sized format to convert the 565 data to. Since TexStorage
2240         // only allows sized internal formats we disallow it.
2241         //
2242         // TODO: As of 4.2, regular GL supports 565. This logic is due for an
2243         // update.
2244         if (texStorageSupported && GR_IS_GR_GL_ES(standard)) {
2245             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2246             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB565;
2247         } else {
2248             info.fInternalFormatForTexImageOrStorage =
2249                     texImageSupportsSizedInternalFormat ? GR_GL_RGB565 : GR_GL_RGB;
2250         }
2251 
2252         if (SkToBool(info.fFlags &FormatInfo::kTexturable_Flag)) {
2253             info.fColorTypeInfoCount = 1;
2254             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2255             int ctIdx = 0;
2256             // Format: RGB565, Surface: kBGR_565
2257             {
2258                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2259                 ctInfo.fColorType = GrColorType::kBGR_565;
2260                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2261                 this->setColorTypeFormat(GrColorType::kBGR_565, GrGLFormat::kRGB565);
2262 
2263                 // External IO ColorTypes:
2264                 ctInfo.fExternalIOFormatCount = 2;
2265                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2266                         ctInfo.fExternalIOFormatCount);
2267                 int ioIdx = 0;
2268                 // Format: RGB565, Surface: kBGR_565, Data: kBGR_565
2269                 {
2270                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2271                     ioFormat.fColorType = GrColorType::kBGR_565;
2272                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2273                     ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2274                     ioFormat.fExternalReadFormat = GR_GL_RGB;
2275                     // Not guaranteed by ES/WebGL.
2276                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2277                 }
2278 
2279                 // Format: RGB565, Surface: kBGR_565, Data: kRGBA_8888
2280                 {
2281                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2282                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2283                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2284                     ioFormat.fExternalTexImageFormat = 0;
2285                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2286                 }
2287             }
2288         }
2289     }
2290 
2291     // Format: RGBA16F
2292     {
2293         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16F);
2294         info.fFormatType = FormatType::kFloat;
2295         info.fInternalFormatForRenderbuffer = GR_GL_RGBA16F;
2296         info.fDefaultExternalFormat = GR_GL_RGBA;
2297         info.fDefaultExternalType = halfFloatType;
2298         info.fDefaultColorType = GrColorType::kRGBA_F16;
2299         bool rgba16FTextureSupport = false;
2300         bool rgba16FRenderTargetSupport = false;
2301 
2302         if (GR_IS_GR_GL(standard)) {
2303             if (version >= GR_GL_VER(3, 0)) {
2304                 rgba16FTextureSupport = true;
2305                 rgba16FRenderTargetSupport = true;
2306             } else if (ctxInfo.hasExtension("GL_ARB_texture_float")) {
2307                 rgba16FTextureSupport = true;
2308             }
2309         } else if (GR_IS_GR_GL_ES(standard)) {
2310             if (version >= GR_GL_VER(3, 0)) {
2311                 rgba16FTextureSupport = true;
2312                 rgba16FRenderTargetSupport =
2313                         version >= GR_GL_VER(3, 2) ||
2314                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2315                         ctxInfo.hasExtension("GL_EXT_color_buffer_float");
2316             } else if (ctxInfo.hasExtension("GL_OES_texture_half_float") &&
2317                        ctxInfo.hasExtension("GL_OES_texture_half_float_linear")) {
2318                 rgba16FTextureSupport = true;
2319                 rgba16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2320             }
2321         } else if (GR_IS_GR_WEBGL(standard)) {
2322             if (version >= GR_GL_VER(2, 0)) {
2323                 rgba16FTextureSupport = true;
2324                 rgba16FRenderTargetSupport =
2325                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2326                         ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
2327                         ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2328                         ctxInfo.hasExtension("EXT_color_buffer_float");
2329             } else if ((ctxInfo.hasExtension("GL_OES_texture_half_float") ||
2330                         ctxInfo.hasExtension("OES_texture_half_float")) &&
2331                        (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") ||
2332                         ctxInfo.hasExtension("OES_texture_half_float_linear"))) {
2333                 rgba16FTextureSupport = true;
2334                 // We don't check for EXT_color_buffer_float as it's only defined for WebGL 2.
2335                 rgba16FRenderTargetSupport =
2336                         ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2337                         ctxInfo.hasExtension("EXT_color_buffer_half_float");
2338             }
2339         }
2340 
2341         if (rgba16FTextureSupport) {
2342             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2343             if (rgba16FRenderTargetSupport) {
2344                 info.fFlags |= fpRenderFlags;
2345             }
2346         }
2347         if (texStorageSupported && !formatWorkarounds.fDisableRGBA16FTexStorageForCrBug1008003) {
2348             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2349             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16F;
2350         } else {
2351             info.fInternalFormatForTexImageOrStorage =
2352                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA16F : GR_GL_RGBA;
2353         }
2354 
2355         if (rgba16FTextureSupport) {
2356             uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2357 
2358             info.fColorTypeInfoCount = 3;
2359             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2360             int ctIdx = 0;
2361             // Format: RGBA16F, Surface: kRGBA_F16
2362             {
2363                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2364                 ctInfo.fColorType = GrColorType::kRGBA_F16;
2365                 ctInfo.fFlags = flags;
2366                 this->setColorTypeFormat(GrColorType::kRGBA_F16, GrGLFormat::kRGBA16F);
2367 
2368                 // External IO ColorTypes:
2369                 ctInfo.fExternalIOFormatCount = 2;
2370                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2371                         ctInfo.fExternalIOFormatCount);
2372                 int ioIdx = 0;
2373                 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F16
2374                 {
2375                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2376                     ioFormat.fColorType = GrColorType::kRGBA_F16;
2377                     ioFormat.fExternalType = halfFloatType;
2378                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2379                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2380                     // Not guaranteed by ES/WebGL.
2381                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2382                 }
2383 
2384                 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F32
2385                 {
2386                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2387                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2388                     ioFormat.fExternalType = GR_GL_FLOAT;
2389                     ioFormat.fExternalTexImageFormat = 0;
2390                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2391                 }
2392             }
2393 
2394             // Format: RGBA16F, Surface: kRGBA_F16_Clamped
2395             {
2396                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2397                 ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
2398                 ctInfo.fFlags = flags;
2399                 this->setColorTypeFormat(GrColorType::kRGBA_F16_Clamped, GrGLFormat::kRGBA16F);
2400 
2401                 // External IO ColorTypes:
2402                 ctInfo.fExternalIOFormatCount = 2;
2403                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2404                         ctInfo.fExternalIOFormatCount);
2405                 int ioIdx = 0;
2406                 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F16_Clamped
2407                 {
2408                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2409                     ioFormat.fColorType = GrColorType::kRGBA_F16_Clamped;
2410                     ioFormat.fExternalType = halfFloatType;
2411                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2412                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2413                     // Not guaranteed by ES/WebGL.
2414                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2415                 }
2416 
2417                 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F32
2418                 {
2419                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2420                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2421                     ioFormat.fExternalType = GR_GL_FLOAT;
2422                     ioFormat.fExternalTexImageFormat = 0;
2423                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2424                 }
2425             }
2426             // Format: RGBA16F, Surface: kRGB_F16F16F16x
2427             {
2428                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2429                 ctInfo.fColorType = GrColorType::kRGB_F16F16F16x;
2430                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2431                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2432                 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2433                 this->setColorTypeFormat(GrColorType::kRGB_F16F16F16x, GrGLFormat::kRGBA16F);
2434 
2435                 // External IO ColorTypes:
2436                 ctInfo.fExternalIOFormatCount = 2;
2437                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2438                         ctInfo.fExternalIOFormatCount);
2439                 int ioIdx = 0;
2440                 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGB_F16F16F16x
2441                 {
2442                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2443                     ioFormat.fColorType = GrColorType::kRGB_F16F16F16x;
2444                     ioFormat.fExternalType = halfFloatType;
2445                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2446                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2447                     // Not guaranteed by ES/WebGL.
2448                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2449                 }
2450                 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGBA_F32
2451                 {
2452                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2453                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2454                     ioFormat.fExternalType = GR_GL_FLOAT;
2455                     ioFormat.fExternalTexImageFormat = 0;
2456                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2457                 }
2458             }
2459         }
2460     }
2461 
2462     // Format: R16F
2463     {
2464         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16F);
2465         info.fFormatType = FormatType::kFloat;
2466         info.fInternalFormatForRenderbuffer = GR_GL_R16F;
2467         info.fDefaultExternalFormat = GR_GL_RED;
2468         info.fDefaultExternalType = halfFloatType;
2469         info.fDefaultColorType = GrColorType::kR_F16;
2470         bool r16FTextureSupport = false;
2471         bool r16FRenderTargetSupport = false;
2472 
2473         if (GR_IS_GR_GL(standard)) {
2474             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg")) {
2475                 r16FTextureSupport = true;
2476                 r16FRenderTargetSupport = true;
2477             }
2478         } else if (GR_IS_GR_GL_ES(standard)) {
2479             // It seems possible that a combination of GL_EXT_texture_rg and
2480             // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
2481             // clear. The latter mentions interaction but that may only be for renderbuffers as
2482             // neither adds the texture format explicitly.
2483             // GL_OES_texture_format_half_float makes no reference to RED formats.
2484             if (version >= GR_GL_VER(3, 0)) {
2485                 r16FTextureSupport = true;
2486                 r16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
2487                                           ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2488                                           ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2489             }
2490         } else if (GR_IS_GR_WEBGL(standard)) {
2491             if (version >= GR_GL_VER(2, 0)) {
2492                 r16FTextureSupport = true;
2493                 r16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2494                                           ctxInfo.hasExtension("EXT_color_buffer_float");
2495             }
2496         }
2497 
2498         if (r16FTextureSupport) {
2499             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2500             if (r16FRenderTargetSupport) {
2501                 info.fFlags |= fpRenderFlags;
2502             }
2503         }
2504         if (texStorageSupported) {
2505             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2506             info.fInternalFormatForTexImageOrStorage = GR_GL_R16F;
2507         } else {
2508             info.fInternalFormatForTexImageOrStorage =
2509                     texImageSupportsSizedInternalFormat ? GR_GL_R16F : GR_GL_RED;
2510         }
2511 
2512         if (r16FTextureSupport) {
2513             // Format: R16F, Surface: kAlpha_F16
2514             info.fColorTypeInfoCount = 1;
2515             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2516             int ctIdx = 0;
2517             {
2518                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2519                 ctInfo.fColorType = GrColorType::kAlpha_F16;
2520                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2521                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2522                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
2523                 this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kR16F);
2524 
2525                 // External IO ColorTypes:
2526                 ctInfo.fExternalIOFormatCount = 2;
2527                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2528                         ctInfo.fExternalIOFormatCount);
2529                 int ioIdx = 0;
2530                 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F16
2531                 {
2532                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2533                     ioFormat.fColorType = GrColorType::kAlpha_F16;
2534                     ioFormat.fExternalType = halfFloatType;
2535                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
2536                     ioFormat.fExternalReadFormat = GR_GL_RED;
2537                     // Not guaranteed by ES/WebGL.
2538                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2539                 }
2540 
2541                 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F32xxx
2542                 {
2543                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2544                     ioFormat.fColorType = GrColorType::kAlpha_F32xxx;
2545                     ioFormat.fExternalType = GR_GL_FLOAT;
2546                     ioFormat.fExternalTexImageFormat = 0;
2547                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2548                 }
2549             }
2550         }
2551     }
2552 
2553     // Format: LUMINANCE16F
2554     {
2555         // NOTE: We disallow lum16f on ES devices if linear filtering modes are not
2556         // supported. This is for simplicity, but a more granular approach is possible.
2557         bool lum16FSupported = false;
2558         bool lum16FSizedFormatSupported = false;
2559         GrGLenum lumHalfFloatType = halfFloatType;
2560         if (GR_IS_GR_GL(standard)) {
2561             if (!fIsCoreProfile && ctxInfo.hasExtension("GL_ARB_texture_float")) {
2562                 lum16FSupported = true;
2563                 lum16FSizedFormatSupported = true;
2564             }
2565         } else if (GR_IS_GR_GL_ES(standard)) {
2566             if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
2567                 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
2568                 lum16FSupported = true;
2569                 // Even in ES 3.0+ LUMINANCE and GL_HALF_FLOAT are not listed as a valid
2570                 // combination. Thus we must use GL_HALF_FLOAT_OES provided by the extension
2571                 // GL_OES_texture_half_float. Note: these two types are not defined to be the same
2572                 // value.
2573                 lumHalfFloatType = GR_GL_HALF_FLOAT_OES;
2574                 // Even on ES3 this extension is required to define LUMINANCE16F.
2575                 lum16FSizedFormatSupported = ctxInfo.hasExtension("GL_EXT_texture_storage");
2576             }
2577         } // No WebGL support
2578 
2579         if (formatWorkarounds.fDisableLuminance16F) {
2580             lum16FSupported = false;
2581         }
2582 
2583         FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE16F);
2584         info.fFormatType = FormatType::kFloat;
2585         info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE16F;
2586         info.fDefaultExternalFormat = GR_GL_LUMINANCE;
2587         info.fDefaultExternalType = lumHalfFloatType;
2588         info.fDefaultColorType = GrColorType::kGray_F16;
2589 
2590         if (lum16FSupported) {
2591             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2592 
2593             if (texStorageSupported && lum16FSizedFormatSupported) {
2594                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2595                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2596             } else if (texImageSupportsSizedInternalFormat && lum16FSizedFormatSupported) {
2597                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2598             } else {
2599                 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
2600             }
2601 
2602             info.fColorTypeInfoCount = 1;
2603             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2604             int ctIdx = 0;
2605             // Format: LUMINANCE16F, Surface: kAlpha_F16
2606             {
2607                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2608                 ctInfo.fColorType = GrColorType::kAlpha_F16;
2609                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2610                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2611                 ctInfo.fWriteSwizzle = skgpu::Swizzle("aaa0");
2612 
2613                 int idx = static_cast<int>(GrColorType::kAlpha_F16);
2614                 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2615                     this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kLUMINANCE16F);
2616                 }
2617 
2618                 // External IO ColorTypes:
2619                 ctInfo.fExternalIOFormatCount = 2;
2620                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2621                         ctInfo.fExternalIOFormatCount);
2622                 int ioIdx = 0;
2623                 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kAlpha_F16
2624                 {
2625                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2626                     ioFormat.fColorType = GrColorType::kAlpha_F16;
2627                     ioFormat.fExternalType = lumHalfFloatType;
2628                     ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
2629                     ioFormat.fExternalReadFormat = 0;
2630                 }
2631 
2632                 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kRGBA_F32
2633                 {
2634                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2635                     ioFormat.fColorType = GrColorType::kRGBA_F32;
2636                     ioFormat.fExternalType = GR_GL_FLOAT;
2637                     ioFormat.fExternalTexImageFormat = 0;
2638                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2639                 }
2640             }
2641         }
2642     }
2643 
2644     // Format: RGBx8
2645     {
2646         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBX8);
2647         info.fFormatType = FormatType::kNormalizedFixedPoint;
2648         info.fInternalFormatForRenderbuffer = GR_GL_RGBX8;
2649         info.fDefaultExternalFormat = GR_GL_RGB;
2650         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2651         info.fDefaultColorType = GrColorType::kRGB_888;
2652 
2653         bool supportsSizedRGBX = false;
2654         // The GL_ANGLE_rgbx_internal_format extension only adds the sized GL_RGBX8 type and does
2655         // not have a way to create a texture of that format with texImage using an unsized type. So
2656         // we require that we either have texture storage support or that tex image supports sized
2657         // formats to say that this format is supported.
2658         if (GR_IS_GR_GL_ES(standard) && ctxInfo.hasExtension("GL_ANGLE_rgbx_internal_format") &&
2659             (texStorageSupported || texImageSupportsSizedInternalFormat)) {
2660             supportsSizedRGBX = true;
2661         }
2662 
2663         if (supportsSizedRGBX) {
2664             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBX8;
2665             info.fFlags = FormatInfo::kTexturable_Flag |
2666                           FormatInfo::kTransfers_Flag |
2667                           msaaRenderFlags;
2668             if (texStorageSupported) {
2669                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2670             }
2671             info.fColorTypeInfoCount = 1;
2672             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2673             int ctIdx = 0;
2674             // Format: RGBX8, Surface: kRGB_888x
2675             {
2676                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2677                 ctInfo.fColorType = GrColorType::kRGB_888x;
2678                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2679                 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGBX8);
2680 
2681                 // External IO ColorTypes:
2682                 ctInfo.fExternalIOFormatCount = 2;
2683                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2684                         ctInfo.fExternalIOFormatCount);
2685                 int ioIdx = 0;
2686                 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888
2687                 {
2688                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2689                     ioFormat.fColorType = GrColorType::kRGB_888;
2690                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2691                     ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2692                     ioFormat.fExternalReadFormat = 0;
2693                 }
2694 
2695                 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888x
2696                 {
2697                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2698                     ioFormat.fColorType = GrColorType::kRGB_888x;
2699                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2700                     ioFormat.fExternalTexImageFormat = 0;
2701                     ioFormat.fExternalReadFormat = GR_GL_RGBX8;
2702                 }
2703             }
2704         }
2705     }
2706 
2707     // Format: RGB8
2708     {
2709         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB8);
2710         info.fFormatType = FormatType::kNormalizedFixedPoint;
2711         info.fInternalFormatForRenderbuffer = GR_GL_RGB8;
2712         info.fDefaultExternalFormat = GR_GL_RGB;
2713         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2714         info.fDefaultColorType = GrColorType::kRGB_888;
2715         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2716         if (GR_IS_GR_GL(standard)) {
2717             // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be
2718             // a supported render buffer format. Since we usually use render buffers for MSAA on
2719             // non-ES GL we don't support MSAA for GL_RGB8. On 4.2+ we could check using
2720             // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if
2721             // this becomes an issue.
2722             info.fFlags |= nonMSAARenderFlags;
2723         } else if (GR_IS_GR_GL_ES(standard)) {
2724             // 3.0 and the extension support this as a render buffer format.
2725             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
2726                 info.fFlags |= msaaRenderFlags;
2727             }
2728         } else if (GR_IS_GR_WEBGL(standard)) {
2729             // WebGL seems to support RBG8
2730             info.fFlags |= msaaRenderFlags;
2731         }
2732         if (texStorageSupported) {
2733             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2734             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB8;
2735         } else {
2736             info.fInternalFormatForTexImageOrStorage =
2737                     texImageSupportsSizedInternalFormat ? GR_GL_RGB8 : GR_GL_RGB;
2738         }
2739 
2740         info.fColorTypeInfoCount = 1;
2741         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2742         int ctIdx = 0;
2743         // Format: RGB8, Surface: kRGB_888x
2744         {
2745             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2746             ctInfo.fColorType = GrColorType::kRGB_888x;
2747             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2748 
2749             int idx = static_cast<int>(GrColorType::kRGB_888x);
2750             if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2751                 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGB8);
2752             }
2753 
2754             // External IO ColorTypes:
2755             ctInfo.fExternalIOFormatCount = 2;
2756             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2757                     ctInfo.fExternalIOFormatCount);
2758             int ioIdx = 0;
2759             // Format: RGB8, Surface: kRGB_888x, Data: kRGB_888
2760             {
2761                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2762                 ioFormat.fColorType = GrColorType::kRGB_888;
2763                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2764                 ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2765                 ioFormat.fExternalReadFormat = 0;
2766             }
2767 
2768             // Format: RGB8, Surface: kRGB_888x, Data: kRGBA_8888
2769             {
2770                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2771                 ioFormat.fColorType = GrColorType::kRGBA_8888;
2772                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2773                 ioFormat.fExternalTexImageFormat = 0;
2774                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2775             }
2776         }
2777     }
2778 
2779     // Format: RG8
2780     {
2781         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG8);
2782         info.fFormatType = FormatType::kNormalizedFixedPoint;
2783         info.fInternalFormatForRenderbuffer = GR_GL_RG8;
2784         info.fDefaultExternalFormat = GR_GL_RG;
2785         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2786         info.fDefaultColorType = GrColorType::kRG_88;
2787         bool rg8Support = false;
2788         if (GR_IS_GR_GL(standard)) {
2789             rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
2790         } else if (GR_IS_GR_GL_ES(standard)) {
2791             rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
2792         } else if (GR_IS_GR_WEBGL(standard)) {
2793             rg8Support = version >= GR_GL_VER(2, 0);
2794         }
2795         if (rg8Support) {
2796             info.fFlags |= FormatInfo::kTexturable_Flag
2797                         |  FormatInfo::kTransfers_Flag
2798                         |  msaaRenderFlags;
2799             if (texStorageSupported) {
2800                 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2801                 info.fInternalFormatForTexImageOrStorage = GR_GL_RG8;
2802             }
2803         }
2804         if (!(info.fFlags & FormatInfo::kUseTexStorage_Flag)) {
2805             info.fInternalFormatForTexImageOrStorage =
2806                     texImageSupportsSizedInternalFormat ? GR_GL_RG8 : GR_GL_RG;
2807         }
2808         if (rg8Support) {
2809             info.fColorTypeInfoCount = 1;
2810             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2811             int ctIdx = 0;
2812             // Format: RG8, Surface: kRG_88
2813             {
2814                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2815                 ctInfo.fColorType = GrColorType::kRG_88;
2816                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2817                 this->setColorTypeFormat(GrColorType::kRG_88, GrGLFormat::kRG8);
2818 
2819                 // External IO ColorTypes:
2820                 ctInfo.fExternalIOFormatCount = 2;
2821                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2822                         ctInfo.fExternalIOFormatCount);
2823                 int ioIdx = 0;
2824                 // Format: RG8, Surface: kRG_88, Data: kRG_88
2825                 {
2826                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2827                     ioFormat.fColorType = GrColorType::kRG_88;
2828                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2829                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
2830                     ioFormat.fExternalReadFormat = 0;
2831                     if (GR_IS_GR_GL(standard) && !formatWorkarounds.fDisallowDirectRG8ReadPixels) {
2832                         ioFormat.fExternalReadFormat = GR_GL_RG;
2833                     }
2834                 }
2835 
2836                 // Format: RG8, Surface: kRG_88, Data: kRGBA_8888
2837                 {
2838                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2839                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2840                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2841                     ioFormat.fExternalTexImageFormat = 0;
2842                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2843                 }
2844             }
2845         }
2846     }
2847 
2848     // Format: RGB10_A2
2849     {
2850         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB10_A2);
2851         info.fFormatType = FormatType::kNormalizedFixedPoint;
2852         info.fInternalFormatForRenderbuffer = GR_GL_RGB10_A2;
2853         info.fDefaultExternalFormat = GR_GL_RGBA;
2854         info.fDefaultExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2855         info.fDefaultColorType = GrColorType::kRGBA_1010102;
2856         if (GR_IS_GR_GL(standard) ||
2857            (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
2858             info.fFlags = FormatInfo::kTexturable_Flag
2859                         | FormatInfo::kTransfers_Flag
2860                         | msaaRenderFlags;
2861         } else if (GR_IS_GR_GL_ES(standard) &&
2862                    ctxInfo.hasExtension("GL_EXT_texture_type_2_10_10_10_REV")) {
2863             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2864         } // No WebGL support
2865 
2866         if (texStorageSupported) {
2867             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2868             info.fInternalFormatForTexImageOrStorage = GR_GL_RGB10_A2;
2869         } else {
2870             info.fInternalFormatForTexImageOrStorage =
2871                     texImageSupportsSizedInternalFormat ? GR_GL_RGB10_A2 : GR_GL_RGBA;
2872         }
2873 
2874         if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2875             bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
2876                     (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
2877 
2878             info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
2879             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2880             int ctIdx = 0;
2881             // Format: RGB10_A2, Surface: kRGBA_1010102
2882             {
2883                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2884                 ctInfo.fColorType = GrColorType::kRGBA_1010102;
2885                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2886                 this->setColorTypeFormat(GrColorType::kRGBA_1010102, GrGLFormat::kRGB10_A2);
2887 
2888                 // External IO ColorTypes:
2889                 ctInfo.fExternalIOFormatCount = 2;
2890                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2891                         ctInfo.fExternalIOFormatCount);
2892                 int ioIdx = 0;
2893                 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_1010102
2894                 {
2895                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2896                     ioFormat.fColorType = GrColorType::kRGBA_1010102;
2897                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2898                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2899                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2900                     // Not guaranteed by ES/WebGL.
2901                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2902                 }
2903 
2904                 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_8888
2905                 {
2906                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2907                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2908                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2909                     ioFormat.fExternalTexImageFormat = 0;
2910                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2911                 }
2912             }
2913             //------------------------------------------------------------------
2914             // Format: RGB10_A2, Surface: kBGRA_1010102
2915             if (supportsBGRAColorType) {
2916                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2917                 ctInfo.fColorType = GrColorType::kBGRA_1010102;
2918                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2919                 this->setColorTypeFormat(GrColorType::kBGRA_1010102, GrGLFormat::kRGB10_A2);
2920 
2921                 // External IO ColorTypes:
2922                 ctInfo.fExternalIOFormatCount = 2;
2923                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2924                         ctInfo.fExternalIOFormatCount);
2925                 int ioIdx = 0;
2926                 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kBGRA_1010102
2927                 {
2928                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2929                     ioFormat.fColorType = GrColorType::kBGRA_1010102;
2930                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2931                     ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2932                     ioFormat.fExternalReadFormat =
2933                             formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2934                     // Not guaranteed by ES/WebGL.
2935                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2936                 }
2937 
2938                 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kRGBA_8888
2939                 {
2940                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2941                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2942                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2943                     ioFormat.fExternalTexImageFormat = 0;
2944                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2945                 }
2946             }
2947             // Format: RGB10_A2, Surface: kRGB_101010x
2948             {
2949                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2950                 ctInfo.fColorType = GrColorType::kRGB_101010x;
2951                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2952                 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2953                 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2954                 this->setColorTypeFormat(GrColorType::kRGB_101010x, GrGLFormat::kRGB10_A2);
2955 
2956                 // External IO ColorTypes:
2957                 ctInfo.fExternalIOFormatCount = 2;
2958                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2959                         ctInfo.fExternalIOFormatCount);
2960                 int ioIdx = 0;
2961                 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGB_101010x
2962                 {
2963                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2964                     ioFormat.fColorType = GrColorType::kRGB_101010x;
2965                     ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2966                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2967                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2968                     // Not guaranteed by ES/WebGL.
2969                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2970                 }
2971                 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGBA_8888
2972                 {
2973                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2974                     ioFormat.fColorType = GrColorType::kRGBA_8888;
2975                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2976                     ioFormat.fExternalTexImageFormat = 0;
2977                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2978                 }
2979             }
2980 
2981         }
2982     }
2983 
2984     // Format: RGBA4
2985     {
2986         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA4);
2987         info.fFormatType = FormatType::kNormalizedFixedPoint;
2988         info.fInternalFormatForRenderbuffer = GR_GL_RGBA4;
2989         info.fDefaultExternalFormat = GR_GL_RGBA;
2990         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
2991         info.fDefaultColorType = GrColorType::kABGR_4444;
2992         info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2993         if (GR_IS_GR_GL(standard)) {
2994             if (version >= GR_GL_VER(4, 2)) {
2995                 info.fFlags |= msaaRenderFlags;
2996             }
2997         } else if (GR_IS_GR_GL_ES(standard)) {
2998             info.fFlags |= msaaRenderFlags;
2999         } else if (GR_IS_GR_WEBGL(standard)) {
3000             info.fFlags |= msaaRenderFlags;
3001         }
3002         if (texStorageSupported) {
3003             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3004             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA4;
3005         } else {
3006             info.fInternalFormatForTexImageOrStorage =
3007                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA4 : GR_GL_RGBA;
3008         }
3009 
3010         info.fColorTypeInfoCount = 1;
3011         info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3012         int ctIdx = 0;
3013         // Format: RGBA4, Surface: kABGR_4444
3014         {
3015             auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3016             ctInfo.fColorType = GrColorType::kABGR_4444;
3017             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3018             this->setColorTypeFormat(GrColorType::kABGR_4444, GrGLFormat::kRGBA4);
3019 
3020             // External IO ColorTypes:
3021             ctInfo.fExternalIOFormatCount = 2;
3022             ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3023                     ctInfo.fExternalIOFormatCount);
3024             int ioIdx = 0;
3025             // Format: RGBA4, Surface: kABGR_4444, Data: kABGR_4444
3026             {
3027                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3028                 ioFormat.fColorType = GrColorType::kABGR_4444;
3029                 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
3030                 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3031                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3032                 // Not guaranteed by ES/WebGL.
3033                 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3034             }
3035 
3036             // Format: RGBA4, Surface: kABGR_4444, Data: kRGBA_8888
3037             {
3038                 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3039                 ioFormat.fColorType = GrColorType::kRGBA_8888;
3040                 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3041                 ioFormat.fExternalTexImageFormat = 0;
3042                 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3043             }
3044         }
3045     }
3046 
3047     // Format: SRGB8_ALPHA8
3048     {
3049         FormatInfo& info = this->getFormatInfo(GrGLFormat::kSRGB8_ALPHA8);
3050         info.fFormatType = FormatType::kNormalizedFixedPoint;
3051         info.fInternalFormatForRenderbuffer = GR_GL_SRGB8_ALPHA8;
3052         info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
3053         info.fDefaultColorType = GrColorType::kRGBA_8888_SRGB;
3054 
3055         // We may modify the default external format below.
3056         info.fDefaultExternalFormat = GR_GL_RGBA;
3057         bool srgb8Alpha8TexStorageSupported = texStorageSupported;
3058         bool srgb8Alpha8TextureSupport = false;
3059         bool srgb8Alpha8RenderTargetSupport = false;
3060         if (GR_IS_GR_GL(standard)) {
3061             if (version >= GR_GL_VER(3, 0)) {
3062                 srgb8Alpha8TextureSupport = true;
3063                 srgb8Alpha8RenderTargetSupport = true;
3064             } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
3065                 srgb8Alpha8TextureSupport = true;
3066                 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
3067                     ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
3068                     srgb8Alpha8RenderTargetSupport = true;
3069                 }
3070             }
3071         } else if (GR_IS_GR_GL_ES(standard)) {
3072             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_sRGB")) {
3073                 srgb8Alpha8TextureSupport = true;
3074                 srgb8Alpha8RenderTargetSupport = true;
3075             }
3076             if (version < GR_GL_VER(3, 0)) {
3077                 // ES 2.0 requires that the external format matches the internal format.
3078                 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3079                 // There is no defined interaction between GL_EXT_sRGB and GL_EXT_texture_storage.
3080                 srgb8Alpha8TexStorageSupported = false;
3081             }
3082         } else if (GR_IS_GR_WEBGL(standard)) {
3083             // sRGB extension should be on most WebGL 1.0 contexts, although sometimes under 2
3084             // names.
3085             if (version >= GR_GL_VER(2, 0) || ctxInfo.hasExtension("GL_EXT_sRGB") ||
3086                 ctxInfo.hasExtension("EXT_sRGB")) {
3087                 srgb8Alpha8TextureSupport = true;
3088                 srgb8Alpha8RenderTargetSupport = true;
3089             }
3090             if (version < GR_GL_VER(2, 0)) {
3091                 // WebGL 1.0 requires that the external format matches the internal format.
3092                 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3093                 // There is no extension to WebGL 1 that adds glTexStorage.
3094                 SkASSERT(!srgb8Alpha8TexStorageSupported);
3095             }
3096         }
3097 
3098         if (srgb8Alpha8TextureSupport) {
3099             info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3100             if (srgb8Alpha8RenderTargetSupport) {
3101                 info.fFlags |= formatWorkarounds.fDisableSRGBRenderWithMSAAForMacAMD
3102                                        ? nonMSAARenderFlags
3103                                        : msaaRenderFlags;
3104             }
3105         }
3106         if (srgb8Alpha8TexStorageSupported) {
3107             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3108             info.fInternalFormatForTexImageOrStorage = GR_GL_SRGB8_ALPHA8;
3109         } else {
3110             info.fInternalFormatForTexImageOrStorage =
3111                     texImageSupportsSizedInternalFormat ? GR_GL_SRGB8_ALPHA8 : GR_GL_SRGB_ALPHA;
3112         }
3113 
3114         if (srgb8Alpha8TextureSupport) {
3115             info.fColorTypeInfoCount = 1;
3116             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3117             int ctIdx = 0;
3118             // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB
3119             {
3120                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3121                 ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
3122                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3123                 this->setColorTypeFormat(GrColorType::kRGBA_8888_SRGB, GrGLFormat::kSRGB8_ALPHA8);
3124 
3125                 // External IO ColorTypes:
3126                 ctInfo.fExternalIOFormatCount = 1;
3127                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3128                         ctInfo.fExternalIOFormatCount);
3129                 int ioIdx = 0;
3130 
3131                 // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB, Data: kRGBA_8888_SRGB
3132                 {
3133                     // GL does not do srgb<->rgb conversions when transferring between cpu and gpu.
3134                     // Thus, the external format is GL_RGBA. See below for note about ES2.0 and
3135                     // glTex[Sub]Image.
3136                     GrGLenum texImageExternalFormat = GR_GL_RGBA;
3137 
3138                     // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the
3139                     // <format> param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and
3140                     // <format> params to match. Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the
3141                     // <format> param. On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the
3142                     // <format> param to glTexImage.
3143                     if (GR_IS_GR_GL_ES(standard) && version == GR_GL_VER(2,0)) {
3144                         texImageExternalFormat = GR_GL_SRGB_ALPHA;
3145                     }
3146                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3147                     ioFormat.fColorType = GrColorType::kRGBA_8888_SRGB;
3148                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3149                     ioFormat.fExternalTexImageFormat = texImageExternalFormat;
3150                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3151                 }
3152             }
3153         }
3154     }
3155 
3156     // Format: COMPRESSED_RGB8_BC1
3157     {
3158         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_BC1);
3159         info.fFormatType = FormatType::kNormalizedFixedPoint;
3160         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
3161         if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3162             if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3163                 info.fFlags = FormatInfo::kTexturable_Flag;
3164             }
3165         } else if (GR_IS_GR_WEBGL(standard)) {
3166             if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3167                 info.fFlags = FormatInfo::kTexturable_Flag;
3168             }
3169         }
3170 
3171         // There are no support GrColorTypes for this format
3172     }
3173 
3174     // Format: COMPRESSED_RGBA8_BC1
3175     {
3176         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGBA8_BC1);
3177         info.fFormatType = FormatType::kNormalizedFixedPoint;
3178         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3179         if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3180             if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3181                 info.fFlags = FormatInfo::kTexturable_Flag;
3182             }
3183         } else if (GR_IS_GR_WEBGL(standard)) {
3184             if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3185                 info.fFlags = FormatInfo::kTexturable_Flag;
3186             }
3187         }
3188 
3189         // There are no support GrColorTypes for this format
3190     }
3191 
3192     // Format: COMPRESSED_RGB8_ETC2
3193     {
3194         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_ETC2);
3195         info.fFormatType = FormatType::kNormalizedFixedPoint;
3196         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB8_ETC2;
3197         if (!formatWorkarounds.fDisallowETC2Compression) {
3198             if (GR_IS_GR_GL(standard)) {
3199                 if (version >= GR_GL_VER(4, 3) ||
3200                     ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
3201                     info.fFlags = FormatInfo::kTexturable_Flag;
3202                 }
3203             } else if (GR_IS_GR_GL_ES(standard)) {
3204                 if (version >= GR_GL_VER(3, 0) ||
3205                     ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture")) {
3206                     info.fFlags = FormatInfo::kTexturable_Flag;
3207                 }
3208             } else if (GR_IS_GR_WEBGL(standard)) {
3209                 if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc")) {
3210                     info.fFlags = FormatInfo::kTexturable_Flag;
3211                 }
3212             }
3213         }
3214 
3215         // There are no support GrColorTypes for this format
3216     }
3217 
3218     // Format: COMPRESSED_ETC1_RGB8
3219     {
3220         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ETC1_RGB8);
3221         info.fFormatType = FormatType::kNormalizedFixedPoint;
3222         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_ETC1_RGB8;
3223         if (GR_IS_GR_GL_ES(standard)) {
3224             if (ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
3225                 info.fFlags = FormatInfo::kTexturable_Flag;
3226             }
3227         } else if (GR_IS_GR_WEBGL(standard)) {
3228             if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc1")) {
3229                 info.fFlags = FormatInfo::kTexturable_Flag;
3230             }
3231         }
3232         // No GL support
3233 
3234         // There are no support GrColorTypes for this format
3235     }
3236 
3237     // Format: COMPRESSED_ASTC_RGB8_4x4
3238     {
3239         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_4x4);
3240         info.fFormatType = FormatType::kNormalizedFixedPoint;
3241         info.fDefaultExternalFormat = GR_GL_RGB;
3242         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_ASTC_4x4;
3243         if (GR_IS_GR_GL_ES(standard)) {
3244             if (ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
3245                 info.fFlags = FormatInfo::kTexturable_Flag;
3246             }
3247         } // No GL or WebGL support
3248 
3249         // There are no support GrColorTypes for this format
3250     }
3251 
3252     // Format: COMPRESSED_ASTC_RGB8_6x6
3253     {
3254         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_6x6);
3255         info.fFormatType = FormatType::kNormalizedFixedPoint;
3256         info.fDefaultExternalFormat = GR_GL_RGB;
3257         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_ASTC_6x6;
3258         if (GR_IS_GR_GL_ES(standard)) {
3259             if (ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
3260                 info.fFlags = FormatInfo::kTexturable_Flag;
3261             }
3262         } // No GL or WebGL support
3263 
3264         // There are no support GrColorTypes for this format
3265     }
3266 
3267     // Format: COMPRESSED_ASTC_RGB8_8x8
3268     {
3269         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_8x8);
3270         info.fFormatType = FormatType::kNormalizedFixedPoint;
3271         info.fDefaultExternalFormat = GR_GL_RGB;
3272         info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_ASTC_8x8;
3273         if (GR_IS_GR_GL_ES(standard)) {
3274             if (ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
3275                 info.fFlags = FormatInfo::kTexturable_Flag;
3276             }
3277         } // No GL or WebGL support
3278 
3279         // There are no support GrColorTypes for this format
3280     }
3281 
3282     // Format: R16
3283     {
3284         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16);
3285         info.fFormatType = FormatType::kNormalizedFixedPoint;
3286         info.fInternalFormatForRenderbuffer = GR_GL_R16;
3287         info.fDefaultExternalFormat = GR_GL_RED;
3288         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3289         info.fDefaultColorType = GrColorType::kR_16;
3290         bool r16Supported = false;
3291         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3292             if (GR_IS_GR_GL(standard)) {
3293                 r16Supported = version >= GR_GL_VER(3, 0) ||
3294                                ctxInfo.hasExtension("GL_ARB_texture_rg");
3295             } else if (GR_IS_GR_GL_ES(standard)) {
3296                 r16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3297             }  // No WebGL support
3298         }
3299 
3300         if (r16Supported) {
3301             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3302             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3303                 info.fFlags |= FormatInfo::kTransfers_Flag;
3304             }
3305         }
3306 
3307         if (texStorageSupported) {
3308             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3309             info.fInternalFormatForTexImageOrStorage = GR_GL_R16;
3310         } else {
3311             info.fInternalFormatForTexImageOrStorage =
3312                     texImageSupportsSizedInternalFormat ? GR_GL_R16 : GR_GL_RED;
3313         }
3314 
3315         if (r16Supported) {
3316             info.fColorTypeInfoCount = 1;
3317             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3318             int ctIdx = 0;
3319             // Format: R16, Surface: kAlpha_16
3320             {
3321                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3322                 ctInfo.fColorType = GrColorType::kAlpha_16;
3323                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3324                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
3325                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
3326                 this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
3327 
3328                 // External IO ColorTypes:
3329                 ctInfo.fExternalIOFormatCount = 2;
3330                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3331                         ctInfo.fExternalIOFormatCount);
3332                 int ioIdx = 0;
3333                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_16
3334                 {
3335                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3336                     ioFormat.fColorType = GrColorType::kAlpha_16;
3337                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3338                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
3339                     ioFormat.fExternalReadFormat = GR_GL_RED;
3340                     // Not guaranteed by ES/WebGL.
3341                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3342                 }
3343 
3344                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
3345                 {
3346                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3347                     ioFormat.fColorType = GrColorType::kAlpha_8xxx;
3348                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3349                     ioFormat.fExternalTexImageFormat = 0;
3350                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3351                 }
3352             }
3353         }
3354     }
3355 
3356     // Format: RG16
3357     {
3358         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16);
3359         info.fFormatType = FormatType::kNormalizedFixedPoint;
3360         info.fInternalFormatForTexImageOrStorage =
3361                 texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3362         info.fInternalFormatForRenderbuffer = GR_GL_RG16;
3363         info.fDefaultExternalFormat = GR_GL_RG;
3364         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3365         info.fDefaultColorType = GrColorType::kRG_1616;
3366         bool rg16Supported = false;
3367         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3368             if (GR_IS_GR_GL(standard)) {
3369                 rg16Supported = version >= GR_GL_VER(3, 0) ||
3370                                 ctxInfo.hasExtension("GL_ARB_texture_rg");
3371             } else if (GR_IS_GR_GL_ES(standard)) {
3372                 rg16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3373             }  // No WebGL support
3374         }
3375 
3376         if (rg16Supported) {
3377             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3378             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3379                 info.fFlags |= FormatInfo::kTransfers_Flag;
3380             }
3381         }
3382 
3383         if (texStorageSupported) {
3384             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3385             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16;
3386         } else {
3387             info.fInternalFormatForTexImageOrStorage =
3388                     texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3389         }
3390 
3391         if (rg16Supported) {
3392             info.fColorTypeInfoCount = 1;
3393             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3394             int ctIdx = 0;
3395             // Format: GR_GL_RG16, Surface: kRG_1616
3396             {
3397                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3398                 ctInfo.fColorType = GrColorType::kRG_1616;
3399                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3400                 this->setColorTypeFormat(GrColorType::kRG_1616, GrGLFormat::kRG16);
3401 
3402                 // External IO ColorTypes:
3403                 ctInfo.fExternalIOFormatCount = 2;
3404                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3405                         ctInfo.fExternalIOFormatCount);
3406                 int ioIdx = 0;
3407                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRG_1616
3408                 {
3409                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3410                     ioFormat.fColorType = GrColorType::kRG_1616;
3411                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3412                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3413                     ioFormat.fExternalReadFormat = GR_GL_RG;
3414                     // Not guaranteed by ES/WebGL.
3415                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3416                 }
3417 
3418                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRGBA_8888
3419                 {
3420                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3421                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3422                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3423                     ioFormat.fExternalTexImageFormat = 0;
3424                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3425                 }
3426             }
3427         }
3428     }
3429 
3430     // Format: RGBA16
3431     {
3432         bool rgba16Support = false;
3433         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3434             if (GR_IS_GR_GL(standard)) {
3435                 rgba16Support = version >= GR_GL_VER(3, 0);
3436             } else if (GR_IS_GR_GL_ES(standard)) {
3437                 rgba16Support = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3438             }  // No WebGL support
3439         }
3440 
3441         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16);
3442         info.fFormatType = FormatType::kNormalizedFixedPoint;
3443 
3444         info.fInternalFormatForRenderbuffer = GR_GL_RGBA16;
3445         info.fDefaultExternalFormat = GR_GL_RGBA;
3446         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3447         info.fDefaultColorType = GrColorType::kRGBA_16161616;
3448         if (rgba16Support) {
3449             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3450             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3451                 info.fFlags |= FormatInfo::kTransfers_Flag;
3452             }
3453         }
3454 
3455         if (texStorageSupported) {
3456             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3457             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16;
3458         } else {
3459             info.fInternalFormatForTexImageOrStorage =
3460                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA16 : GR_GL_RGBA;
3461         }
3462 
3463         if (rgba16Support) {
3464             // Format: GR_GL_RGBA16, Surface: kRGBA_16161616
3465             info.fColorTypeInfoCount = 1;
3466             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3467             int ctIdx = 0;
3468             {
3469                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3470                 ctInfo.fColorType = GrColorType::kRGBA_16161616;
3471                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3472                 this->setColorTypeFormat(GrColorType::kRGBA_16161616, GrGLFormat::kRGBA16);
3473 
3474                 // External IO ColorTypes:
3475                 ctInfo.fExternalIOFormatCount = 2;
3476                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3477                         ctInfo.fExternalIOFormatCount);
3478                 int ioIdx = 0;
3479                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_16161616
3480                 {
3481                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3482                     ioFormat.fColorType = GrColorType::kRGBA_16161616;
3483                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3484                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3485                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3486                     // Not guaranteed by ES/WebGL.
3487                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3488                 }
3489 
3490                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_8888
3491                 {
3492                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3493                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3494                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3495                     ioFormat.fExternalTexImageFormat = 0;
3496                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3497                 }
3498             }
3499         }
3500     }
3501 
3502     // Format:RG16F
3503     {
3504         bool rg16FTextureSupport = false;
3505         bool rg16FRenderTargetSupport = false;
3506         if (GR_IS_GR_GL(standard)) {
3507             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
3508                 rg16FTextureSupport = true;
3509                 rg16FRenderTargetSupport = true;
3510             }
3511         } else if (GR_IS_GR_GL_ES(standard)) {
3512             // It seems possible that a combination of GL_EXT_texture_rg and
3513             // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
3514             // clear. The latter mentions interaction but that may only be for renderbuffers as
3515             // neither adds the texture format explicitly.
3516             // GL_OES_texture_format_half_float makes no reference to RG formats.
3517             if (version >= GR_GL_VER(3, 0)) {
3518                 rg16FTextureSupport = true;
3519                 rg16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
3520                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3521                                            ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
3522             }
3523         } else if (GR_IS_GR_WEBGL(standard)) {
3524             if (version >= GR_GL_VER(2, 0)) {
3525                 rg16FTextureSupport = true;
3526                 rg16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
3527                                            ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
3528                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3529                                            ctxInfo.hasExtension("EXT_color_buffer_float");
3530             }
3531         }
3532 
3533         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16F);
3534         info.fFormatType = FormatType::kFloat;
3535         info.fInternalFormatForRenderbuffer = GR_GL_RG16F;
3536         info.fDefaultExternalFormat = GR_GL_RG;
3537         info.fDefaultExternalType = halfFloatType;
3538         info.fDefaultColorType = GrColorType::kRG_F16;
3539         if (rg16FTextureSupport) {
3540             info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3541             if (rg16FRenderTargetSupport) {
3542                 info.fFlags |= fpRenderFlags;
3543             }
3544         }
3545 
3546         if (texStorageSupported) {
3547             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3548             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16F;
3549         } else {
3550             info.fInternalFormatForTexImageOrStorage =
3551                     texImageSupportsSizedInternalFormat ? GR_GL_RG16F : GR_GL_RG;
3552         }
3553 
3554         if (rg16FTextureSupport) {
3555             info.fColorTypeInfoCount = 1;
3556             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3557             int ctIdx = 0;
3558             // Format: GR_GL_RG16F, Surface: kRG_F16
3559             {
3560                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3561                 ctInfo.fColorType = GrColorType::kRG_F16;
3562                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3563                 this->setColorTypeFormat(GrColorType::kRG_F16, GrGLFormat::kRG16F);
3564 
3565                 // External IO ColorTypes:
3566                 ctInfo.fExternalIOFormatCount = 2;
3567                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3568                         ctInfo.fExternalIOFormatCount);
3569                 int ioIdx = 0;
3570                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRG_F16
3571                 {
3572                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3573                     ioFormat.fColorType = GrColorType::kRG_F16;
3574                     ioFormat.fExternalType = halfFloatType;
3575                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3576                     ioFormat.fExternalReadFormat = GR_GL_RG;
3577                     // Not guaranteed by ES/WebGL.
3578                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3579                 }
3580 
3581                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRGBA_F32
3582                 {
3583                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3584                     ioFormat.fColorType = GrColorType::kRGBA_F32;
3585                     ioFormat.fExternalType = GR_GL_FLOAT;
3586                     ioFormat.fExternalTexImageFormat = 0;
3587                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3588                 }
3589             }
3590         }
3591     }
3592 
3593     this->setupSampleCounts(ctxInfo, gli);
3594 
3595 #ifdef SK_DEBUG
3596     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3597         if (GrGLFormat::kUnknown == static_cast<GrGLFormat>(i)) {
3598             continue;
3599         }
3600         const auto& formatInfo = fFormatTable[i];
3601         // Make sure we didn't set fbo attachable with msaa and not fbo attachable.
3602         SkASSERT(!((formatInfo.fFlags & FormatInfo::kFBOColorAttachmentWithMSAA_Flag) &&
3603                   !(formatInfo.fFlags & FormatInfo::kFBOColorAttachment_Flag)));
3604 
3605         // Make sure we set all the formats' FormatType
3606         SkASSERT(formatInfo.fFormatType != FormatType::kUnknown);
3607 
3608         // Make sure if we added a ColorTypeInfo we filled it out
3609         for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
3610             const auto& ctInfo = formatInfo.fColorTypeInfos[j];
3611             SkASSERT(ctInfo.fColorType != GrColorType::kUnknown);
3612             // Seems silly to add a color type if we don't support any flags on it.
3613             SkASSERT(ctInfo.fFlags);
3614             // Make sure if we added any ExternalIOFormats we filled it out
3615             for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
3616                 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
3617                 SkASSERT(ioInfo.fColorType != GrColorType::kUnknown);
3618             }
3619         }
3620     }
3621 #endif
3622 }
3623 
setupSampleCounts(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)3624 void GrGLCaps::setupSampleCounts(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
3625     GrGLStandard standard = ctxInfo.standard();
3626     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
3627     sk_ignore_unused_variable(standard);
3628     GrGLVersion version = ctxInfo.version();
3629 
3630     int maxSampleCnt = 1;
3631     if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
3632         GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
3633     } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
3634         GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
3635     }
3636     // Chrome has a mock GL implementation that returns 0.
3637     maxSampleCnt = std::max(1, maxSampleCnt);
3638 
3639     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3640         if (FormatInfo::kFBOColorAttachmentWithMSAA_Flag & fFormatTable[i].fFlags) {
3641             // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
3642             SkASSERT(FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags);
3643             SkASSERT(GrGLCaps::kNone_MSFBOType != fMSFBOType);
3644             if ((GR_IS_GR_GL(standard) &&
3645                   (version >= GR_GL_VER(4,2) ||
3646                    ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
3647                 (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0))) {
3648                 // Implicite resolve may have a lower max samples than the per format MSAA.
3649                 const bool multisampleIsImplicit =
3650                         GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
3651                         GrGLCaps::kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
3652                 int count;
3653                 GrGLFormat grGLFormat = static_cast<GrGLFormat>(i);
3654                 GrGLenum glFormat = this->getRenderbufferInternalFormat(grGLFormat);
3655                 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat,
3656                                           GR_GL_NUM_SAMPLE_COUNTS, 1, &count);
3657                 if (count) {
3658                     std::unique_ptr<int[]> temp(new int[count]);
3659                     GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_SAMPLES,
3660                                               count, temp.get());
3661                     // GL has a concept of MSAA rasterization with a single sample but we do not.
3662                     if (count && temp[count - 1] == 1) {
3663                         --count;
3664                         SkASSERT(!count || temp[count -1] > 1);
3665                     }
3666                     fFormatTable[i].fColorSampleCounts.reserve(count + 1);
3667                     // We initialize our supported values with 1 (no msaa) and reverse the order
3668                     // returned by GL so that the array is ascending.
3669                     fFormatTable[i].fColorSampleCounts.push_back(1);
3670                     for (int j = 0; j < count; ++j) {
3671 #if defined(SK_BUILD_FOR_IOS) && TARGET_OS_SIMULATOR
3672                         // The iOS simulator is reporting incorrect values for sample counts,
3673                         // so force them to be a power of 2.
3674                         int sampleCnt = SkPrevPow2(temp[count - j - 1]);
3675 #else
3676                         int sampleCnt = temp[count - j - 1];
3677 #endif
3678                         if (multisampleIsImplicit && sampleCnt > maxSampleCnt) {
3679                             break;
3680                         }
3681                         fFormatTable[i].fColorSampleCounts.push_back(sampleCnt);
3682                     }
3683                 }
3684             } else {
3685                 // Fake out the table using some semi-standard counts up to the max allowed sample
3686                 // count.
3687                 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
3688                 int count = std::size(kDefaultSamples);
3689                 for (; count > 0; --count) {
3690                     if (kDefaultSamples[count - 1] <= maxSampleCnt) {
3691                         break;
3692                     }
3693                 }
3694                 if (count > 0) {
3695                     fFormatTable[i].fColorSampleCounts.append(count, kDefaultSamples);
3696                 }
3697             }
3698         } else if (FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags) {
3699             fFormatTable[i].fColorSampleCounts.resize(1);
3700             fFormatTable[i].fColorSampleCounts[0] = 1;
3701         }
3702     }
3703 }
3704 
canCopyTexSubImage(GrGLFormat dstFormat,bool dstHasMSAARenderBuffer,const GrTextureType * dstTypeIfTexture,GrGLFormat srcFormat,bool srcHasMSAARenderBuffer,const GrTextureType * srcTypeIfTexture) const3705 bool GrGLCaps::canCopyTexSubImage(GrGLFormat dstFormat, bool dstHasMSAARenderBuffer,
3706                                   const GrTextureType* dstTypeIfTexture,
3707                                   GrGLFormat srcFormat, bool srcHasMSAARenderBuffer,
3708                                   const GrTextureType* srcTypeIfTexture) const {
3709     // When it comes to format types and component sizes the gl spec is fairly complex as
3710     // requirements differ depending on many properties (e.g. if the internalFormat was created with
3711     // a sized format or not). These affect the rules about which format types can be copied to
3712     // which other types. For now we are being more restrictive and requiring that the types must
3713     // match exactly.
3714     if (this->getFormatDefaultExternalType(dstFormat) !=
3715         this->getFormatDefaultExternalType(srcFormat)) {
3716         return false;
3717     }
3718 
3719     // Either both the src and dst formats need to be SRGB or both need to not be SRGB
3720     if (GrGLFormatIsSRGB(dstFormat) != GrGLFormatIsSRGB(srcFormat)) {
3721         return false;
3722     }
3723 
3724     if (GR_IS_GR_GL_ES(fStandard)) {
3725         // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3726         // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it.
3727         // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3728         // avoids bugs with using glBlitFramebuffer.
3729         if ((dstFormat == GrGLFormat::kBGRA8 || srcFormat == GrGLFormat::kBGRA8) &&
3730             !fAllowBGRA8CopyTexSubImage) {
3731             return false;
3732         }
3733 
3734         // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3735         // and SRGB isn't in the spec. There doesn't appear to be any extension that adds it.
3736         // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3737         // avoids bugs with using glBlitFramebuffer.
3738         if ((GrGLFormatIsSRGB(dstFormat) || GrGLFormatIsSRGB(srcFormat)) &&
3739             !fAllowSRGBCopyTexSubImage) {
3740             return false;
3741         }
3742 
3743         // Table 3.9 of the ES2 spec and 3.16 of ES3 spec indicates the supported internal base
3744         // formats with CopyTexSubImage. Each base format can be copied to itself or formats with
3745         // less channels.
3746         uint32_t dstChannels = GrGLFormatChannels(dstFormat);
3747         uint32_t srcChannels = GrGLFormatChannels(srcFormat);
3748         if (!dstChannels || !srcChannels) {
3749             // The formats don't represent color channels (i.e. may be depth stencil)
3750             return false;
3751         }
3752         // The dst channels have to be a subset of the srcChannels, except R, RG, or RGB, channels
3753         // can go to LUM. (See expansion of Table 3.9 in EXT_texture_rg).
3754         if ((dstChannels & srcChannels) != srcChannels) {
3755             if (dstChannels == kGray_SkColorChannelFlag ||
3756                 dstChannels == kGrayAlpha_SkColorChannelFlags) {
3757                 // The dst can't have gray if the src is alpha-only.
3758                 if (srcChannels == kAlpha_SkColorChannelFlag) {
3759                     return false;
3760                 }
3761             } else {
3762                 return false;
3763             }
3764         }
3765     }
3766 
3767     // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
3768     if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
3769         return false;
3770     }
3771 
3772     // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
3773     // texture.
3774     if (!dstTypeIfTexture) {
3775         return false;
3776     }
3777 
3778     // Check that we could wrap the source in an FBO, that the dst is not TEXTURE_EXTERNAL, that no
3779     // mirroring is required
3780     return this->canFormatBeFBOColorAttachment(srcFormat) &&
3781            (!srcTypeIfTexture || *srcTypeIfTexture != GrTextureType::kExternal) &&
3782            *dstTypeIfTexture != GrTextureType::kExternal;
3783 }
3784 
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) const3785 bool GrGLCaps::canCopyAsBlit(GrGLFormat dstFormat, int dstSampleCnt,
3786                              const GrTextureType* dstTypeIfTexture,
3787                              GrGLFormat srcFormat, int srcSampleCnt,
3788                              const GrTextureType* srcTypeIfTexture,
3789                              const SkRect& srcBounds, bool srcBoundsExact,
3790                              const SkIRect& srcRect, const SkIRect& dstRect) const {
3791     auto blitFramebufferFlags = fBlitFramebufferFlags;
3792     if (!this->canFormatBeFBOColorAttachment(dstFormat) ||
3793         !this->canFormatBeFBOColorAttachment(srcFormat)) {
3794         return false;
3795     }
3796 
3797     if (dstTypeIfTexture && *dstTypeIfTexture == GrTextureType::kExternal) {
3798         return false;
3799     }
3800     if (srcTypeIfTexture && *srcTypeIfTexture == GrTextureType::kExternal) {
3801         return false;
3802     }
3803 
3804     if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3805         return false;
3806     }
3807 
3808     if (dstSampleCnt > 1 && dstSampleCnt != srcSampleCnt) {
3809         // Regardless of support-level, all blits require src and dst sample counts to match if
3810         // the dst is MSAA.
3811         return false;
3812     }
3813 
3814     if (srcRect.width() != dstRect.width() || srcRect.height() != dstRect.height()) {
3815         // If the blit would scale contents, it's only valid for non-MSAA framebuffers that we
3816         // can write directly to.
3817         if ((GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) ||
3818             this->useDrawInsteadOfAllRenderTargetWrites() || srcSampleCnt > 1) {
3819             return false;
3820         }
3821     }
3822 
3823     if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3824         if (srcSampleCnt > 1) {
3825             if (1 == dstSampleCnt) {
3826                 return false;
3827             }
3828             if (SkRect::Make(srcRect) != srcBounds || !srcBoundsExact) {
3829                 return false;
3830             }
3831         }
3832     }
3833 
3834     if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3835         if (dstSampleCnt > 1) {
3836             return false;
3837         }
3838     }
3839 
3840     if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3841         if (srcFormat != dstFormat) {
3842             return false;
3843         }
3844     } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3845         if (srcSampleCnt > 1 && srcFormat != dstFormat) {
3846             return false;
3847         }
3848     }
3849 
3850     if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3851         if (srcSampleCnt > 1) {
3852             if (dstRect != srcRect) {
3853                 return false;
3854             }
3855         }
3856     }
3857     return true;
3858 }
3859 
canCopyAsDraw(GrGLFormat dstFormat,bool srcIsTexturable,bool scalingCopy) const3860 bool GrGLCaps::canCopyAsDraw(GrGLFormat dstFormat, bool srcIsTexturable, bool scalingCopy) const {
3861     return this->isFormatRenderable(dstFormat, 1) &&
3862            srcIsTexturable &&
3863            !(fDisableScalingCopyAsDraws && scalingCopy);
3864 }
3865 
has_msaa_render_buffer(const GrSurfaceProxy * surf,const GrGLCaps & glCaps)3866 static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
3867     const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
3868     if (!rt) {
3869         return false;
3870     }
3871     // A RT has a separate MSAA renderbuffer if:
3872     // 1) It's multisampled
3873     // 2) We're using an extension with separate MSAA renderbuffers
3874     // 3) It's not FBO 0, which is special and always auto-resolves
3875     return rt->numSamples() > 1 &&
3876            glCaps.usesMSAARenderBuffers() &&
3877            !rt->glRTFBOIDIs0();
3878 }
3879 
onCanCopySurface(const GrSurfaceProxy * dst,const SkIRect & dstRect,const GrSurfaceProxy * src,const SkIRect & srcRect) const3880 bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
3881                                 const GrSurfaceProxy* src, const SkIRect& srcRect) const {
3882     if (src->isProtected() == GrProtected::kYes && dst->isProtected() != GrProtected::kYes) {
3883         return false;
3884     }
3885 
3886     int dstSampleCnt = 0;
3887     int srcSampleCnt = 0;
3888     if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
3889         dstSampleCnt = rtProxy->numSamples();
3890     }
3891     if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
3892         srcSampleCnt = rtProxy->numSamples();
3893     }
3894     SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
3895     SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
3896 
3897     const GrTextureProxy* dstTex = dst->asTextureProxy();
3898     const GrTextureProxy* srcTex = src->asTextureProxy();
3899 
3900     GrTextureType dstTexType;
3901     GrTextureType* dstTexTypePtr = nullptr;
3902     GrTextureType srcTexType;
3903     GrTextureType* srcTexTypePtr = nullptr;
3904     if (dstTex) {
3905         dstTexType = dstTex->textureType();
3906         dstTexTypePtr = &dstTexType;
3907     }
3908     if (srcTex) {
3909         srcTexType = srcTex->textureType();
3910         srcTexTypePtr = &srcTexType;
3911     }
3912 
3913     auto dstFormat = GrBackendFormats::AsGLFormat(dst->backendFormat());
3914     auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3915     // Only copyAsBlit() and copyAsDraw() can handle scaling between src and dst.
3916     const bool scalingCopy = srcRect.size() != dstRect.size();
3917     if (!scalingCopy &&
3918         this->canCopyTexSubImage(dstFormat, has_msaa_render_buffer(dst, *this), dstTexTypePtr,
3919                                  srcFormat, has_msaa_render_buffer(src, *this), srcTexTypePtr)) {
3920         return true;
3921     }
3922     return this->canCopyAsBlit(dstFormat, dstSampleCnt, dstTexTypePtr, srcFormat, srcSampleCnt,
3923                                srcTexTypePtr, src->getBoundsRect(), src->priv().isExact(), srcRect,
3924                                dstRect) ||
3925            this->canCopyAsDraw(dstFormat, SkToBool(srcTex), scalingCopy);
3926 }
3927 
getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType colorType) const3928 GrCaps::DstCopyRestrictions GrGLCaps::getDstCopyRestrictions(const GrRenderTargetProxy* src,
3929                                                              GrColorType colorType) const {
3930     // If the src is a texture, we can implement the blit as a draw assuming the config is
3931     // renderable.
3932     if (src->asTextureProxy() && !this->isFormatAsColorTypeRenderable(colorType,
3933                                                                       src->backendFormat())) {
3934         return {};
3935     }
3936 
3937     if (const auto* texProxy = src->asTextureProxy()) {
3938         if (texProxy->textureType() == GrTextureType::kExternal) {
3939             // Not supported for FBO blit or CopyTexSubImage. Caller will have to fall back to a
3940             // draw (if the source is also a texture).
3941             return {};
3942         }
3943     }
3944 
3945     // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
3946     // possible and we return false to fallback to creating a render target dst for render-to-
3947     // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
3948     // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
3949     DstCopyRestrictions blitFramebufferRestrictions = {};
3950     if (src->numSamples() > 1 &&
3951         (fBlitFramebufferFlags & kResolveMustBeFull_BlitFrambufferFlag)) {
3952         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3953         blitFramebufferRestrictions.fMustCopyWholeSrc = true;
3954         // Mirroring causes rects to mismatch later, don't allow it.
3955     } else if (src->numSamples() > 1 && (fBlitFramebufferFlags &
3956                                          kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
3957         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3958     }
3959 
3960     auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3961     // Check for format issues with glCopyTexSubImage2D
3962     if (srcFormat == GrGLFormat::kBGRA8) {
3963         // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
3964         // then we set up for that, otherwise fail.
3965         if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3966             return blitFramebufferRestrictions;
3967         }
3968         // Caller will have to use a draw.
3969         return {};
3970     }
3971 
3972     {
3973         bool srcIsMSAARenderbuffer = src->numSamples() > 1 &&
3974                                      this->usesMSAARenderBuffers();
3975         if (srcIsMSAARenderbuffer) {
3976             // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
3977             // blit or fail.
3978             if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3979                 return blitFramebufferRestrictions;
3980             }
3981             // Caller will have to use a draw.
3982             return {};
3983         }
3984     }
3985 
3986     // We'll do a CopyTexSubImage, no restrictions.
3987     return {};
3988 }
3989 
applyDriverCorrectnessWorkarounds(const GrGLContextInfo & ctxInfo,const GrContextOptions & contextOptions,const GrGLInterface * glInterface,GrShaderCaps * shaderCaps,FormatWorkarounds * formatWorkarounds)3990 void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
3991                                                  const GrContextOptions& contextOptions,
3992                                                  const GrGLInterface* glInterface,
3993                                                  GrShaderCaps* shaderCaps,
3994                                                  FormatWorkarounds* formatWorkarounds) {
3995     // A driver bug on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
3996     // Thus we are disabling this extension for now on Adreno4xx devices.
3997     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
3998         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
3999         fDriverBugWorkarounds.disable_discard_framebuffer) {
4000         fInvalidateFBType = kNone_InvalidateFBType;
4001     }
4002 
4003     if (ctxInfo.renderer() == GrGLRenderer::kIntelCherryView) {
4004         // When running DMSAA_dst_read_with_existing_barrier with DMSAA disabled on linux Intel
4005         // HD405, the test fails when using texture barriers. Oddly the gpu doing the draw which
4006         // uses the barrier correctly. It is the next draw, which does not use or need a barrier,
4007         // that is blending with a dst as if the barrier draw didn't happen. Since this GPU is not
4008         // that important to us and this driver bug could probably manifest itself in the wild, we
4009         // are just disabling texture barrier support for the gpu.
4010         fTextureBarrierSupport = false;
4011     }
4012 
4013     // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
4014     // 340.96 and 367.57.
4015     if (GR_IS_GR_GL(ctxInfo.standard()) && ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4016         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
4017         fClearTextureSupport = false;
4018     }
4019 
4020     // glBlitFramebuffer seems to produce incorrect results on QC, Mali400, and Tegra3 but
4021     // glCopyTexSubImage2D works (even though there is no extension that specifically allows it).
4022     if (ctxInfo.vendor()   == GrGLVendor::kQualcomm  ||
4023         ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
4024         ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4025         fAllowBGRA8CopyTexSubImage = true;
4026     }
4027     // glCopyTexSubImage2D works for sRGB with GLES 3.0 and on some GPUs with GLES 2.0
4028     if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
4029         ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
4030         ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4031         fAllowSRGBCopyTexSubImage = true;
4032     }
4033 
4034     // http://anglebug.com/6030
4035     if (fMSFBOType == kES_EXT_MsToTexture_MSFBOType &&
4036         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4037         // As GL_EXT_multisampled_render_to_texture supporting issue,
4038         // fall back to default dmsaa path
4039         if ((ctxInfo.vendor()  == GrGLVendor::kIntel ||
4040              ctxInfo.angleVendor() == GrGLVendor::kIntel) &&
4041              ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake) {
4042             fMSFBOType = kStandard_MSFBOType;
4043             fMSAAResolvesAutomatically = false;
4044         }
4045         else {
4046             fDisallowDynamicMSAA = true;
4047         }
4048     }
4049 
4050     // http://skbug.com/12081
4051     if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
4052         fDisallowDynamicMSAA = true;
4053     }
4054 
4055     // Below we are aggressive about turning off all mapping/transfer functionality together. This
4056     // could be finer grained if code paths and tests were adjusted to check more specific caps.
4057     // For example it might be possible to support buffer to buffer transfers even if buffer mapping
4058     // or buffer to surface transfers don't work.
4059 #if defined(__has_feature)
4060 #if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
4061     // See skbug.com/7058
4062     fMapBufferType = kNone_MapBufferType;
4063     fMapBufferFlags = kNone_MapFlags;
4064     fTransferFromBufferToTextureSupport = false;
4065     fTransferFromSurfaceToBufferSupport = false;
4066     fTransferFromBufferToBufferSupport  = false;
4067     fTransferBufferType = TransferBufferType::kNone;
4068 #endif
4069 #endif
4070 
4071     // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
4072     // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
4073     // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
4074     // unclear whether this really affects a wide range of devices.
4075     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4076         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
4077         fMapBufferType = kNone_MapBufferType;
4078         fMapBufferFlags = kNone_MapFlags;
4079         fTransferFromBufferToTextureSupport = false;
4080         fTransferFromSurfaceToBufferSupport = false;
4081         fTransferFromBufferToBufferSupport  = false;
4082         fTransferBufferType = TransferBufferType::kNone;
4083     }
4084 
4085     // The TransferPixelsToTexture test fails on ANGLE D3D9 and D3D11 if this is enabled.
4086     // https://anglebug.com/5542
4087     if (angle_backend_is_d3d(ctxInfo.angleBackend())) {
4088         fTransferPixelsToRowBytesSupport = false;
4089     }
4090 
4091     // Using MIPs on this GPU seems to be a source of trouble.
4092     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4093         fMipmapSupport = false;
4094     }
4095 
4096 #ifdef SK_BUILD_FOR_ANDROID
4097     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4098         // Flutter found glTexSubImage2D for GL_RED is much slower than GL_ALPHA on the
4099         // "MC18 PERSONAL SHOPPER"
4100         formatWorkarounds->fDisallowR8ForPowerVRSGX54x = true;
4101     }
4102 #endif
4103 
4104     // Reported on skia-discuss as occurring with these GL strings:
4105     // GL_VERSION:  3.1.0 - Build 9.17.10.4459
4106     // GL_VENDOR:   Intel
4107     // GL_RENDERER: Intel(R) HD Graphics 2000
4108     // https://groups.google.com/g/skia-discuss/c/dYV1blEAda0/m/-zuZLXQKAwAJ?utm_medium=email&utm_source=footer
4109     // See also http://skbug.com/9286
4110     if (ctxInfo.renderer() == GrGLRenderer::kIntelSandyBridge &&
4111         ctxInfo.driver() == GrGLDriver::kIntel) {
4112         fMapBufferType  = kNone_MapBufferType;
4113         fMapBufferFlags = kNone_MapFlags;
4114         // On skia-discuss it was reported that after turning off mapping there was this
4115         // shader compilation error.
4116         // ERROR: 0:18: 'assign' :  cannot convert from '3-component vector of float' to 'varying 2-component vector of float'
4117         // for this line:
4118         // vTransformedCoords_5_S0 = mat3x2(umatrix_S1_c0_c1) * vec3(_tmp_2_inPosition, 1.0);
4119         fShaderCaps->fNonsquareMatrixSupport = false;
4120     }
4121 
4122     if (ctxInfo.isOverCommandBuffer() && ctxInfo.version() >= GR_GL_VER(3,0)) {
4123         formatWorkarounds->fDisallowTextureUnorm16 = true;  // http://crbug.com/1224108
4124         formatWorkarounds->fDisallowETC2Compression = true;  // http://crbug.com/1224111
4125         fTransferFromSurfaceToBufferSupport = false;  // http://crbug.com/1224138
4126 
4127         // http://crbug.com/1224117
4128         fMapBufferFlags = kNone_MapFlags;
4129         fMapBufferType = kNone_MapBufferType;
4130     }
4131 
4132     // https://b.corp.google.com/issues/143074513
4133     // https://skbug.com/11152
4134     if (ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4135         ctxInfo.renderer() == GrGLRenderer::kAdreno620) {
4136         fMSFBOType = kNone_MSFBOType;
4137         fMSAAResolvesAutomatically = false;
4138     }
4139 
4140 #ifndef SK_BUILD_FOR_IOS
4141     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x   ||
4142         ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue ||
4143         (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx && !ctxInfo.isOverCommandBuffer())) {
4144         fPerformColorClearsAsDraws = true;
4145     }
4146 #endif
4147 
4148     // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
4149     if (ctxInfo.renderer() == GrGLRenderer::kAMDRadeonHD7xxx ||
4150         ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M4xx) {
4151         fPerformColorClearsAsDraws = true;
4152     }
4153 
4154 #ifdef SK_BUILD_FOR_MAC
4155     // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
4156     // full screen clears
4157     // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
4158     // perform full screen clears.
4159     // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
4160     // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
4161     // crbug.com/1039912 - Crash rate in glClear spiked after OS update, affecting mostly
4162     //   Broadwell on 10.13+
4163     if (ctxInfo.vendor() == GrGLVendor::kIntel &&
4164         (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12) ||
4165          ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell)) {
4166         fPerformColorClearsAsDraws = true;
4167     }
4168     // crbug.com/969609 - NVIDIA on Mac sometimes segfaults during glClear in chrome. It seems
4169     // mostly concentrated in 10.13/14, GT 650Ms, driver 12+. But there are instances of older
4170     // drivers and GTX 775s, so we'll start with a broader workaround.
4171     if (ctxInfo.vendor() == GrGLVendor::kNVIDIA) {
4172         fPerformColorClearsAsDraws = true;
4173     }
4174 #endif
4175 
4176     // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
4177     // bugs seems to involve clearing too much and not skipping the clear.
4178     // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
4179     // but only for D3D11 ANGLE.
4180     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4181         fPerformColorClearsAsDraws = true;
4182     }
4183 
4184     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4185         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4186         // This is known to be fixed sometime between driver 145.0 and 219.0
4187         if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
4188             fPerformStencilClearsAsDraws = true;
4189         }
4190         // This is known to be fixed sometime between driver 129.0 and 145.0 on Nexus 6P.
4191         // On driver 129 on Android M it fails the unit tests called WritePixelsPendingIO without
4192         // the workaround. It passes on Android N with driver 145 without the workaround.
4193         // skbug.com/11834
4194         if (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(145, 0, 0)) {
4195             fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4196         }
4197     }
4198 
4199     if (fDriverBugWorkarounds.gl_clear_broken) {
4200         fPerformColorClearsAsDraws = true;
4201         fPerformStencilClearsAsDraws = true;
4202     }
4203 
4204     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4205         // It appears that all the Adreno GPUs have less than optimal performance when
4206         // drawing w/ large index buffers.
4207         fAvoidLargeIndexBufferDraws = true;
4208     }
4209 
4210     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
4211         (ctxInfo.renderer() == GrGLRenderer::kWebGL &&
4212          ctxInfo.webglRenderer() == GrGLRenderer::kMali4xx)) {
4213         // Perspective SDF text runs significantly slower on Mali-4xx hardware
4214         fDisablePerspectiveSDFText = true;
4215     }
4216 
4217     // This was reproduced on the following configurations:
4218     // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
4219     // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
4220     // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
4221     // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
4222     // and not produced on:
4223     // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
4224     // The particular lines that get dropped from test images varies across different devices.
4225     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4226         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
4227         fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
4228     }
4229 
4230     // TODO: Don't apply this on iOS?
4231     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4232         // Our Chromebook with GrGLRenderer::kPowerVRRogue crashes on large instanced draws. The
4233         // current minimum number of instances observed to crash is somewhere between 2^14 and 2^15.
4234         // Keep the number of instances below 1000, just to be safe.
4235         fMaxInstancesPerDrawWithoutCrashing = 999;
4236     } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
4237         fMaxInstancesPerDrawWithoutCrashing = 0x4000000;
4238     }
4239 
4240 #ifndef SK_BUILD_FOR_IOS
4241     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4242         // We saw this bug on a TecnoSpark 3 Pro with a PowerVR GE8300.
4243         // GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4244         // Possibly this could be more limited by driver version or HW generation.
4245         // When using samplers, we are seeing a bug where the gpu is sometimes not sampling the
4246         // correct mip level data. A workaround to this issue is that when binding a texture we also
4247         // set some texture state, and it seems like any inividual state works (e.g. min/mag filter,
4248         // base level, max level, etc.). Currently we just set the min filter level every time we
4249         // bind a texture as the workaround.
4250         fMustSetAnyTexParameterToEnableMipmapping = true;
4251         // ColorTypeBackendAllocationTest failed for kAlpha_8 and kGray_8 when using
4252         // GL_UNPACK_ROW_LENGTH. Perhaps this could be a more limited workaround by applying
4253         // only to single channel 8 bit unorm formats but we only have a monolithic query for this
4254         // support at present.
4255         fWritePixelsRowBytesSupport = false;
4256         // TransferPixelsToTextureTest fails for all color types on
4257         // TecnoSpark 3 Pro with a PowerVR GE8300, GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4258         // if GL_UNPACK_ROW_LENGTH is used.
4259         fTransferPixelsToRowBytesSupport = false;
4260     }
4261 #endif
4262 
4263     // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
4264     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4265         fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4266         fUseDrawInsteadOfAllRenderTargetWrites = true;
4267     }
4268 
4269 #ifdef SK_BUILD_FOR_MAC
4270     static constexpr bool isMAC = true;
4271 #else
4272     static constexpr bool isMAC = false;
4273 #endif
4274 
4275 #ifdef SK_BUILD_FOR_ANDROID
4276     // Older versions of Android have problems with setting GL_TEXTURE_BASE_LEVEL or
4277     // GL_TEXTURE_MAX_LEVEL on GL_TEXTURE_EXTERTNAL_OES textures. We just leave them as is and hope
4278     // the client never changes them either.
4279     fDontSetBaseOrMaxLevelForExternalTextures = true;
4280     // PowerVR can crash setting the levels on Android up to Q for any texture?
4281     // https://crbug.com/1123874
4282     if (ctxInfo.vendor() == GrGLVendor::kImagination) {
4283         fMipmapLevelControlSupport =  false;
4284     }
4285 #endif
4286 
4287     // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
4288     // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
4289     // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
4290     // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
4291     if (fMipmapLevelControlSupport &&
4292         !ctxInfo.isOverCommandBuffer() &&  // http://crbug.com/1224110
4293         (contextOptions.fDoManualMipmapping                 ||
4294          ctxInfo.vendor()  == GrGLVendor::kIntel            ||
4295          (ctxInfo.driver() == GrGLDriver::kNVIDIA && isMAC) ||
4296          ctxInfo.vendor()  == GrGLVendor::kATI)) {
4297         fDoManualMipmapping = true;
4298     }
4299 
4300     // See http://crbug.com/710443
4301 #ifdef SK_BUILD_FOR_MAC
4302     if (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell) {
4303         fClearToBoundaryValuesIsBroken = true;
4304     }
4305 #endif
4306     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4307         fDrawArraysBaseVertexIsBroken = true;
4308     }
4309 
4310     // b/40043081, b/40045491: indirect draws in ANGLE + D3D are very slow
4311     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 ||
4312         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4313         fBaseVertexBaseInstanceSupport = false;
4314         fNativeDrawIndirectSupport = false;
4315         fMultiDrawType = MultiDrawType::kNone;
4316     }
4317 
4318     // https://b.corp.google.com/issues/188410972
4319     if (ctxInfo.isRunningOverVirgl()) {
4320         fDrawInstancedSupport = false;
4321     }
4322 
4323     // http://anglebug.com/4538
4324     if (fBaseVertexBaseInstanceSupport && !fDrawInstancedSupport) {
4325         fBaseVertexBaseInstanceSupport = false;
4326         fNativeDrawIndirectSupport = false;
4327         fMultiDrawType = MultiDrawType::kNone;
4328     }
4329 
4330     // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
4331     // Galaxy S7.
4332     // TODO: Once this is fixed we can update the check here to look at a driver version number too.
4333     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4334         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other) {
4335         shaderCaps->fFBFetchSupport = false;
4336     }
4337 
4338     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4339         // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
4340         // so we must do the abs first in a separate expression.
4341         shaderCaps->fCanUseMinAndAbsTogether = false;
4342 
4343         // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
4344         // must avoid this condition.
4345         shaderCaps->fCanUseFractForNegativeValues = false;
4346     }
4347 
4348     // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
4349     // thus must us -1.0 * %s.x to work correctly
4350     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4351         shaderCaps->fMustForceNegatedAtanParamToFloat = true;
4352     }
4353 
4354 #if defined(SK_BUILD_FOR_MAC)
4355     if (ctxInfo.vendor() == GrGLVendor::kATI) {
4356         // The Radeon GLSL compiler on Mac gets confused by ldexp(..., -x).
4357         // Convert to ldexp(..., x * -1).
4358         // http://skbug.com/12076
4359         shaderCaps->fMustForceNegatedLdexpParamToMultiply = true;
4360     }
4361 #endif
4362 
4363     // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
4364     // when floor and abs are called on the same line. Thus we must execute an Op between them to
4365     // make sure the compiler doesn't re-inline them even if we break the calls apart.
4366     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4367         shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
4368     }
4369 
4370     // On Adreno devices with framebuffer fetch support, there is a bug where they always return
4371     // the original dst color when reading the outColor even after being written to. By using a
4372     // local outColor we can work around this bug.
4373     if (shaderCaps->fFBFetchSupport && ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4374         shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
4375     }
4376 
4377     // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
4378     // color, and that uniform contains an opaque color, and the output of the shader is only based
4379     // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
4380     // that the shader always outputs opaque values. In that case, it appears to remove the shader
4381     // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
4382     // insert an extra bit of math on the uniform that confuses the compiler just enough...
4383     if (ctxInfo.renderer() == GrGLRenderer::kMaliT) {
4384         shaderCaps->fMustObfuscateUniformColor = true;
4385     }
4386 
4387 #if defined(SK_BUILD_FOR_ANDROID)
4388     // On the following GPUs, the Perlin noise code needs to aggressively snap to multiples
4389     // of 1/255 to avoid artifacts in the double table lookup:
4390     //    Tegra3, PowerVRGE8320 (Wembley), MaliG76, and Adreno308
4391     // Given the range of vendors we're just blanket enabling it on Android for OpenGL.
4392     fShaderCaps->fPerlinNoiseRoundingFix = true;
4393 #endif
4394 
4395     // On Mali 400 there is a bug using dFd* in the x direction. So we avoid using it when possible.
4396     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx) {
4397         fShaderCaps->fAvoidDfDxForGradientsWhenPossible = true;
4398     }
4399 
4400 #ifdef SK_BUILD_FOR_WIN
4401     // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
4402     //
4403     // Basically, if a shader has a construct like:
4404     //
4405     // float x = someCondition ? someValue : 0;
4406     // float2 result = (0 == x) ? float2(x, x)
4407     //                          : float2(2 * x / x, 0);
4408     //
4409     // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
4410     // we've explicitly guarded the division with a check against zero. This manifests in much
4411     // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
4412     // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
4413     if (angle_backend_is_d3d(ctxInfo.angleBackend()) || ctxInfo.isOverCommandBuffer()) {
4414         shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
4415     }
4416 #endif
4417 
4418     // The Adreno 5xx and 6xx produce incorrect results when comparing a pair of matrices.
4419     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4420         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4421         ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4422         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4423         ctxInfo.renderer() == GrGLRenderer::kAdreno630 ||
4424         ctxInfo.renderer() == GrGLRenderer::kAdreno640 ||
4425         ctxInfo.renderer() == GrGLRenderer::kAdreno6xx_other) {
4426         shaderCaps->fRewriteMatrixComparisons = true;
4427     }
4428 
4429     // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
4430     // (rare) situations. It's sporadic, and mostly on older drivers. Additionally, old Adreno
4431     // compilers (see crbug.com/skia/4078) crash when accessing .zw of gl_FragCoord, so just bypass
4432     // using gl_FragCoord at all to get around it.
4433     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4434         shaderCaps->fCanUseFragCoord = false;
4435     }
4436 
4437     // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
4438     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4439         shaderCaps->fCanUseFragCoord = false;
4440     }
4441 
4442     if (fDriverBugWorkarounds.add_and_true_to_loop_condition) {
4443         shaderCaps->fAddAndTrueToLoopCondition = true;
4444     }
4445 
4446     if (fDriverBugWorkarounds.unfold_short_circuit_as_ternary_operation) {
4447         shaderCaps->fUnfoldShortCircuitAsTernary = true;
4448     }
4449 
4450     if (fDriverBugWorkarounds.emulate_abs_int_function) {
4451         shaderCaps->fEmulateAbsIntFunction = true;
4452     }
4453 
4454     if (fDriverBugWorkarounds.rewrite_do_while_loops) {
4455         shaderCaps->fRewriteDoWhileLoops = true;
4456     }
4457 
4458     if (fDriverBugWorkarounds.remove_pow_with_constant_exponent) {
4459         shaderCaps->fRemovePowWithConstantExponent = true;
4460     }
4461 
4462     if (fDriverBugWorkarounds.disable_dual_source_blending_support) {
4463         shaderCaps->fDualSourceBlendingSupport = false;
4464     }
4465 
4466     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4467         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4468         shaderCaps->fMustWriteToFragColor = true;
4469     }
4470 
4471     // Disabling advanced blend on various platforms with major known issues. We also block Chrome
4472     // command buffer for now until its own denylists can be updated.
4473     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
4474         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
4475         ctxInfo.renderer() == GrGLRenderer::kAdreno530       ||
4476         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4477         ctxInfo.driver()   == GrGLDriver::kIntel             ||
4478         ctxInfo.angleVendor() == GrGLVendor::kIntel          ||
4479         ctxInfo.isOverCommandBuffer()                        ||
4480         ctxInfo.vendor()   == GrGLVendor::kARM /* http://skbug.com/11906 */) {
4481         fBlendEquationSupport = kBasic_BlendEquationSupport;
4482         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4483     }
4484 
4485     // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
4486     if (((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4487           ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0)) ||
4488          (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4489           ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4490           ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(337, 00, 0))) &&
4491         kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
4492         fBlendEquationSupport = kBasic_BlendEquationSupport;
4493         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4494     }
4495 
4496     if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
4497         fBlendEquationSupport = kBasic_BlendEquationSupport;
4498         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4499     }
4500 
4501     if (this->advancedBlendEquationSupport()) {
4502         if ((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4503              ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) ||
4504             (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4505              ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4506              ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(355, 00, 0))) {
4507             // Disable color-dodge and color-burn on pre-355.00 NVIDIA.
4508             fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorDodge)) |
4509                                        (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4510         }
4511         if (ctxInfo.vendor() == GrGLVendor::kARM) {
4512             // Disable color-burn on ARM until the fix is released.
4513             fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4514         }
4515     }
4516 
4517     // On Adreno 5xx devices, there is a bug where we first draw using dual source blending. Thus
4518     // the dst blend func references the dst. Then the next draw we disable blending. However, on
4519     // the second draw the driver has a bug where it tries to access the second color output again.
4520     // This is fixed by reseting the blend function to anything that does not reference src2 when we
4521     // disable blending.
4522     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4523         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4524         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4525         ctxInfo.renderer() == GrGLRenderer::kAdreno640) {
4526         fMustResetBlendFuncBetweenDualSourceAndDisable = true;
4527     }
4528 
4529     // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
4530     // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
4531     // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
4532     // skbug.com/7713
4533     if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
4534         ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330 &&
4535         !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
4536         shaderCaps->fExternalTextureSupport = true;
4537         shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
4538         shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
4539     }
4540 
4541 #ifdef SK_BUILD_FOR_IOS
4542     // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
4543     // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
4544     // is to just disable the feature.
4545     // https://github.com/flutter/flutter/issues/16718
4546     // https://bugreport.apple.com/web/?problemID=39948888
4547     fWritePixelsRowBytesSupport = false;
4548     // This affects all iOS devices for transfering from a PBO as well (presumably the issue is in
4549     // the GL->Metal layer).
4550     fTransferPixelsToRowBytesSupport = false;
4551 #endif
4552 
4553     if (ctxInfo.vendor()   == GrGLVendor::kIntel       ||  // IntelIris640 drops draws completely.
4554         ctxInfo.webglVendor() == GrGLVendor::kIntel    ||  // Disable if the webgl vendor is Intel
4555         ctxInfo.renderer() == GrGLRenderer::kMaliT     ||  // Some curves appear flat on GalaxyS6.
4556         ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4557         ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4558         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||  // We get garbage on Adreno405.
4559         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {  // D3D9 conic strokes fail.
4560         fDisableTessellationPathRenderer = true;
4561     }
4562     // We found that on Wembley devices (PowerVR GE8320) that using tessellation path renderer would
4563     // cause lots of rendering errors where it seemed like vertices were in the wrong place. This
4564     // led to lots of GMs drawing nothing (e.g. dashing4) or lots of garbage. The Wembley devices
4565     // were running Android 12 with a driver version of 1.13. We previously had TecnoSpark devices
4566     // with the same GPU running on Android P (driver 1.10) which did not have this issue. We don't
4567     // know when the bug appeared in the driver so for now we disable tessellation path renderer for
4568     // all matching gpus regardless of driver version.
4569     //
4570     // 2022-10-28 Update: Testing via Flutter found this is not a problem on driver version 1.15.
4571     // See https://github.com/flutter/flutter/issues/113596
4572     // GL_VERSION : OpenGL ES 3.1 build 1.15@6133109
4573     // GL_RENDERER: PowerVR Rogue AXE-1-16M
4574     // GL_VENDOR  : Imagination Technologies
4575     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue &&
4576         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 15, 0)) {
4577         fDisableTessellationPathRenderer = true;
4578     }
4579 
4580     // The Wembley device draws the mesh_update GM incorrectly when using transfer buffers. Buffer
4581     // to buffer transfers affect draws earlier in the GL command sequence.
4582     // Android API: 31
4583     // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4584     // GL_RENDERER: PowerVR Rogue GE8300
4585     // GL_VENDOR  : Imagination Technologies
4586     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4587         fTransferFromBufferToBufferSupport = false;
4588     }
4589 
4590     // The Wembley device fails shader compilations with no error message when there is a const
4591     // parameter. Given that we've already passed through SkSL compilation and enforced that the
4592     // parameter is never written, it is harmless to strip the const off when writing GLSL.
4593     // Android API: 31
4594     // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4595     // GL_RENDERER: PowerVR Rogue GE8300
4596     // GL_VENDOR  : Imagination Technologies
4597     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4598         fShaderCaps->fRemoveConstFromFunctionParameters = true;
4599     }
4600 #ifdef SK_BUILD_FOR_WIN
4601     // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
4602     if (ctxInfo.driver() == GrGLDriver::kIntel ||
4603         (ctxInfo.angleVendor()  == GrGLVendor::kIntel &&
4604          ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL)) {
4605         fNativeDrawIndexedIndirectIsBroken = true;
4606         fUseClientSideIndirectBuffers = true;
4607     }
4608 #endif
4609 
4610     // PowerVRGX6250 drops every pixel if we modify the sample mask while color writes are disabled.
4611     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4612         fNeverDisableColorWrites = true;
4613         shaderCaps->fMustWriteToFragColor = true;
4614     }
4615 
4616     // It appears that Qualcomm drivers don't actually support
4617     // GL_NV_shader_noperspective_interpolation in ES 3.00 or 3.10 shaders, only 3.20.
4618     // https://crbug.com/986581
4619     if (ctxInfo.vendor() == GrGLVendor::kQualcomm &&
4620         SkSL::GLSLGeneration::k320es != ctxInfo.glslGeneration()) {
4621         shaderCaps->fNoPerspectiveInterpolationSupport = false;
4622     }
4623 
4624     // We disable srgb write control for Adreno4xx devices.
4625     // see: https://bug.skia.org/5329
4626     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4627         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4628         fSRGBWriteControl = false;
4629     }
4630 
4631     // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
4632 #if defined(SK_BUILD_FOR_MAC)
4633     if (ctxInfo.vendor() == GrGLVendor::kATI) {
4634         formatWorkarounds->fDisableSRGBRenderWithMSAAForMacAMD = true;
4635     }
4636 #endif
4637 
4638     // Command buffer fails glTexSubImage2D with type == GL_HALF_FLOAT_OES if a GL_RGBA16F texture
4639     // is created with glTexStorage2D. See crbug.com/1008003.
4640     formatWorkarounds->fDisableRGBA16FTexStorageForCrBug1008003 =
4641             ctxInfo.isOverCommandBuffer() && ctxInfo.version() < GR_GL_VER(3, 0);
4642 
4643 #if defined(SK_BUILD_FOR_WIN)
4644     // On Intel Windows ES contexts it seems that using texture storage with BGRA causes
4645     // problems with cross-context SkImages.
4646     formatWorkarounds->fDisableBGRATextureStorageForIntelWindowsES =
4647             ctxInfo.driver() == GrGLDriver::kIntel && GR_IS_GR_GL_ES(ctxInfo.standard());
4648 #endif
4649 
4650     // On the Intel Iris 6100, interacting with LUM16F seems to confuse the driver. After
4651     // writing to/reading from a LUM16F texture reads from/writes to other formats behave
4652     // erratically.
4653     // All Adrenos claim to support LUM16F but don't appear to actually do so.
4654     // The failing devices/gpus were: Nexus5/Adreno330, Nexus5x/Adreno418, Pixel/Adreno530,
4655     // Pixel2XL/Adreno540 and Pixel3/Adreno630
4656     formatWorkarounds->fDisableLuminance16F =
4657             (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell ||
4658              ctxInfo.vendor() == GrGLVendor::kQualcomm) &&
4659             ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown;
4660 
4661 #ifdef SK_BUILD_FOR_MAC
4662     // On a MacBookPro 11.5 running MacOS 10.13 with a Radeon M370X the TransferPixelsFrom test
4663     // fails when transferring out from a GL_RG8 texture using GL_RG/GL_UNSIGNED_BYTE.
4664     // The same error also occurs in MacOS 10.15 with a Radeon Pro 5300M.
4665     formatWorkarounds->fDisallowDirectRG8ReadPixels =
4666             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M3xx  ||
4667             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonPro5xxx ||
4668             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonProVegaxx;
4669 #endif
4670 
4671 #ifdef SK_BUILD_FOR_ANDROID
4672     // crbug.com/945506. Telemetry reported a memory usage regression for Android Go Chrome/WebView
4673     // when using glTexStorage2D. This appears to affect OOP-R (so not just over command buffer).
4674     // Update 10/2023, it looks like this may just effect chrome Android GO devices which are
4675     // running on Mali-T720. It does not seem to impact Qualcomm devices. We have no tests to verify
4676     // if newer ARM devices are impacted, so for now we keep this disabled on all ARM by default.
4677     //
4678     // We allow the client to pass in a GrContextOption flag to say they prefer having tex storage
4679     // support regadless of memory usage impacts. This is important for supporting Protected
4680     // textures as they require tex storage support.
4681     if (ctxInfo.vendor() == GrGLVendor::kARM &&
4682         !contextOptions.fAlwaysUseTexStorageWhenAvailable &&
4683         !fSupportsProtectedContent) {
4684         formatWorkarounds->fDisableTexStorage = true;
4685     }
4686 #endif
4687 
4688     // https://github.com/flutter/flutter/issues/38700
4689     if (ctxInfo.driver() == GrGLDriver::kAndroidEmulator) {
4690         shaderCaps->fNoDefaultPrecisionForExternalSamplers = true;
4691     }
4692 
4693     // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
4694     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4695         fTiledRenderingSupport = false;
4696     }
4697     // https://github.com/flutter/flutter/issues/47164
4698     // https://github.com/flutter/flutter/issues/47804
4699     if (fTiledRenderingSupport && (!glInterface->fFunctions.fStartTiling ||
4700                                    !glInterface->fFunctions.fEndTiling)) {
4701         // Some devices expose the QCOM tiled memory extension string but don't actually provide the
4702         // start and end tiling functions (see above flutter bugs). To work around this, the funcs
4703         // are marked optional in the interface generator, but we turn off the tiled rendering cap
4704         // if they aren't provided. This disabling is in driver workarounds so that SKQP will still
4705         // fail on devices that advertise the extension w/o the functions.
4706         fTiledRenderingSupport = false;
4707     }
4708 
4709     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {
4710         formatWorkarounds->fDisallowBGRA8ReadPixels = true;
4711     }
4712 
4713     // We disable MSAA for older Intel GPUs. Before Gen9, performance was very bad. Even with Gen9,
4714     // we've seen driver crashes in the wild.
4715     // (crbug.com/527565, crbug.com/983926)
4716     if (ctxInfo.vendor() == GrGLVendor::kIntel || ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4717         // Gen11 seems mostly ok, except we avoid drawing lines with MSAA. (anglebug.com/7796)
4718         if (ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake &&
4719             contextOptions.fAllowMSAAOnNewIntel) {
4720             if (fMSFBOType != kNone_MSFBOType) {
4721                 fAvoidLineDraws = true;
4722             }
4723         } else {
4724             fMSFBOType = kNone_MSFBOType;
4725         }
4726     }
4727 
4728     // ANGLE's D3D9 backend + AMD GPUs are flaky with program binary caching (skbug.com/10395)
4729     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 &&
4730         ctxInfo.angleVendor()  == GrGLVendor::kATI) {
4731         fProgramBinarySupport = false;
4732     }
4733 
4734     // skbug.com/11204. Avoid recursion issue in SurfaceContext::writePixels.
4735     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4736         fReuseScratchTextures = false;
4737     }
4738 
4739     // skbug.com/11935. Don't reorder on these GPUs in GL on old drivers.
4740     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4741         ctxInfo.renderer() == GrGLRenderer::kAdreno640) &&
4742         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(571, 0, 0)) {
4743         fAvoidReorderingRenderTasks = true;
4744     }
4745 
4746     // http://crbug.com/1197152
4747     // http://b/187364475
4748     // We could limit this < 1.13 on ChromeOS but we don't really have a good way to detect
4749     // ChromeOS from here.
4750     if (ctxInfo.renderer()      == GrGLRenderer::kPowerVRRogue &&
4751         ctxInfo.driver()        == GrGLDriver::kImagination    &&
4752         ctxInfo.driverVersion() <  GR_GL_DRIVER_VER(1, 16, 0)) {
4753         fShaderCaps->fShaderDerivativeSupport = false;
4754     }
4755 
4756     if (ctxInfo.driver() == GrGLDriver::kFreedreno) {
4757         formatWorkarounds->fDisallowUnorm16Transfers = true;
4758     }
4759 
4760     // If we keep rebind the same texture to an FBO's color attachment but changing between MSAA and
4761     // non-MSAA we get corruption in the texture contents. Binding texture 0 and then rebinding the
4762     // original texture avoids this.
4763     // This was found on Nexus 5, Android 6.0.1, build M4B30Z
4764     // GL_VENDOR  : "Qualcomm"
4765     // GL_RENDERER: "Adreno (TM) 330"
4766     // GL_VERSION : "OpenGL ES 3.0 V@127.0 AU@  (GIT@I96aee987eb)"
4767     //
4768     // We also so alpha blending issues on these GMs skbug_9819, p3_ovals, p3 on Mali-Gxx devices
4769     // The GM issues were observed on a Galaxy S9 running Android 10:
4770     // GL_VERSION : "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
4771     // GL_RENDERER: "Mali-G72"
4772     // GL_VENDOR  : "ARM"
4773     // and a P30 running Android 9:
4774     // GL_VERSION : "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
4775     // GL_RENDERER: "Mali-G76"
4776     // GL_VENDOR  : "ARM"
4777     // but *not* a Galaxy S20 running Android 10:
4778     // GL_VERSION : "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
4779     // GL_RENDERER: "Mali-G77"
4780     // GL_VENDOR  : "ARM"
4781     // It's unclear if the difference is driver version or Bifrost vs Valhall. The workaround is
4782     // fairly trivial so just applying to all Bifrost and Valhall.
4783     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4784          ctxInfo.driver()   == GrGLDriver::kQualcomm) ||
4785         (ctxInfo.renderer() == GrGLRenderer::kMaliG)) {
4786         fBindTexture0WhenChangingTextureFBOMultisampleCount = true;
4787     }
4788 
4789     // skbug.com/12640
4790     // We found that on the Galaxy S7 the TransferPixelsTo test would fail after adding
4791     // glCheckFramebufferStatus() checks when making new FBOs. Note that the returned status was
4792     // GL_FRAMEBUFFER_COMPLETE. Switching the color binding to ID 0 and back to the original
4793     // afterwards works around the issue.
4794     // GL_VENDOR  : "ARM"
4795     // GL_RENDERER: "Mali-T880"
4796     // GL_VERSION : "OpenGL ES 3.2 v1.r22p0-01rel0.f294e54ceb2cb2d81039204fa4b0402e"
4797     //
4798     // This *didn't* reproduce on a Kevin ChromeOS device:
4799     // GL_VENDOR  : "ARM"
4800     // GL_RENDERER: "Mali-T860"
4801     // GL_VERSION : "OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3"
4802     if (ctxInfo.renderer()      == GrGLRenderer::kMaliT &&
4803         ctxInfo.driver()        == GrGLDriver::kARM     &&
4804         ctxInfo.driverVersion()  < GR_GL_DRIVER_VER(1, 26, 0)) {
4805         fRebindColorAttachmentAfterCheckFramebufferStatus = true;
4806     }
4807 
4808     // skbug.com/13286
4809     // We found that the P30 produces a GL error when setting GL_TEXTURE_MAX_ANISOTROPY as a sampler
4810     // parameter but not as a texture parameter. We are disabling anisotropy on drivers that may
4811     // be affected.
4812     //
4813     // FAIL on P30
4814     // GL_VENDOR  : ARM
4815     // GL_RENDERER: Mali-G76
4816     // GL_VERSION : OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5
4817     //
4818     // PASS on Pixel6
4819     // GL_VENDOR  : ARM
4820     // GL_RENDERER: Mali-G78
4821     // GL_VERSION : OpenGL ES 3.2 v1.r32p1-00pxl0.b7e5868a59a273f4a9f58d1657ef99de
4822     //
4823     // PASS on Galaxy S30:
4824     // GL_VENDOR  : ARM
4825     // GL_RENDERER: Mali-G77
4826     // GL_VERSION : OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###
4827     //
4828     // PASS on Galaxy S9:
4829     // GL_VENDOR  : ARM
4830     // GL_RENDERER: Mali-G72
4831     // GL_VENDOR  : OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###
4832     if (ctxInfo.renderer()      == GrGLRenderer::kMaliG &&
4833         ctxInfo.driver()        == GrGLDriver::kARM     &&
4834         ctxInfo.driverVersion()  < GR_GL_DRIVER_VER(1, 19, 0)) {
4835         fAnisoSupport = false;
4836     }
4837 
4838     // b/229626353
4839     // On certain classes of Adreno running WebGL, glTexSubImage2D() occasionally fails to upload
4840     // texels on time for sampling. The solution is to call glFlush() before glTexSubImage2D().
4841     // Seen on:
4842     // * Nexus 5x (Adreno 418)
4843     // * Nexus 6 (Adreno 420)
4844     // * Pixel 3 (Adreno 630)
4845     if (ctxInfo.renderer()       == GrGLRenderer::kWebGL &&
4846         (ctxInfo.webglRenderer() == GrGLRenderer::kAdreno4xx_other ||
4847          ctxInfo.webglRenderer() == GrGLRenderer::kAdreno630)) {
4848         fFlushBeforeWritePixels = true;
4849     }
4850     // crbug.com/1395777
4851     // There appears to be a driver bug in GLSL program linking on Mali 400 and 450 devices with
4852     // driver version 2.1.199xx that causes the copy-as-draw programs in GrGLGpu to fail. The crash
4853     // rate increased when scaling copy support was added, so disallow scaling copy-as-draws on
4854     // these devices.
4855     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx &&
4856         ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(2, 1, 19900)) {
4857         fDisableScalingCopyAsDraws = true;
4858     }
4859     // skbug.com/14194
4860     // Setting the max level is technically unnecessary, but on Intel drivers it makes it
4861     // clear that a rendering feedback loop is not occurring, and avoids hitting a slow path.
4862     // When running on ANGLE, however, this triggers the validator because we can only use
4863     // levels between BASE_LEVEL and MAX_LEVEL for a framebuffer, and we're trying to use
4864     // MAX_LEVEL+1. So instead we set up sync points between each mipmap level render.
4865     if (ctxInfo.vendor() == GrGLVendor::kIntel  &&
4866         ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown) {
4867         fRegenerateMipmapType = RegenerateMipmapType::kBasePlusMaxLevel;
4868     } else if (ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4869         fRegenerateMipmapType = RegenerateMipmapType::kBasePlusSync;
4870     }
4871 #ifdef SK_BUILD_FOR_MAC
4872     // On Apple Silicon, RG88 requires 2-byte alignment for transfer buffer readback
4873     if (ctxInfo.vendor() == GrGLVendor::kApple) {
4874         fPadRG88TransferAlignment = true;
4875     }
4876 #endif
4877 }
4878 
onApplyOptionsOverrides(const GrContextOptions & options)4879 void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
4880     if (options.fDisableDriverCorrectnessWorkarounds) {
4881         SkASSERT(!fDoManualMipmapping);
4882         SkASSERT(!fClearToBoundaryValuesIsBroken);
4883         SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
4884         SkASSERT(!fDrawArraysBaseVertexIsBroken);
4885         SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
4886         SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
4887         SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
4888         SkASSERT(!fDontSetBaseOrMaxLevelForExternalTextures);
4889         SkASSERT(!fNeverDisableColorWrites);
4890     }
4891     if (options.fShaderCacheStrategy < GrContextOptions::ShaderCacheStrategy::kBackendBinary) {
4892         fProgramBinarySupport = false;
4893     }
4894 
4895     switch (options.fSkipGLErrorChecks) {
4896         case GrContextOptions::Enable::kNo:
4897             fSkipErrorChecks = false;
4898             break;
4899         case GrContextOptions::Enable::kYes:
4900             fSkipErrorChecks = true;
4901             break;
4902         case GrContextOptions::Enable::kDefault:
4903             break;
4904     }
4905 }
4906 
onSurfaceSupportsWritePixels(const GrSurface * surface) const4907 bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
4908     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4909         if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4910             if (tex->hasBaseLevelBeenBoundToFBO()) {
4911                 return false;
4912             }
4913         }
4914     }
4915     if (auto rt = surface->asRenderTarget()) {
4916         if (fUseDrawInsteadOfAllRenderTargetWrites) {
4917             return false;
4918         }
4919         if (rt->numSamples() > 1 && this->usesMSAARenderBuffers()) {
4920             return false;
4921         }
4922         return SkToBool(surface->asTexture());
4923     }
4924     return true;
4925 }
4926 
surfaceSupportsReadPixels(const GrSurface * surface) const4927 GrCaps::SurfaceReadPixelsSupport GrGLCaps::surfaceSupportsReadPixels(
4928         const GrSurface* surface) const {
4929     if (surface->isProtected()) {
4930         return SurfaceReadPixelsSupport::kUnsupported;
4931     }
4932     if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4933         // We don't support reading pixels directly from EXTERNAL textures as it would require
4934         // binding the texture to a FBO. For now we also disallow reading back directly
4935         // from compressed textures.
4936         if (tex->target() == GR_GL_TEXTURE_EXTERNAL || GrGLFormatIsCompressed(tex->format())) {
4937             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4938         }
4939     } else if (auto rt = static_cast<const GrGLRenderTarget*>(surface->asRenderTarget())) {
4940         // glReadPixels does not allow reading back from a MSAA framebuffer. If the underlying
4941         // GrSurface doesn't have a second FBO to resolve to then we must make a copy.
4942         if (rt->numSamples() > 1 && !rt->asTexture()) {
4943             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4944         }
4945     }
4946     return SurfaceReadPixelsSupport::kSupported;
4947 }
4948 
offset_alignment_for_transfer_buffer(GrGLenum externalType)4949 size_t offset_alignment_for_transfer_buffer(GrGLenum externalType) {
4950     // This switch is derived from a table titled "Pixel data type parameter values and the
4951     // corresponding GL data types" in the OpenGL spec (Table 8.2 in OpenGL 4.5).
4952     switch (externalType) {
4953         case GR_GL_UNSIGNED_BYTE:                   return sizeof(GrGLubyte);
4954         case GR_GL_BYTE:                            return sizeof(GrGLbyte);
4955         case GR_GL_UNSIGNED_SHORT:                  return sizeof(GrGLushort);
4956         case GR_GL_SHORT:                           return sizeof(GrGLshort);
4957         case GR_GL_UNSIGNED_INT:                    return sizeof(GrGLuint);
4958         case GR_GL_INT:                             return sizeof(GrGLint);
4959         case GR_GL_HALF_FLOAT:                      return sizeof(GrGLhalf);
4960         case GR_GL_HALF_FLOAT_OES:                  return sizeof(GrGLhalf);
4961         case GR_GL_FLOAT:                           return sizeof(GrGLfloat);
4962         case GR_GL_UNSIGNED_SHORT_5_6_5:            return sizeof(GrGLushort);
4963         case GR_GL_UNSIGNED_SHORT_4_4_4_4:          return sizeof(GrGLushort);
4964         case GR_GL_UNSIGNED_SHORT_5_5_5_1:          return sizeof(GrGLushort);
4965         case GR_GL_UNSIGNED_INT_2_10_10_10_REV:     return sizeof(GrGLuint);
4966 #if 0  // GL types we currently don't use. Here for future reference.
4967         case GR_GL_UNSIGNED_BYTE_3_3_2:             return sizeof(GrGLubyte);
4968         case GR_GL_UNSIGNED_BYTE_2_3_3_REV:         return sizeof(GrGLubyte);
4969         case GR_GL_UNSIGNED_SHORT_5_6_5_REV:        return sizeof(GrGLushort);
4970         case GR_GL_UNSIGNED_SHORT_4_4_4_4_REV:      return sizeof(GrGLushort);
4971         case GR_GL_UNSIGNED_SHORT_1_5_5_5_REV:      return sizeof(GrGLushort);
4972         case GR_GL_UNSIGNED_INT_8_8_8_8:            return sizeof(GrGLuint);
4973         case GR_GL_UNSIGNED_INT_8_8_8_8_REV:        return sizeof(GrGLuint);
4974         case GR_GL_UNSIGNED_INT_10_10_10_2:         return sizeof(GrGLuint);
4975         case GR_GL_UNSIGNED_INT_24_8:               return sizeof(GrGLuint);
4976         case GR_GL_UNSIGNED_INT_10F_11F_11F_REV:    return sizeof(GrGLuint);
4977         case GR_GL_UNSIGNED_INT_5_9_9_9_REV:        return sizeof(GrGLuint);
4978         // This one is not corresponding to a GL data type and the spec just says it is 4.
4979         case GR_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:  return 4;
4980 #endif
4981         default:                                    return 0;
4982     }
4983 }
4984 
onSupportedReadPixelsColorType(GrColorType srcColorType,const GrBackendFormat & srcBackendFormat,GrColorType dstColorType) const4985 GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
4986         GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
4987         GrColorType dstColorType) const {
4988 
4989     SkTextureCompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
4990     if (compression != SkTextureCompressionType::kNone) {
4991         return {SkTextureCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
4992                                                        : GrColorType::kRGBA_8888,
4993                 0};
4994     }
4995 
4996     // We first try to find a supported read pixels GrColorType that matches the requested
4997     // dstColorType. If that doesn't exists we will use any valid read pixels GrColorType.
4998     GrCaps::SupportedRead fallbackRead = {GrColorType::kUnknown, 0};
4999     const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(srcBackendFormat));
5000     bool foundSrcCT = false;
5001     for (int i = 0; !foundSrcCT && i < formatInfo.fColorTypeInfoCount; ++i) {
5002         if (formatInfo.fColorTypeInfos[i].fColorType == srcColorType) {
5003             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
5004             foundSrcCT = true;
5005             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
5006                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
5007                 if (ioInfo.fExternalReadFormat != 0) {
5008                     if (formatInfo.fHaveQueriedImplementationReadSupport ||
5009                         !ioInfo.fRequiresImplementationReadQuery) {
5010                         GrGLenum transferOffsetAlignment = 0;
5011                         if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
5012                             transferOffsetAlignment =
5013                                     offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
5014                             if (dstColorType == GrColorType::kRG_88 && fPadRG88TransferAlignment) {
5015                                 transferOffsetAlignment = 2;
5016                             }
5017                         }
5018                         if (ioInfo.fColorType == dstColorType) {
5019                             return {dstColorType, transferOffsetAlignment};
5020                         }
5021                         // Currently we just pick the first supported format that we find as our
5022                         // fallback.
5023                         if (fallbackRead.fColorType == GrColorType::kUnknown) {
5024                             fallbackRead = {ioInfo.fColorType, transferOffsetAlignment};
5025                         }
5026                     }
5027                 }
5028             }
5029         }
5030     }
5031     return fallbackRead;
5032 }
5033 
supportedWritePixelsColorType(GrColorType surfaceColorType,const GrBackendFormat & surfaceFormat,GrColorType srcColorType) const5034 GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfaceColorType,
5035                                                                const GrBackendFormat& surfaceFormat,
5036                                                                GrColorType srcColorType) const {
5037     // We first try to find a supported write pixels GrColorType that matches the data's
5038     // srcColorType. If that doesn't exists we will use any supported GrColorType.
5039     GrColorType fallbackCT = GrColorType::kUnknown;
5040     const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(surfaceFormat));
5041     bool foundSurfaceCT = false;
5042     size_t transferOffsetAlignment = 0;
5043     if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
5044         transferOffsetAlignment = 1;
5045     }
5046     for (int i = 0; !foundSurfaceCT && i < formatInfo.fColorTypeInfoCount; ++i) {
5047         if (formatInfo.fColorTypeInfos[i].fColorType == surfaceColorType) {
5048             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
5049             foundSurfaceCT = true;
5050             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
5051                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
5052                 if (ioInfo.fExternalTexImageFormat != 0) {
5053                     if (ioInfo.fColorType == srcColorType) {
5054                         return {srcColorType, transferOffsetAlignment};
5055                     }
5056                     // Currently we just pick the first supported format that we find as our
5057                     // fallback.
5058                     if (fallbackCT == GrColorType::kUnknown) {
5059                         fallbackCT = ioInfo.fColorType;
5060                     }
5061                 }
5062             }
5063         }
5064     }
5065     return {fallbackCT, transferOffsetAlignment};
5066 }
5067 
programBinaryFormatIsValid(GrGLenum binaryFormat) const5068 bool GrGLCaps::programBinaryFormatIsValid(GrGLenum binaryFormat) const {
5069     return std::find(fProgramBinaryFormats.begin(), fProgramBinaryFormats.end(), binaryFormat) !=
5070            fProgramBinaryFormats.end();
5071 }
5072 
onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget & backendRT) const5073 bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
5074     GrGLFramebufferInfo fbInfo;
5075     SkAssertResult(GrBackendRenderTargets::GetGLFramebufferInfo(backendRT, &fbInfo));
5076     // Window Rectangles are not supported for FBO 0;
5077     return fbInfo.fFBOID != 0;
5078 }
5079 
isFormatSRGB(const GrBackendFormat & format) const5080 bool GrGLCaps::isFormatSRGB(const GrBackendFormat& format) const {
5081     return GrBackendFormats::AsGLFormat(format) == GrGLFormat::kSRGB8_ALPHA8;
5082 }
5083 
isFormatTexturable(const GrBackendFormat & format,GrTextureType textureType) const5084 bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType textureType) const {
5085     if (textureType == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5086         return false;
5087     }
5088     return this->isFormatTexturable(GrBackendFormats::AsGLFormat(format));
5089 }
5090 
isFormatTexturable(GrGLFormat format) const5091 bool GrGLCaps::isFormatTexturable(GrGLFormat format) const {
5092     const FormatInfo& info = this->getFormatInfo(format);
5093     return SkToBool(info.fFlags & FormatInfo::kTexturable_Flag);
5094 }
5095 
isFormatAsColorTypeRenderable(GrColorType ct,const GrBackendFormat & format,int sampleCount) const5096 bool GrGLCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
5097                                              int sampleCount) const {
5098     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5099         return false;
5100     }
5101     if (format.textureType() == GrTextureType::kExternal) {
5102         return false;
5103     }
5104     auto f = GrBackendFormats::AsGLFormat(format);
5105     const FormatInfo& info = this->getFormatInfo(f);
5106     if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
5107         return false;
5108     }
5109 
5110     return this->isFormatRenderable(f, sampleCount);
5111 }
5112 
isFormatRenderable(const GrBackendFormat & format,int sampleCount) const5113 bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
5114     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5115         return false;
5116     }
5117     if (format.textureType() == GrTextureType::kExternal) {
5118         return false;
5119     }
5120     return this->isFormatRenderable(GrBackendFormats::AsGLFormat(format), sampleCount);
5121 }
5122 
getRenderTargetSampleCount(int requestedCount,GrGLFormat format) const5123 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrGLFormat format) const {
5124     const FormatInfo& info = this->getFormatInfo(format);
5125 
5126     int count = info.fColorSampleCounts.size();
5127     if (!count) {
5128         return 0;
5129     }
5130 
5131     requestedCount = std::max(1, requestedCount);
5132     if (1 == requestedCount) {
5133         return info.fColorSampleCounts[0] == 1 ? 1 : 0;
5134     }
5135 
5136     for (int sampleCount : info.fColorSampleCounts) {
5137         if (sampleCount >= requestedCount) {
5138             if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5139                 sampleCount = std::min(sampleCount, 4);
5140             }
5141             return sampleCount;
5142         }
5143     }
5144     return 0;
5145 }
5146 
maxRenderTargetSampleCount(GrGLFormat format) const5147 int GrGLCaps::maxRenderTargetSampleCount(GrGLFormat format) const {
5148     const FormatInfo& info = this->getFormatInfo(format);
5149     const auto& table = info.fColorSampleCounts;
5150     if (table.empty()) {
5151         return 0;
5152     }
5153     int count = table[table.size() - 1];
5154     if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5155         count = std::min(count, 4);
5156     }
5157     return count;
5158 }
5159 
canFormatBeFBOColorAttachment(GrGLFormat format) const5160 bool GrGLCaps::canFormatBeFBOColorAttachment(GrGLFormat format) const {
5161     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kFBOColorAttachment_Flag);
5162 }
5163 
isFormatCopyable(const GrBackendFormat & format) const5164 bool GrGLCaps::isFormatCopyable(const GrBackendFormat& format) const {
5165     // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
5166     // requires the src to be an FBO attachment, blit requires both src and dst to be FBO
5167     // attachments, and draw requires the dst to be an FBO attachment. Thus to copy from and to
5168     // the same config, we need that config to be bindable to an FBO.
5169     return this->canFormatBeFBOColorAttachment(GrBackendFormats::AsGLFormat(format));
5170 }
5171 
formatSupportsTexStorage(GrGLFormat format) const5172 bool GrGLCaps::formatSupportsTexStorage(GrGLFormat format) const {
5173     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kUseTexStorage_Flag);
5174 }
5175 
shouldQueryImplementationReadSupport(GrGLFormat format) const5176 bool GrGLCaps::shouldQueryImplementationReadSupport(GrGLFormat format) const {
5177     const auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5178     if (!formatInfo.fHaveQueriedImplementationReadSupport) {
5179         // Check whether we will actually learn anything useful.
5180         bool needQuery = false;
5181         for (int i = 0; i < formatInfo.fColorTypeInfoCount && !needQuery; ++i) {
5182             const auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5183             for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5184                 if (surfCTInfo.fExternalIOFormats[j].fRequiresImplementationReadQuery) {
5185                     needQuery = true;
5186                     break;
5187                 }
5188             }
5189         }
5190         if (!needQuery) {
5191             // Pretend we already checked it.
5192             const_cast<FormatInfo&>(formatInfo).fHaveQueriedImplementationReadSupport = true;
5193         }
5194     }
5195     return !formatInfo.fHaveQueriedImplementationReadSupport;
5196 }
5197 
didQueryImplementationReadSupport(GrGLFormat format,GrGLenum readFormat,GrGLenum readType) const5198 void GrGLCaps::didQueryImplementationReadSupport(GrGLFormat format,
5199                                                  GrGLenum readFormat,
5200                                                  GrGLenum readType) const {
5201     auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5202     for (int i = 0; i < formatInfo.fColorTypeInfoCount; ++i) {
5203         auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5204         for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5205             auto& readCTInfo = surfCTInfo.fExternalIOFormats[j];
5206             if (readCTInfo.fRequiresImplementationReadQuery) {
5207                 if (readCTInfo.fExternalReadFormat != readFormat ||
5208                     readCTInfo.fExternalType != readType) {
5209                     // Don't zero out fExternalType. It's also used for writing data to the texture!
5210                     readCTInfo.fExternalReadFormat = 0;
5211                 }
5212             }
5213         }
5214     }
5215     formatInfo.fHaveQueriedImplementationReadSupport = true;
5216 }
5217 
onAreColorTypeAndFormatCompatible(GrColorType ct,const GrBackendFormat & format) const5218 bool GrGLCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
5219                                                  const GrBackendFormat& format) const {
5220     GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5221     const auto& info = this->getFormatInfo(glFormat);
5222     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5223         if (info.fColorTypeInfos[i].fColorType == ct) {
5224             return true;
5225         }
5226     }
5227     return false;
5228 }
5229 
onGetDefaultBackendFormat(GrColorType ct) const5230 GrBackendFormat GrGLCaps::onGetDefaultBackendFormat(GrColorType ct) const {
5231     auto format = this->getFormatFromColorType(ct);
5232     if (format == GrGLFormat::kUnknown) {
5233         return {};
5234     }
5235     return GrBackendFormats::MakeGL(GrGLFormatToEnum(format), GR_GL_TEXTURE_2D);
5236 }
5237 
getBackendFormatFromCompressionType(SkTextureCompressionType compressionType) const5238 GrBackendFormat GrGLCaps::getBackendFormatFromCompressionType(
5239         SkTextureCompressionType compressionType) const {
5240     switch (compressionType) {
5241         case SkTextureCompressionType::kNone:
5242             return {};
5243         case SkTextureCompressionType::kETC2_RGB8_UNORM:
5244             // if ETC2 is available default to that format
5245             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_ETC2)) {
5246                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D);
5247             }
5248             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ETC1_RGB8)) {
5249                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D);
5250             }
5251             return {};
5252         case SkTextureCompressionType::kBC1_RGB8_UNORM:
5253             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_BC1)) {
5254                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
5255                                                 GR_GL_TEXTURE_2D);
5256             }
5257             return {};
5258         case SkTextureCompressionType::kBC1_RGBA8_UNORM:
5259             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGBA8_BC1)) {
5260                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
5261                                                 GR_GL_TEXTURE_2D);
5262             }
5263             return {};
5264         case SkTextureCompressionType::kASTC_RGBA8_4x4:
5265             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_4x4)) {
5266                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_4x4,
5267                                                GR_GL_TEXTURE_2D);
5268             }
5269             return {};
5270         case SkTextureCompressionType::kASTC_RGBA8_6x6:
5271             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_6x6)) {
5272                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_6x6,
5273                                                GR_GL_TEXTURE_2D);
5274             }
5275             return {};
5276         case SkTextureCompressionType::kASTC_RGBA8_8x8:
5277             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ASTC_RGBA8_8x8)) {
5278                 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_8x8,
5279                                                GR_GL_TEXTURE_2D);
5280             }
5281             return {};
5282     }
5283 
5284     SkUNREACHABLE;
5285 }
5286 
onGetReadSwizzle(const GrBackendFormat & format,GrColorType colorType) const5287 skgpu::Swizzle GrGLCaps::onGetReadSwizzle(const GrBackendFormat& format,
5288                                           GrColorType colorType) const {
5289     GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5290     const auto& info = this->getFormatInfo(glFormat);
5291     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5292         const auto& ctInfo = info.fColorTypeInfos[i];
5293         if (ctInfo.fColorType == colorType) {
5294             return ctInfo.fReadSwizzle;
5295         }
5296     }
5297     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5298                  (int)colorType, (int)glFormat);
5299     return {};
5300 }
5301 
getWriteSwizzle(const GrBackendFormat & format,GrColorType colorType) const5302 skgpu::Swizzle GrGLCaps::getWriteSwizzle(const GrBackendFormat& format,
5303                                          GrColorType colorType) const {
5304     const auto& info = this->getFormatInfo(GrBackendFormats::AsGLFormat(format));
5305     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5306         const auto& ctInfo = info.fColorTypeInfos[i];
5307         if (ctInfo.fColorType == colorType) {
5308             return ctInfo.fWriteSwizzle;
5309         }
5310     }
5311     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5312                  (int)colorType,
5313                  (int)GrBackendFormats::AsGLFormat(format));
5314     return {};
5315 }
5316 
onGetDstSampleFlagsForProxy(const GrRenderTargetProxy * rt) const5317 GrDstSampleFlags GrGLCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
5318     if (rt->asTextureProxy()) {
5319         return GrDstSampleFlags::kRequiresTextureBarrier;
5320     }
5321     return GrDstSampleFlags::kNone;
5322 }
5323 
onSupportsDynamicMSAA(const GrRenderTargetProxy * rtProxy) const5324 bool GrGLCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
5325     return !fDisallowDynamicMSAA;
5326 }
5327 
computeFormatKey(const GrBackendFormat & format) const5328 uint64_t GrGLCaps::computeFormatKey(const GrBackendFormat& format) const {
5329     auto glFormat = GrBackendFormats::AsGLFormat(format);
5330     return (uint64_t)(glFormat);
5331 }
5332 
makeDesc(GrRenderTarget *,const GrProgramInfo & programInfo,ProgramDescOverrideFlags overrideFlags) const5333 GrProgramDesc GrGLCaps::makeDesc(GrRenderTarget* /* rt */,
5334                                  const GrProgramInfo& programInfo,
5335                                  ProgramDescOverrideFlags overrideFlags) const {
5336     SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
5337     GrProgramDesc desc;
5338     GrProgramDesc::Build(&desc, programInfo, *this);
5339     return desc;
5340 }
5341 
5342 #if defined(GPU_TEST_UTILS)
getTestingCombinations() const5343 std::vector<GrTest::TestFormatColorTypeCombination> GrGLCaps::getTestingCombinations() const {
5344     std::vector<GrTest::TestFormatColorTypeCombination> combos = {
5345         { GrColorType::kAlpha_8,
5346           GrBackendFormats::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D) },
5347         { GrColorType::kAlpha_8,
5348           GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5349         { GrColorType::kBGR_565,
5350           GrBackendFormats::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D) },
5351         { GrColorType::kABGR_4444,
5352           GrBackendFormats::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D) },
5353         { GrColorType::kRGBA_8888,
5354           GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5355         { GrColorType::kRGBA_8888_SRGB,
5356           GrBackendFormats::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D) },
5357         { GrColorType::kRGB_888x,
5358           GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5359         { GrColorType::kRGB_888x,
5360           GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) },
5361         { GrColorType::kRGB_888x,
5362           GrBackendFormats::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D) },
5363         { GrColorType::kRGB_888x,
5364           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D) },
5365         { GrColorType::kRGB_888x,
5366           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D) },
5367         { GrColorType::kRGBA_8888,
5368           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_4x4, GR_GL_TEXTURE_2D) },
5369         { GrColorType::kRGBA_8888,
5370           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_6x6, GR_GL_TEXTURE_2D) },
5371         { GrColorType::kRGBA_8888,
5372           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_8x8, GR_GL_TEXTURE_2D) },
5373         { GrColorType::kRGB_888x,
5374           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5375         { GrColorType::kRGBA_8888,
5376           GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5377         { GrColorType::kRG_88,
5378           GrBackendFormats::MakeGL(GR_GL_RG8, GR_GL_TEXTURE_2D) },
5379         { GrColorType::kRGBA_1010102,
5380           GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5381         { GrColorType::kRGB_101010x,
5382           GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5383         { GrColorType::kGray_8,
5384           GrBackendFormats::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D) },
5385         { GrColorType::kGray_8,
5386           GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5387         { GrColorType::kGrayAlpha_88,
5388           GrBackendFormats::MakeGL(GR_GL_LUMINANCE8_ALPHA8, GR_GL_TEXTURE_2D) },
5389         { GrColorType::kAlpha_F16,
5390           GrBackendFormats::MakeGL(GR_GL_R16F, GR_GL_TEXTURE_2D) },
5391         { GrColorType::kAlpha_F16,
5392           GrBackendFormats::MakeGL(GR_GL_LUMINANCE16F, GR_GL_TEXTURE_2D) },
5393         { GrColorType::kRGBA_F16,
5394           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5395         { GrColorType::kRGBA_F16_Clamped,
5396           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5397         { GrColorType::kRGB_F16F16F16x,
5398           GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5399         { GrColorType::kAlpha_16,
5400           GrBackendFormats::MakeGL(GR_GL_R16, GR_GL_TEXTURE_2D) },
5401         { GrColorType::kRG_1616,
5402           GrBackendFormats::MakeGL(GR_GL_RG16, GR_GL_TEXTURE_2D) },
5403         { GrColorType::kRGBA_16161616,
5404           GrBackendFormats::MakeGL(GR_GL_RGBA16, GR_GL_TEXTURE_2D) },
5405         { GrColorType::kRG_F16,
5406           GrBackendFormats::MakeGL(GR_GL_RG16F, GR_GL_TEXTURE_2D) },
5407     };
5408 
5409     if (GR_IS_GR_GL(fStandard)) {
5410         combos.push_back({ GrColorType::kBGRA_8888,
5411                            GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) });
5412         combos.push_back({ GrColorType::kBGRA_1010102,
5413                            GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) });
5414     } else {
5415         SkASSERT(GR_IS_GR_GL_ES(fStandard) || GR_IS_GR_WEBGL(fStandard));
5416 
5417         combos.push_back({ GrColorType::kBGRA_8888,
5418                            GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) });
5419     }
5420     if (this->rectangleTextureSupport()) {
5421         size_t count2D = combos.size();
5422         for (size_t i = 0; i < count2D; ++i) {
5423             auto combo2D = combos[i];
5424             GrGLenum formatEnum = GrBackendFormats::AsGLFormatEnum(combo2D.fFormat);
5425             combos.push_back({combo2D.fColorType,
5426                               GrBackendFormats::MakeGL(formatEnum, GR_GL_TEXTURE_RECTANGLE)});
5427         }
5428     }
5429     return combos;
5430 }
5431 #endif
5432