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