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