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