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