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