• 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
2875     {
2876         FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ASTC_RGBA8);
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: R16
2890     {
2891         FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16);
2892         info.fFormatType = FormatType::kNormalizedFixedPoint;
2893         info.fInternalFormatForRenderbuffer = GR_GL_R16;
2894         info.fDefaultExternalFormat = GR_GL_RED;
2895         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
2896         info.fDefaultColorType = GrColorType::kR_16;
2897         bool r16Supported = false;
2898         if (!formatWorkarounds.fDisallowTextureUnorm16) {
2899             if (GR_IS_GR_GL(standard)) {
2900                 r16Supported = version >= GR_GL_VER(3, 0) ||
2901                                ctxInfo.hasExtension("GL_ARB_texture_rg");
2902             } else if (GR_IS_GR_GL_ES(standard)) {
2903                 r16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
2904             }  // No WebGL support
2905         }
2906 
2907         if (r16Supported) {
2908             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
2909             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
2910                 info.fFlags |= FormatInfo::kTransfers_Flag;
2911             }
2912         }
2913 
2914         if (texStorageSupported) {
2915             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2916             info.fInternalFormatForTexImageOrStorage = GR_GL_R16;
2917         } else {
2918             info.fInternalFormatForTexImageOrStorage =
2919                     texImageSupportsSizedInternalFormat ? GR_GL_R16 : GR_GL_RED;
2920         }
2921 
2922         if (r16Supported) {
2923             info.fColorTypeInfoCount = 1;
2924             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2925             int ctIdx = 0;
2926             // Format: R16, Surface: kAlpha_16
2927             {
2928                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2929                 ctInfo.fColorType = GrColorType::kAlpha_16;
2930                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2931                 ctInfo.fReadSwizzle = GrSwizzle("000r");
2932                 ctInfo.fWriteSwizzle = GrSwizzle("a000");
2933                 this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
2934 
2935                 // External IO ColorTypes:
2936                 ctInfo.fExternalIOFormatCount = 2;
2937                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2938                         ctInfo.fExternalIOFormatCount);
2939                 int ioIdx = 0;
2940                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_16
2941                 {
2942                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2943                     ioFormat.fColorType = GrColorType::kAlpha_16;
2944                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
2945                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
2946                     ioFormat.fExternalReadFormat = GR_GL_RED;
2947                     // Not guaranteed by ES/WebGL.
2948                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2949                 }
2950 
2951                 // Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
2952                 {
2953                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2954                     ioFormat.fColorType = GrColorType::kAlpha_8xxx;
2955                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2956                     ioFormat.fExternalTexImageFormat = 0;
2957                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
2958                 }
2959             }
2960         }
2961     }
2962 
2963     // Format: RG16
2964     {
2965         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16);
2966         info.fFormatType = FormatType::kNormalizedFixedPoint;
2967         info.fInternalFormatForTexImageOrStorage =
2968                 texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
2969         info.fInternalFormatForRenderbuffer = GR_GL_RG16;
2970         info.fDefaultExternalFormat = GR_GL_RG;
2971         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
2972         info.fDefaultColorType = GrColorType::kRG_1616;
2973         bool rg16Supported = false;
2974         if (!formatWorkarounds.fDisallowTextureUnorm16) {
2975             if (GR_IS_GR_GL(standard)) {
2976                 rg16Supported = version >= GR_GL_VER(3, 0) ||
2977                                 ctxInfo.hasExtension("GL_ARB_texture_rg");
2978             } else if (GR_IS_GR_GL_ES(standard)) {
2979                 rg16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
2980             }  // No WebGL support
2981         }
2982 
2983         if (rg16Supported) {
2984             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
2985             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
2986                 info.fFlags |= FormatInfo::kTransfers_Flag;
2987             }
2988         }
2989 
2990         if (texStorageSupported) {
2991             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2992             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16;
2993         } else {
2994             info.fInternalFormatForTexImageOrStorage =
2995                     texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
2996         }
2997 
2998         if (rg16Supported) {
2999             info.fColorTypeInfoCount = 1;
3000             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3001             int ctIdx = 0;
3002             // Format: GR_GL_RG16, Surface: kRG_1616
3003             {
3004                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3005                 ctInfo.fColorType = GrColorType::kRG_1616;
3006                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3007                 this->setColorTypeFormat(GrColorType::kRG_1616, GrGLFormat::kRG16);
3008 
3009                 // External IO ColorTypes:
3010                 ctInfo.fExternalIOFormatCount = 2;
3011                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3012                         ctInfo.fExternalIOFormatCount);
3013                 int ioIdx = 0;
3014                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRG_1616
3015                 {
3016                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3017                     ioFormat.fColorType = GrColorType::kRG_1616;
3018                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3019                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3020                     ioFormat.fExternalReadFormat = GR_GL_RG;
3021                     // Not guaranteed by ES/WebGL.
3022                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3023                 }
3024 
3025                 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRGBA_8888
3026                 {
3027                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3028                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3029                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3030                     ioFormat.fExternalTexImageFormat = 0;
3031                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3032                 }
3033             }
3034         }
3035     }
3036 
3037     // Format: RGBA16
3038     {
3039         bool rgba16Support = false;
3040         if (!formatWorkarounds.fDisallowTextureUnorm16) {
3041             if (GR_IS_GR_GL(standard)) {
3042                 rgba16Support = version >= GR_GL_VER(3, 0);
3043             } else if (GR_IS_GR_GL_ES(standard)) {
3044                 rgba16Support = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3045             }  // No WebGL support
3046         }
3047 
3048         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16);
3049         info.fFormatType = FormatType::kNormalizedFixedPoint;
3050 
3051         info.fInternalFormatForRenderbuffer = GR_GL_RGBA16;
3052         info.fDefaultExternalFormat = GR_GL_RGBA;
3053         info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3054         info.fDefaultColorType = GrColorType::kRGBA_16161616;
3055         if (rgba16Support) {
3056             info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3057             if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3058                 info.fFlags |= FormatInfo::kTransfers_Flag;
3059             }
3060         }
3061 
3062         if (texStorageSupported) {
3063             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3064             info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16;
3065         } else {
3066             info.fInternalFormatForTexImageOrStorage =
3067                     texImageSupportsSizedInternalFormat ? GR_GL_RGBA16 : GR_GL_RGBA;
3068         }
3069 
3070         if (rgba16Support) {
3071             // Format: GR_GL_RGBA16, Surface: kRGBA_16161616
3072             info.fColorTypeInfoCount = 1;
3073             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3074             int ctIdx = 0;
3075             {
3076                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3077                 ctInfo.fColorType = GrColorType::kRGBA_16161616;
3078                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3079                 this->setColorTypeFormat(GrColorType::kRGBA_16161616, GrGLFormat::kRGBA16);
3080 
3081                 // External IO ColorTypes:
3082                 ctInfo.fExternalIOFormatCount = 2;
3083                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3084                         ctInfo.fExternalIOFormatCount);
3085                 int ioIdx = 0;
3086                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_16161616
3087                 {
3088                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3089                     ioFormat.fColorType = GrColorType::kRGBA_16161616;
3090                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3091                     ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3092                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3093                     // Not guaranteed by ES/WebGL.
3094                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3095                 }
3096 
3097                 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_8888
3098                 {
3099                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3100                     ioFormat.fColorType = GrColorType::kRGBA_8888;
3101                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3102                     ioFormat.fExternalTexImageFormat = 0;
3103                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3104                 }
3105             }
3106         }
3107     }
3108 
3109     // Format:RG16F
3110     {
3111         bool rg16FTextureSupport = false;
3112         bool rg16FRenderTargetSupport = false;
3113         if (GR_IS_GR_GL(standard)) {
3114             if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
3115                 rg16FTextureSupport = true;
3116                 rg16FRenderTargetSupport = true;
3117             }
3118         } else if (GR_IS_GR_GL_ES(standard)) {
3119             // It seems possible that a combination of GL_EXT_texture_rg and
3120             // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
3121             // clear. The latter mentions interaction but that may only be for renderbuffers as
3122             // neither adds the texture format explicitly.
3123             // GL_OES_texture_format_half_float makes no reference to RG formats.
3124             if (version >= GR_GL_VER(3, 0)) {
3125                 rg16FTextureSupport = true;
3126                 rg16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
3127                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3128                                            ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
3129             }
3130         } else if (GR_IS_GR_WEBGL(standard)) {
3131             if (version >= GR_GL_VER(2, 0)) {
3132                 rg16FTextureSupport = true;
3133                 rg16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
3134                                            ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
3135                                            ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3136                                            ctxInfo.hasExtension("EXT_color_buffer_float");
3137             }
3138         }
3139 
3140         FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16F);
3141         info.fFormatType = FormatType::kFloat;
3142         info.fInternalFormatForRenderbuffer = GR_GL_RG16F;
3143         info.fDefaultExternalFormat = GR_GL_RG;
3144         info.fDefaultExternalType = halfFloatType;
3145         info.fDefaultColorType = GrColorType::kRG_F16;
3146         if (rg16FTextureSupport) {
3147             info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3148             if (rg16FRenderTargetSupport) {
3149                 info.fFlags |= fpRenderFlags;
3150             }
3151         }
3152 
3153         if (texStorageSupported) {
3154             info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3155             info.fInternalFormatForTexImageOrStorage = GR_GL_RG16F;
3156         } else {
3157             info.fInternalFormatForTexImageOrStorage =
3158                     texImageSupportsSizedInternalFormat ? GR_GL_RG16F : GR_GL_RG;
3159         }
3160 
3161         if (rg16FTextureSupport) {
3162             info.fColorTypeInfoCount = 1;
3163             info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3164             int ctIdx = 0;
3165             // Format: GR_GL_RG16F, Surface: kRG_F16
3166             {
3167                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3168                 ctInfo.fColorType = GrColorType::kRG_F16;
3169                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3170                 this->setColorTypeFormat(GrColorType::kRG_F16, GrGLFormat::kRG16F);
3171 
3172                 // External IO ColorTypes:
3173                 ctInfo.fExternalIOFormatCount = 2;
3174                 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3175                         ctInfo.fExternalIOFormatCount);
3176                 int ioIdx = 0;
3177                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRG_F16
3178                 {
3179                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3180                     ioFormat.fColorType = GrColorType::kRG_F16;
3181                     ioFormat.fExternalType = halfFloatType;
3182                     ioFormat.fExternalTexImageFormat = GR_GL_RG;
3183                     ioFormat.fExternalReadFormat = GR_GL_RG;
3184                     // Not guaranteed by ES/WebGL.
3185                     ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3186                 }
3187 
3188                 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRGBA_F32
3189                 {
3190                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3191                     ioFormat.fColorType = GrColorType::kRGBA_F32;
3192                     ioFormat.fExternalType = GR_GL_FLOAT;
3193                     ioFormat.fExternalTexImageFormat = 0;
3194                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
3195                 }
3196             }
3197         }
3198     }
3199 
3200     this->setupSampleCounts(ctxInfo, gli);
3201 
3202 #ifdef SK_DEBUG
3203     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3204         if (GrGLFormat::kUnknown == static_cast<GrGLFormat>(i)) {
3205             continue;
3206         }
3207         const auto& formatInfo = fFormatTable[i];
3208         // Make sure we didn't set fbo attachable with msaa and not fbo attachable.
3209         SkASSERT(!((formatInfo.fFlags & FormatInfo::kFBOColorAttachmentWithMSAA_Flag) &&
3210                   !(formatInfo.fFlags & FormatInfo::kFBOColorAttachment_Flag)));
3211 
3212         // Make sure we set all the formats' FormatType
3213         SkASSERT(formatInfo.fFormatType != FormatType::kUnknown);
3214 
3215         // Make sure if we added a ColorTypeInfo we filled it out
3216         for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
3217             const auto& ctInfo = formatInfo.fColorTypeInfos[j];
3218             SkASSERT(ctInfo.fColorType != GrColorType::kUnknown);
3219             // Seems silly to add a color type if we don't support any flags on it.
3220             SkASSERT(ctInfo.fFlags);
3221             // Make sure if we added any ExternalIOFormats we filled it out
3222             for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
3223                 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
3224                 SkASSERT(ioInfo.fColorType != GrColorType::kUnknown);
3225             }
3226         }
3227     }
3228 #endif
3229 }
3230 
setupSampleCounts(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)3231 void GrGLCaps::setupSampleCounts(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
3232     GrGLStandard standard = ctxInfo.standard();
3233     // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
3234     sk_ignore_unused_variable(standard);
3235     GrGLVersion version = ctxInfo.version();
3236 
3237     for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3238         if (FormatInfo::kFBOColorAttachmentWithMSAA_Flag & fFormatTable[i].fFlags) {
3239             // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
3240             SkASSERT(FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags);
3241             if ((GR_IS_GR_GL(standard) &&
3242                   (version >= GR_GL_VER(4,2) ||
3243                    ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
3244                 (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0))) {
3245                 int count;
3246                 GrGLFormat grGLFormat = static_cast<GrGLFormat>(i);
3247                 GrGLenum glFormat = this->getRenderbufferInternalFormat(grGLFormat);
3248                 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat,
3249                                           GR_GL_NUM_SAMPLE_COUNTS, 1, &count);
3250                 if (count) {
3251                     std::unique_ptr<int[]> temp(new int[count]);
3252                     GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_SAMPLES,
3253                                               count, temp.get());
3254                     // GL has a concept of MSAA rasterization with a single sample but we do not.
3255                     if (count && temp[count - 1] == 1) {
3256                         --count;
3257                         SkASSERT(!count || temp[count -1] > 1);
3258                     }
3259                     fFormatTable[i].fColorSampleCounts.setCount(count+1);
3260                     // We initialize our supported values with 1 (no msaa) and reverse the order
3261                     // returned by GL so that the array is ascending.
3262                     fFormatTable[i].fColorSampleCounts[0] = 1;
3263                     for (int j = 0; j < count; ++j) {
3264 #if defined(SK_BUILD_FOR_IOS) && TARGET_OS_SIMULATOR
3265                         // The iOS simulator is reporting incorrect values for sample counts,
3266                         // so force them to be a power of 2.
3267                         fFormatTable[i].fColorSampleCounts[j+1] = SkPrevPow2(temp[count - j - 1]);
3268 #else
3269                         fFormatTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
3270 #endif
3271                     }
3272                 }
3273             } else {
3274                 // Fake out the table using some semi-standard counts up to the max allowed sample
3275                 // count.
3276                 int maxSampleCnt = 1;
3277                 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
3278                     GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
3279                 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
3280                     GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
3281                 }
3282                 // Chrome has a mock GL implementation that returns 0.
3283                 maxSampleCnt = std::max(1, maxSampleCnt);
3284 
3285                 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
3286                 int count = SK_ARRAY_COUNT(kDefaultSamples);
3287                 for (; count > 0; --count) {
3288                     if (kDefaultSamples[count - 1] <= maxSampleCnt) {
3289                         break;
3290                     }
3291                 }
3292                 if (count > 0) {
3293                     fFormatTable[i].fColorSampleCounts.append(count, kDefaultSamples);
3294                 }
3295             }
3296         } else if (FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags) {
3297             fFormatTable[i].fColorSampleCounts.setCount(1);
3298             fFormatTable[i].fColorSampleCounts[0] = 1;
3299         }
3300     }
3301 }
3302 
canCopyTexSubImage(GrGLFormat dstFormat,bool dstHasMSAARenderBuffer,const GrTextureType * dstTypeIfTexture,GrGLFormat srcFormat,bool srcHasMSAARenderBuffer,const GrTextureType * srcTypeIfTexture) const3303 bool GrGLCaps::canCopyTexSubImage(GrGLFormat dstFormat, bool dstHasMSAARenderBuffer,
3304                                   const GrTextureType* dstTypeIfTexture,
3305                                   GrGLFormat srcFormat, bool srcHasMSAARenderBuffer,
3306                                   const GrTextureType* srcTypeIfTexture) const {
3307     // When it comes to format types and component sizes the gl spec is fairly complex as
3308     // requirements differ depending on many properties (e.g. if the internalFormat was created with
3309     // a sized format or not). These affect the rules about which format types can be copied to
3310     // which other types. For now we are being more restrictive and requiring that the types must
3311     // match exactly.
3312     if (this->getFormatDefaultExternalType(dstFormat) !=
3313         this->getFormatDefaultExternalType(srcFormat)) {
3314         return false;
3315     }
3316 
3317     // Either both the src and dst formats need to be SRGB or both need to not be SRGB
3318     if (GrGLFormatIsSRGB(dstFormat) != GrGLFormatIsSRGB(srcFormat)) {
3319         return false;
3320     }
3321 
3322     if (GR_IS_GR_GL_ES(fStandard)) {
3323         // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3324         // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it.
3325         // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3326         // avoids bugs with using glBlitFramebuffer.
3327         if ((dstFormat == GrGLFormat::kBGRA8 || srcFormat == GrGLFormat::kBGRA8) &&
3328             !fAllowBGRA8CopyTexSubImage) {
3329             return false;
3330         }
3331 
3332         // Table 3.9 of the ES2 spec and 3.16 of ES3 spec indicates the supported internal base
3333         // formats with CopyTexSubImage. Each base format can be copied to itself or formats with
3334         // less channels.
3335         uint32_t dstChannels = GrGLFormatChannels(dstFormat);
3336         uint32_t srcChannels = GrGLFormatChannels(srcFormat);
3337         if (!dstChannels || !srcChannels) {
3338             // The formats don't represent color channels (i.e. may be depth stencil)
3339             return false;
3340         }
3341         // The dst channels have to be a subset of the srcChannels, except R, RG, or RGB, channels
3342         // can go to LUM. (See expansion of Table 3.9 in EXT_texture_rg).
3343         if ((dstChannels & srcChannels) != srcChannels) {
3344             if (dstChannels == kGray_SkColorChannelFlag ||
3345                 dstChannels == kGrayAlpha_SkColorChannelFlags) {
3346                 // The dst can't have gray if the src is alpha-only.
3347                 if (srcChannels == kAlpha_SkColorChannelFlag) {
3348                     return false;
3349                 }
3350             } else {
3351                 return false;
3352             }
3353         }
3354     }
3355 
3356     // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
3357     if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
3358         return false;
3359     }
3360 
3361     // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
3362     // texture.
3363     if (!dstTypeIfTexture) {
3364         return false;
3365     }
3366 
3367     // Check that we could wrap the source in an FBO, that the dst is not TEXTURE_EXTERNAL, that no
3368     // mirroring is required
3369     return this->canFormatBeFBOColorAttachment(srcFormat) &&
3370            (!srcTypeIfTexture || *srcTypeIfTexture != GrTextureType::kExternal) &&
3371            *dstTypeIfTexture != GrTextureType::kExternal;
3372 }
3373 
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) const3374 bool GrGLCaps::canCopyAsBlit(GrGLFormat dstFormat, int dstSampleCnt,
3375                              const GrTextureType* dstTypeIfTexture,
3376                              GrGLFormat srcFormat, int srcSampleCnt,
3377                              const GrTextureType* srcTypeIfTexture,
3378                              const SkRect& srcBounds, bool srcBoundsExact,
3379                              const SkIRect& srcRect, const SkIPoint& dstPoint) const {
3380     auto blitFramebufferFlags = fBlitFramebufferFlags;
3381     if (!this->canFormatBeFBOColorAttachment(dstFormat) ||
3382         !this->canFormatBeFBOColorAttachment(srcFormat)) {
3383         return false;
3384     }
3385 
3386     if (dstTypeIfTexture && *dstTypeIfTexture == GrTextureType::kExternal) {
3387         return false;
3388     }
3389     if (srcTypeIfTexture && *srcTypeIfTexture == GrTextureType::kExternal) {
3390         return false;
3391     }
3392 
3393     if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3394         return false;
3395     }
3396 
3397     if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3398         if (srcSampleCnt > 1) {
3399             if (1 == dstSampleCnt) {
3400                 return false;
3401             }
3402             if (SkRect::Make(srcRect) != srcBounds || !srcBoundsExact) {
3403                 return false;
3404             }
3405         }
3406     }
3407 
3408     if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3409         if (dstSampleCnt > 1) {
3410             return false;
3411         }
3412     }
3413 
3414     if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3415         if (srcFormat != dstFormat) {
3416             return false;
3417         }
3418     } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3419         if (srcSampleCnt > 1 && srcFormat != dstFormat) {
3420             return false;
3421         }
3422     }
3423 
3424     if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3425         if (srcSampleCnt > 1) {
3426             if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
3427                 return false;
3428             }
3429         }
3430     }
3431     return true;
3432 }
3433 
canCopyAsDraw(GrGLFormat dstFormat,bool srcIsTexturable) const3434 bool GrGLCaps::canCopyAsDraw(GrGLFormat dstFormat, bool srcIsTexturable) const {
3435     return this->isFormatRenderable(dstFormat, 1) && srcIsTexturable;
3436 }
3437 
has_msaa_render_buffer(const GrSurfaceProxy * surf,const GrGLCaps & glCaps)3438 static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
3439     const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
3440     if (!rt) {
3441         return false;
3442     }
3443     // A RT has a separate MSAA renderbuffer if:
3444     // 1) It's multisampled
3445     // 2) We're using an extension with separate MSAA renderbuffers
3446     // 3) It's not FBO 0, which is special and always auto-resolves
3447     return rt->numSamples() > 1 &&
3448            glCaps.usesMSAARenderBuffers() &&
3449            !rt->glRTFBOIDIs0();
3450 }
3451 
onCanCopySurface(const GrSurfaceProxy * dst,const GrSurfaceProxy * src,const SkIRect & srcRect,const SkIPoint & dstPoint) const3452 bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
3453                                 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
3454     int dstSampleCnt = 0;
3455     int srcSampleCnt = 0;
3456     if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
3457         dstSampleCnt = rtProxy->numSamples();
3458     }
3459     if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
3460         srcSampleCnt = rtProxy->numSamples();
3461     }
3462     SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
3463     SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
3464 
3465     const GrTextureProxy* dstTex = dst->asTextureProxy();
3466     const GrTextureProxy* srcTex = src->asTextureProxy();
3467 
3468     GrTextureType dstTexType;
3469     GrTextureType* dstTexTypePtr = nullptr;
3470     GrTextureType srcTexType;
3471     GrTextureType* srcTexTypePtr = nullptr;
3472     if (dstTex) {
3473         dstTexType = dstTex->textureType();
3474         dstTexTypePtr = &dstTexType;
3475     }
3476     if (srcTex) {
3477         srcTexType = srcTex->textureType();
3478         srcTexTypePtr = &srcTexType;
3479     }
3480 
3481     auto dstFormat = dst->backendFormat().asGLFormat();
3482     auto srcFormat = src->backendFormat().asGLFormat();
3483     return this->canCopyTexSubImage(dstFormat, has_msaa_render_buffer(dst, *this), dstTexTypePtr,
3484                                     srcFormat, has_msaa_render_buffer(src, *this), srcTexTypePtr) ||
3485            this->canCopyAsBlit(dstFormat, dstSampleCnt, dstTexTypePtr, srcFormat, srcSampleCnt,
3486                                srcTexTypePtr, src->getBoundsRect(), src->priv().isExact(), srcRect,
3487                                dstPoint) ||
3488            this->canCopyAsDraw(dstFormat, SkToBool(srcTex));
3489 }
3490 
getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType colorType) const3491 GrCaps::DstCopyRestrictions GrGLCaps::getDstCopyRestrictions(const GrRenderTargetProxy* src,
3492                                                              GrColorType colorType) const {
3493     // If the src is a texture, we can implement the blit as a draw assuming the config is
3494     // renderable.
3495     if (src->asTextureProxy() && !this->isFormatAsColorTypeRenderable(colorType,
3496                                                                       src->backendFormat())) {
3497         return {};
3498     }
3499 
3500     if (const auto* texProxy = src->asTextureProxy()) {
3501         if (texProxy->textureType() == GrTextureType::kExternal) {
3502             // Not supported for FBO blit or CopyTexSubImage. Caller will have to fall back to a
3503             // draw (if the source is also a texture).
3504             return {};
3505         }
3506     }
3507 
3508     // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
3509     // possible and we return false to fallback to creating a render target dst for render-to-
3510     // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
3511     // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
3512     DstCopyRestrictions blitFramebufferRestrictions = {};
3513     if (src->numSamples() > 1 &&
3514         (fBlitFramebufferFlags & kResolveMustBeFull_BlitFrambufferFlag)) {
3515         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3516         blitFramebufferRestrictions.fMustCopyWholeSrc = true;
3517         // Mirroring causes rects to mismatch later, don't allow it.
3518     } else if (src->numSamples() > 1 && (fBlitFramebufferFlags &
3519                                          kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
3520         blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3521     }
3522 
3523     auto srcFormat = src->backendFormat().asGLFormat();
3524     // Check for format issues with glCopyTexSubImage2D
3525     if (srcFormat == GrGLFormat::kBGRA8) {
3526         // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
3527         // then we set up for that, otherwise fail.
3528         if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3529             return blitFramebufferRestrictions;
3530         }
3531         // Caller will have to use a draw.
3532         return {};
3533     }
3534 
3535     {
3536         bool srcIsMSAARenderbuffer = src->numSamples() > 1 &&
3537                                      this->usesMSAARenderBuffers();
3538         if (srcIsMSAARenderbuffer) {
3539             // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
3540             // blit or fail.
3541             if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3542                 return blitFramebufferRestrictions;
3543             }
3544             // Caller will have to use a draw.
3545             return {};
3546         }
3547     }
3548 
3549     // We'll do a CopyTexSubImage, no restrictions.
3550     return {};
3551 }
3552 
applyDriverCorrectnessWorkarounds(const GrGLContextInfo & ctxInfo,const GrContextOptions & contextOptions,const GrGLInterface * glInterface,GrShaderCaps * shaderCaps,FormatWorkarounds * formatWorkarounds)3553 void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
3554                                                  const GrContextOptions& contextOptions,
3555                                                  const GrGLInterface* glInterface,
3556                                                  GrShaderCaps* shaderCaps,
3557                                                  FormatWorkarounds* formatWorkarounds) {
3558     // A driver bug on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
3559     // Thus we are disabling this extension for now on Adreno4xx devices.
3560     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
3561         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
3562         fDriverBugWorkarounds.disable_discard_framebuffer) {
3563         fInvalidateFBType = kNone_InvalidateFBType;
3564     }
3565 
3566     if (ctxInfo.renderer() == GrGLRenderer::kIntelCherryView) {
3567         // When running DMSAA_dst_read_with_existing_barrier with DMSAA disabled on linux Intel
3568         // HD405, the test fails when using texture barriers. Oddly the gpu doing the draw which
3569         // uses the barrier correctly. It is the next draw, which does not use or need a barrier,
3570         // that is blending with a dst as if the barrier draw didn't happen. Since this GPU is not
3571         // that important to us and this driver bug could probably manifest itself in the wild, we
3572         // are just disabling texture barrier support for the gpu.
3573         fTextureBarrierSupport = false;
3574     }
3575 
3576     // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
3577     // 340.96 and 367.57.
3578     if (GR_IS_GR_GL(ctxInfo.standard()) && ctxInfo.driver() == GrGLDriver::kNVIDIA &&
3579         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
3580         fClearTextureSupport = false;
3581     }
3582 
3583     // glBlitFramebuffer seems to produce incorrect results on QC, Mali400, and Tegra3 but
3584     // glCopyTexSubImage2D works (even though there is no extension that specifically allows it).
3585     if (ctxInfo.vendor()   == GrGLVendor::kQualcomm  ||
3586         ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
3587         ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3588         fAllowBGRA8CopyTexSubImage = true;
3589     }
3590 
3591     // http://anglebug.com/6030
3592     if (fMSFBOType == kES_EXT_MsToTexture_MSFBOType &&
3593         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
3594         fDisallowDynamicMSAA = true;
3595     }
3596 
3597     // http://skbug.com/12081
3598     if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
3599         fDisallowDynamicMSAA = true;
3600     }
3601 
3602 #if defined(__has_feature)
3603 #if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
3604     // See skbug.com/7058
3605     fMapBufferType = kNone_MapBufferType;
3606     fMapBufferFlags = kNone_MapFlags;
3607     fTransferFromBufferToTextureSupport = false;
3608     fTransferFromSurfaceToBufferSupport = false;
3609     fTransferBufferType = TransferBufferType::kNone;
3610 #endif
3611 #endif
3612 
3613     // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
3614     // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
3615     // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
3616     // unclear whether this really affects a wide range of devices.
3617     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
3618         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
3619         fMapBufferType = kNone_MapBufferType;
3620         fMapBufferFlags = kNone_MapFlags;
3621         fTransferFromBufferToTextureSupport = false;
3622         fTransferFromSurfaceToBufferSupport = false;
3623         fTransferBufferType = TransferBufferType::kNone;
3624     }
3625 
3626     // The TransferPixelsToTexture test fails on ANGLE D3D9 and D3D11 if this is enabled.
3627     // https://anglebug.com/5542
3628     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 ||
3629         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
3630         fTransferPixelsToRowBytesSupport = false;
3631     }
3632 
3633     // Using MIPs on this GPU seems to be a source of trouble.
3634     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
3635         fMipmapSupport = false;
3636     }
3637 
3638 #ifdef SK_BUILD_FOR_ANDROID
3639     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
3640         // Flutter found glTexSubImage2D for GL_RED is much slower than GL_ALPHA on the
3641         // "MC18 PERSONAL SHOPPER"
3642         formatWorkarounds->fDisallowR8ForPowerVRSGX54x = true;
3643     }
3644 #endif
3645 
3646     if (ctxInfo.isOverCommandBuffer() && ctxInfo.version() >= GR_GL_VER(3,0)) {
3647         formatWorkarounds->fDisallowTextureUnorm16 = true;  // http://crbug.com/1224108
3648         formatWorkarounds->fDisallowETC2Compression = true;  // http://crbug.com/1224111
3649         fTransferFromSurfaceToBufferSupport = false;  // http://crbug.com/1224138
3650 
3651         // http://crbug.com/1224117
3652         fMapBufferFlags = kNone_MapFlags;
3653         fMapBufferType = kNone_MapBufferType;
3654     }
3655 
3656     // https://b.corp.google.com/issues/143074513
3657     // https://skbug.com/11152
3658     if (ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
3659         ctxInfo.renderer() == GrGLRenderer::kAdreno620) {
3660         fMSFBOType = kNone_MSFBOType;
3661         fMSAAResolvesAutomatically = false;
3662     }
3663 
3664 #ifndef SK_BUILD_FOR_IOS
3665     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x   ||
3666         ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue ||
3667         (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx && !ctxInfo.isOverCommandBuffer())) {
3668         fPerformColorClearsAsDraws = true;
3669     }
3670 #endif
3671 
3672     // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
3673     if (ctxInfo.renderer() == GrGLRenderer::kAMDRadeonHD7xxx ||
3674         ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M4xx) {
3675         fPerformColorClearsAsDraws = true;
3676     }
3677 
3678 #ifdef SK_BUILD_FOR_MAC
3679     // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
3680     // full screen clears
3681     // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
3682     // perform full screen clears.
3683     // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
3684     // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
3685     // crbug.com/1039912 - Crash rate in glClear spiked after OS update, affecting mostly
3686     //   Broadwell on 10.13+
3687     if (ctxInfo.vendor() == GrGLVendor::kIntel &&
3688         (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12) ||
3689          ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell)) {
3690         fPerformColorClearsAsDraws = true;
3691     }
3692     // crbug.com/969609 - NVIDIA on Mac sometimes segfaults during glClear in chrome. It seems
3693     // mostly concentrated in 10.13/14, GT 650Ms, driver 12+. But there are instances of older
3694     // drivers and GTX 775s, so we'll start with a broader workaround.
3695     if (ctxInfo.vendor() == GrGLVendor::kNVIDIA) {
3696         fPerformColorClearsAsDraws = true;
3697     }
3698 #endif
3699 
3700     // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
3701     // bugs seems to involve clearing too much and not skipping the clear.
3702     // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
3703     // but only for D3D11 ANGLE.
3704     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
3705         fPerformColorClearsAsDraws = true;
3706     }
3707 
3708     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
3709         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
3710         // This is known to be fixed sometime between driver 145.0 and 219.0
3711         if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
3712             fPerformStencilClearsAsDraws = true;
3713         }
3714         // This is known to be fixed sometime between driver 129.0 and 145.0 on Nexus 6P.
3715         // On driver 129 on Android M it fails the unit tests called WritePixelsPendingIO without
3716         // the workaround. It passes on Android N with driver 145 without the workaround.
3717         // skbug.com/11834
3718         if (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(145, 0, 0)) {
3719             fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
3720         }
3721     }
3722 
3723     if (fDriverBugWorkarounds.gl_clear_broken) {
3724         fPerformColorClearsAsDraws = true;
3725         fPerformStencilClearsAsDraws = true;
3726     }
3727 
3728     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
3729         // It appears that all the Adreno GPUs have less than optimal performance when
3730         // drawing w/ large index buffers.
3731         fAvoidLargeIndexBufferDraws = true;
3732     }
3733 
3734     // This was reproduced on the following configurations:
3735     // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
3736     // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
3737     // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
3738     // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
3739     // and not produced on:
3740     // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
3741     // The particular lines that get dropped from test images varies across different devices.
3742     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
3743         ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
3744         fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
3745     }
3746 
3747     // TODO: Don't apply this on iOS?
3748     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
3749         // Our Chromebook with GrGLRenderer::kPowerVRRogue crashes on large instanced draws. The
3750         // current minimum number of instances observed to crash is somewhere between 2^14 and 2^15.
3751         // Keep the number of instances below 1000, just to be safe.
3752         fMaxInstancesPerDrawWithoutCrashing = 999;
3753     } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
3754         fMaxInstancesPerDrawWithoutCrashing = 0x4000000;
3755     }
3756 
3757 #ifndef SK_BUILD_FOR_IOS
3758     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
3759         // We saw this bug on a TecnoSpark 3 Pro with a PowerVR GE8300.
3760         // GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
3761         // Possibly this could be more limited by driver version or HW generation.
3762         // When using samplers, we are seeing a bug where the gpu is sometimes not sampling the
3763         // correct mip level data. A workaround to this issue is that when binding a texture we also
3764         // set some texture state, and it seems like any inividual state works (e.g. min/mag filter,
3765         // base level, max level, etc.). Currently we just set the min filter level every time we
3766         // bind a texture as the workaround.
3767         fMustSetAnyTexParameterToEnableMipmapping = true;
3768         // ColorTypeBackendAllocationTest failed for kAlpha_8 and kGray_8 when using
3769         // GL_UNPACK_ROW_LENGTH. Perhaps this could be a more limited workaround by applying
3770         // only to single channel 8 bit unorm formats but we only have a monolithic query for this
3771         // support at present.
3772         fWritePixelsRowBytesSupport = false;
3773         // TransferPixelsToTextureTest fails for all color types on
3774         // TecnoSpark 3 Pro with a PowerVR GE8300, GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
3775         // if GL_UNPACK_ROW_LENGTH is used.
3776         fTransferPixelsToRowBytesSupport = false;
3777     }
3778 #endif
3779 
3780     // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
3781     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3782         fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
3783         fUseDrawInsteadOfAllRenderTargetWrites = true;
3784     }
3785 
3786 #ifdef SK_BUILD_FOR_MAC
3787     static constexpr bool isMAC = true;
3788 #else
3789     static constexpr bool isMAC = false;
3790 #endif
3791 
3792 #ifdef SK_BUILD_FOR_ANDROID
3793     // Older versions of Android have problems with setting GL_TEXTURE_BASE_LEVEL or
3794     // GL_TEXTURE_MAX_LEVEL on GL_TEXTURE_EXTERTNAL_OES textures. We just leave them as is and hope
3795     // the client never changes them either.
3796     fDontSetBaseOrMaxLevelForExternalTextures = true;
3797     // PowerVR can crash setting the levels on Android up to Q for any texture?
3798     // https://crbug.com/1123874
3799     if (ctxInfo.vendor() == GrGLVendor::kImagination) {
3800         fMipmapLevelControlSupport =  false;
3801     }
3802 #endif
3803 
3804     // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
3805     // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
3806     // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
3807     // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
3808     if (fMipmapLevelControlSupport &&
3809         !ctxInfo.isOverCommandBuffer() &&  // http://crbug.com/1224110
3810         (contextOptions.fDoManualMipmapping                 ||
3811          ctxInfo.vendor()  == GrGLVendor::kIntel            ||
3812          (ctxInfo.driver() == GrGLDriver::kNVIDIA && isMAC) ||
3813          ctxInfo.vendor()  == GrGLVendor::kATI)) {
3814         fDoManualMipmapping = true;
3815     }
3816 
3817     // See http://crbug.com/710443
3818 #ifdef SK_BUILD_FOR_MAC
3819     if (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell) {
3820         fClearToBoundaryValuesIsBroken = true;
3821     }
3822 #endif
3823     if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
3824         fDrawArraysBaseVertexIsBroken = true;
3825     }
3826 
3827     // https://b.corp.google.com/issues/188410972
3828     if (ctxInfo.renderer() == GrGLRenderer::kVirgl) {
3829         fDrawInstancedSupport = false;
3830     }
3831 
3832     // http://anglebug.com/4538
3833     if (fBaseVertexBaseInstanceSupport && !fDrawInstancedSupport) {
3834         fBaseVertexBaseInstanceSupport = false;
3835         fNativeDrawIndirectSupport = false;
3836         fMultiDrawType = MultiDrawType::kNone;
3837     }
3838 
3839     // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
3840     // Galaxy S7.
3841     // TODO: Once this is fixed we can update the check here to look at a driver version number too.
3842     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
3843         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other) {
3844         shaderCaps->fFBFetchSupport = false;
3845     }
3846 
3847     // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
3848     // function that may require a gradient calculation inside a conditional block may return
3849     // undefined results". This appears to be an issue with the 'any' call since even the simple
3850     // "result=black; if (any()) result=white;" code fails to compile.
3851     shaderCaps->fCanUseAnyFunctionInShader = (ctxInfo.vendor() != GrGLVendor::kImagination);
3852 
3853     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3854         // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
3855         // so we must do the abs first in a separate expression.
3856         shaderCaps->fCanUseMinAndAbsTogether = false;
3857 
3858         // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
3859         // must avoid this condition.
3860         shaderCaps->fCanUseFractForNegativeValues = false;
3861 
3862         // Seeing crashes on Tegra3 with inlined functions that have early returns. Looks like the
3863         // do { ... break; } while (false); construct is causing a crash in the driver.
3864         shaderCaps->fCanUseDoLoops = false;
3865     }
3866 
3867     // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
3868     // thus must us -1.0 * %s.x to work correctly
3869     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
3870         shaderCaps->fMustForceNegatedAtanParamToFloat = true;
3871     }
3872 
3873 #if defined(SK_BUILD_FOR_MAC)
3874     if (ctxInfo.vendor() == GrGLVendor::kATI) {
3875         // The Radeon GLSL compiler on Mac gets confused by ldexp(..., -x).
3876         // Convert to ldexp(..., x * -1).
3877         // http://skbug.com/12076
3878         shaderCaps->fMustForceNegatedLdexpParamToMultiply = true;
3879     }
3880 #endif
3881 
3882     // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
3883     // when floor and abs are called on the same line. Thus we must execute an Op between them to
3884     // make sure the compiler doesn't re-inline them even if we break the calls apart.
3885     if (ctxInfo.vendor() == GrGLVendor::kIntel) {
3886         shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
3887     }
3888 
3889     // On Adreno devices with framebuffer fetch support, there is a bug where they always return
3890     // the original dst color when reading the outColor even after being written to. By using a
3891     // local outColor we can work around this bug.
3892     if (shaderCaps->fFBFetchSupport && ctxInfo.vendor() == GrGLVendor::kQualcomm) {
3893         shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
3894     }
3895 
3896     // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
3897     // color, and that uniform contains an opaque color, and the output of the shader is only based
3898     // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
3899     // that the shader always outputs opaque values. In that case, it appears to remove the shader
3900     // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
3901     // insert an extra bit of math on the uniform that confuses the compiler just enough...
3902     if (ctxInfo.renderer() == GrGLRenderer::kMaliT) {
3903         shaderCaps->fMustObfuscateUniformColor = true;
3904     }
3905 
3906     // On Mali G series GPUs, applying transfer functions in the fragment shader with half-floats
3907     // produces answers that are much less accurate than expected/required. This forces full floats
3908     // for some intermediate values to get acceptable results.
3909     if (ctxInfo.renderer() == GrGLRenderer::kMaliG) {
3910         fShaderCaps->fColorSpaceMathNeedsFloat = true;
3911     }
3912 
3913     // On Mali 400 there is a bug using dFd* in the x direction. So we avoid using it when possible.
3914     if (ctxInfo.renderer() == GrGLRenderer::kMali4xx) {
3915         fShaderCaps->fAvoidDfDxForGradientsWhenPossible = true;
3916     }
3917 
3918 #ifdef SK_BUILD_FOR_WIN
3919     // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
3920     //
3921     // Basically, if a shader has a construct like:
3922     //
3923     // float x = someCondition ? someValue : 0;
3924     // float2 result = (0 == x) ? float2(x, x)
3925     //                          : float2(2 * x / x, 0);
3926     //
3927     // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
3928     // we've explicitly guarded the division with a check against zero. This manifests in much
3929     // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
3930     // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
3931     if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown || ctxInfo.isOverCommandBuffer()) {
3932         shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
3933     }
3934 #endif
3935 
3936     // The Adreno 5xx and 6xx produce incorrect results when comparing a pair of matrices.
3937     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
3938         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
3939         ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
3940         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
3941         ctxInfo.renderer() == GrGLRenderer::kAdreno630 ||
3942         ctxInfo.renderer() == GrGLRenderer::kAdreno640 ||
3943         ctxInfo.renderer() == GrGLRenderer::kAdreno6xx_other) {
3944         shaderCaps->fRewriteMatrixComparisons = true;
3945     }
3946 
3947     // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
3948     // (rare) situations. It's sporadic, and mostly on older drivers. Additionally, old Adreno
3949     // compilers (see crbug.com/skia/4078) crash when accessing .zw of gl_FragCoord, so just bypass
3950     // using gl_FragCoord at all to get around it.
3951     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
3952         shaderCaps->fCanUseFragCoord = false;
3953     }
3954 
3955     // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
3956     if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3957         shaderCaps->fCanUseFragCoord = false;
3958     }
3959 
3960     // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
3961     // (Are they implemented with fp16?)
3962     if (ctxInfo.vendor() == GrGLVendor::kARM) {
3963         shaderCaps->fIncompleteShortIntPrecision = true;
3964     }
3965 
3966     if (fDriverBugWorkarounds.add_and_true_to_loop_condition) {
3967         shaderCaps->fAddAndTrueToLoopCondition = true;
3968     }
3969 
3970     if (fDriverBugWorkarounds.unfold_short_circuit_as_ternary_operation) {
3971         shaderCaps->fUnfoldShortCircuitAsTernary = true;
3972     }
3973 
3974     if (fDriverBugWorkarounds.emulate_abs_int_function) {
3975         shaderCaps->fEmulateAbsIntFunction = true;
3976     }
3977 
3978     if (fDriverBugWorkarounds.rewrite_do_while_loops) {
3979         shaderCaps->fRewriteDoWhileLoops = true;
3980     }
3981 
3982     if (fDriverBugWorkarounds.remove_pow_with_constant_exponent) {
3983         shaderCaps->fRemovePowWithConstantExponent = true;
3984     }
3985 
3986     if (fDriverBugWorkarounds.disable_dual_source_blending_support) {
3987         shaderCaps->fDualSourceBlendingSupport = false;
3988     }
3989 
3990     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
3991         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
3992         shaderCaps->fMustWriteToFragColor = true;
3993     }
3994 
3995     // Disabling advanced blend on various platforms with major known issues. We also block Chrome
3996     // command buffer for now until its own denylists can be updated.
3997     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
3998         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
3999         ctxInfo.renderer() == GrGLRenderer::kAdreno530       ||
4000         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4001         ctxInfo.driver()   == GrGLDriver::kIntel             ||
4002         ctxInfo.isOverCommandBuffer()                        ||
4003         ctxInfo.vendor()   == GrGLVendor::kARM /* http://skbug.com/11906 */) {
4004         fBlendEquationSupport = kBasic_BlendEquationSupport;
4005         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4006     }
4007 
4008     // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
4009     if (ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4010         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
4011         kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
4012         fBlendEquationSupport = kBasic_BlendEquationSupport;
4013         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4014     }
4015 
4016     if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
4017         fBlendEquationSupport = kBasic_BlendEquationSupport;
4018         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4019     }
4020 
4021     if (this->advancedBlendEquationSupport()) {
4022         if (ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4023             ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
4024             // Disable color-dodge and color-burn on pre-355.00 NVIDIA.
4025             fAdvBlendEqDisableFlags |= (1 << kColorDodge_GrBlendEquation) |
4026                                     (1 << kColorBurn_GrBlendEquation);
4027         }
4028         if (ctxInfo.vendor() == GrGLVendor::kARM) {
4029             // Disable color-burn on ARM until the fix is released.
4030             fAdvBlendEqDisableFlags |= (1 << kColorBurn_GrBlendEquation);
4031         }
4032     }
4033 
4034     // On Adreno 5xx devices, there is a bug where we first draw using dual source blending. Thus
4035     // the dst blend func references the dst. Then the next draw we disable blending. However, on
4036     // the second draw the driver has a bug where it tries to access the second color output again.
4037     // This is fixed by reseting the blend function to anything that does not reference src2 when we
4038     // disable blending.
4039     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4040         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4041         ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4042         ctxInfo.renderer() == GrGLRenderer::kAdreno640) {
4043         fMustResetBlendFuncBetweenDualSourceAndDisable = true;
4044     }
4045 
4046     // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
4047     // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
4048     // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
4049     // skbug.com/7713
4050     if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
4051         ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
4052         !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
4053         shaderCaps->fExternalTextureSupport = true;
4054         shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
4055         shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
4056     }
4057 
4058 #ifdef SK_BUILD_FOR_IOS
4059     // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
4060     // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
4061     // is to just disable the feature.
4062     // https://github.com/flutter/flutter/issues/16718
4063     // https://bugreport.apple.com/web/?problemID=39948888
4064     fWritePixelsRowBytesSupport = false;
4065     // This affects all iOS devices for transfering from a PBO as well (presumably the issue is in
4066     // the GL->Metal layer).
4067     fTransferPixelsToRowBytesSupport = false;
4068 #endif
4069 
4070     if (ctxInfo.vendor()   == GrGLVendor::kIntel       ||  // IntelIris640 drops draws completely.
4071         ctxInfo.renderer() == GrGLRenderer::kMaliT     ||  // Some curves appear flat on GalaxyS6.
4072         ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4073         ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4074         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||  // We get garbage on Adreno405.
4075         ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {  // D3D9 conic strokes fail.
4076         fDisableTessellationPathRenderer = true;
4077     }
4078     // We found that on Wembley devices (PowerVR GE8320) that using tessellation path renderer would
4079     // cause lots of rendering errors where it seemed like vertices were in the wrong place. This
4080     // led to lots of GMs drawing nothing (e.g. dashing4) or lots of garbage. The Wembley devices
4081     // were running Android 12 with a driver version of 1.13. We previously had TecnoSpark devices
4082     // with the same GPU running on Android P (driver 1.10) which did not have this issue. We don't
4083     // know when the bug appeared in the driver so for now we disable tessellation path renderer for
4084     // all matching gpus regardless of driver version.
4085     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4086         fDisableTessellationPathRenderer = true;
4087     }
4088 
4089     // http://skbug.com/9739
4090     bool isNVIDIAPascal =
4091             ctxInfo.driver() == GrGLDriver::kNVIDIA                              &&
4092             ctxInfo.hasExtension("GL_NV_conservative_raster_pre_snap_triangles") &&  // Pascal+.
4093             !ctxInfo.hasExtension("GL_NV_conservative_raster_underestimation");      // Volta+.
4094     if (isNVIDIAPascal && ctxInfo.driverVersion() < GR_GL_DRIVER_VER(440, 00, 0)) {
4095         if (GR_IS_GR_GL(ctxInfo.standard())) {
4096             // glMemoryBarrier wasn't around until version 4.2.
4097             if (ctxInfo.version() >= GR_GL_VER(4,2)) {
4098                 fRequiresManualFBBarrierAfterTessellatedStencilDraw = true;
4099             } else {
4100                 shaderCaps->fMaxTessellationSegments = 0;
4101             }
4102         } else {
4103             // glMemoryBarrier wasn't around until es version 3.1.
4104             if (ctxInfo.version() >= GR_GL_VER(3,1)) {
4105                 fRequiresManualFBBarrierAfterTessellatedStencilDraw = true;
4106             } else {
4107                 shaderCaps->fMaxTessellationSegments = 0;
4108             }
4109         }
4110     }
4111 
4112     if (ctxInfo.driver() == GrGLDriver::kQualcomm) {
4113         // Qualcomm fails to link programs with tessellation and does not give an error message.
4114         // http://skbug.com/9740
4115         shaderCaps->fMaxTessellationSegments = 0;
4116     }
4117 
4118 #ifdef SK_BUILD_FOR_WIN
4119     // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
4120     if (ctxInfo.driver() == GrGLDriver::kIntel ||
4121         (ctxInfo.angleVendor()  == GrGLVendor::kIntel &&
4122          ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL)) {
4123         fNativeDrawIndexedIndirectIsBroken = true;
4124         fUseClientSideIndirectBuffers = true;
4125     }
4126 #endif
4127 
4128     // PowerVRGX6250 drops every pixel if we modify the sample mask while color writes are disabled.
4129     if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4130         fNeverDisableColorWrites = true;
4131         shaderCaps->fMustWriteToFragColor = true;
4132     }
4133 
4134     // It appears that Qualcomm drivers don't actually support
4135     // GL_NV_shader_noperspective_interpolation in ES 3.00 or 3.10 shaders, only 3.20.
4136     // https://crbug.com/986581
4137     if (ctxInfo.vendor() == GrGLVendor::kQualcomm &&
4138         k320es_GrGLSLGeneration != ctxInfo.glslGeneration()) {
4139         shaderCaps->fNoPerspectiveInterpolationSupport = false;
4140     }
4141 
4142     // We disable srgb write control for Adreno4xx devices.
4143     // see: https://bug.skia.org/5329
4144     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4145         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4146         fSRGBWriteControl = false;
4147     }
4148 
4149     // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
4150 #if defined(SK_BUILD_FOR_MAC)
4151     if (ctxInfo.vendor() == GrGLVendor::kATI) {
4152         formatWorkarounds->fDisableSRGBRenderWithMSAAForMacAMD = true;
4153     }
4154 #endif
4155 
4156     // Command buffer fails glTexSubImage2D with type == GL_HALF_FLOAT_OES if a GL_RGBA16F texture
4157     // is created with glTexStorage2D. See crbug.com/1008003.
4158     formatWorkarounds->fDisableRGBA16FTexStorageForCrBug1008003 =
4159             ctxInfo.isOverCommandBuffer() && ctxInfo.version() < GR_GL_VER(3, 0);
4160 
4161 #if defined(SK_BUILD_FOR_WIN)
4162     // On Intel Windows ES contexts it seems that using texture storage with BGRA causes
4163     // problems with cross-context SkImages.
4164     formatWorkarounds->fDisableBGRATextureStorageForIntelWindowsES =
4165             ctxInfo.driver() == GrGLDriver::kIntel && GR_IS_GR_GL_ES(ctxInfo.standard());
4166 #endif
4167 
4168     // On the Intel Iris 6100, interacting with LUM16F seems to confuse the driver. After
4169     // writing to/reading from a LUM16F texture reads from/writes to other formats behave
4170     // erratically.
4171     // All Adrenos claim to support LUM16F but don't appear to actually do so.
4172     // The failing devices/gpus were: Nexus5/Adreno330, Nexus5x/Adreno418, Pixel/Adreno530,
4173     // Pixel2XL/Adreno540 and Pixel3/Adreno630
4174     formatWorkarounds->fDisableLuminance16F = ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell ||
4175                                               ctxInfo.vendor()   == GrGLVendor::kQualcomm;
4176 
4177 #ifdef SK_BUILD_FOR_MAC
4178     // On a MacBookPro 11.5 running MacOS 10.13 with a Radeon M370X the TransferPixelsFrom test
4179     // fails when transferring out from a GL_RG8 texture using GL_RG/GL_UNSIGNED_BYTE.
4180     // The same error also occurs in MacOS 10.15 with a Radeon Pro 5300M.
4181     formatWorkarounds->fDisallowDirectRG8ReadPixels =
4182             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M3xx  ||
4183             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonPro5xxx ||
4184             ctxInfo.renderer() == GrGLRenderer::kAMDRadeonProVegaxx;
4185 #endif
4186 
4187 #ifdef SK_BUILD_FOR_ANDROID
4188     // We don't usually use glTexStorage() on Android for performance reasons. (crbug.com/945506).
4189     // On a NVIDIA Shield TV running Android 7.0 creating a texture with glTexImage2D() with
4190     // internal format GL_LUMINANCE8 fails. However, it succeeds with glTexStorage2D().
4191     //
4192     // Additionally, on the Nexus 9 running Android 6.0.1 formats added by GL_EXT_texture_rg and
4193     // GL_EXT_texture_norm16 cause errors if they are created with glTexImage2D() with
4194     // an unsized internal format. We wouldn't normally do that but Chrome can limit us
4195     // artificially to ES2. (crbug.com/1003481)
4196     if (ctxInfo.vendor() == GrGLVendor::kNVIDIA) {
4197         formatWorkarounds->fDontDisableTexStorageOnAndroid = true;
4198     }
4199 #endif
4200 
4201     // https://github.com/flutter/flutter/issues/38700
4202     if (ctxInfo.driver() == GrGLDriver::kAndroidEmulator) {
4203         shaderCaps->fNoDefaultPrecisionForExternalSamplers = true;
4204     }
4205 
4206     // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
4207     if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4208         fTiledRenderingSupport = false;
4209     }
4210     // https://github.com/flutter/flutter/issues/47164
4211     // https://github.com/flutter/flutter/issues/47804
4212     if (fTiledRenderingSupport && (!glInterface->fFunctions.fStartTiling ||
4213                                    !glInterface->fFunctions.fEndTiling)) {
4214         // Some devices expose the QCOM tiled memory extension string but don't actually provide the
4215         // start and end tiling functions (see above flutter bugs). To work around this, the funcs
4216         // are marked optional in the interface generator, but we turn off the tiled rendering cap
4217         // if they aren't provided. This disabling is in driver workarounds so that SKQP will still
4218         // fail on devices that advertise the extension w/o the functions.
4219         fTiledRenderingSupport = false;
4220     }
4221 
4222     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {
4223         formatWorkarounds->fDisallowBGRA8ReadPixels = true;
4224     }
4225 
4226     // We disable MSAA for all Intel GPUs. Before Gen9, performance was very bad. Even with Gen9,
4227     // we've seen driver crashes in the wild. We don't have data on Gen11 yet.
4228     // (crbug.com/527565, crbug.com/983926)
4229     if (ctxInfo.vendor() == GrGLVendor::kIntel ||
4230         ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4231         fMSFBOType = kNone_MSFBOType;
4232     }
4233 
4234     // ANGLE doesn't support do-while loops.
4235     if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown) {
4236         shaderCaps->fCanUseDoLoops = false;
4237     }
4238 
4239     // ANGLE's D3D9 backend + AMD GPUs are flaky with program binary caching (skbug.com/10395)
4240     if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 &&
4241         ctxInfo.angleVendor()  == GrGLVendor::kATI) {
4242         fProgramBinarySupport = false;
4243     }
4244 
4245     // Two Adreno 530 devices (LG G6 and OnePlus 3T) appear to have driver bugs that are corrupting
4246     // SkSL::Program memory. To get better/different crash reports, disable node-pooling, so that
4247     // program allocations aren't reused.  (crbug.com/1147008, crbug.com/1164271)
4248     if (ctxInfo.renderer() == GrGLRenderer::kAdreno530) {
4249         shaderCaps->fUseNodePools = false;
4250     }
4251 
4252     // skbug.com/11204. Avoid recursion issue in SurfaceContext::writePixels.
4253     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4254         fReuseScratchTextures = false;
4255     }
4256 
4257     // skbug.com/11935. Don't reorder on these GPUs in GL on old drivers.
4258     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4259         ctxInfo.renderer() == GrGLRenderer::kAdreno640) &&
4260         ctxInfo.driverVersion() < GR_GL_DRIVER_VER(571, 0, 0)) {
4261         fAvoidReorderingRenderTasks = true;
4262     }
4263 
4264     // http://skbug.com/11965
4265     if (ctxInfo.renderer() == GrGLRenderer::kGoogleSwiftShader) {
4266         fShaderCaps->fVertexIDSupport = false;
4267     }
4268 
4269     // http://crbug.com/1197152
4270     // http://b/187364475
4271     // We could limit this < 1.13 on ChromeOS but we don't really have a good way to detect
4272     // ChromeOS from here.
4273     if (ctxInfo.renderer()      == GrGLRenderer::kPowerVRRogue &&
4274         ctxInfo.driver()        == GrGLDriver::kImagination    &&
4275         ctxInfo.driverVersion() <  GR_GL_DRIVER_VER(1, 16, 0)) {
4276         fShaderCaps->fShaderDerivativeSupport = false;
4277     }
4278 
4279     if (ctxInfo.driver() == GrGLDriver::kFreedreno) {
4280         formatWorkarounds->fDisallowUnorm16Transfers = true;
4281     }
4282 
4283     // If we keep rebind the same texture to an FBO's color attachment but changing between MSAA and
4284     // non-MSAA we get corruption in the texture contents. Binding texture 0 and then rebinding the
4285     // original texture avoids this.
4286     // This was found on Nexus 5, Android 6.0.1, build M4B30Z
4287     // GL_VENDOR  : "Qualcomm"
4288     // GL_RENDERER: "Adreno (TM) 330"
4289     // GL_VERSION : "OpenGL ES 3.0 V@127.0 AU@  (GIT@I96aee987eb)"
4290     //
4291     // We also so alpha blending issues on these GMs skbug_9819, p3_ovals, p3 on Mali-Gxx devices
4292     // The GM issues were observed on a Galaxy S9 running Android 10:
4293     // GL_VERSION : "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
4294     // GL_RENDERER: "Mali-G72"
4295     // GL_VENDOR  : "ARM"
4296     // and a P30 running Android 9:
4297     // GL_VERSION : "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
4298     // GL_RENDERER: "Mali-G76"
4299     // GL_VENDOR  : "ARM"
4300     // but *not* a Galaxy S20 running Android 10:
4301     // GL_VERSION : "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
4302     // GL_RENDERER: "Mali-G77"
4303     // GL_VENDOR  : "ARM"
4304     // It's unclear if the difference is driver version or Bifrost vs Valhall. The workaround is
4305     // fairly trivial so just applying to all Bifrost and Valhall.
4306     if ((ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4307          ctxInfo.driver()   == GrGLDriver::kQualcomm) ||
4308         (ctxInfo.renderer() == GrGLRenderer::kMaliG)) {
4309         fBindTexture0WhenChangingTextureFBOMultisampleCount = true;
4310     }
4311 
4312     // skbug.com/12640
4313     // We found that on the Galaxy S7 the TransferPixelsTo test would fail after adding
4314     // glCheckFramebufferStatus() checks when making new FBOs. Note that the returned status was
4315     // GL_FRAMEBUFFER_COMPLETE. Switching the color binding to ID 0 and back to the original
4316     // afterwards works around the issue.
4317     // GL_VENDOR  : "ARM"
4318     // GL_RENDERER: "Mali-T880"
4319     // GL_VERSION : "OpenGL ES 3.2 v1.r22p0-01rel0.f294e54ceb2cb2d81039204fa4b0402e"
4320     //
4321     // This *didn't* reproduce on a Kevin ChromeOS device:
4322     // GL_VENDOR  : "ARM"
4323     // GL_RENDERER: "Mali-T860"
4324     // GL_VERSION : "OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3"
4325     if (ctxInfo.renderer()      == GrGLRenderer::kMaliT &&
4326         ctxInfo.driver()        == GrGLDriver::kARM     &&
4327         ctxInfo.driverVersion()  < GR_GL_DRIVER_VER(1, 26, 0)) {
4328         fRebindColorAttachmentAfterCheckFramebufferStatus = true;
4329     }
4330 }
4331 
onApplyOptionsOverrides(const GrContextOptions & options)4332 void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
4333     if (options.fDisableDriverCorrectnessWorkarounds) {
4334         SkASSERT(!fDoManualMipmapping);
4335         SkASSERT(!fClearToBoundaryValuesIsBroken);
4336         SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
4337         SkASSERT(!fDrawArraysBaseVertexIsBroken);
4338         SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
4339         SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
4340         SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
4341         SkASSERT(!fDontSetBaseOrMaxLevelForExternalTextures);
4342         SkASSERT(!fNeverDisableColorWrites);
4343     }
4344     if (options.fShaderCacheStrategy < GrContextOptions::ShaderCacheStrategy::kBackendBinary) {
4345         fProgramBinarySupport = false;
4346     }
4347 
4348     switch (options.fSkipGLErrorChecks) {
4349         case GrContextOptions::Enable::kNo:
4350             fSkipErrorChecks = false;
4351             break;
4352         case GrContextOptions::Enable::kYes:
4353             fSkipErrorChecks = true;
4354             break;
4355         case GrContextOptions::Enable::kDefault:
4356             break;
4357     }
4358 }
4359 
onSurfaceSupportsWritePixels(const GrSurface * surface) const4360 bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
4361     if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4362         if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4363             if (tex->hasBaseLevelBeenBoundToFBO()) {
4364                 return false;
4365             }
4366         }
4367     }
4368     if (auto rt = surface->asRenderTarget()) {
4369         if (fUseDrawInsteadOfAllRenderTargetWrites) {
4370             return false;
4371         }
4372         if (rt->numSamples() > 1 && this->usesMSAARenderBuffers()) {
4373             return false;
4374         }
4375         return SkToBool(surface->asTexture());
4376     }
4377     return true;
4378 }
4379 
surfaceSupportsReadPixels(const GrSurface * surface) const4380 GrCaps::SurfaceReadPixelsSupport GrGLCaps::surfaceSupportsReadPixels(
4381         const GrSurface* surface) const {
4382     if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4383         // We don't support reading pixels directly from EXTERNAL textures as it would require
4384         // binding the texture to a FBO. For now we also disallow reading back directly
4385         // from compressed textures.
4386         if (tex->target() == GR_GL_TEXTURE_EXTERNAL || GrGLFormatIsCompressed(tex->format())) {
4387             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4388         }
4389     } else if (auto rt = static_cast<const GrGLRenderTarget*>(surface->asRenderTarget())) {
4390         // glReadPixels does not allow reading back from a MSAA framebuffer. If the underlying
4391         // GrSurface doesn't have a second FBO to resolve to then we must make a copy.
4392         if (rt->numSamples() > 1 && !rt->asTexture()) {
4393             return SurfaceReadPixelsSupport::kCopyToTexture2D;
4394         }
4395     }
4396     return SurfaceReadPixelsSupport::kSupported;
4397 }
4398 
offset_alignment_for_transfer_buffer(GrGLenum externalType)4399 size_t offset_alignment_for_transfer_buffer(GrGLenum externalType) {
4400     // This switch is derived from a table titled "Pixel data type parameter values and the
4401     // corresponding GL data types" in the OpenGL spec (Table 8.2 in OpenGL 4.5).
4402     switch (externalType) {
4403         case GR_GL_UNSIGNED_BYTE:                   return sizeof(GrGLubyte);
4404         case GR_GL_BYTE:                            return sizeof(GrGLbyte);
4405         case GR_GL_UNSIGNED_SHORT:                  return sizeof(GrGLushort);
4406         case GR_GL_SHORT:                           return sizeof(GrGLshort);
4407         case GR_GL_UNSIGNED_INT:                    return sizeof(GrGLuint);
4408         case GR_GL_INT:                             return sizeof(GrGLint);
4409         case GR_GL_HALF_FLOAT:                      return sizeof(GrGLhalf);
4410         case GR_GL_HALF_FLOAT_OES:                  return sizeof(GrGLhalf);
4411         case GR_GL_FLOAT:                           return sizeof(GrGLfloat);
4412         case GR_GL_UNSIGNED_SHORT_5_6_5:            return sizeof(GrGLushort);
4413         case GR_GL_UNSIGNED_SHORT_4_4_4_4:          return sizeof(GrGLushort);
4414         case GR_GL_UNSIGNED_SHORT_5_5_5_1:          return sizeof(GrGLushort);
4415         case GR_GL_UNSIGNED_INT_2_10_10_10_REV:     return sizeof(GrGLuint);
4416 #if 0  // GL types we currently don't use. Here for future reference.
4417         case GR_GL_UNSIGNED_BYTE_3_3_2:             return sizeof(GrGLubyte);
4418         case GR_GL_UNSIGNED_BYTE_2_3_3_REV:         return sizeof(GrGLubyte);
4419         case GR_GL_UNSIGNED_SHORT_5_6_5_REV:        return sizeof(GrGLushort);
4420         case GR_GL_UNSIGNED_SHORT_4_4_4_4_REV:      return sizeof(GrGLushort);
4421         case GR_GL_UNSIGNED_SHORT_1_5_5_5_REV:      return sizeof(GrGLushort);
4422         case GR_GL_UNSIGNED_INT_8_8_8_8:            return sizeof(GrGLuint);
4423         case GR_GL_UNSIGNED_INT_8_8_8_8_REV:        return sizeof(GrGLuint);
4424         case GR_GL_UNSIGNED_INT_10_10_10_2:         return sizeof(GrGLuint);
4425         case GR_GL_UNSIGNED_INT_24_8:               return sizeof(GrGLuint);
4426         case GR_GL_UNSIGNED_INT_10F_11F_11F_REV:    return sizeof(GrGLuint);
4427         case GR_GL_UNSIGNED_INT_5_9_9_9_REV:        return sizeof(GrGLuint);
4428         // This one is not corresponding to a GL data type and the spec just says it is 4.
4429         case GR_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:  return 4;
4430 #endif
4431         default:                                    return 0;
4432     }
4433 }
4434 
onSupportedReadPixelsColorType(GrColorType srcColorType,const GrBackendFormat & srcBackendFormat,GrColorType dstColorType) const4435 GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
4436         GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
4437         GrColorType dstColorType) const {
4438 
4439     SkImage::CompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
4440     if (compression != SkImage::CompressionType::kNone) {
4441         return {SkCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
4442                                                        : GrColorType::kRGBA_8888,
4443                 0};
4444     }
4445 
4446     // We first try to find a supported read pixels GrColorType that matches the requested
4447     // dstColorType. If that doesn't exists we will use any valid read pixels GrColorType.
4448     GrCaps::SupportedRead fallbackRead = {GrColorType::kUnknown, 0};
4449     const auto& formatInfo = this->getFormatInfo(srcBackendFormat.asGLFormat());
4450     bool foundSrcCT = false;
4451     for (int i = 0; !foundSrcCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4452         if (formatInfo.fColorTypeInfos[i].fColorType == srcColorType) {
4453             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4454             foundSrcCT = true;
4455             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4456                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4457                 if (ioInfo.fExternalReadFormat != 0) {
4458                     if (formatInfo.fHaveQueriedImplementationReadSupport ||
4459                         !ioInfo.fRequiresImplementationReadQuery) {
4460                         GrGLenum transferOffsetAlignment = 0;
4461                         if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4462                             transferOffsetAlignment =
4463                                     offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
4464                         }
4465                         if (ioInfo.fColorType == dstColorType) {
4466                             return {dstColorType, transferOffsetAlignment};
4467                         }
4468                         // Currently we just pick the first supported format that we find as our
4469                         // fallback.
4470                         if (fallbackRead.fColorType == GrColorType::kUnknown) {
4471                             fallbackRead = {ioInfo.fColorType, transferOffsetAlignment};
4472                         }
4473                     }
4474                 }
4475             }
4476         }
4477     }
4478     return fallbackRead;
4479 }
4480 
supportedWritePixelsColorType(GrColorType surfaceColorType,const GrBackendFormat & surfaceFormat,GrColorType srcColorType) const4481 GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfaceColorType,
4482                                                                const GrBackendFormat& surfaceFormat,
4483                                                                GrColorType srcColorType) const {
4484     // We first try to find a supported write pixels GrColorType that matches the data's
4485     // srcColorType. If that doesn't exists we will use any supported GrColorType.
4486     GrColorType fallbackCT = GrColorType::kUnknown;
4487     const auto& formatInfo = this->getFormatInfo(surfaceFormat.asGLFormat());
4488     bool foundSurfaceCT = false;
4489     size_t transferOffsetAlignment = 0;
4490     if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4491         transferOffsetAlignment = 1;
4492     }
4493     for (int i = 0; !foundSurfaceCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4494         if (formatInfo.fColorTypeInfos[i].fColorType == surfaceColorType) {
4495             const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4496             foundSurfaceCT = true;
4497             for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4498                 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4499                 if (ioInfo.fExternalTexImageFormat != 0) {
4500                     if (ioInfo.fColorType == srcColorType) {
4501                         return {srcColorType, transferOffsetAlignment};
4502                     }
4503                     // Currently we just pick the first supported format that we find as our
4504                     // fallback.
4505                     if (fallbackCT == GrColorType::kUnknown) {
4506                         fallbackCT = ioInfo.fColorType;
4507                     }
4508                 }
4509             }
4510         }
4511     }
4512     return {fallbackCT, transferOffsetAlignment};
4513 }
4514 
onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget & backendRT) const4515 bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
4516     GrGLFramebufferInfo fbInfo;
4517     SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
4518     // Window Rectangles are not supported for FBO 0;
4519     return fbInfo.fFBOID != 0;
4520 }
4521 
isFormatSRGB(const GrBackendFormat & format) const4522 bool GrGLCaps::isFormatSRGB(const GrBackendFormat& format) const {
4523     return format.asGLFormat() == GrGLFormat::kSRGB8_ALPHA8;
4524 }
4525 
isFormatTexturable(const GrBackendFormat & format,GrTextureType textureType) const4526 bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType textureType) const {
4527     if (textureType == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
4528         return false;
4529     }
4530     return this->isFormatTexturable(format.asGLFormat());
4531 }
4532 
isFormatTexturable(GrGLFormat format) const4533 bool GrGLCaps::isFormatTexturable(GrGLFormat format) const {
4534     const FormatInfo& info = this->getFormatInfo(format);
4535     return SkToBool(info.fFlags & FormatInfo::kTexturable_Flag);
4536 }
4537 
isFormatAsColorTypeRenderable(GrColorType ct,const GrBackendFormat & format,int sampleCount) const4538 bool GrGLCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
4539                                              int sampleCount) const {
4540     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
4541         return false;
4542     }
4543     if (format.textureType() == GrTextureType::kExternal) {
4544         return false;
4545     }
4546     auto f = format.asGLFormat();
4547     const FormatInfo& info = this->getFormatInfo(f);
4548     if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
4549         return false;
4550     }
4551 
4552     return this->isFormatRenderable(f, sampleCount);
4553 }
4554 
isFormatRenderable(const GrBackendFormat & format,int sampleCount) const4555 bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
4556     if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
4557         return false;
4558     }
4559     if (format.textureType() == GrTextureType::kExternal) {
4560         return false;
4561     }
4562     return this->isFormatRenderable(format.asGLFormat(), sampleCount);
4563 }
4564 
getRenderTargetSampleCount(int requestedCount,GrGLFormat format) const4565 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrGLFormat format) const {
4566     const FormatInfo& info = this->getFormatInfo(format);
4567 
4568     int count = info.fColorSampleCounts.count();
4569     if (!count) {
4570         return 0;
4571     }
4572 
4573     requestedCount = std::max(1, requestedCount);
4574     if (1 == requestedCount) {
4575         return info.fColorSampleCounts[0] == 1 ? 1 : 0;
4576     }
4577 
4578     for (int sampleCount : info.fColorSampleCounts) {
4579         if (sampleCount >= requestedCount) {
4580             if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
4581                 sampleCount = std::min(sampleCount, 4);
4582             }
4583             return sampleCount;
4584         }
4585     }
4586     return 0;
4587 }
4588 
maxRenderTargetSampleCount(GrGLFormat format) const4589 int GrGLCaps::maxRenderTargetSampleCount(GrGLFormat format) const {
4590     const FormatInfo& info = this->getFormatInfo(format);
4591     const auto& table = info.fColorSampleCounts;
4592     if (!table.count()) {
4593         return 0;
4594     }
4595     int count = table[table.count() - 1];
4596     if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
4597         count = std::min(count, 4);
4598     }
4599     return count;
4600 }
4601 
canFormatBeFBOColorAttachment(GrGLFormat format) const4602 bool GrGLCaps::canFormatBeFBOColorAttachment(GrGLFormat format) const {
4603     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kFBOColorAttachment_Flag);
4604 }
4605 
isFormatCopyable(const GrBackendFormat & format) const4606 bool GrGLCaps::isFormatCopyable(const GrBackendFormat& format) const {
4607     // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
4608     // requires the src to be an FBO attachment, blit requires both src and dst to be FBO
4609     // attachments, and draw requires the dst to be an FBO attachment. Thus to copy from and to
4610     // the same config, we need that config to be bindable to an FBO.
4611     return this->canFormatBeFBOColorAttachment(format.asGLFormat());
4612 }
4613 
formatSupportsTexStorage(GrGLFormat format) const4614 bool GrGLCaps::formatSupportsTexStorage(GrGLFormat format) const {
4615     return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kUseTexStorage_Flag);
4616 }
4617 
shouldQueryImplementationReadSupport(GrGLFormat format) const4618 bool GrGLCaps::shouldQueryImplementationReadSupport(GrGLFormat format) const {
4619     const auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
4620     if (!formatInfo.fHaveQueriedImplementationReadSupport) {
4621         // Check whether we will actually learn anything useful.
4622         bool needQuery = false;
4623         for (int i = 0; i < formatInfo.fColorTypeInfoCount && !needQuery; ++i) {
4624             const auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
4625             for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
4626                 if (surfCTInfo.fExternalIOFormats[j].fRequiresImplementationReadQuery) {
4627                     needQuery = true;
4628                     break;
4629                 }
4630             }
4631         }
4632         if (!needQuery) {
4633             // Pretend we already checked it.
4634             const_cast<FormatInfo&>(formatInfo).fHaveQueriedImplementationReadSupport = true;
4635         }
4636     }
4637     return !formatInfo.fHaveQueriedImplementationReadSupport;
4638 }
4639 
didQueryImplementationReadSupport(GrGLFormat format,GrGLenum readFormat,GrGLenum readType) const4640 void GrGLCaps::didQueryImplementationReadSupport(GrGLFormat format,
4641                                                  GrGLenum readFormat,
4642                                                  GrGLenum readType) const {
4643     auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
4644     for (int i = 0; i < formatInfo.fColorTypeInfoCount; ++i) {
4645         auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
4646         for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
4647             auto& readCTInfo = surfCTInfo.fExternalIOFormats[j];
4648             if (readCTInfo.fRequiresImplementationReadQuery) {
4649                 if (readCTInfo.fExternalReadFormat != readFormat ||
4650                     readCTInfo.fExternalType != readType) {
4651                     // Don't zero out fExternalType. It's also used for writing data to the texture!
4652                     readCTInfo.fExternalReadFormat = 0;
4653                 }
4654             }
4655         }
4656     }
4657     formatInfo.fHaveQueriedImplementationReadSupport = true;
4658 }
4659 
onAreColorTypeAndFormatCompatible(GrColorType ct,const GrBackendFormat & format) const4660 bool GrGLCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
4661                                                  const GrBackendFormat& format) const {
4662     GrGLFormat glFormat = format.asGLFormat();
4663     const auto& info = this->getFormatInfo(glFormat);
4664     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
4665         if (info.fColorTypeInfos[i].fColorType == ct) {
4666             return true;
4667         }
4668     }
4669     return false;
4670 }
4671 
onGetDefaultBackendFormat(GrColorType ct) const4672 GrBackendFormat GrGLCaps::onGetDefaultBackendFormat(GrColorType ct) const {
4673     auto format = this->getFormatFromColorType(ct);
4674     if (format == GrGLFormat::kUnknown) {
4675         return {};
4676     }
4677     return GrBackendFormat::MakeGL(GrGLFormatToEnum(format), GR_GL_TEXTURE_2D);
4678 }
4679 
getBackendFormatFromCompressionType(SkImage::CompressionType compressionType) const4680 GrBackendFormat GrGLCaps::getBackendFormatFromCompressionType(
4681         SkImage::CompressionType compressionType) const {
4682     switch (compressionType) {
4683         case SkImage::CompressionType::kNone:
4684             return {};
4685         case SkImage::CompressionType::kETC2_RGB8_UNORM:
4686             // if ETC2 is available default to that format
4687             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_ETC2)) {
4688                 return GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D);
4689             }
4690             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ETC1_RGB8)) {
4691                 return GrBackendFormat::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D);
4692             }
4693             return {};
4694         case SkImage::CompressionType::kBC1_RGB8_UNORM:
4695             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_BC1)) {
4696                 return GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
4697                                                GR_GL_TEXTURE_2D);
4698             }
4699             return {};
4700         case SkImage::CompressionType::kBC1_RGBA8_UNORM:
4701             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGBA8_BC1)) {
4702                 return GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
4703                                                GR_GL_TEXTURE_2D);
4704             }
4705             return {};
4706         case SkImage::CompressionType::kASTC_RGBA8_UNORM:
4707             if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ASTC_RGBA8)) {
4708                 return GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_4x4,
4709                                                GR_GL_TEXTURE_2D);
4710             }
4711             return {};
4712     }
4713 
4714     SkUNREACHABLE;
4715 }
4716 
onGetReadSwizzle(const GrBackendFormat & format,GrColorType colorType) const4717 GrSwizzle GrGLCaps::onGetReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
4718     GrGLFormat glFormat = format.asGLFormat();
4719     const auto& info = this->getFormatInfo(glFormat);
4720     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
4721         const auto& ctInfo = info.fColorTypeInfos[i];
4722         if (ctInfo.fColorType == colorType) {
4723             return ctInfo.fReadSwizzle;
4724         }
4725     }
4726     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
4727                  (int)colorType, (int)glFormat);
4728     return {};
4729 }
4730 
getWriteSwizzle(const GrBackendFormat & format,GrColorType colorType) const4731 GrSwizzle GrGLCaps::getWriteSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
4732     const auto& info = this->getFormatInfo(format.asGLFormat());
4733     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
4734         const auto& ctInfo = info.fColorTypeInfos[i];
4735         if (ctInfo.fColorType == colorType) {
4736             return ctInfo.fWriteSwizzle;
4737         }
4738     }
4739     SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
4740                  (int)colorType, (int)format.asGLFormat());
4741     return {};
4742 }
4743 
onGetDstSampleFlagsForProxy(const GrRenderTargetProxy * rt) const4744 GrDstSampleFlags GrGLCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
4745     if (rt->asTextureProxy()) {
4746         return GrDstSampleFlags::kRequiresTextureBarrier;
4747     }
4748     return GrDstSampleFlags::kNone;
4749 }
4750 
onSupportsDynamicMSAA(const GrRenderTargetProxy * rtProxy) const4751 bool GrGLCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
4752     return !fDisallowDynamicMSAA;
4753 }
4754 
computeFormatKey(const GrBackendFormat & format) const4755 uint64_t GrGLCaps::computeFormatKey(const GrBackendFormat& format) const {
4756     auto glFormat = format.asGLFormat();
4757     return (uint64_t)(glFormat);
4758 }
4759 
makeDesc(GrRenderTarget *,const GrProgramInfo & programInfo,ProgramDescOverrideFlags overrideFlags) const4760 GrProgramDesc GrGLCaps::makeDesc(GrRenderTarget* /* rt */,
4761                                  const GrProgramInfo& programInfo,
4762                                  ProgramDescOverrideFlags overrideFlags) const {
4763     SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
4764     GrProgramDesc desc;
4765     GrProgramDesc::Build(&desc, programInfo, *this);
4766     return desc;
4767 }
4768 
4769 #if GR_TEST_UTILS
getTestingCombinations() const4770 std::vector<GrCaps::TestFormatColorTypeCombination> GrGLCaps::getTestingCombinations() const {
4771     std::vector<GrCaps::TestFormatColorTypeCombination> combos = {
4772         { GrColorType::kAlpha_8,
4773           GrBackendFormat::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D) },
4774         { GrColorType::kAlpha_8,
4775           GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
4776         { GrColorType::kBGR_565,
4777           GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D) },
4778         { GrColorType::kABGR_4444,
4779           GrBackendFormat::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D) },
4780         { GrColorType::kRGBA_8888,
4781           GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
4782         { GrColorType::kRGBA_8888_SRGB,
4783           GrBackendFormat::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D) },
4784         { GrColorType::kRGB_888x,
4785           GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
4786         { GrColorType::kRGB_888x,
4787           GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D) },
4788         { GrColorType::kRGB_888x,
4789           GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D) },
4790         { GrColorType::kRGB_888x,
4791           GrBackendFormat::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D) },
4792         { GrColorType::kRGBA_8888,
4793           GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGBA_ASTC_4x4, GR_GL_TEXTURE_2D) },
4794         { GrColorType::kRGB_888x,
4795           GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
4796         { GrColorType::kRGBA_8888,
4797           GrBackendFormat::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
4798         { GrColorType::kRG_88,
4799           GrBackendFormat::MakeGL(GR_GL_RG8, GR_GL_TEXTURE_2D) },
4800         { GrColorType::kRGBA_1010102,
4801           GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
4802         { GrColorType::kGray_8,
4803           GrBackendFormat::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D) },
4804         { GrColorType::kGray_8,
4805           GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
4806         { GrColorType::kGrayAlpha_88,
4807           GrBackendFormat::MakeGL(GR_GL_LUMINANCE8_ALPHA8, GR_GL_TEXTURE_2D) },
4808         { GrColorType::kAlpha_F16,
4809           GrBackendFormat::MakeGL(GR_GL_R16F, GR_GL_TEXTURE_2D) },
4810         { GrColorType::kAlpha_F16,
4811           GrBackendFormat::MakeGL(GR_GL_LUMINANCE16F, GR_GL_TEXTURE_2D) },
4812         { GrColorType::kRGBA_F16,
4813           GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
4814         { GrColorType::kRGBA_F16_Clamped,
4815           GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
4816         { GrColorType::kAlpha_16,
4817           GrBackendFormat::MakeGL(GR_GL_R16, GR_GL_TEXTURE_2D) },
4818         { GrColorType::kRG_1616,
4819           GrBackendFormat::MakeGL(GR_GL_RG16, GR_GL_TEXTURE_2D) },
4820         { GrColorType::kRGBA_16161616,
4821           GrBackendFormat::MakeGL(GR_GL_RGBA16, GR_GL_TEXTURE_2D) },
4822         { GrColorType::kRG_F16,
4823           GrBackendFormat::MakeGL(GR_GL_RG16F, GR_GL_TEXTURE_2D) },
4824     };
4825 
4826     if (GR_IS_GR_GL(fStandard)) {
4827         combos.push_back({ GrColorType::kBGRA_8888,
4828                            GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) });
4829         combos.push_back({ GrColorType::kBGRA_1010102,
4830                            GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) });
4831     } else {
4832         SkASSERT(GR_IS_GR_GL_ES(fStandard) || GR_IS_GR_WEBGL(fStandard));
4833 
4834         combos.push_back({ GrColorType::kBGRA_8888,
4835                            GrBackendFormat::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) });
4836     }
4837     if (this->rectangleTextureSupport()) {
4838         size_t count2D = combos.size();
4839         for (size_t i = 0; i < count2D; ++i) {
4840             auto combo2D = combos[i];
4841             GrGLenum formatEnum = GrGLFormatToEnum(combo2D.fFormat.asGLFormat());
4842             combos.push_back({combo2D.fColorType,
4843                               GrBackendFormat::MakeGL(formatEnum, GR_GL_TEXTURE_RECTANGLE)});
4844         }
4845     }
4846     return combos;
4847 }
4848 #endif
4849