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