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