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