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