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 shaderCaps->fVertexIDSupport = true;
1104 } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1105 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es;
1106 }
1107
1108 // isinf() exists in GLSL 1.3 and above, but hardware without proper IEEE support is allowed to
1109 // always return false, so it's potentially meaningless. In GLSL 3.3 and GLSL ES3+, isinf() is
1110 // required to actually identify infinite values. (GPUs are not required to _produce_ infinite
1111 // values via operations like `num / 0.0` until GLSL 4.1.)
1112 shaderCaps->fInfinitySupport = (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330);
1113
1114 // Using isinf or isnan with ANGLE will disable fast-math (which is a good thing!), but that
1115 // leads to hangs in the Metal shader compiler service for some of our tessellation shaders,
1116 // running on Intel Macs. For now, pretend that we don't have infinity support, even when we're
1117 // targeting ANGLE's ES3 to Metal.
1118 if (ctxInfo.angleBackend() == GrGLANGLEBackend::kMetal &&
1119 ctxInfo.angleVendor() == GrGLVendor::kIntel) {
1120 shaderCaps->fInfinitySupport = false;
1121 }
1122
1123 if (GR_IS_GR_GL(standard)) {
1124 shaderCaps->fNonconstantArrayIndexSupport = true;
1125 } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1126 shaderCaps->fNonconstantArrayIndexSupport =
1127 (ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k300es);
1128 }
1129
1130 if (GR_IS_GR_GL(standard)) {
1131 shaderCaps->fBitManipulationSupport =
1132 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1133 } else if (GR_IS_GR_GL_ES(standard) || GR_IS_GR_WEBGL(standard)) {
1134 shaderCaps->fBitManipulationSupport =
1135 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k310es;
1136 }
1137
1138 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
1139 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
1140 shaderCaps->fHasLowFragmentPrecision = ctxInfo.renderer() == GrGLRenderer::kMali4xx;
1141
1142 if (GR_IS_GR_GL(standard)) {
1143 shaderCaps->fBuiltinFMASupport =
1144 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k400;
1145 } else if (GR_IS_GR_GL_ES(standard)) {
1146 shaderCaps->fBuiltinFMASupport =
1147 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k320es;
1148 } else if (GR_IS_GR_WEBGL(standard)) {
1149 shaderCaps->fBuiltinFMASupport = false;
1150 }
1151
1152 shaderCaps->fBuiltinDeterminantSupport = ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k150;
1153 }
1154
initFSAASupport(const GrContextOptions & contextOptions,const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)1155 void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions,
1156 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
1157 if (GR_IS_GR_GL(ctxInfo.standard())) {
1158 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1159 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
1160 fMSFBOType = kStandard_MSFBOType;
1161 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1162 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
1163 fMSFBOType = kStandard_MSFBOType;
1164 }
1165 } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1166 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
1167 // ES3 driver bugs on at least one device with a tiled GPU (N10).
1168 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1169 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1170 fMSAAResolvesAutomatically = true;
1171 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1172 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
1173 fMSAAResolvesAutomatically = true;
1174 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1175 fMSFBOType = kStandard_MSFBOType;
1176 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
1177 fMSFBOType = kStandard_MSFBOType;
1178 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
1179 fMSFBOType = kStandard_MSFBOType;
1180 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1181 fMSFBOType = kES_Apple_MSFBOType;
1182 }
1183 } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1184 // No support in WebGL 1, but there is for 2.0
1185 if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1186 fMSFBOType = kStandard_MSFBOType;
1187 } else {
1188 fMSFBOType = kNone_MSFBOType;
1189 }
1190 }
1191 }
1192
initBlendEqationSupport(const GrGLContextInfo & ctxInfo)1193 void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
1194 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
1195
1196 bool layoutQualifierSupport = false;
1197 if ((GR_IS_GR_GL(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k140) ||
1198 (GR_IS_GR_GL_ES(fStandard) && shaderCaps->fGLSLGeneration >= SkSL::GLSLGeneration::k300es)){
1199 layoutQualifierSupport = true;
1200 } else if (GR_IS_GR_WEBGL(fStandard)) {
1201 return;
1202 }
1203
1204 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1205 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1206 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1207 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1208 layoutQualifierSupport) {
1209 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1210 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1211 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1212 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1213 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1214 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
1215 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1216 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1217 }
1218 }
1219
1220
initStencilSupport(const GrGLContextInfo & ctxInfo)1221 void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
1222
1223 // Build up list of legal stencil formats (though perhaps not supported on
1224 // the particular gpu/driver) from most preferred to least.
1225
1226 // We push back stencil formats onto the fStencilFormats array in order of most preferred to
1227 // least preferred.
1228
1229 if (GR_IS_GR_GL(ctxInfo.standard())) {
1230 bool supportsPackedDS =
1231 ctxInfo.version() >= GR_GL_VER(3,0) ||
1232 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1233 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1234
1235 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1236 // require FBO support we can expect these are legal formats and don't
1237 // check.
1238 fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1239 fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX16;
1240 if (supportsPackedDS) {
1241 fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1242 }
1243 } else if (GR_IS_GR_GL_ES(ctxInfo.standard())) {
1244 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1245 // for other formats.
1246
1247 fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1248 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1249 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
1250 fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1251 }
1252 } else if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
1253 fStencilFormats.push_back() = GrGLFormat::kSTENCIL_INDEX8;
1254 if (ctxInfo.version() >= GR_GL_VER(2,0)) {
1255 fStencilFormats.push_back() = GrGLFormat::kDEPTH24_STENCIL8;
1256 }
1257 }
1258 }
1259
1260 #ifdef SK_ENABLE_DUMP_GPU
1261 #include "src/utils/SkJSONWriter.h"
1262
multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType)1263 static const char* multi_draw_type_name(GrGLCaps::MultiDrawType multiDrawType) {
1264 switch (multiDrawType) {
1265 case GrGLCaps::MultiDrawType::kNone : return "kNone";
1266 case GrGLCaps::MultiDrawType::kMultiDrawIndirect : return "kMultiDrawIndirect";
1267 case GrGLCaps::MultiDrawType::kANGLEOrWebGL : return "kMultiDrawIndirect";
1268 }
1269 SkUNREACHABLE;
1270 }
1271
onDumpJSON(SkJSONWriter * writer) const1272 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
1273
1274 // We are called by the base class, which has already called beginObject(). We choose to nest
1275 // all of our caps information in a named sub-object.
1276 writer->beginObject("GL caps");
1277
1278 writer->beginArray("Stencil Formats");
1279
1280 for (int i = 0; i < fStencilFormats.size(); ++i) {
1281 writer->beginObject(nullptr, false);
1282 writer->appendS32("stencil bits", GrGLFormatStencilBits(fStencilFormats[i]));
1283 writer->appendS32("total bytes", GrGLFormatBytesPerBlock(fStencilFormats[i]));
1284 writer->endObject();
1285 }
1286
1287 writer->endArray();
1288
1289 auto msfboStr = [&] {
1290 switch (fMSFBOType) {
1291 case kNone_MSFBOType: return "None";
1292 case kStandard_MSFBOType: return "Standard";
1293 case kES_Apple_MSFBOType: return "Apple";
1294 case kES_IMG_MsToTexture_MSFBOType: return "IMG MS To Texture";
1295 case kES_EXT_MsToTexture_MSFBOType: return "EXT MS To Texture";
1296 }
1297 SkUNREACHABLE;
1298 };
1299
1300 auto invalidateFBTypeStr = [&] {
1301 switch (fInvalidateFBType) {
1302 case kNone_InvalidateFBType: return "None";
1303 case kDiscard_InvalidateFBType: return "Discard";
1304 case kInvalidate_InvalidateFBType: return "Invalidate";
1305 }
1306 SkUNREACHABLE;
1307 };
1308
1309 auto invalidateBufferTypeStr = [&] {
1310 switch (fInvalidateBufferType) {
1311 case InvalidateBufferType::kNone: return "None";
1312 case InvalidateBufferType::kNullData: return "Null data hint";
1313 case InvalidateBufferType::kInvalidate: return "Invalidate";
1314 }
1315 SkUNREACHABLE;
1316 };
1317
1318 auto mapBufferTypeStr = [&] {
1319 switch (fMapBufferType) {
1320 case kNone_MapBufferType: return "None";
1321 case kMapBuffer_MapBufferType: return "MapBuffer";
1322 case kMapBufferRange_MapBufferType: return "MapBufferRange";
1323 case kChromium_MapBufferType: return "Chromium";
1324 }
1325 SkUNREACHABLE;
1326 };
1327
1328 writer->appendBool("Core Profile", fIsCoreProfile);
1329 writer->appendCString("MSAA Type", msfboStr());
1330 writer->appendCString("Invalidate FB Type", invalidateFBTypeStr());
1331 writer->appendCString("Invalidate Buffer Type", invalidateBufferTypeStr());
1332 writer->appendCString("Map Buffer Type", mapBufferTypeStr());
1333 writer->appendCString("Multi Draw Type", multi_draw_type_name(fMultiDrawType));
1334 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1335 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
1336
1337 writer->appendBool("Texture Usage support", fTextureUsageSupport);
1338 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1339 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
1340 writer->appendBool("Debug support", fDebugSupport);
1341 writer->appendBool("ES2 compatibility support", fES2CompatibilitySupport);
1342 writer->appendBool("Strict Protectedness", fStrictProtectedness);
1343 writer->appendBool("drawRangeElements support", fDrawRangeElementsSupport);
1344 writer->appendBool("Base (vertex base) instance support", fBaseVertexBaseInstanceSupport);
1345 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1346 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1347 writer->appendBool("Mipmap LOD control support", fMipmapLodControlSupport);
1348 writer->appendBool("Mipmap level control support", fMipmapLevelControlSupport);
1349 writer->appendBool("Clear texture support", fClearTextureSupport);
1350 writer->appendBool("Program binary support", fProgramBinarySupport);
1351 writer->appendBool("Program parameters support", fProgramParameterSupport);
1352 writer->appendBool("Sampler object support", fSamplerObjectSupport);
1353 writer->appendBool("Using sampler objects", fUseSamplerObjects);
1354 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1355 writer->appendBool("Tiled rendering support", fTiledRenderingSupport);
1356 writer->appendBool("Fence sync support", fFenceSyncSupport);
1357 writer->appendBool("FB fetch requires enable per sample", fFBFetchRequiresEnablePerSample);
1358 writer->appendBool("sRGB Write Control", fSRGBWriteControl);
1359
1360 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1361 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1362 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1363 fUseDrawInsteadOfAllRenderTargetWrites);
1364 writer->appendBool("Max instances per draw without crashing (or zero)",
1365 fMaxInstancesPerDrawWithoutCrashing);
1366
1367 writer->beginArray("formats");
1368
1369 for (int i = 0; i < kGrGLColorFormatCount; ++i) {
1370 writer->beginObject(nullptr, false);
1371 writer->appendHexU32("flags", fFormatTable[i].fFlags);
1372 writer->appendHexU32("f_type", (uint32_t)fFormatTable[i].fFormatType);
1373 writer->appendHexU32("c_internal", fFormatTable[i].fCompressedInternalFormat);
1374 writer->appendHexU32("i_for_teximage", fFormatTable[i].fInternalFormatForTexImageOrStorage);
1375 writer->appendHexU32("i_for_renderbuffer", fFormatTable[i].fInternalFormatForRenderbuffer);
1376 writer->appendHexU32("default_ex_format", fFormatTable[i].fDefaultExternalFormat);
1377 writer->appendHexU32("default_ex_type", fFormatTable[i].fDefaultExternalType);
1378 writer->appendHexU32("default_color_type", (uint32_t)fFormatTable[i].fDefaultColorType);
1379
1380 writer->beginArray("surface color types");
1381 for (int j = 0; j < fFormatTable[i].fColorTypeInfoCount; ++j) {
1382 const auto& ctInfo = fFormatTable[i].fColorTypeInfos[j];
1383 writer->beginObject(nullptr, false);
1384 writer->appendHexU32("colorType", (uint32_t)ctInfo.fColorType);
1385 writer->appendHexU32("flags", ctInfo.fFlags);
1386
1387 writer->beginArray("data color types");
1388 for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
1389 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
1390 writer->beginObject(nullptr, false);
1391 writer->appendHexU32("colorType", (uint32_t)ioInfo.fColorType);
1392 writer->appendHexU32("ex_type", ioInfo.fExternalType);
1393 writer->appendHexU32("ex_teximage", ioInfo.fExternalTexImageFormat);
1394 writer->appendHexU32("ex_read", ioInfo.fExternalReadFormat);
1395 writer->endObject();
1396 }
1397 writer->endArray();
1398 writer->endObject();
1399 }
1400 writer->endArray();
1401 writer->endObject();
1402 }
1403
1404 writer->endArray();
1405 writer->endObject();
1406 }
1407 #else
onDumpJSON(SkJSONWriter * writer) const1408 void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const { }
1409 #endif
1410
getTexImageExternalFormatAndType(GrGLFormat surfaceFormat,GrGLenum * externalFormat,GrGLenum * externalType) const1411 void GrGLCaps::getTexImageExternalFormatAndType(GrGLFormat surfaceFormat, GrGLenum* externalFormat,
1412 GrGLenum* externalType) const {
1413 const auto& info = this->getFormatInfo(surfaceFormat);
1414 *externalType = info.fDefaultExternalType;
1415 *externalFormat = info.fDefaultExternalFormat;
1416 }
1417
getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,GrGLenum * externalFormat,GrGLenum * externalType,GrColorType * colorType) const1418 void GrGLCaps::getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format,
1419 GrGLenum* externalFormat,
1420 GrGLenum* externalType,
1421 GrColorType* colorType) const {
1422 const auto& info = this->getFormatInfo(format);
1423 *externalType = info.fDefaultExternalType;
1424 *externalFormat = info.fDefaultExternalFormat;
1425 *colorType = info.fDefaultColorType;
1426 }
1427
getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1428 void GrGLCaps::getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat,
1429 GrColorType surfaceColorType,
1430 GrColorType memoryColorType,
1431 GrGLenum* externalFormat,
1432 GrGLenum* externalType) const {
1433 this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1434 kTexImage_ExternalFormatUsage, externalFormat, externalType);
1435 }
1436
getReadPixelsFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,GrGLenum * externalFormat,GrGLenum * externalType) const1437 void GrGLCaps::getReadPixelsFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1438 GrColorType memoryColorType, GrGLenum* externalFormat,
1439 GrGLenum* externalType) const {
1440 this->getExternalFormat(surfaceFormat, surfaceColorType, memoryColorType,
1441 kReadPixels_ExternalFormatUsage, externalFormat, externalType);
1442 }
1443
getExternalFormat(GrGLFormat surfaceFormat,GrColorType surfaceColorType,GrColorType memoryColorType,ExternalFormatUsage usage,GrGLenum * externalFormat,GrGLenum * externalType) const1444 void GrGLCaps::getExternalFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
1445 GrColorType memoryColorType, ExternalFormatUsage usage,
1446 GrGLenum* externalFormat, GrGLenum* externalType) const {
1447 SkASSERT(externalFormat && externalType);
1448 *externalFormat = this->getFormatInfo(surfaceFormat).externalFormat(
1449 surfaceColorType, memoryColorType, usage);
1450 *externalType = this->getFormatInfo(surfaceFormat).externalType(
1451 surfaceColorType, memoryColorType);
1452 }
1453
setStencilFormatIndexForFormat(GrGLFormat format,int index)1454 void GrGLCaps::setStencilFormatIndexForFormat(GrGLFormat format, int index) {
1455 SkASSERT(!this->hasStencilFormatBeenDeterminedForFormat(format));
1456 this->getFormatInfo(format).fStencilFormatIndex =
1457 index < 0 ? FormatInfo::kUnsupported_StencilFormatIndex : index;
1458 }
1459
setColorTypeFormat(GrColorType colorType,GrGLFormat format)1460 void GrGLCaps::setColorTypeFormat(GrColorType colorType, GrGLFormat format) {
1461 int idx = static_cast<int>(colorType);
1462 SkASSERT(fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown);
1463 fColorTypeToFormatTable[idx] = format;
1464 }
1465
initFormatTable(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli,const FormatWorkarounds & formatWorkarounds)1466 void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1467 const FormatWorkarounds& formatWorkarounds) {
1468 GrGLStandard standard = ctxInfo.standard();
1469 // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
1470 sk_ignore_unused_variable(standard);
1471 GrGLVersion version = ctxInfo.version();
1472
1473 uint32_t nonMSAARenderFlags = FormatInfo::kFBOColorAttachment_Flag;
1474 uint32_t msaaRenderFlags = nonMSAARenderFlags;
1475 if (kNone_MSFBOType != fMSFBOType) {
1476 msaaRenderFlags |= FormatInfo::kFBOColorAttachmentWithMSAA_Flag;
1477 }
1478
1479 bool texStorageSupported = false;
1480 if (GR_IS_GR_GL(standard)) {
1481 // The EXT version can apply to either GL or GLES.
1482 texStorageSupported = version >= GR_GL_VER(4,2) ||
1483 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1484 ctxInfo.hasExtension("GL_EXT_texture_storage");
1485 } else if (GR_IS_GR_GL_ES(standard)) {
1486 texStorageSupported = version >= GR_GL_VER(3,0) ||
1487 ctxInfo.hasExtension("GL_EXT_texture_storage");
1488 } else if (GR_IS_GR_WEBGL(standard)) {
1489 texStorageSupported = version >= GR_GL_VER(2,0);
1490 }
1491 if (fDriverBugWorkarounds.disable_texture_storage) {
1492 texStorageSupported = false;
1493 }
1494
1495 if (formatWorkarounds.fDisableTexStorage) {
1496 texStorageSupported = false;
1497 }
1498
1499 // ES 2.0 requires that the internal/external formats match so we can't use sized internal
1500 // formats for glTexImage until ES 3.0. TODO: Support sized internal formats in WebGL2.
1501 bool texImageSupportsSizedInternalFormat =
1502 (GR_IS_GR_GL(standard) || (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0)));
1503
1504 // for now we don't support floating point MSAA on ES
1505 uint32_t fpRenderFlags = (GR_IS_GR_GL(standard)) ? msaaRenderFlags : nonMSAARenderFlags;
1506
1507 for (int i = 0; i < kGrColorTypeCnt; ++i) {
1508 fColorTypeToFormatTable[i] = GrGLFormat::kUnknown;
1509 }
1510
1511 ///////////////////////////////////////////////////////////////////////////
1512
1513 GrGLenum halfFloatType = GR_GL_HALF_FLOAT;
1514 if ((GR_IS_GR_GL_ES(standard) && version < GR_GL_VER(3, 0)) ||
1515 (GR_IS_GR_WEBGL(standard) && version < GR_GL_VER(2, 0))) {
1516 halfFloatType = GR_GL_HALF_FLOAT_OES;
1517 }
1518
1519 // Format: RGBA8
1520 {
1521 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA8);
1522 info.fFormatType = FormatType::kNormalizedFixedPoint;
1523 info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
1524 info.fDefaultExternalFormat = GR_GL_RGBA;
1525 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1526 info.fDefaultColorType = GrColorType::kRGBA_8888;
1527 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1528 if (GR_IS_GR_GL(standard)) {
1529 info.fFlags |= msaaRenderFlags;
1530 } else if (GR_IS_GR_GL_ES(standard)) {
1531 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1532 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1533 info.fFlags |= msaaRenderFlags;
1534 }
1535 } else if (GR_IS_GR_WEBGL(standard)) {
1536 info.fFlags |= msaaRenderFlags;
1537 }
1538
1539 if (texStorageSupported) {
1540 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1541 info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA8;
1542 } else {
1543 info.fInternalFormatForTexImageOrStorage =
1544 texImageSupportsSizedInternalFormat ? GR_GL_RGBA8 : GR_GL_RGBA;
1545 }
1546
1547 bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
1548 (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
1549 info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
1550 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1551 int ctIdx = 0;
1552 // Format: RGBA8, Surface: kRGBA_8888
1553 {
1554 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1555 ctInfo.fColorType = GrColorType::kRGBA_8888;
1556 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1557 this->setColorTypeFormat(GrColorType::kRGBA_8888, GrGLFormat::kRGBA8);
1558
1559 // External IO ColorTypes:
1560 ctInfo.fExternalIOFormatCount = 2;
1561 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1562 ctInfo.fExternalIOFormatCount);
1563 int ioIdx = 0;
1564 // Format: RGBA8, Surface: kRGBA_8888, Data: kRGBA_8888
1565 {
1566 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1567 ioFormat.fColorType = GrColorType::kRGBA_8888;
1568 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1569 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1570 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1571 }
1572 // Format: RGBA8, Surface: kRGBA_8888, Data: kBGRA_8888
1573 {
1574 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1575 ioFormat.fColorType = GrColorType::kBGRA_8888;
1576 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1577 ioFormat.fExternalTexImageFormat = 0; // TODO: Enable this on non-ES GL
1578 ioFormat.fExternalReadFormat =
1579 formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1580 // Not guaranteed by ES/WebGL.
1581 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1582 }
1583 }
1584
1585 // Format: RGBA8, Surface: kBGRA_8888
1586 if (supportsBGRAColorType) {
1587 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1588 ctInfo.fColorType = GrColorType::kBGRA_8888;
1589 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1590 this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kRGBA8);
1591
1592 // External IO ColorTypes:
1593 ctInfo.fExternalIOFormatCount = 2;
1594 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1595 ctInfo.fExternalIOFormatCount);
1596 int ioIdx = 0;
1597 // Format: RGBA8, Surface: kBGRA_8888, Data: kBGRA_8888
1598 {
1599 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1600 ioFormat.fColorType = GrColorType::kBGRA_8888;
1601 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1602 ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
1603 ioFormat.fExternalReadFormat =
1604 formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
1605 // Not guaranteed by ES/WebGL.
1606 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1607 }
1608
1609 // Format: RGBA8, Surface: kBGRA_8888, Data: kRGBA_8888
1610 {
1611 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1612 ioFormat.fColorType = GrColorType::kRGBA_8888;
1613 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1614 ioFormat.fExternalTexImageFormat = 0;
1615 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1616 }
1617 }
1618
1619 // Format: RGBA8, Surface: kRGB_888x
1620 {
1621 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1622 ctInfo.fColorType = GrColorType::kRGB_888x;
1623 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1624 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
1625
1626 // External IO ColorTypes:
1627 ctInfo.fExternalIOFormatCount = 1;
1628 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1629 ctInfo.fExternalIOFormatCount);
1630 int ioIdx = 0;
1631 // Format: RGBA8, Surface: kRGB_888x, Data: kRGBA_888x
1632 {
1633 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1634 ioFormat.fColorType = GrColorType::kRGB_888x;
1635 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1636 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
1637 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1638 }
1639 }
1640 }
1641
1642 // Format: R8
1643 {
1644 FormatInfo& info = this->getFormatInfo(GrGLFormat::kR8);
1645 info.fFormatType = FormatType::kNormalizedFixedPoint;
1646 info.fInternalFormatForRenderbuffer = GR_GL_R8;
1647 info.fDefaultExternalFormat = GR_GL_RED;
1648 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1649 info.fDefaultColorType = GrColorType::kR_8;
1650 bool r8Support = false;
1651 if (GR_IS_GR_GL(standard)) {
1652 r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1653 } else if (GR_IS_GR_GL_ES(standard)) {
1654 r8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1655 } else if (GR_IS_GR_WEBGL(standard)) {
1656 r8Support = ctxInfo.version() >= GR_GL_VER(2, 0);
1657 }
1658 if (formatWorkarounds.fDisallowR8ForPowerVRSGX54x) {
1659 r8Support = false;
1660 }
1661
1662 if (r8Support) {
1663 info.fFlags |= FormatInfo::kTexturable_Flag
1664 | FormatInfo::kTransfers_Flag
1665 | msaaRenderFlags;
1666 }
1667
1668 if (texStorageSupported) {
1669 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1670 info.fInternalFormatForTexImageOrStorage = GR_GL_R8;
1671 } else {
1672 info.fInternalFormatForTexImageOrStorage =
1673 texImageSupportsSizedInternalFormat ? GR_GL_R8 : GR_GL_RED;
1674 }
1675
1676 if (r8Support) {
1677 info.fColorTypeInfoCount = 3;
1678 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1679 int ctIdx = 0;
1680 // Format: R8, Surface: kR_8
1681 {
1682 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1683 ctInfo.fColorType = GrColorType::kR_8;
1684 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1685 this->setColorTypeFormat(GrColorType::kR_8, GrGLFormat::kR8);
1686
1687 // External IO ColorTypes:
1688 ctInfo.fExternalIOFormatCount = 2;
1689 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1690 ctInfo.fExternalIOFormatCount);
1691 int ioIdx = 0;
1692 // Format: R8, Surface: kR_8, Data: kR_8
1693 {
1694 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1695 ioFormat.fColorType = GrColorType::kR_8;
1696 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1697 ioFormat.fExternalTexImageFormat = GR_GL_RED;
1698 ioFormat.fExternalReadFormat = GR_GL_RED;
1699 // Not guaranteed by ES/WebGL.
1700 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1701 }
1702
1703 // Format: R8, Surface: kR_8, Data: kR_8xxx
1704 {
1705 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1706 ioFormat.fColorType = GrColorType::kR_8xxx;
1707 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1708 ioFormat.fExternalTexImageFormat = 0;
1709 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1710 }
1711 }
1712
1713 // Format: R8, Surface: kAlpha_8
1714 {
1715 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1716 ctInfo.fColorType = GrColorType::kAlpha_8;
1717 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1718 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
1719 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
1720 this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kR8);
1721
1722 // External IO ColorTypes:
1723 ctInfo.fExternalIOFormatCount = 2;
1724 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1725 ctInfo.fExternalIOFormatCount);
1726 int ioIdx = 0;
1727 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8
1728 {
1729 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1730 ioFormat.fColorType = GrColorType::kAlpha_8;
1731 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1732 ioFormat.fExternalTexImageFormat = GR_GL_RED;
1733 ioFormat.fExternalReadFormat = GR_GL_RED;
1734 // Not guaranteed by ES/WebGL.
1735 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1736 }
1737
1738 // Format: R8, Surface: kAlpha_8, Data: kAlpha_8xxx
1739 {
1740 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1741 ioFormat.fColorType = GrColorType::kAlpha_8xxx;
1742 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1743 ioFormat.fExternalTexImageFormat = 0;
1744 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1745 }
1746 }
1747
1748 // Format: R8, Surface: kGray_8
1749 {
1750 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1751 ctInfo.fColorType = GrColorType::kGray_8;
1752 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1753 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
1754 this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kR8);
1755
1756 // External IO ColorTypes:
1757 ctInfo.fExternalIOFormatCount = 2;
1758 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1759 ctInfo.fExternalIOFormatCount);
1760 int ioIdx = 0;
1761 // Format: R8, Surface: kGray_8, Data: kGray_8
1762 {
1763 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1764 ioFormat.fColorType = GrColorType::kGray_8;
1765 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1766 ioFormat.fExternalTexImageFormat = GR_GL_RED;
1767 ioFormat.fExternalReadFormat = GR_GL_RED;
1768 // Not guaranteed by ES/WebGL.
1769 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1770 }
1771
1772 // Format: R8, Surface: kGray_8, Data: kGray_8xxx
1773 {
1774 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1775 ioFormat.fColorType = GrColorType::kGray_8xxx;
1776 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1777 ioFormat.fExternalTexImageFormat = 0;
1778 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1779 }
1780 }
1781 }
1782 }
1783
1784 // Format: ALPHA8
1785 {
1786 bool alpha8IsValidForGL = GR_IS_GR_GL(standard) &&
1787 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1788 bool alpha8IsValidForGLES = GR_IS_GR_GL_ES(standard);
1789 bool alpha8IsValidForWebGL = GR_IS_GR_WEBGL(standard);
1790
1791 FormatInfo& info = this->getFormatInfo(GrGLFormat::kALPHA8);
1792 info.fFormatType = FormatType::kNormalizedFixedPoint;
1793 // GL_EXT_texture_storage adds GL_ALPHA8 for texture storage. However, ES3 has glTexStorage
1794 // but does not have GL_ALPHA8 (and requires a sized internal format for glTexStorage).
1795 // WebGL never has GL_ALPHA8.
1796 bool alpha8SizedEnumSupported =
1797 alpha8IsValidForGL ||
1798 (alpha8IsValidForGLES && ctxInfo.hasExtension("GL_EXT_texture_storage"));
1799 bool alpha8TexStorageSupported = alpha8SizedEnumSupported && texStorageSupported;
1800
1801 bool alpha8IsRenderable = false;
1802 if (alpha8IsValidForGL) {
1803 // Core profile removes ALPHA8 support.
1804 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1805 alpha8IsRenderable = ctxInfo.version() >= GR_GL_VER(3, 0) ||
1806 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1807 }
1808 info.fInternalFormatForRenderbuffer = GR_GL_ALPHA8;
1809 info.fDefaultExternalFormat = GR_GL_ALPHA;
1810 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1811 info.fDefaultColorType = GrColorType::kAlpha_8;
1812 if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1813 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1814 }
1815 if (alpha8IsRenderable && alpha8IsValidForGL) {
1816 // We will use ALPHA8 to create MSAA renderbuffers.
1817 SkASSERT(alpha8SizedEnumSupported);
1818 info.fFlags |= msaaRenderFlags;
1819 }
1820 if (alpha8TexStorageSupported) {
1821 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1822 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1823 } else {
1824 // Even if GL_ALPHA8 is added to ES by GL_EXT_texture_storage it doesn't become legal
1825 // for glTexImage2D.
1826 if (!GR_IS_GR_GL_ES(standard) && texImageSupportsSizedInternalFormat &&
1827 alpha8SizedEnumSupported) {
1828 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA8;
1829 } else {
1830 info.fInternalFormatForTexImageOrStorage = GR_GL_ALPHA;
1831 }
1832 }
1833
1834 if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1835 info.fColorTypeInfoCount = 1;
1836 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1837 int ctIdx = 0;
1838 // Format: ALPHA8, Surface: kAlpha_8
1839 {
1840 if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
1841 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1842 ctInfo.fColorType = GrColorType::kAlpha_8;
1843 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
1844 ColorTypeInfo::kRenderable_Flag;
1845 int idx = static_cast<int>(GrColorType::kAlpha_8);
1846 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1847 this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kALPHA8);
1848 }
1849
1850 // External IO ColorTypes:
1851 ctInfo.fExternalIOFormatCount = 2;
1852 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1853 ctInfo.fExternalIOFormatCount);
1854 int ioIdx = 0;
1855 // Format: ALPHA8, Surface: kAlpha_8, Data: kAlpha_8
1856 {
1857 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1858 ioFormat.fColorType = GrColorType::kAlpha_8;
1859 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1860 ioFormat.fExternalTexImageFormat = GR_GL_ALPHA;
1861 ioFormat.fExternalReadFormat = GR_GL_ALPHA;
1862 // Not guaranteed by ES/WebGL.
1863 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
1864 }
1865
1866 // Format: ALPHA8, Surface: kAlpha_8, Data: kRGBA_8888
1867 {
1868 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1869 ioFormat.fColorType = GrColorType::kRGBA_8888;
1870 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1871 ioFormat.fExternalTexImageFormat = 0;
1872 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1873 }
1874 }
1875 }
1876 }
1877 }
1878
1879 // Do we support the lumincance and luminance_alpha formats
1880 bool lum8Supported = false;
1881 bool lum8SizedFormatSupported = false;
1882 if (GR_IS_GR_GL(standard) && !fIsCoreProfile) {
1883 lum8Supported = true;
1884 lum8SizedFormatSupported = true;
1885 } else if (GR_IS_GR_GL_ES(standard)) {
1886 lum8Supported = true;
1887 // Even on ES3 this extension is required to define LUMINANCE8. GL_LUMINANCE8 is not a
1888 // valid internal format for TexImage2D so we need to be using texture storage to use
1889 // it. Even though we check the extension for texture storage here, we also check to see
1890 // if texStorageSupported may have been disabled for a workaround.
1891 lum8SizedFormatSupported =
1892 texStorageSupported && ctxInfo.hasExtension("GL_EXT_texture_storage");
1893 } else if (GR_IS_GR_WEBGL(standard)) {
1894 lum8Supported = true;
1895 }
1896
1897 // Format: LUMINANCE8
1898 {
1899 FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8);
1900 info.fFormatType = FormatType::kNormalizedFixedPoint;
1901 info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8;
1902 info.fDefaultExternalFormat = GR_GL_LUMINANCE;
1903 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1904 info.fDefaultColorType = GrColorType::kGray_8;
1905
1906 if (lum8Supported) {
1907 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1908 }
1909 if (texStorageSupported && lum8SizedFormatSupported) {
1910 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1911 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1912 } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1913 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8;
1914 } else {
1915 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
1916 }
1917 // We are not enabling attaching to an FBO for LUMINANCE8 mostly because of confusion in the
1918 // spec. For GLES it does not seem to ever support LUMINANCE8 being color-renderable. For GL
1919 // versions less than 3.0 it is provided by GL_ARB_framebuffer_object. However, the original
1920 // version of that extension did not add LUMINANCE8, but was added in a later revsion. So
1921 // even the presence of that extension does not guarantee support. GL 3.0 and higher (core
1922 // or compatibility) do not list LUMINANCE8 as color-renderable (which is strange since the
1923 // GL_ARB_framebuffer_object extension was meant to bring 3.0 functionality to lower
1924 // versions).
1925
1926 if (lum8Supported) {
1927 info.fColorTypeInfoCount = 1;
1928 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1929 int ctIdx = 0;
1930 // Format: LUMINANCE8, Surface: kGray_8
1931 {
1932 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1933 ctInfo.fColorType = GrColorType::kGray_8;
1934 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1935 int idx = static_cast<int>(GrColorType::kGray_8);
1936 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1937 this->setColorTypeFormat(GrColorType::kGray_8, GrGLFormat::kLUMINANCE8);
1938 }
1939
1940 // External IO ColorTypes:
1941 ctInfo.fExternalIOFormatCount = 2;
1942 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
1943 ctInfo.fExternalIOFormatCount);
1944 int ioIdx = 0;
1945 // Format: LUMINANCE8, Surface: kGray_8, Data: kGray_8
1946 {
1947 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1948 ioFormat.fColorType = GrColorType::kGray_8;
1949 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1950 ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
1951 ioFormat.fExternalReadFormat = 0;
1952 }
1953
1954 // Format: LUMINANCE8, Surface: kGray_8, Data: kRGBA_8888
1955 {
1956 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
1957 ioFormat.fColorType = GrColorType::kRGBA_8888;
1958 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
1959 ioFormat.fExternalTexImageFormat = 0;
1960 ioFormat.fExternalReadFormat = GR_GL_RGBA;
1961 }
1962 }
1963 }
1964 }
1965
1966 // Format: LUMINANCE8_ALPHA8
1967 {
1968 FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE8_ALPHA8);
1969 info.fFormatType = FormatType::kNormalizedFixedPoint;
1970 info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE8_ALPHA8;
1971 info.fDefaultExternalFormat = GR_GL_LUMINANCE_ALPHA;
1972 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
1973 info.fDefaultColorType = GrColorType::kGrayAlpha_88;
1974 if (lum8Supported) {
1975 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
1976 }
1977 if (texStorageSupported && lum8SizedFormatSupported) {
1978 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
1979 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1980 } else if (texImageSupportsSizedInternalFormat && lum8SizedFormatSupported) {
1981 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE8_ALPHA8;
1982 } else {
1983 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE_ALPHA;
1984 }
1985 // See note in LUMINANCE8 section about not attaching to framebuffers.
1986
1987 if (lum8Supported) {
1988 info.fColorTypeInfoCount = 1;
1989 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1990 int ctIdx = 0;
1991 // Format: LUMINANCE8_ALPHA8, Surface: kGrayAlpha_88
1992 {
1993 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1994 ctInfo.fColorType = GrColorType::kGrayAlpha_88;
1995 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1996 int idx = static_cast<int>(GrColorType::kGrayAlpha_88);
1997 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
1998 this->setColorTypeFormat(GrColorType::kGrayAlpha_88,
1999 GrGLFormat::kLUMINANCE8_ALPHA8);
2000 }
2001
2002 // External IO ColorTypes:
2003 ctInfo.fExternalIOFormatCount = 2;
2004 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2005 ctInfo.fExternalIOFormatCount);
2006 int ioIdx = 0;
2007 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kGrayAlpha_88
2008 {
2009 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2010 ioFormat.fColorType = GrColorType::kGrayAlpha_88;
2011 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2012 ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE_ALPHA;
2013 ioFormat.fExternalReadFormat = 0;
2014 }
2015
2016 // Format: LUMINANCE8, Surface: kGrayAlpha_88, Data: kRGBA_8888
2017 {
2018 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2019 ioFormat.fColorType = GrColorType::kRGBA_8888;
2020 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2021 ioFormat.fExternalTexImageFormat = 0;
2022 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2023 }
2024 }
2025 }
2026 }
2027 // Format: BGRA8
2028 {
2029 FormatInfo& info = this->getFormatInfo(GrGLFormat::kBGRA8);
2030 info.fFormatType = FormatType::kNormalizedFixedPoint;
2031
2032 info.fDefaultExternalFormat = GR_GL_BGRA;
2033 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2034 info.fDefaultColorType = GrColorType::kBGRA_8888;
2035
2036 GrGLenum bgraTexImageFormat;
2037 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2038 // as a base format. Which base format depends on which extension is used.
2039 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2040 // GL_EXT_texture_format_BGRA8888:
2041 // This extension adds GL_BGRA as an unsized internal format. However, it is
2042 // written against ES 2.0 and therefore doesn't define a GL_BGRA8 as ES 2.0 doesn't
2043 // have sized internal formats. See later where we check for tex storage BGRA8
2044 // support.
2045 bgraTexImageFormat = GR_GL_BGRA;
2046 } else {
2047 // GL_APPLE_texture_format_BGRA8888:
2048 // ES 2.0: the extension makes BGRA an external format but not an internal format.
2049 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format
2050 // for glTexImage (just for glTexStorage).
2051 bgraTexImageFormat = GR_GL_RGBA;
2052 }
2053
2054 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have
2055 // the GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texture_storage and
2056 // GL_EXT_texture_format_BGRA8888.
2057 bool supportsBGRATexStorage = false;
2058
2059 if (GR_IS_GR_GL_ES(standard)) {
2060 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
2061 // The GL_EXT_texture_format_BGRA8888 extension adds BGRA color renderbuffer support
2062 // for ES 2.0. The extension adds BGRA to the supported renerable formats in table
2063 // 4.5. In ES 2.0. All the extensions that add multisample support, all reference
2064 // table 4.5 as the formats that are supported. Thus we can use msaaRenderFlags.
2065 // Additionally, the renderable support was added in a later revision of the
2066 // extension. So it is possible for older drivers to support the extension but only
2067 // an early revision of it without renderable support. We have no way of
2068 // distinguishing between the two and assume renderable.
2069
2070
2071 info.fFlags = FormatInfo::kTexturable_Flag
2072 | FormatInfo::kTransfers_Flag;
2073 // Only enable BGRA msaa if we know we're going through Angle. The spec for
2074 // GL_EXT_texture_format_BGRA8888 was updated in 2016 to add support for GL_BGRA_EXT
2075 // as a sized, renderable format. But we may end up running on old drivers written
2076 // against earlier version of the spec. Also the interactions between all these
2077 // extensions are very suibtle and it wouldn't be hard for a driver to mess them up.
2078 // We are confident that Angle does it as we expect. Our non-angle test bots do seem
2079 // to pass and draw correctly so we could consider enabling this more broadly in the
2080 // future.
2081 // In addition, we also need to disable BGRA MSAA on Mesa. When a client attempts
2082 // to wrap a GPU-backed texture into an SkSurface with MSAA, Ganesh will create
2083 // a MSAA renderbuffer to first render to before resolving to the single-sampled
2084 // texture. Mesa claims to support EXT_texture_format_BGRA8888, and according to
2085 // the spec, this should imply support for both BGRA textures and renderbuffers.
2086 // In practice, however, Mesa only supports BGRA textures and will error on
2087 // glRenderbufferStorage* if the internalformat is BGRA.
2088 if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown &&
2089 ctxInfo.angleDriver() != GrGLDriver::kMesa) {
2090 // Angle incorrectly requires GL_BGRA8_EXT for the interalFormat for both ES2
2091 // and ES3 even though this extension does not define that value. The extension
2092 // only defines GL_BGRA_EXT as an internal format.
2093 info.fInternalFormatForRenderbuffer = GR_GL_BGRA8;
2094 info.fFlags |= msaaRenderFlags;
2095 } else {
2096 // It is not clear what the correct format to use on ES3 is. This extension only
2097 // defines GL_BGRA_EXT. That is definitely the correct thing to use on ES2, but
2098 // its unclear whether that is valid in ES3 or if it wants something like
2099 // GL_BGRA8_EXT (which is only defined in the apple extenstion). For now we set
2100 // everything to use BGRA since its the only explicitly defined value. Until we
2101 // enable MSAA for non-angle this is a moot point.
2102 info.fInternalFormatForRenderbuffer = GR_GL_BGRA;
2103 info.fFlags |= nonMSAARenderFlags;
2104 }
2105 // GL_EXT_texture storage has defined interactions with
2106 // GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but
2107 // without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format.
2108 if (ctxInfo.hasExtension("GL_EXT_texture_storage") &&
2109 !formatWorkarounds.fDisableBGRATextureStorageForIntelWindowsES) {
2110 supportsBGRATexStorage = true;
2111 }
2112 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
2113 // This APPLE extension introduces complexity on ES2. It leaves the internal format
2114 // as RGBA, but allows BGRA as the external format. From testing, it appears that
2115 // the driver remembers the external format when the texture is created (with
2116 // TexImage). If you then try to upload data in the other swizzle (with
2117 // TexSubImage), it fails. We could work around this, but it adds even more state
2118 // tracking to code that is already too tricky. Instead, we opt not to support BGRA
2119 // on ES2 with this extension. This also side-steps some ambiguous interactions with
2120 // the texture storage extension.
2121 if (version >= GR_GL_VER(3,0)) {
2122 // The APPLE extension doesn't explicitly make this renderable, but
2123 // internally it appears to use RGBA8, which we'll patch up below.
2124 info.fFlags = FormatInfo::kTexturable_Flag
2125 | FormatInfo::kTransfers_Flag
2126 | msaaRenderFlags;
2127 // The GL_APPLE_texture_format_BGRA8888 does not add support for BGRA color
2128 // renderbuffers at all so we use RGBA here.
2129 info.fInternalFormatForRenderbuffer = GR_GL_RGBA8;
2130 supportsBGRATexStorage = true;
2131 }
2132 }
2133 }
2134 if (texStorageSupported && supportsBGRATexStorage) {
2135 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2136 info.fInternalFormatForTexImageOrStorage = GR_GL_BGRA8;
2137 } else {
2138 info.fInternalFormatForTexImageOrStorage = bgraTexImageFormat;
2139 }
2140
2141 if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2142 info.fColorTypeInfoCount = 2;
2143 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2144 int ctIdx = 0;
2145 // Format: BGRA8, Surface: kBGRA_8888
2146 {
2147 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2148 ctInfo.fColorType = GrColorType::kBGRA_8888;
2149 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2150 this->setColorTypeFormat(GrColorType::kBGRA_8888, GrGLFormat::kBGRA8);
2151
2152 // External IO ColorTypes:
2153 ctInfo.fExternalIOFormatCount = 2;
2154 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2155 ctInfo.fExternalIOFormatCount);
2156 int ioIdx = 0;
2157 // Format: BGRA8, Surface: kBGRA_8888, Data: kBGRA_8888
2158 {
2159 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2160 ioFormat.fColorType = GrColorType::kBGRA_8888;
2161 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2162 ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2163 ioFormat.fExternalReadFormat = 0;
2164 ioFormat.fExternalReadFormat =
2165 formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2166 // Not guaranteed by ES/WebGL.
2167 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2168 }
2169
2170 // Format: BGRA8, Surface: kBGRA_8888, Data: kRGBA_8888
2171 {
2172 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2173 ioFormat.fColorType = GrColorType::kRGBA_8888;
2174 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2175 ioFormat.fExternalTexImageFormat = 0;
2176 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2177 }
2178 }
2179
2180 // Format: BGRA8, Surface: kRGB_888x
2181 {
2182 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2183 ctInfo.fColorType = GrColorType::kRGB_888x;
2184 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2185 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2186
2187 // External IO ColorTypes:
2188 ctInfo.fExternalIOFormatCount = 1;
2189 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2190 ctInfo.fExternalIOFormatCount);
2191 int ioIdx = 0;
2192 // Format: BGRA8, Surface: kRGB_888x, Data: kRGBA_888x
2193 {
2194 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2195 ioFormat.fColorType = GrColorType::kRGB_888x;
2196 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2197 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2198 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2199 }
2200 }
2201 }
2202 }
2203
2204 // Format: RGB565
2205 {
2206 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB565);
2207 info.fFormatType = FormatType::kNormalizedFixedPoint;
2208 info.fInternalFormatForRenderbuffer = GR_GL_RGB565;
2209 info.fDefaultExternalFormat = GR_GL_RGB;
2210 info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2211 info.fDefaultColorType = GrColorType::kBGR_565;
2212 if (GR_IS_GR_GL(standard)) {
2213 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
2214 info.fFlags = FormatInfo::kTexturable_Flag
2215 | FormatInfo::kTransfers_Flag
2216 | msaaRenderFlags;
2217 }
2218 } else if (GR_IS_GR_GL_ES(standard)) {
2219 info.fFlags = FormatInfo::kTexturable_Flag
2220 | FormatInfo::kTransfers_Flag
2221 | msaaRenderFlags;
2222 } else if (GR_IS_GR_WEBGL(standard)) {
2223 info.fFlags = FormatInfo::kTexturable_Flag
2224 | FormatInfo::kTransfers_Flag
2225 | msaaRenderFlags;
2226 }
2227 // 565 is not a sized internal format on desktop GL. So on desktop with
2228 // 565 we always use an unsized internal format to let the system pick
2229 // the best sized format to convert the 565 data to. Since TexStorage
2230 // only allows sized internal formats we disallow it.
2231 //
2232 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
2233 // update.
2234 if (texStorageSupported && GR_IS_GR_GL_ES(standard)) {
2235 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2236 info.fInternalFormatForTexImageOrStorage = GR_GL_RGB565;
2237 } else {
2238 info.fInternalFormatForTexImageOrStorage =
2239 texImageSupportsSizedInternalFormat ? GR_GL_RGB565 : GR_GL_RGB;
2240 }
2241
2242 if (SkToBool(info.fFlags &FormatInfo::kTexturable_Flag)) {
2243 info.fColorTypeInfoCount = 1;
2244 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2245 int ctIdx = 0;
2246 // Format: RGB565, Surface: kBGR_565
2247 {
2248 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2249 ctInfo.fColorType = GrColorType::kBGR_565;
2250 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2251 this->setColorTypeFormat(GrColorType::kBGR_565, GrGLFormat::kRGB565);
2252
2253 // External IO ColorTypes:
2254 ctInfo.fExternalIOFormatCount = 2;
2255 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2256 ctInfo.fExternalIOFormatCount);
2257 int ioIdx = 0;
2258 // Format: RGB565, Surface: kBGR_565, Data: kBGR_565
2259 {
2260 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2261 ioFormat.fColorType = GrColorType::kBGR_565;
2262 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2263 ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2264 ioFormat.fExternalReadFormat = GR_GL_RGB;
2265 // Not guaranteed by ES/WebGL.
2266 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2267 }
2268
2269 // Format: RGB565, Surface: kBGR_565, Data: kRGBA_8888
2270 {
2271 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2272 ioFormat.fColorType = GrColorType::kRGBA_8888;
2273 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2274 ioFormat.fExternalTexImageFormat = 0;
2275 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2276 }
2277 }
2278 }
2279 }
2280
2281 // Format: RGBA16F
2282 {
2283 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16F);
2284 info.fFormatType = FormatType::kFloat;
2285 info.fInternalFormatForRenderbuffer = GR_GL_RGBA16F;
2286 info.fDefaultExternalFormat = GR_GL_RGBA;
2287 info.fDefaultExternalType = halfFloatType;
2288 info.fDefaultColorType = GrColorType::kRGBA_F16;
2289 bool rgba16FTextureSupport = false;
2290 bool rgba16FRenderTargetSupport = false;
2291
2292 if (GR_IS_GR_GL(standard)) {
2293 if (version >= GR_GL_VER(3, 0)) {
2294 rgba16FTextureSupport = true;
2295 rgba16FRenderTargetSupport = true;
2296 } else if (ctxInfo.hasExtension("GL_ARB_texture_float")) {
2297 rgba16FTextureSupport = true;
2298 }
2299 } else if (GR_IS_GR_GL_ES(standard)) {
2300 if (version >= GR_GL_VER(3, 0)) {
2301 rgba16FTextureSupport = true;
2302 rgba16FRenderTargetSupport =
2303 version >= GR_GL_VER(3, 2) ||
2304 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2305 ctxInfo.hasExtension("GL_EXT_color_buffer_float");
2306 } else if (ctxInfo.hasExtension("GL_OES_texture_half_float") &&
2307 ctxInfo.hasExtension("GL_OES_texture_half_float_linear")) {
2308 rgba16FTextureSupport = true;
2309 rgba16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2310 }
2311 } else if (GR_IS_GR_WEBGL(standard)) {
2312 if (version >= GR_GL_VER(2, 0)) {
2313 rgba16FTextureSupport = true;
2314 rgba16FRenderTargetSupport =
2315 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2316 ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
2317 ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2318 ctxInfo.hasExtension("EXT_color_buffer_float");
2319 } else if ((ctxInfo.hasExtension("GL_OES_texture_half_float") ||
2320 ctxInfo.hasExtension("OES_texture_half_float")) &&
2321 (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") ||
2322 ctxInfo.hasExtension("OES_texture_half_float_linear"))) {
2323 rgba16FTextureSupport = true;
2324 // We don't check for EXT_color_buffer_float as it's only defined for WebGL 2.
2325 rgba16FRenderTargetSupport =
2326 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
2327 ctxInfo.hasExtension("EXT_color_buffer_half_float");
2328 }
2329 }
2330
2331 if (rgba16FTextureSupport) {
2332 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2333 if (rgba16FRenderTargetSupport) {
2334 info.fFlags |= fpRenderFlags;
2335 }
2336 }
2337 if (texStorageSupported && !formatWorkarounds.fDisableRGBA16FTexStorageForCrBug1008003) {
2338 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2339 info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16F;
2340 } else {
2341 info.fInternalFormatForTexImageOrStorage =
2342 texImageSupportsSizedInternalFormat ? GR_GL_RGBA16F : GR_GL_RGBA;
2343 }
2344
2345 if (rgba16FTextureSupport) {
2346 uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2347
2348 info.fColorTypeInfoCount = 3;
2349 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2350 int ctIdx = 0;
2351 // Format: RGBA16F, Surface: kRGBA_F16
2352 {
2353 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2354 ctInfo.fColorType = GrColorType::kRGBA_F16;
2355 ctInfo.fFlags = flags;
2356 this->setColorTypeFormat(GrColorType::kRGBA_F16, GrGLFormat::kRGBA16F);
2357
2358 // External IO ColorTypes:
2359 ctInfo.fExternalIOFormatCount = 2;
2360 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2361 ctInfo.fExternalIOFormatCount);
2362 int ioIdx = 0;
2363 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F16
2364 {
2365 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2366 ioFormat.fColorType = GrColorType::kRGBA_F16;
2367 ioFormat.fExternalType = halfFloatType;
2368 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2369 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2370 // Not guaranteed by ES/WebGL.
2371 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2372 }
2373
2374 // Format: RGBA16F, Surface: kRGBA_F16, Data: kRGBA_F32
2375 {
2376 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2377 ioFormat.fColorType = GrColorType::kRGBA_F32;
2378 ioFormat.fExternalType = GR_GL_FLOAT;
2379 ioFormat.fExternalTexImageFormat = 0;
2380 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2381 }
2382 }
2383
2384 // Format: RGBA16F, Surface: kRGBA_F16_Clamped
2385 {
2386 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2387 ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
2388 ctInfo.fFlags = flags;
2389 this->setColorTypeFormat(GrColorType::kRGBA_F16_Clamped, GrGLFormat::kRGBA16F);
2390
2391 // External IO ColorTypes:
2392 ctInfo.fExternalIOFormatCount = 2;
2393 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2394 ctInfo.fExternalIOFormatCount);
2395 int ioIdx = 0;
2396 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F16_Clamped
2397 {
2398 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2399 ioFormat.fColorType = GrColorType::kRGBA_F16_Clamped;
2400 ioFormat.fExternalType = halfFloatType;
2401 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2402 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2403 // Not guaranteed by ES/WebGL.
2404 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2405 }
2406
2407 // Format: RGBA16F, Surface: kRGBA_F16_Clamped, Data: kRGBA_F32
2408 {
2409 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2410 ioFormat.fColorType = GrColorType::kRGBA_F32;
2411 ioFormat.fExternalType = GR_GL_FLOAT;
2412 ioFormat.fExternalTexImageFormat = 0;
2413 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2414 }
2415 }
2416 // Format: RGBA16F, Surface: kRGB_F16F16F16x
2417 {
2418 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2419 ctInfo.fColorType = GrColorType::kRGB_F16F16F16x;
2420 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2421 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2422 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2423 this->setColorTypeFormat(GrColorType::kRGB_F16F16F16x, GrGLFormat::kRGBA16F);
2424
2425 // External IO ColorTypes:
2426 ctInfo.fExternalIOFormatCount = 2;
2427 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2428 ctInfo.fExternalIOFormatCount);
2429 int ioIdx = 0;
2430 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGB_F16F16F16x
2431 {
2432 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2433 ioFormat.fColorType = GrColorType::kRGB_F16F16F16x;
2434 ioFormat.fExternalType = halfFloatType;
2435 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2436 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2437 // Not guaranteed by ES/WebGL.
2438 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2439 }
2440 // Format: RGBA16F, Surface: kRGB_F16F16F16x, Data: kRGBA_F32
2441 {
2442 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2443 ioFormat.fColorType = GrColorType::kRGBA_F32;
2444 ioFormat.fExternalType = GR_GL_FLOAT;
2445 ioFormat.fExternalTexImageFormat = 0;
2446 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2447 }
2448 }
2449 }
2450 }
2451
2452 // Format: R16F
2453 {
2454 FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16F);
2455 info.fFormatType = FormatType::kFloat;
2456 info.fInternalFormatForRenderbuffer = GR_GL_R16F;
2457 info.fDefaultExternalFormat = GR_GL_RED;
2458 info.fDefaultExternalType = halfFloatType;
2459 info.fDefaultColorType = GrColorType::kR_F16;
2460 bool r16FTextureSupport = false;
2461 bool r16FRenderTargetSupport = false;
2462
2463 if (GR_IS_GR_GL(standard)) {
2464 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg")) {
2465 r16FTextureSupport = true;
2466 r16FRenderTargetSupport = true;
2467 }
2468 } else if (GR_IS_GR_GL_ES(standard)) {
2469 // It seems possible that a combination of GL_EXT_texture_rg and
2470 // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
2471 // clear. The latter mentions interaction but that may only be for renderbuffers as
2472 // neither adds the texture format explicitly.
2473 // GL_OES_texture_format_half_float makes no reference to RED formats.
2474 if (version >= GR_GL_VER(3, 0)) {
2475 r16FTextureSupport = true;
2476 r16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
2477 ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2478 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
2479 }
2480 } else if (GR_IS_GR_WEBGL(standard)) {
2481 if (version >= GR_GL_VER(2, 0)) {
2482 r16FTextureSupport = true;
2483 r16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
2484 ctxInfo.hasExtension("EXT_color_buffer_float");
2485 }
2486 }
2487
2488 if (r16FTextureSupport) {
2489 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2490 if (r16FRenderTargetSupport) {
2491 info.fFlags |= fpRenderFlags;
2492 }
2493 }
2494 if (texStorageSupported) {
2495 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2496 info.fInternalFormatForTexImageOrStorage = GR_GL_R16F;
2497 } else {
2498 info.fInternalFormatForTexImageOrStorage =
2499 texImageSupportsSizedInternalFormat ? GR_GL_R16F : GR_GL_RED;
2500 }
2501
2502 if (r16FTextureSupport) {
2503 // Format: R16F, Surface: kAlpha_F16
2504 info.fColorTypeInfoCount = 1;
2505 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2506 int ctIdx = 0;
2507 {
2508 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2509 ctInfo.fColorType = GrColorType::kAlpha_F16;
2510 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2511 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2512 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
2513 this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kR16F);
2514
2515 // External IO ColorTypes:
2516 ctInfo.fExternalIOFormatCount = 2;
2517 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2518 ctInfo.fExternalIOFormatCount);
2519 int ioIdx = 0;
2520 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F16
2521 {
2522 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2523 ioFormat.fColorType = GrColorType::kAlpha_F16;
2524 ioFormat.fExternalType = halfFloatType;
2525 ioFormat.fExternalTexImageFormat = GR_GL_RED;
2526 ioFormat.fExternalReadFormat = GR_GL_RED;
2527 // Not guaranteed by ES/WebGL.
2528 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2529 }
2530
2531 // Format: R16F, Surface: kAlpha_F16, Data: kAlpha_F32xxx
2532 {
2533 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2534 ioFormat.fColorType = GrColorType::kAlpha_F32xxx;
2535 ioFormat.fExternalType = GR_GL_FLOAT;
2536 ioFormat.fExternalTexImageFormat = 0;
2537 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2538 }
2539 }
2540 }
2541 }
2542
2543 // Format: LUMINANCE16F
2544 {
2545 // NOTE: We disallow lum16f on ES devices if linear filtering modes are not
2546 // supported. This is for simplicity, but a more granular approach is possible.
2547 bool lum16FSupported = false;
2548 bool lum16FSizedFormatSupported = false;
2549 GrGLenum lumHalfFloatType = halfFloatType;
2550 if (GR_IS_GR_GL(standard)) {
2551 if (!fIsCoreProfile && ctxInfo.hasExtension("GL_ARB_texture_float")) {
2552 lum16FSupported = true;
2553 lum16FSizedFormatSupported = true;
2554 }
2555 } else if (GR_IS_GR_GL_ES(standard)) {
2556 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
2557 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
2558 lum16FSupported = true;
2559 // Even in ES 3.0+ LUMINANCE and GL_HALF_FLOAT are not listed as a valid
2560 // combination. Thus we must use GL_HALF_FLOAT_OES provided by the extension
2561 // GL_OES_texture_half_float. Note: these two types are not defined to be the same
2562 // value.
2563 lumHalfFloatType = GR_GL_HALF_FLOAT_OES;
2564 // Even on ES3 this extension is required to define LUMINANCE16F.
2565 lum16FSizedFormatSupported = ctxInfo.hasExtension("GL_EXT_texture_storage");
2566 }
2567 } // No WebGL support
2568
2569 if (formatWorkarounds.fDisableLuminance16F) {
2570 lum16FSupported = false;
2571 }
2572
2573 FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE16F);
2574 info.fFormatType = FormatType::kFloat;
2575 info.fInternalFormatForRenderbuffer = GR_GL_LUMINANCE16F;
2576 info.fDefaultExternalFormat = GR_GL_LUMINANCE;
2577 info.fDefaultExternalType = lumHalfFloatType;
2578 info.fDefaultColorType = GrColorType::kGray_F16;
2579
2580 if (lum16FSupported) {
2581 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2582
2583 if (texStorageSupported && lum16FSizedFormatSupported) {
2584 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2585 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2586 } else if (texImageSupportsSizedInternalFormat && lum16FSizedFormatSupported) {
2587 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE16F;
2588 } else {
2589 info.fInternalFormatForTexImageOrStorage = GR_GL_LUMINANCE;
2590 }
2591
2592 info.fColorTypeInfoCount = 1;
2593 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2594 int ctIdx = 0;
2595 // Format: LUMINANCE16F, Surface: kAlpha_F16
2596 {
2597 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2598 ctInfo.fColorType = GrColorType::kAlpha_F16;
2599 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2600 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
2601 ctInfo.fWriteSwizzle = skgpu::Swizzle("aaa0");
2602
2603 int idx = static_cast<int>(GrColorType::kAlpha_F16);
2604 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2605 this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kLUMINANCE16F);
2606 }
2607
2608 // External IO ColorTypes:
2609 ctInfo.fExternalIOFormatCount = 2;
2610 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2611 ctInfo.fExternalIOFormatCount);
2612 int ioIdx = 0;
2613 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kAlpha_F16
2614 {
2615 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2616 ioFormat.fColorType = GrColorType::kAlpha_F16;
2617 ioFormat.fExternalType = lumHalfFloatType;
2618 ioFormat.fExternalTexImageFormat = GR_GL_LUMINANCE;
2619 ioFormat.fExternalReadFormat = 0;
2620 }
2621
2622 // Format: LUMINANCE16F, Surface: kAlpha_F16, Data: kRGBA_F32
2623 {
2624 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2625 ioFormat.fColorType = GrColorType::kRGBA_F32;
2626 ioFormat.fExternalType = GR_GL_FLOAT;
2627 ioFormat.fExternalTexImageFormat = 0;
2628 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2629 }
2630 }
2631 }
2632 }
2633
2634 // Format: RGBx8
2635 {
2636 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBX8);
2637 info.fFormatType = FormatType::kNormalizedFixedPoint;
2638 info.fInternalFormatForRenderbuffer = GR_GL_RGBX8;
2639 info.fDefaultExternalFormat = GR_GL_RGB;
2640 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2641 info.fDefaultColorType = GrColorType::kRGB_888;
2642
2643 bool supportsSizedRGBX = false;
2644 // The GL_ANGLE_rgbx_internal_format extension only adds the sized GL_RGBX8 type and does
2645 // not have a way to create a texture of that format with texImage using an unsized type. So
2646 // we require that we either have texture storage support or that tex image supports sized
2647 // formats to say that this format is supported.
2648 if (GR_IS_GR_GL_ES(standard) && ctxInfo.hasExtension("GL_ANGLE_rgbx_internal_format") &&
2649 (texStorageSupported || texImageSupportsSizedInternalFormat)) {
2650 supportsSizedRGBX = true;
2651 }
2652
2653 if (supportsSizedRGBX) {
2654 info.fInternalFormatForTexImageOrStorage = GR_GL_RGBX8;
2655 info.fFlags = FormatInfo::kTexturable_Flag |
2656 FormatInfo::kTransfers_Flag |
2657 msaaRenderFlags;
2658 if (texStorageSupported) {
2659 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2660 }
2661 info.fColorTypeInfoCount = 1;
2662 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2663 int ctIdx = 0;
2664 // Format: RGBX8, Surface: kRGB_888x
2665 {
2666 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2667 ctInfo.fColorType = GrColorType::kRGB_888x;
2668 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2669 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGBX8);
2670
2671 // External IO ColorTypes:
2672 ctInfo.fExternalIOFormatCount = 2;
2673 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2674 ctInfo.fExternalIOFormatCount);
2675 int ioIdx = 0;
2676 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888
2677 {
2678 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2679 ioFormat.fColorType = GrColorType::kRGB_888;
2680 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2681 ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2682 ioFormat.fExternalReadFormat = 0;
2683 }
2684
2685 // Format: RGBX8, Surface: kRGB_888x, Data: kRGB_888x
2686 {
2687 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2688 ioFormat.fColorType = GrColorType::kRGB_888x;
2689 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2690 ioFormat.fExternalTexImageFormat = 0;
2691 ioFormat.fExternalReadFormat = GR_GL_RGBX8;
2692 }
2693 }
2694 }
2695 }
2696
2697 // Format: RGB8
2698 {
2699 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB8);
2700 info.fFormatType = FormatType::kNormalizedFixedPoint;
2701 info.fInternalFormatForRenderbuffer = GR_GL_RGB8;
2702 info.fDefaultExternalFormat = GR_GL_RGB;
2703 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2704 info.fDefaultColorType = GrColorType::kRGB_888;
2705 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2706 if (GR_IS_GR_GL(standard)) {
2707 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be
2708 // a supported render buffer format. Since we usually use render buffers for MSAA on
2709 // non-ES GL we don't support MSAA for GL_RGB8. On 4.2+ we could check using
2710 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if
2711 // this becomes an issue.
2712 info.fFlags |= nonMSAARenderFlags;
2713 } else if (GR_IS_GR_GL_ES(standard)) {
2714 // 3.0 and the extension support this as a render buffer format.
2715 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
2716 info.fFlags |= msaaRenderFlags;
2717 }
2718 } else if (GR_IS_GR_WEBGL(standard)) {
2719 // WebGL seems to support RBG8
2720 info.fFlags |= msaaRenderFlags;
2721 }
2722 if (texStorageSupported) {
2723 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2724 info.fInternalFormatForTexImageOrStorage = GR_GL_RGB8;
2725 } else {
2726 info.fInternalFormatForTexImageOrStorage =
2727 texImageSupportsSizedInternalFormat ? GR_GL_RGB8 : GR_GL_RGB;
2728 }
2729
2730 info.fColorTypeInfoCount = 1;
2731 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2732 int ctIdx = 0;
2733 // Format: RGB8, Surface: kRGB_888x
2734 {
2735 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2736 ctInfo.fColorType = GrColorType::kRGB_888x;
2737 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2738
2739 int idx = static_cast<int>(GrColorType::kRGB_888x);
2740 if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
2741 this->setColorTypeFormat(GrColorType::kRGB_888x, GrGLFormat::kRGB8);
2742 }
2743
2744 // External IO ColorTypes:
2745 ctInfo.fExternalIOFormatCount = 2;
2746 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2747 ctInfo.fExternalIOFormatCount);
2748 int ioIdx = 0;
2749 // Format: RGB8, Surface: kRGB_888x, Data: kRGB_888
2750 {
2751 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2752 ioFormat.fColorType = GrColorType::kRGB_888;
2753 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2754 ioFormat.fExternalTexImageFormat = GR_GL_RGB;
2755 ioFormat.fExternalReadFormat = 0;
2756 }
2757
2758 // Format: RGB8, Surface: kRGB_888x, Data: kRGBA_8888
2759 {
2760 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2761 ioFormat.fColorType = GrColorType::kRGBA_8888;
2762 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2763 ioFormat.fExternalTexImageFormat = 0;
2764 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2765 }
2766 }
2767 }
2768
2769 // Format: RG8
2770 {
2771 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG8);
2772 info.fFormatType = FormatType::kNormalizedFixedPoint;
2773 info.fInternalFormatForRenderbuffer = GR_GL_RG8;
2774 info.fDefaultExternalFormat = GR_GL_RG;
2775 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
2776 info.fDefaultColorType = GrColorType::kRG_88;
2777 bool rg8Support = false;
2778 if (GR_IS_GR_GL(standard)) {
2779 rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
2780 } else if (GR_IS_GR_GL_ES(standard)) {
2781 rg8Support = version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
2782 } else if (GR_IS_GR_WEBGL(standard)) {
2783 rg8Support = version >= GR_GL_VER(2, 0);
2784 }
2785 if (rg8Support) {
2786 info.fFlags |= FormatInfo::kTexturable_Flag
2787 | FormatInfo::kTransfers_Flag
2788 | msaaRenderFlags;
2789 if (texStorageSupported) {
2790 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2791 info.fInternalFormatForTexImageOrStorage = GR_GL_RG8;
2792 }
2793 }
2794 if (!(info.fFlags & FormatInfo::kUseTexStorage_Flag)) {
2795 info.fInternalFormatForTexImageOrStorage =
2796 texImageSupportsSizedInternalFormat ? GR_GL_RG8 : GR_GL_RG;
2797 }
2798 if (rg8Support) {
2799 info.fColorTypeInfoCount = 1;
2800 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2801 int ctIdx = 0;
2802 // Format: RG8, Surface: kRG_88
2803 {
2804 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2805 ctInfo.fColorType = GrColorType::kRG_88;
2806 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2807 this->setColorTypeFormat(GrColorType::kRG_88, GrGLFormat::kRG8);
2808
2809 // External IO ColorTypes:
2810 ctInfo.fExternalIOFormatCount = 2;
2811 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2812 ctInfo.fExternalIOFormatCount);
2813 int ioIdx = 0;
2814 // Format: RG8, Surface: kRG_88, Data: kRG_88
2815 {
2816 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2817 ioFormat.fColorType = GrColorType::kRG_88;
2818 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2819 ioFormat.fExternalTexImageFormat = GR_GL_RG;
2820 ioFormat.fExternalReadFormat = 0;
2821 if (GR_IS_GR_GL(standard) && !formatWorkarounds.fDisallowDirectRG8ReadPixels) {
2822 ioFormat.fExternalReadFormat = GR_GL_RG;
2823 }
2824 }
2825
2826 // Format: RG8, Surface: kRG_88, Data: kRGBA_8888
2827 {
2828 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2829 ioFormat.fColorType = GrColorType::kRGBA_8888;
2830 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2831 ioFormat.fExternalTexImageFormat = 0;
2832 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2833 }
2834 }
2835 }
2836 }
2837
2838 // Format: RGB10_A2
2839 {
2840 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB10_A2);
2841 info.fFormatType = FormatType::kNormalizedFixedPoint;
2842 info.fInternalFormatForRenderbuffer = GR_GL_RGB10_A2;
2843 info.fDefaultExternalFormat = GR_GL_RGBA;
2844 info.fDefaultExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2845 info.fDefaultColorType = GrColorType::kRGBA_1010102;
2846 if (GR_IS_GR_GL(standard) ||
2847 (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
2848 info.fFlags = FormatInfo::kTexturable_Flag
2849 | FormatInfo::kTransfers_Flag
2850 | msaaRenderFlags;
2851 } else if (GR_IS_GR_GL_ES(standard) &&
2852 ctxInfo.hasExtension("GL_EXT_texture_type_2_10_10_10_REV")) {
2853 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2854 } // No WebGL support
2855
2856 if (texStorageSupported) {
2857 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2858 info.fInternalFormatForTexImageOrStorage = GR_GL_RGB10_A2;
2859 } else {
2860 info.fInternalFormatForTexImageOrStorage =
2861 texImageSupportsSizedInternalFormat ? GR_GL_RGB10_A2 : GR_GL_RGBA;
2862 }
2863
2864 if (SkToBool(info.fFlags & FormatInfo::kTexturable_Flag)) {
2865 bool supportsBGRAColorType = GR_IS_GR_GL(standard) &&
2866 (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra"));
2867
2868 info.fColorTypeInfoCount = supportsBGRAColorType ? 3 : 2;
2869 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
2870 int ctIdx = 0;
2871 // Format: RGB10_A2, Surface: kRGBA_1010102
2872 {
2873 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2874 ctInfo.fColorType = GrColorType::kRGBA_1010102;
2875 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2876 this->setColorTypeFormat(GrColorType::kRGBA_1010102, GrGLFormat::kRGB10_A2);
2877
2878 // External IO ColorTypes:
2879 ctInfo.fExternalIOFormatCount = 2;
2880 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2881 ctInfo.fExternalIOFormatCount);
2882 int ioIdx = 0;
2883 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_1010102
2884 {
2885 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2886 ioFormat.fColorType = GrColorType::kRGBA_1010102;
2887 ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2888 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2889 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2890 // Not guaranteed by ES/WebGL.
2891 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2892 }
2893
2894 // Format: RGB10_A2, Surface: kRGBA_1010102, Data: kRGBA_8888
2895 {
2896 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2897 ioFormat.fColorType = GrColorType::kRGBA_8888;
2898 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2899 ioFormat.fExternalTexImageFormat = 0;
2900 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2901 }
2902 }
2903 //------------------------------------------------------------------
2904 // Format: RGB10_A2, Surface: kBGRA_1010102
2905 if (supportsBGRAColorType) {
2906 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2907 ctInfo.fColorType = GrColorType::kBGRA_1010102;
2908 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
2909 this->setColorTypeFormat(GrColorType::kBGRA_1010102, GrGLFormat::kRGB10_A2);
2910
2911 // External IO ColorTypes:
2912 ctInfo.fExternalIOFormatCount = 2;
2913 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2914 ctInfo.fExternalIOFormatCount);
2915 int ioIdx = 0;
2916 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kBGRA_1010102
2917 {
2918 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2919 ioFormat.fColorType = GrColorType::kBGRA_1010102;
2920 ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2921 ioFormat.fExternalTexImageFormat = GR_GL_BGRA;
2922 ioFormat.fExternalReadFormat =
2923 formatWorkarounds.fDisallowBGRA8ReadPixels ? 0 : GR_GL_BGRA;
2924 // Not guaranteed by ES/WebGL.
2925 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2926 }
2927
2928 // Format: RGB10_A2, Surface: kBGRA_1010102, Data: kRGBA_8888
2929 {
2930 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2931 ioFormat.fColorType = GrColorType::kRGBA_8888;
2932 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2933 ioFormat.fExternalTexImageFormat = 0;
2934 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2935 }
2936 }
2937 // Format: RGB10_A2, Surface: kRGB_101010x
2938 {
2939 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
2940 ctInfo.fColorType = GrColorType::kRGB_101010x;
2941 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
2942 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
2943 ctInfo.fWriteSwizzle = skgpu::Swizzle::RGB1();
2944 this->setColorTypeFormat(GrColorType::kRGB_101010x, GrGLFormat::kRGB10_A2);
2945
2946 // External IO ColorTypes:
2947 ctInfo.fExternalIOFormatCount = 2;
2948 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
2949 ctInfo.fExternalIOFormatCount);
2950 int ioIdx = 0;
2951 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGB_101010x
2952 {
2953 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2954 ioFormat.fColorType = GrColorType::kRGB_101010x;
2955 ioFormat.fExternalType = GR_GL_UNSIGNED_INT_2_10_10_10_REV;
2956 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
2957 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2958 // Not guaranteed by ES/WebGL.
2959 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
2960 }
2961 // Format: RGB10_A2, Surface: kRGB_101010x, Data: kRGBA_8888
2962 {
2963 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
2964 ioFormat.fColorType = GrColorType::kRGBA_8888;
2965 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
2966 ioFormat.fExternalTexImageFormat = 0;
2967 ioFormat.fExternalReadFormat = GR_GL_RGBA;
2968 }
2969 }
2970
2971 }
2972 }
2973
2974 // Format: RGBA4
2975 {
2976 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA4);
2977 info.fFormatType = FormatType::kNormalizedFixedPoint;
2978 info.fInternalFormatForRenderbuffer = GR_GL_RGBA4;
2979 info.fDefaultExternalFormat = GR_GL_RGBA;
2980 info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
2981 info.fDefaultColorType = GrColorType::kABGR_4444;
2982 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
2983 if (GR_IS_GR_GL(standard)) {
2984 if (version >= GR_GL_VER(4, 2)) {
2985 info.fFlags |= msaaRenderFlags;
2986 }
2987 } else if (GR_IS_GR_GL_ES(standard)) {
2988 info.fFlags |= msaaRenderFlags;
2989 } else if (GR_IS_GR_WEBGL(standard)) {
2990 info.fFlags |= msaaRenderFlags;
2991 }
2992 if (texStorageSupported) {
2993 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
2994 info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA4;
2995 } else {
2996 info.fInternalFormatForTexImageOrStorage =
2997 texImageSupportsSizedInternalFormat ? GR_GL_RGBA4 : GR_GL_RGBA;
2998 }
2999
3000 info.fColorTypeInfoCount = 1;
3001 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3002 int ctIdx = 0;
3003 // Format: RGBA4, Surface: kABGR_4444
3004 {
3005 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3006 ctInfo.fColorType = GrColorType::kABGR_4444;
3007 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3008 this->setColorTypeFormat(GrColorType::kABGR_4444, GrGLFormat::kRGBA4);
3009
3010 // External IO ColorTypes:
3011 ctInfo.fExternalIOFormatCount = 2;
3012 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3013 ctInfo.fExternalIOFormatCount);
3014 int ioIdx = 0;
3015 // Format: RGBA4, Surface: kABGR_4444, Data: kABGR_4444
3016 {
3017 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3018 ioFormat.fColorType = GrColorType::kABGR_4444;
3019 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
3020 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3021 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3022 // Not guaranteed by ES/WebGL.
3023 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3024 }
3025
3026 // Format: RGBA4, Surface: kABGR_4444, Data: kRGBA_8888
3027 {
3028 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3029 ioFormat.fColorType = GrColorType::kRGBA_8888;
3030 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3031 ioFormat.fExternalTexImageFormat = 0;
3032 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3033 }
3034 }
3035 }
3036
3037 // Format: SRGB8_ALPHA8
3038 {
3039 FormatInfo& info = this->getFormatInfo(GrGLFormat::kSRGB8_ALPHA8);
3040 info.fFormatType = FormatType::kNormalizedFixedPoint;
3041 info.fInternalFormatForRenderbuffer = GR_GL_SRGB8_ALPHA8;
3042 info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
3043 info.fDefaultColorType = GrColorType::kRGBA_8888_SRGB;
3044
3045 // We may modify the default external format below.
3046 info.fDefaultExternalFormat = GR_GL_RGBA;
3047 bool srgb8Alpha8TexStorageSupported = texStorageSupported;
3048 bool srgb8Alpha8TextureSupport = false;
3049 bool srgb8Alpha8RenderTargetSupport = false;
3050 if (GR_IS_GR_GL(standard)) {
3051 if (version >= GR_GL_VER(3, 0)) {
3052 srgb8Alpha8TextureSupport = true;
3053 srgb8Alpha8RenderTargetSupport = true;
3054 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
3055 srgb8Alpha8TextureSupport = true;
3056 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
3057 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
3058 srgb8Alpha8RenderTargetSupport = true;
3059 }
3060 }
3061 } else if (GR_IS_GR_GL_ES(standard)) {
3062 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_sRGB")) {
3063 srgb8Alpha8TextureSupport = true;
3064 srgb8Alpha8RenderTargetSupport = true;
3065 }
3066 if (version < GR_GL_VER(3, 0)) {
3067 // ES 2.0 requires that the external format matches the internal format.
3068 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3069 // There is no defined interaction between GL_EXT_sRGB and GL_EXT_texture_storage.
3070 srgb8Alpha8TexStorageSupported = false;
3071 }
3072 } else if (GR_IS_GR_WEBGL(standard)) {
3073 // sRGB extension should be on most WebGL 1.0 contexts, although sometimes under 2
3074 // names.
3075 if (version >= GR_GL_VER(2, 0) || ctxInfo.hasExtension("GL_EXT_sRGB") ||
3076 ctxInfo.hasExtension("EXT_sRGB")) {
3077 srgb8Alpha8TextureSupport = true;
3078 srgb8Alpha8RenderTargetSupport = true;
3079 }
3080 if (version < GR_GL_VER(2, 0)) {
3081 // WebGL 1.0 requires that the external format matches the internal format.
3082 info.fDefaultExternalFormat = GR_GL_SRGB_ALPHA;
3083 // There is no extension to WebGL 1 that adds glTexStorage.
3084 SkASSERT(!srgb8Alpha8TexStorageSupported);
3085 }
3086 }
3087
3088 if (srgb8Alpha8TextureSupport) {
3089 info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3090 if (srgb8Alpha8RenderTargetSupport) {
3091 info.fFlags |= formatWorkarounds.fDisableSRGBRenderWithMSAAForMacAMD
3092 ? nonMSAARenderFlags
3093 : msaaRenderFlags;
3094 }
3095 }
3096 if (srgb8Alpha8TexStorageSupported) {
3097 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3098 info.fInternalFormatForTexImageOrStorage = GR_GL_SRGB8_ALPHA8;
3099 } else {
3100 info.fInternalFormatForTexImageOrStorage =
3101 texImageSupportsSizedInternalFormat ? GR_GL_SRGB8_ALPHA8 : GR_GL_SRGB_ALPHA;
3102 }
3103
3104 if (srgb8Alpha8TextureSupport) {
3105 info.fColorTypeInfoCount = 1;
3106 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3107 int ctIdx = 0;
3108 // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB
3109 {
3110 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3111 ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
3112 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3113 this->setColorTypeFormat(GrColorType::kRGBA_8888_SRGB, GrGLFormat::kSRGB8_ALPHA8);
3114
3115 // External IO ColorTypes:
3116 ctInfo.fExternalIOFormatCount = 1;
3117 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3118 ctInfo.fExternalIOFormatCount);
3119 int ioIdx = 0;
3120
3121 // Format: SRGB8_ALPHA8, Surface: kRGBA_8888_SRGB, Data: kRGBA_8888_SRGB
3122 {
3123 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu.
3124 // Thus, the external format is GL_RGBA. See below for note about ES2.0 and
3125 // glTex[Sub]Image.
3126 GrGLenum texImageExternalFormat = GR_GL_RGBA;
3127
3128 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the
3129 // <format> param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and
3130 // <format> params to match. Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the
3131 // <format> param. On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the
3132 // <format> param to glTexImage.
3133 if (GR_IS_GR_GL_ES(standard) && version == GR_GL_VER(2,0)) {
3134 texImageExternalFormat = GR_GL_SRGB_ALPHA;
3135 }
3136 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3137 ioFormat.fColorType = GrColorType::kRGBA_8888_SRGB;
3138 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3139 ioFormat.fExternalTexImageFormat = texImageExternalFormat;
3140 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3141 }
3142 }
3143 }
3144 }
3145
3146 // Format: COMPRESSED_RGB8_BC1
3147 {
3148 FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_BC1);
3149 info.fFormatType = FormatType::kNormalizedFixedPoint;
3150 info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
3151 if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3152 if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3153 info.fFlags = FormatInfo::kTexturable_Flag;
3154 }
3155 } else if (GR_IS_GR_WEBGL(standard)) {
3156 if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3157 info.fFlags = FormatInfo::kTexturable_Flag;
3158 }
3159 }
3160
3161 // There are no support GrColorTypes for this format
3162 }
3163
3164 // Format: COMPRESSED_RGBA8_BC1
3165 {
3166 FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGBA8_BC1);
3167 info.fFormatType = FormatType::kNormalizedFixedPoint;
3168 info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3169 if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
3170 if (ctxInfo.hasExtension("GL_EXT_texture_compression_s3tc")) {
3171 info.fFlags = FormatInfo::kTexturable_Flag;
3172 }
3173 } else if (GR_IS_GR_WEBGL(standard)) {
3174 if (ctxInfo.hasExtension("WEBGL_compressed_texture_s3tc")) {
3175 info.fFlags = FormatInfo::kTexturable_Flag;
3176 }
3177 }
3178
3179 // There are no support GrColorTypes for this format
3180 }
3181
3182 // Format: COMPRESSED_RGB8_ETC2
3183 {
3184 FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_RGB8_ETC2);
3185 info.fFormatType = FormatType::kNormalizedFixedPoint;
3186 info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_RGB8_ETC2;
3187 if (!formatWorkarounds.fDisallowETC2Compression) {
3188 if (GR_IS_GR_GL(standard)) {
3189 if (version >= GR_GL_VER(4, 3) ||
3190 ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
3191 info.fFlags = FormatInfo::kTexturable_Flag;
3192 }
3193 } else if (GR_IS_GR_GL_ES(standard)) {
3194 if (version >= GR_GL_VER(3, 0) ||
3195 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture")) {
3196 info.fFlags = FormatInfo::kTexturable_Flag;
3197 }
3198 } else if (GR_IS_GR_WEBGL(standard)) {
3199 if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc")) {
3200 info.fFlags = FormatInfo::kTexturable_Flag;
3201 }
3202 }
3203 }
3204
3205 // There are no support GrColorTypes for this format
3206 }
3207
3208 // Format: COMPRESSED_ETC1_RGB8
3209 {
3210 FormatInfo& info = this->getFormatInfo(GrGLFormat::kCOMPRESSED_ETC1_RGB8);
3211 info.fFormatType = FormatType::kNormalizedFixedPoint;
3212 info.fInternalFormatForTexImageOrStorage = GR_GL_COMPRESSED_ETC1_RGB8;
3213 if (GR_IS_GR_GL_ES(standard)) {
3214 if (ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
3215 info.fFlags = FormatInfo::kTexturable_Flag;
3216 }
3217 } else if (GR_IS_GR_WEBGL(standard)) {
3218 if (ctxInfo.hasExtension("WEBGL_compressed_texture_etc1")) {
3219 info.fFlags = FormatInfo::kTexturable_Flag;
3220 }
3221 }
3222 // No GL support
3223
3224 // There are no support GrColorTypes for this format
3225 }
3226
3227 // Format: R16
3228 {
3229 FormatInfo& info = this->getFormatInfo(GrGLFormat::kR16);
3230 info.fFormatType = FormatType::kNormalizedFixedPoint;
3231 info.fInternalFormatForRenderbuffer = GR_GL_R16;
3232 info.fDefaultExternalFormat = GR_GL_RED;
3233 info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3234 info.fDefaultColorType = GrColorType::kR_16;
3235 bool r16Supported = false;
3236 if (!formatWorkarounds.fDisallowTextureUnorm16) {
3237 if (GR_IS_GR_GL(standard)) {
3238 r16Supported = version >= GR_GL_VER(3, 0) ||
3239 ctxInfo.hasExtension("GL_ARB_texture_rg");
3240 } else if (GR_IS_GR_GL_ES(standard)) {
3241 r16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3242 } // No WebGL support
3243 }
3244
3245 if (r16Supported) {
3246 info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3247 if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3248 info.fFlags |= FormatInfo::kTransfers_Flag;
3249 }
3250 }
3251
3252 if (texStorageSupported) {
3253 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3254 info.fInternalFormatForTexImageOrStorage = GR_GL_R16;
3255 } else {
3256 info.fInternalFormatForTexImageOrStorage =
3257 texImageSupportsSizedInternalFormat ? GR_GL_R16 : GR_GL_RED;
3258 }
3259
3260 if (r16Supported) {
3261 info.fColorTypeInfoCount = 1;
3262 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3263 int ctIdx = 0;
3264 // Format: R16, Surface: kAlpha_16
3265 {
3266 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3267 ctInfo.fColorType = GrColorType::kAlpha_16;
3268 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3269 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
3270 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
3271 this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
3272
3273 // External IO ColorTypes:
3274 ctInfo.fExternalIOFormatCount = 2;
3275 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3276 ctInfo.fExternalIOFormatCount);
3277 int ioIdx = 0;
3278 // Format: R16, Surface: kAlpha_16, Data: kAlpha_16
3279 {
3280 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3281 ioFormat.fColorType = GrColorType::kAlpha_16;
3282 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3283 ioFormat.fExternalTexImageFormat = GR_GL_RED;
3284 ioFormat.fExternalReadFormat = GR_GL_RED;
3285 // Not guaranteed by ES/WebGL.
3286 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3287 }
3288
3289 // Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
3290 {
3291 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3292 ioFormat.fColorType = GrColorType::kAlpha_8xxx;
3293 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3294 ioFormat.fExternalTexImageFormat = 0;
3295 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3296 }
3297 }
3298 }
3299 }
3300
3301 // Format: RG16
3302 {
3303 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16);
3304 info.fFormatType = FormatType::kNormalizedFixedPoint;
3305 info.fInternalFormatForTexImageOrStorage =
3306 texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3307 info.fInternalFormatForRenderbuffer = GR_GL_RG16;
3308 info.fDefaultExternalFormat = GR_GL_RG;
3309 info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3310 info.fDefaultColorType = GrColorType::kRG_1616;
3311 bool rg16Supported = false;
3312 if (!formatWorkarounds.fDisallowTextureUnorm16) {
3313 if (GR_IS_GR_GL(standard)) {
3314 rg16Supported = version >= GR_GL_VER(3, 0) ||
3315 ctxInfo.hasExtension("GL_ARB_texture_rg");
3316 } else if (GR_IS_GR_GL_ES(standard)) {
3317 rg16Supported = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3318 } // No WebGL support
3319 }
3320
3321 if (rg16Supported) {
3322 info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3323 if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3324 info.fFlags |= FormatInfo::kTransfers_Flag;
3325 }
3326 }
3327
3328 if (texStorageSupported) {
3329 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3330 info.fInternalFormatForTexImageOrStorage = GR_GL_RG16;
3331 } else {
3332 info.fInternalFormatForTexImageOrStorage =
3333 texImageSupportsSizedInternalFormat ? GR_GL_RG16 : GR_GL_RG;
3334 }
3335
3336 if (rg16Supported) {
3337 info.fColorTypeInfoCount = 1;
3338 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3339 int ctIdx = 0;
3340 // Format: GR_GL_RG16, Surface: kRG_1616
3341 {
3342 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3343 ctInfo.fColorType = GrColorType::kRG_1616;
3344 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3345 this->setColorTypeFormat(GrColorType::kRG_1616, GrGLFormat::kRG16);
3346
3347 // External IO ColorTypes:
3348 ctInfo.fExternalIOFormatCount = 2;
3349 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3350 ctInfo.fExternalIOFormatCount);
3351 int ioIdx = 0;
3352 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRG_1616
3353 {
3354 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3355 ioFormat.fColorType = GrColorType::kRG_1616;
3356 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3357 ioFormat.fExternalTexImageFormat = GR_GL_RG;
3358 ioFormat.fExternalReadFormat = GR_GL_RG;
3359 // Not guaranteed by ES/WebGL.
3360 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3361 }
3362
3363 // Format: GR_GL_RG16, Surface: kRG_1616, Data: kRGBA_8888
3364 {
3365 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3366 ioFormat.fColorType = GrColorType::kRGBA_8888;
3367 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3368 ioFormat.fExternalTexImageFormat = 0;
3369 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3370 }
3371 }
3372 }
3373 }
3374
3375 // Format: RGBA16
3376 {
3377 bool rgba16Support = false;
3378 if (!formatWorkarounds.fDisallowTextureUnorm16) {
3379 if (GR_IS_GR_GL(standard)) {
3380 rgba16Support = version >= GR_GL_VER(3, 0);
3381 } else if (GR_IS_GR_GL_ES(standard)) {
3382 rgba16Support = ctxInfo.hasExtension("GL_EXT_texture_norm16");
3383 } // No WebGL support
3384 }
3385
3386 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGBA16);
3387 info.fFormatType = FormatType::kNormalizedFixedPoint;
3388
3389 info.fInternalFormatForRenderbuffer = GR_GL_RGBA16;
3390 info.fDefaultExternalFormat = GR_GL_RGBA;
3391 info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT;
3392 info.fDefaultColorType = GrColorType::kRGBA_16161616;
3393 if (rgba16Support) {
3394 info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
3395 if (!formatWorkarounds.fDisallowUnorm16Transfers) {
3396 info.fFlags |= FormatInfo::kTransfers_Flag;
3397 }
3398 }
3399
3400 if (texStorageSupported) {
3401 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3402 info.fInternalFormatForTexImageOrStorage = GR_GL_RGBA16;
3403 } else {
3404 info.fInternalFormatForTexImageOrStorage =
3405 texImageSupportsSizedInternalFormat ? GR_GL_RGBA16 : GR_GL_RGBA;
3406 }
3407
3408 if (rgba16Support) {
3409 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616
3410 info.fColorTypeInfoCount = 1;
3411 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3412 int ctIdx = 0;
3413 {
3414 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3415 ctInfo.fColorType = GrColorType::kRGBA_16161616;
3416 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3417 this->setColorTypeFormat(GrColorType::kRGBA_16161616, GrGLFormat::kRGBA16);
3418
3419 // External IO ColorTypes:
3420 ctInfo.fExternalIOFormatCount = 2;
3421 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3422 ctInfo.fExternalIOFormatCount);
3423 int ioIdx = 0;
3424 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_16161616
3425 {
3426 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3427 ioFormat.fColorType = GrColorType::kRGBA_16161616;
3428 ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
3429 ioFormat.fExternalTexImageFormat = GR_GL_RGBA;
3430 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3431 // Not guaranteed by ES/WebGL.
3432 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3433 }
3434
3435 // Format: GR_GL_RGBA16, Surface: kRGBA_16161616, Data: kRGBA_8888
3436 {
3437 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3438 ioFormat.fColorType = GrColorType::kRGBA_8888;
3439 ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
3440 ioFormat.fExternalTexImageFormat = 0;
3441 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3442 }
3443 }
3444 }
3445 }
3446
3447 // Format:RG16F
3448 {
3449 bool rg16FTextureSupport = false;
3450 bool rg16FRenderTargetSupport = false;
3451 if (GR_IS_GR_GL(standard)) {
3452 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
3453 rg16FTextureSupport = true;
3454 rg16FRenderTargetSupport = true;
3455 }
3456 } else if (GR_IS_GR_GL_ES(standard)) {
3457 // It seems possible that a combination of GL_EXT_texture_rg and
3458 // GL_EXT_color_buffer_half_float might add this format to ES 2.0 but it is not entirely
3459 // clear. The latter mentions interaction but that may only be for renderbuffers as
3460 // neither adds the texture format explicitly.
3461 // GL_OES_texture_format_half_float makes no reference to RG formats.
3462 if (version >= GR_GL_VER(3, 0)) {
3463 rg16FTextureSupport = true;
3464 rg16FRenderTargetSupport = version >= GR_GL_VER(3, 2) ||
3465 ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3466 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float");
3467 }
3468 } else if (GR_IS_GR_WEBGL(standard)) {
3469 if (version >= GR_GL_VER(2, 0)) {
3470 rg16FTextureSupport = true;
3471 rg16FRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_color_buffer_half_float") ||
3472 ctxInfo.hasExtension("EXT_color_buffer_half_float") ||
3473 ctxInfo.hasExtension("GL_EXT_color_buffer_float") ||
3474 ctxInfo.hasExtension("EXT_color_buffer_float");
3475 }
3476 }
3477
3478 FormatInfo& info = this->getFormatInfo(GrGLFormat::kRG16F);
3479 info.fFormatType = FormatType::kFloat;
3480 info.fInternalFormatForRenderbuffer = GR_GL_RG16F;
3481 info.fDefaultExternalFormat = GR_GL_RG;
3482 info.fDefaultExternalType = halfFloatType;
3483 info.fDefaultColorType = GrColorType::kRG_F16;
3484 if (rg16FTextureSupport) {
3485 info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
3486 if (rg16FRenderTargetSupport) {
3487 info.fFlags |= fpRenderFlags;
3488 }
3489 }
3490
3491 if (texStorageSupported) {
3492 info.fFlags |= FormatInfo::kUseTexStorage_Flag;
3493 info.fInternalFormatForTexImageOrStorage = GR_GL_RG16F;
3494 } else {
3495 info.fInternalFormatForTexImageOrStorage =
3496 texImageSupportsSizedInternalFormat ? GR_GL_RG16F : GR_GL_RG;
3497 }
3498
3499 if (rg16FTextureSupport) {
3500 info.fColorTypeInfoCount = 1;
3501 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
3502 int ctIdx = 0;
3503 // Format: GR_GL_RG16F, Surface: kRG_F16
3504 {
3505 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
3506 ctInfo.fColorType = GrColorType::kRG_F16;
3507 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
3508 this->setColorTypeFormat(GrColorType::kRG_F16, GrGLFormat::kRG16F);
3509
3510 // External IO ColorTypes:
3511 ctInfo.fExternalIOFormatCount = 2;
3512 ctInfo.fExternalIOFormats = std::make_unique<ColorTypeInfo::ExternalIOFormats[]>(
3513 ctInfo.fExternalIOFormatCount);
3514 int ioIdx = 0;
3515 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRG_F16
3516 {
3517 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3518 ioFormat.fColorType = GrColorType::kRG_F16;
3519 ioFormat.fExternalType = halfFloatType;
3520 ioFormat.fExternalTexImageFormat = GR_GL_RG;
3521 ioFormat.fExternalReadFormat = GR_GL_RG;
3522 // Not guaranteed by ES/WebGL.
3523 ioFormat.fRequiresImplementationReadQuery = !GR_IS_GR_GL(standard);
3524 }
3525
3526 // Format: GR_GL_RG16F, Surface: kRG_F16, Data: kRGBA_F32
3527 {
3528 auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
3529 ioFormat.fColorType = GrColorType::kRGBA_F32;
3530 ioFormat.fExternalType = GR_GL_FLOAT;
3531 ioFormat.fExternalTexImageFormat = 0;
3532 ioFormat.fExternalReadFormat = GR_GL_RGBA;
3533 }
3534 }
3535 }
3536 }
3537
3538 this->setupSampleCounts(ctxInfo, gli);
3539
3540 #ifdef SK_DEBUG
3541 for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3542 if (GrGLFormat::kUnknown == static_cast<GrGLFormat>(i)) {
3543 continue;
3544 }
3545 const auto& formatInfo = fFormatTable[i];
3546 // Make sure we didn't set fbo attachable with msaa and not fbo attachable.
3547 SkASSERT(!((formatInfo.fFlags & FormatInfo::kFBOColorAttachmentWithMSAA_Flag) &&
3548 !(formatInfo.fFlags & FormatInfo::kFBOColorAttachment_Flag)));
3549
3550 // Make sure we set all the formats' FormatType
3551 SkASSERT(formatInfo.fFormatType != FormatType::kUnknown);
3552
3553 // Make sure if we added a ColorTypeInfo we filled it out
3554 for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
3555 const auto& ctInfo = formatInfo.fColorTypeInfos[j];
3556 SkASSERT(ctInfo.fColorType != GrColorType::kUnknown);
3557 // Seems silly to add a color type if we don't support any flags on it.
3558 SkASSERT(ctInfo.fFlags);
3559 // Make sure if we added any ExternalIOFormats we filled it out
3560 for (int k = 0; k < ctInfo.fExternalIOFormatCount; ++k) {
3561 const auto& ioInfo = ctInfo.fExternalIOFormats[k];
3562 SkASSERT(ioInfo.fColorType != GrColorType::kUnknown);
3563 }
3564 }
3565 }
3566 #endif
3567 }
3568
setupSampleCounts(const GrGLContextInfo & ctxInfo,const GrGLInterface * gli)3569 void GrGLCaps::setupSampleCounts(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
3570 GrGLStandard standard = ctxInfo.standard();
3571 // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set
3572 sk_ignore_unused_variable(standard);
3573 GrGLVersion version = ctxInfo.version();
3574
3575 int maxSampleCnt = 1;
3576 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
3577 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
3578 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
3579 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
3580 }
3581 // Chrome has a mock GL implementation that returns 0.
3582 maxSampleCnt = std::max(1, maxSampleCnt);
3583
3584 for (int i = 0; i < kGrGLColorFormatCount; ++i) {
3585 if (FormatInfo::kFBOColorAttachmentWithMSAA_Flag & fFormatTable[i].fFlags) {
3586 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
3587 SkASSERT(FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags);
3588 SkASSERT(GrGLCaps::kNone_MSFBOType != fMSFBOType);
3589 if ((GR_IS_GR_GL(standard) &&
3590 (version >= GR_GL_VER(4,2) ||
3591 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
3592 (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3,0))) {
3593 // Implicite resolve may have a lower max samples than the per format MSAA.
3594 const bool multisampleIsImplicit =
3595 GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
3596 GrGLCaps::kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
3597 int count;
3598 GrGLFormat grGLFormat = static_cast<GrGLFormat>(i);
3599 GrGLenum glFormat = this->getRenderbufferInternalFormat(grGLFormat);
3600 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat,
3601 GR_GL_NUM_SAMPLE_COUNTS, 1, &count);
3602 if (count) {
3603 std::unique_ptr<int[]> temp(new int[count]);
3604 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_SAMPLES,
3605 count, temp.get());
3606 // GL has a concept of MSAA rasterization with a single sample but we do not.
3607 if (count && temp[count - 1] == 1) {
3608 --count;
3609 SkASSERT(!count || temp[count -1] > 1);
3610 }
3611 fFormatTable[i].fColorSampleCounts.reserve(count + 1);
3612 // We initialize our supported values with 1 (no msaa) and reverse the order
3613 // returned by GL so that the array is ascending.
3614 fFormatTable[i].fColorSampleCounts.push_back(1);
3615 for (int j = 0; j < count; ++j) {
3616 #if defined(SK_BUILD_FOR_IOS) && TARGET_OS_SIMULATOR
3617 // The iOS simulator is reporting incorrect values for sample counts,
3618 // so force them to be a power of 2.
3619 int sampleCnt = SkPrevPow2(temp[count - j - 1]);
3620 #else
3621 int sampleCnt = temp[count - j - 1];
3622 #endif
3623 if (multisampleIsImplicit && sampleCnt > maxSampleCnt) {
3624 break;
3625 }
3626 fFormatTable[i].fColorSampleCounts.push_back(sampleCnt);
3627 }
3628 }
3629 } else {
3630 // Fake out the table using some semi-standard counts up to the max allowed sample
3631 // count.
3632 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
3633 int count = std::size(kDefaultSamples);
3634 for (; count > 0; --count) {
3635 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
3636 break;
3637 }
3638 }
3639 if (count > 0) {
3640 fFormatTable[i].fColorSampleCounts.append(count, kDefaultSamples);
3641 }
3642 }
3643 } else if (FormatInfo::kFBOColorAttachment_Flag & fFormatTable[i].fFlags) {
3644 fFormatTable[i].fColorSampleCounts.resize(1);
3645 fFormatTable[i].fColorSampleCounts[0] = 1;
3646 }
3647 }
3648 }
3649
canCopyTexSubImage(GrGLFormat dstFormat,bool dstHasMSAARenderBuffer,const GrTextureType * dstTypeIfTexture,GrGLFormat srcFormat,bool srcHasMSAARenderBuffer,const GrTextureType * srcTypeIfTexture) const3650 bool GrGLCaps::canCopyTexSubImage(GrGLFormat dstFormat, bool dstHasMSAARenderBuffer,
3651 const GrTextureType* dstTypeIfTexture,
3652 GrGLFormat srcFormat, bool srcHasMSAARenderBuffer,
3653 const GrTextureType* srcTypeIfTexture) const {
3654 // When it comes to format types and component sizes the gl spec is fairly complex as
3655 // requirements differ depending on many properties (e.g. if the internalFormat was created with
3656 // a sized format or not). These affect the rules about which format types can be copied to
3657 // which other types. For now we are being more restrictive and requiring that the types must
3658 // match exactly.
3659 if (this->getFormatDefaultExternalType(dstFormat) !=
3660 this->getFormatDefaultExternalType(srcFormat)) {
3661 return false;
3662 }
3663
3664 // Either both the src and dst formats need to be SRGB or both need to not be SRGB
3665 if (GrGLFormatIsSRGB(dstFormat) != GrGLFormatIsSRGB(srcFormat)) {
3666 return false;
3667 }
3668
3669 if (GR_IS_GR_GL_ES(fStandard)) {
3670 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3671 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it.
3672 // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3673 // avoids bugs with using glBlitFramebuffer.
3674 if ((dstFormat == GrGLFormat::kBGRA8 || srcFormat == GrGLFormat::kBGRA8) &&
3675 !fAllowBGRA8CopyTexSubImage) {
3676 return false;
3677 }
3678
3679 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
3680 // and SRGB isn't in the spec. There doesn't appear to be any extension that adds it.
3681 // ANGLE, for one, does not allow it. However, we've found it works on some drivers and
3682 // avoids bugs with using glBlitFramebuffer.
3683 if ((GrGLFormatIsSRGB(dstFormat) || GrGLFormatIsSRGB(srcFormat)) &&
3684 !fAllowSRGBCopyTexSubImage) {
3685 return false;
3686 }
3687
3688 // Table 3.9 of the ES2 spec and 3.16 of ES3 spec indicates the supported internal base
3689 // formats with CopyTexSubImage. Each base format can be copied to itself or formats with
3690 // less channels.
3691 uint32_t dstChannels = GrGLFormatChannels(dstFormat);
3692 uint32_t srcChannels = GrGLFormatChannels(srcFormat);
3693 if (!dstChannels || !srcChannels) {
3694 // The formats don't represent color channels (i.e. may be depth stencil)
3695 return false;
3696 }
3697 // The dst channels have to be a subset of the srcChannels, except R, RG, or RGB, channels
3698 // can go to LUM. (See expansion of Table 3.9 in EXT_texture_rg).
3699 if ((dstChannels & srcChannels) != srcChannels) {
3700 if (dstChannels == kGray_SkColorChannelFlag ||
3701 dstChannels == kGrayAlpha_SkColorChannelFlags) {
3702 // The dst can't have gray if the src is alpha-only.
3703 if (srcChannels == kAlpha_SkColorChannelFlag) {
3704 return false;
3705 }
3706 } else {
3707 return false;
3708 }
3709 }
3710 }
3711
3712 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
3713 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
3714 return false;
3715 }
3716
3717 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
3718 // texture.
3719 if (!dstTypeIfTexture) {
3720 return false;
3721 }
3722
3723 // Check that we could wrap the source in an FBO, that the dst is not TEXTURE_EXTERNAL, that no
3724 // mirroring is required
3725 return this->canFormatBeFBOColorAttachment(srcFormat) &&
3726 (!srcTypeIfTexture || *srcTypeIfTexture != GrTextureType::kExternal) &&
3727 *dstTypeIfTexture != GrTextureType::kExternal;
3728 }
3729
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) const3730 bool GrGLCaps::canCopyAsBlit(GrGLFormat dstFormat, int dstSampleCnt,
3731 const GrTextureType* dstTypeIfTexture,
3732 GrGLFormat srcFormat, int srcSampleCnt,
3733 const GrTextureType* srcTypeIfTexture,
3734 const SkRect& srcBounds, bool srcBoundsExact,
3735 const SkIRect& srcRect, const SkIRect& dstRect) const {
3736 auto blitFramebufferFlags = fBlitFramebufferFlags;
3737 if (!this->canFormatBeFBOColorAttachment(dstFormat) ||
3738 !this->canFormatBeFBOColorAttachment(srcFormat)) {
3739 return false;
3740 }
3741
3742 if (dstTypeIfTexture && *dstTypeIfTexture == GrTextureType::kExternal) {
3743 return false;
3744 }
3745 if (srcTypeIfTexture && *srcTypeIfTexture == GrTextureType::kExternal) {
3746 return false;
3747 }
3748
3749 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
3750 return false;
3751 }
3752
3753 if (dstSampleCnt > 1 && dstSampleCnt != srcSampleCnt) {
3754 // Regardless of support-level, all blits require src and dst sample counts to match if
3755 // the dst is MSAA.
3756 return false;
3757 }
3758
3759 if (srcRect.width() != dstRect.width() || srcRect.height() != dstRect.height()) {
3760 // If the blit would scale contents, it's only valid for non-MSAA framebuffers that we
3761 // can write directly to.
3762 if ((GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) ||
3763 this->useDrawInsteadOfAllRenderTargetWrites() || srcSampleCnt > 1) {
3764 return false;
3765 }
3766 }
3767
3768 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
3769 if (srcSampleCnt > 1) {
3770 if (1 == dstSampleCnt) {
3771 return false;
3772 }
3773 if (SkRect::Make(srcRect) != srcBounds || !srcBoundsExact) {
3774 return false;
3775 }
3776 }
3777 }
3778
3779 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
3780 if (dstSampleCnt > 1) {
3781 return false;
3782 }
3783 }
3784
3785 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
3786 if (srcFormat != dstFormat) {
3787 return false;
3788 }
3789 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3790 if (srcSampleCnt > 1 && srcFormat != dstFormat) {
3791 return false;
3792 }
3793 }
3794
3795 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
3796 if (srcSampleCnt > 1) {
3797 if (dstRect != srcRect) {
3798 return false;
3799 }
3800 }
3801 }
3802 return true;
3803 }
3804
canCopyAsDraw(GrGLFormat dstFormat,bool srcIsTexturable,bool scalingCopy) const3805 bool GrGLCaps::canCopyAsDraw(GrGLFormat dstFormat, bool srcIsTexturable, bool scalingCopy) const {
3806 return this->isFormatRenderable(dstFormat, 1) &&
3807 srcIsTexturable &&
3808 !(fDisableScalingCopyAsDraws && scalingCopy);
3809 }
3810
has_msaa_render_buffer(const GrSurfaceProxy * surf,const GrGLCaps & glCaps)3811 static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
3812 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
3813 if (!rt) {
3814 return false;
3815 }
3816 // A RT has a separate MSAA renderbuffer if:
3817 // 1) It's multisampled
3818 // 2) We're using an extension with separate MSAA renderbuffers
3819 // 3) It's not FBO 0, which is special and always auto-resolves
3820 return rt->numSamples() > 1 &&
3821 glCaps.usesMSAARenderBuffers() &&
3822 !rt->glRTFBOIDIs0();
3823 }
3824
onCanCopySurface(const GrSurfaceProxy * dst,const SkIRect & dstRect,const GrSurfaceProxy * src,const SkIRect & srcRect) const3825 bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
3826 const GrSurfaceProxy* src, const SkIRect& srcRect) const {
3827 if (src->isProtected() == GrProtected::kYes && dst->isProtected() != GrProtected::kYes) {
3828 return false;
3829 }
3830
3831 int dstSampleCnt = 0;
3832 int srcSampleCnt = 0;
3833 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
3834 dstSampleCnt = rtProxy->numSamples();
3835 }
3836 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
3837 srcSampleCnt = rtProxy->numSamples();
3838 }
3839 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
3840 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
3841
3842 const GrTextureProxy* dstTex = dst->asTextureProxy();
3843 const GrTextureProxy* srcTex = src->asTextureProxy();
3844
3845 GrTextureType dstTexType;
3846 GrTextureType* dstTexTypePtr = nullptr;
3847 GrTextureType srcTexType;
3848 GrTextureType* srcTexTypePtr = nullptr;
3849 if (dstTex) {
3850 dstTexType = dstTex->textureType();
3851 dstTexTypePtr = &dstTexType;
3852 }
3853 if (srcTex) {
3854 srcTexType = srcTex->textureType();
3855 srcTexTypePtr = &srcTexType;
3856 }
3857
3858 auto dstFormat = GrBackendFormats::AsGLFormat(dst->backendFormat());
3859 auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3860 // Only copyAsBlit() and copyAsDraw() can handle scaling between src and dst.
3861 const bool scalingCopy = srcRect.size() != dstRect.size();
3862 if (!scalingCopy &&
3863 this->canCopyTexSubImage(dstFormat, has_msaa_render_buffer(dst, *this), dstTexTypePtr,
3864 srcFormat, has_msaa_render_buffer(src, *this), srcTexTypePtr)) {
3865 return true;
3866 }
3867 return this->canCopyAsBlit(dstFormat, dstSampleCnt, dstTexTypePtr, srcFormat, srcSampleCnt,
3868 srcTexTypePtr, src->getBoundsRect(), src->priv().isExact(), srcRect,
3869 dstRect) ||
3870 this->canCopyAsDraw(dstFormat, SkToBool(srcTex), scalingCopy);
3871 }
3872
getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType colorType) const3873 GrCaps::DstCopyRestrictions GrGLCaps::getDstCopyRestrictions(const GrRenderTargetProxy* src,
3874 GrColorType colorType) const {
3875 // If the src is a texture, we can implement the blit as a draw assuming the config is
3876 // renderable.
3877 if (src->asTextureProxy() && !this->isFormatAsColorTypeRenderable(colorType,
3878 src->backendFormat())) {
3879 return {};
3880 }
3881
3882 if (const auto* texProxy = src->asTextureProxy()) {
3883 if (texProxy->textureType() == GrTextureType::kExternal) {
3884 // Not supported for FBO blit or CopyTexSubImage. Caller will have to fall back to a
3885 // draw (if the source is also a texture).
3886 return {};
3887 }
3888 }
3889
3890 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
3891 // possible and we return false to fallback to creating a render target dst for render-to-
3892 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
3893 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
3894 DstCopyRestrictions blitFramebufferRestrictions = {};
3895 if (src->numSamples() > 1 &&
3896 (fBlitFramebufferFlags & kResolveMustBeFull_BlitFrambufferFlag)) {
3897 blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3898 blitFramebufferRestrictions.fMustCopyWholeSrc = true;
3899 // Mirroring causes rects to mismatch later, don't allow it.
3900 } else if (src->numSamples() > 1 && (fBlitFramebufferFlags &
3901 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
3902 blitFramebufferRestrictions.fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kYes;
3903 }
3904
3905 auto srcFormat = GrBackendFormats::AsGLFormat(src->backendFormat());
3906 // Check for format issues with glCopyTexSubImage2D
3907 if (srcFormat == GrGLFormat::kBGRA8) {
3908 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
3909 // then we set up for that, otherwise fail.
3910 if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3911 return blitFramebufferRestrictions;
3912 }
3913 // Caller will have to use a draw.
3914 return {};
3915 }
3916
3917 {
3918 bool srcIsMSAARenderbuffer = src->numSamples() > 1 &&
3919 this->usesMSAARenderBuffers();
3920 if (srcIsMSAARenderbuffer) {
3921 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
3922 // blit or fail.
3923 if (this->canFormatBeFBOColorAttachment(srcFormat)) {
3924 return blitFramebufferRestrictions;
3925 }
3926 // Caller will have to use a draw.
3927 return {};
3928 }
3929 }
3930
3931 // We'll do a CopyTexSubImage, no restrictions.
3932 return {};
3933 }
3934
applyDriverCorrectnessWorkarounds(const GrGLContextInfo & ctxInfo,const GrContextOptions & contextOptions,const GrGLInterface * glInterface,GrShaderCaps * shaderCaps,FormatWorkarounds * formatWorkarounds)3935 void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
3936 const GrContextOptions& contextOptions,
3937 const GrGLInterface* glInterface,
3938 GrShaderCaps* shaderCaps,
3939 FormatWorkarounds* formatWorkarounds) {
3940 // A driver bug on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
3941 // Thus we are disabling this extension for now on Adreno4xx devices.
3942 if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
3943 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
3944 fDriverBugWorkarounds.disable_discard_framebuffer) {
3945 fInvalidateFBType = kNone_InvalidateFBType;
3946 }
3947
3948 if (ctxInfo.renderer() == GrGLRenderer::kIntelCherryView) {
3949 // When running DMSAA_dst_read_with_existing_barrier with DMSAA disabled on linux Intel
3950 // HD405, the test fails when using texture barriers. Oddly the gpu doing the draw which
3951 // uses the barrier correctly. It is the next draw, which does not use or need a barrier,
3952 // that is blending with a dst as if the barrier draw didn't happen. Since this GPU is not
3953 // that important to us and this driver bug could probably manifest itself in the wild, we
3954 // are just disabling texture barrier support for the gpu.
3955 fTextureBarrierSupport = false;
3956 }
3957
3958 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
3959 // 340.96 and 367.57.
3960 if (GR_IS_GR_GL(ctxInfo.standard()) && ctxInfo.driver() == GrGLDriver::kNVIDIA &&
3961 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
3962 fClearTextureSupport = false;
3963 }
3964
3965 // glBlitFramebuffer seems to produce incorrect results on QC, Mali400, and Tegra3 but
3966 // glCopyTexSubImage2D works (even though there is no extension that specifically allows it).
3967 if (ctxInfo.vendor() == GrGLVendor::kQualcomm ||
3968 ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
3969 ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3970 fAllowBGRA8CopyTexSubImage = true;
3971 }
3972 // glCopyTexSubImage2D works for sRGB with GLES 3.0 and on some GPUs with GLES 2.0
3973 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
3974 ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
3975 ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
3976 fAllowSRGBCopyTexSubImage = true;
3977 }
3978
3979 // http://anglebug.com/6030
3980 if (fMSFBOType == kES_EXT_MsToTexture_MSFBOType &&
3981 ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
3982 // As GL_EXT_multisampled_render_to_texture supporting issue,
3983 // fall back to default dmsaa path
3984 if ((ctxInfo.vendor() == GrGLVendor::kIntel ||
3985 ctxInfo.angleVendor() == GrGLVendor::kIntel) &&
3986 ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake) {
3987 fMSFBOType = kStandard_MSFBOType;
3988 fMSAAResolvesAutomatically = false;
3989 }
3990 else {
3991 fDisallowDynamicMSAA = true;
3992 }
3993 }
3994
3995 // http://skbug.com/12081
3996 if (GR_IS_GR_WEBGL(ctxInfo.standard())) {
3997 fDisallowDynamicMSAA = true;
3998 }
3999
4000 // Below we are aggressive about turning off all mapping/transfer functionality together. This
4001 // could be finer grained if code paths and tests were adjusted to check more specific caps.
4002 // For example it might be possible to support buffer to buffer transfers even if buffer mapping
4003 // or buffer to surface transfers don't work.
4004 #if defined(__has_feature)
4005 #if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
4006 // See skbug.com/7058
4007 fMapBufferType = kNone_MapBufferType;
4008 fMapBufferFlags = kNone_MapFlags;
4009 fTransferFromBufferToTextureSupport = false;
4010 fTransferFromSurfaceToBufferSupport = false;
4011 fTransferFromBufferToBufferSupport = false;
4012 fTransferBufferType = TransferBufferType::kNone;
4013 #endif
4014 #endif
4015
4016 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
4017 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
4018 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
4019 // unclear whether this really affects a wide range of devices.
4020 if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4021 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
4022 fMapBufferType = kNone_MapBufferType;
4023 fMapBufferFlags = kNone_MapFlags;
4024 fTransferFromBufferToTextureSupport = false;
4025 fTransferFromSurfaceToBufferSupport = false;
4026 fTransferFromBufferToBufferSupport = false;
4027 fTransferBufferType = TransferBufferType::kNone;
4028 }
4029
4030 // The TransferPixelsToTexture test fails on ANGLE D3D9 and D3D11 if this is enabled.
4031 // https://anglebug.com/5542
4032 if (angle_backend_is_d3d(ctxInfo.angleBackend())) {
4033 fTransferPixelsToRowBytesSupport = false;
4034 }
4035
4036 // Using MIPs on this GPU seems to be a source of trouble.
4037 if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4038 fMipmapSupport = false;
4039 }
4040
4041 #ifdef SK_BUILD_FOR_ANDROID
4042 if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x) {
4043 // Flutter found glTexSubImage2D for GL_RED is much slower than GL_ALPHA on the
4044 // "MC18 PERSONAL SHOPPER"
4045 formatWorkarounds->fDisallowR8ForPowerVRSGX54x = true;
4046 }
4047 #endif
4048
4049 // Reported on skia-discuss as occurring with these GL strings:
4050 // GL_VERSION: 3.1.0 - Build 9.17.10.4459
4051 // GL_VENDOR: Intel
4052 // GL_RENDERER: Intel(R) HD Graphics 2000
4053 // https://groups.google.com/g/skia-discuss/c/dYV1blEAda0/m/-zuZLXQKAwAJ?utm_medium=email&utm_source=footer
4054 // See also http://skbug.com/9286
4055 if (ctxInfo.renderer() == GrGLRenderer::kIntelSandyBridge &&
4056 ctxInfo.driver() == GrGLDriver::kIntel) {
4057 fMapBufferType = kNone_MapBufferType;
4058 fMapBufferFlags = kNone_MapFlags;
4059 // On skia-discuss it was reported that after turning off mapping there was this
4060 // shader compilation error.
4061 // ERROR: 0:18: 'assign' : cannot convert from '3-component vector of float' to 'varying 2-component vector of float'
4062 // for this line:
4063 // vTransformedCoords_5_S0 = mat3x2(umatrix_S1_c0_c1) * vec3(_tmp_2_inPosition, 1.0);
4064 fShaderCaps->fNonsquareMatrixSupport = false;
4065 }
4066
4067 if (ctxInfo.isOverCommandBuffer() && ctxInfo.version() >= GR_GL_VER(3,0)) {
4068 formatWorkarounds->fDisallowTextureUnorm16 = true; // http://crbug.com/1224108
4069 formatWorkarounds->fDisallowETC2Compression = true; // http://crbug.com/1224111
4070 fTransferFromSurfaceToBufferSupport = false; // http://crbug.com/1224138
4071
4072 // http://crbug.com/1224117
4073 fMapBufferFlags = kNone_MapFlags;
4074 fMapBufferType = kNone_MapBufferType;
4075 }
4076
4077 // https://b.corp.google.com/issues/143074513
4078 // https://skbug.com/11152
4079 if (ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4080 ctxInfo.renderer() == GrGLRenderer::kAdreno620) {
4081 fMSFBOType = kNone_MSFBOType;
4082 fMSAAResolvesAutomatically = false;
4083 }
4084
4085 #ifndef SK_BUILD_FOR_IOS
4086 if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x ||
4087 ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue ||
4088 (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx && !ctxInfo.isOverCommandBuffer())) {
4089 fPerformColorClearsAsDraws = true;
4090 }
4091 #endif
4092
4093 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
4094 if (ctxInfo.renderer() == GrGLRenderer::kAMDRadeonHD7xxx ||
4095 ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M4xx) {
4096 fPerformColorClearsAsDraws = true;
4097 }
4098
4099 #ifdef SK_BUILD_FOR_MAC
4100 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
4101 // full screen clears
4102 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
4103 // perform full screen clears.
4104 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
4105 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
4106 // crbug.com/1039912 - Crash rate in glClear spiked after OS update, affecting mostly
4107 // Broadwell on 10.13+
4108 if (ctxInfo.vendor() == GrGLVendor::kIntel &&
4109 (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12) ||
4110 ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell)) {
4111 fPerformColorClearsAsDraws = true;
4112 }
4113 // crbug.com/969609 - NVIDIA on Mac sometimes segfaults during glClear in chrome. It seems
4114 // mostly concentrated in 10.13/14, GT 650Ms, driver 12+. But there are instances of older
4115 // drivers and GTX 775s, so we'll start with a broader workaround.
4116 if (ctxInfo.vendor() == GrGLVendor::kNVIDIA) {
4117 fPerformColorClearsAsDraws = true;
4118 }
4119 #endif
4120
4121 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
4122 // bugs seems to involve clearing too much and not skipping the clear.
4123 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
4124 // but only for D3D11 ANGLE.
4125 if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4126 fPerformColorClearsAsDraws = true;
4127 }
4128
4129 if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4130 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4131 // This is known to be fixed sometime between driver 145.0 and 219.0
4132 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
4133 fPerformStencilClearsAsDraws = true;
4134 }
4135 // This is known to be fixed sometime between driver 129.0 and 145.0 on Nexus 6P.
4136 // On driver 129 on Android M it fails the unit tests called WritePixelsPendingIO without
4137 // the workaround. It passes on Android N with driver 145 without the workaround.
4138 // skbug.com/11834
4139 if (ctxInfo.driverVersion() < GR_GL_DRIVER_VER(145, 0, 0)) {
4140 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4141 }
4142 }
4143
4144 if (fDriverBugWorkarounds.gl_clear_broken) {
4145 fPerformColorClearsAsDraws = true;
4146 fPerformStencilClearsAsDraws = true;
4147 }
4148
4149 if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4150 // It appears that all the Adreno GPUs have less than optimal performance when
4151 // drawing w/ large index buffers.
4152 fAvoidLargeIndexBufferDraws = true;
4153 }
4154
4155 if (ctxInfo.renderer() == GrGLRenderer::kMali4xx ||
4156 (ctxInfo.renderer() == GrGLRenderer::kWebGL &&
4157 ctxInfo.webglRenderer() == GrGLRenderer::kMali4xx)) {
4158 // Perspective SDF text runs significantly slower on Mali-4xx hardware
4159 fDisablePerspectiveSDFText = true;
4160 }
4161
4162 // This was reproduced on the following configurations:
4163 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
4164 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
4165 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
4166 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
4167 // and not produced on:
4168 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
4169 // The particular lines that get dropped from test images varies across different devices.
4170 if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4171 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
4172 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
4173 }
4174
4175 // TODO: Don't apply this on iOS?
4176 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4177 // Our Chromebook with GrGLRenderer::kPowerVRRogue crashes on large instanced draws. The
4178 // current minimum number of instances observed to crash is somewhere between 2^14 and 2^15.
4179 // Keep the number of instances below 1000, just to be safe.
4180 fMaxInstancesPerDrawWithoutCrashing = 999;
4181 } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
4182 fMaxInstancesPerDrawWithoutCrashing = 0x4000000;
4183 }
4184
4185 #ifndef SK_BUILD_FOR_IOS
4186 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4187 // We saw this bug on a TecnoSpark 3 Pro with a PowerVR GE8300.
4188 // GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4189 // Possibly this could be more limited by driver version or HW generation.
4190 // When using samplers, we are seeing a bug where the gpu is sometimes not sampling the
4191 // correct mip level data. A workaround to this issue is that when binding a texture we also
4192 // set some texture state, and it seems like any inividual state works (e.g. min/mag filter,
4193 // base level, max level, etc.). Currently we just set the min filter level every time we
4194 // bind a texture as the workaround.
4195 fMustSetAnyTexParameterToEnableMipmapping = true;
4196 // ColorTypeBackendAllocationTest failed for kAlpha_8 and kGray_8 when using
4197 // GL_UNPACK_ROW_LENGTH. Perhaps this could be a more limited workaround by applying
4198 // only to single channel 8 bit unorm formats but we only have a monolithic query for this
4199 // support at present.
4200 fWritePixelsRowBytesSupport = false;
4201 // TransferPixelsToTextureTest fails for all color types on
4202 // TecnoSpark 3 Pro with a PowerVR GE8300, GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
4203 // if GL_UNPACK_ROW_LENGTH is used.
4204 fTransferPixelsToRowBytesSupport = false;
4205 }
4206 #endif
4207
4208 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
4209 if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4210 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
4211 fUseDrawInsteadOfAllRenderTargetWrites = true;
4212 }
4213
4214 #ifdef SK_BUILD_FOR_MAC
4215 static constexpr bool isMAC = true;
4216 #else
4217 static constexpr bool isMAC = false;
4218 #endif
4219
4220 #ifdef SK_BUILD_FOR_ANDROID
4221 // Older versions of Android have problems with setting GL_TEXTURE_BASE_LEVEL or
4222 // GL_TEXTURE_MAX_LEVEL on GL_TEXTURE_EXTERTNAL_OES textures. We just leave them as is and hope
4223 // the client never changes them either.
4224 fDontSetBaseOrMaxLevelForExternalTextures = true;
4225 // PowerVR can crash setting the levels on Android up to Q for any texture?
4226 // https://crbug.com/1123874
4227 if (ctxInfo.vendor() == GrGLVendor::kImagination) {
4228 fMipmapLevelControlSupport = false;
4229 }
4230 #endif
4231
4232 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
4233 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
4234 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
4235 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
4236 if (fMipmapLevelControlSupport &&
4237 !ctxInfo.isOverCommandBuffer() && // http://crbug.com/1224110
4238 (contextOptions.fDoManualMipmapping ||
4239 ctxInfo.vendor() == GrGLVendor::kIntel ||
4240 (ctxInfo.driver() == GrGLDriver::kNVIDIA && isMAC) ||
4241 ctxInfo.vendor() == GrGLVendor::kATI)) {
4242 fDoManualMipmapping = true;
4243 }
4244
4245 // See http://crbug.com/710443
4246 #ifdef SK_BUILD_FOR_MAC
4247 if (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell) {
4248 fClearToBoundaryValuesIsBroken = true;
4249 }
4250 #endif
4251 if (ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4252 fDrawArraysBaseVertexIsBroken = true;
4253 }
4254
4255 // b/40043081, b/40045491: indirect draws in ANGLE + D3D are very slow
4256 if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 ||
4257 ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D11) {
4258 fBaseVertexBaseInstanceSupport = false;
4259 fNativeDrawIndirectSupport = false;
4260 fMultiDrawType = MultiDrawType::kNone;
4261 }
4262
4263 // https://b.corp.google.com/issues/188410972
4264 if (ctxInfo.isRunningOverVirgl()) {
4265 fDrawInstancedSupport = false;
4266 }
4267
4268 // http://anglebug.com/4538
4269 if (fBaseVertexBaseInstanceSupport && !fDrawInstancedSupport) {
4270 fBaseVertexBaseInstanceSupport = false;
4271 fNativeDrawIndirectSupport = false;
4272 fMultiDrawType = MultiDrawType::kNone;
4273 }
4274
4275 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
4276 // Galaxy S7.
4277 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
4278 if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4279 ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other) {
4280 shaderCaps->fFBFetchSupport = false;
4281 }
4282
4283 if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4284 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
4285 // so we must do the abs first in a separate expression.
4286 shaderCaps->fCanUseMinAndAbsTogether = false;
4287
4288 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
4289 // must avoid this condition.
4290 shaderCaps->fCanUseFractForNegativeValues = false;
4291 }
4292
4293 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
4294 // thus must us -1.0 * %s.x to work correctly
4295 if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4296 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
4297 }
4298
4299 #if defined(SK_BUILD_FOR_MAC)
4300 if (ctxInfo.vendor() == GrGLVendor::kATI) {
4301 // The Radeon GLSL compiler on Mac gets confused by ldexp(..., -x).
4302 // Convert to ldexp(..., x * -1).
4303 // http://skbug.com/12076
4304 shaderCaps->fMustForceNegatedLdexpParamToMultiply = true;
4305 }
4306 #endif
4307
4308 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
4309 // when floor and abs are called on the same line. Thus we must execute an Op between them to
4310 // make sure the compiler doesn't re-inline them even if we break the calls apart.
4311 if (ctxInfo.vendor() == GrGLVendor::kIntel) {
4312 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
4313 }
4314
4315 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
4316 // the original dst color when reading the outColor even after being written to. By using a
4317 // local outColor we can work around this bug.
4318 if (shaderCaps->fFBFetchSupport && ctxInfo.vendor() == GrGLVendor::kQualcomm) {
4319 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
4320 }
4321
4322 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
4323 // color, and that uniform contains an opaque color, and the output of the shader is only based
4324 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
4325 // that the shader always outputs opaque values. In that case, it appears to remove the shader
4326 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
4327 // insert an extra bit of math on the uniform that confuses the compiler just enough...
4328 if (ctxInfo.renderer() == GrGLRenderer::kMaliT) {
4329 shaderCaps->fMustObfuscateUniformColor = true;
4330 }
4331
4332 #if defined(SK_BUILD_FOR_ANDROID)
4333 // On the following GPUs, the Perlin noise code needs to aggressively snap to multiples
4334 // of 1/255 to avoid artifacts in the double table lookup:
4335 // Tegra3, PowerVRGE8320 (Wembley), MaliG76, and Adreno308
4336 // Given the range of vendors we're just blanket enabling it on Android for OpenGL.
4337 fShaderCaps->fPerlinNoiseRoundingFix = true;
4338 #endif
4339
4340 // On Mali 400 there is a bug using dFd* in the x direction. So we avoid using it when possible.
4341 if (ctxInfo.renderer() == GrGLRenderer::kMali4xx) {
4342 fShaderCaps->fAvoidDfDxForGradientsWhenPossible = true;
4343 }
4344
4345 #ifdef SK_BUILD_FOR_WIN
4346 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
4347 //
4348 // Basically, if a shader has a construct like:
4349 //
4350 // float x = someCondition ? someValue : 0;
4351 // float2 result = (0 == x) ? float2(x, x)
4352 // : float2(2 * x / x, 0);
4353 //
4354 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
4355 // we've explicitly guarded the division with a check against zero. This manifests in much
4356 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
4357 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
4358 if (angle_backend_is_d3d(ctxInfo.angleBackend()) || ctxInfo.isOverCommandBuffer()) {
4359 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
4360 }
4361 #endif
4362
4363 // The Adreno 5xx and 6xx produce incorrect results when comparing a pair of matrices.
4364 if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4365 ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4366 ctxInfo.renderer() == GrGLRenderer::kAdreno615 ||
4367 ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4368 ctxInfo.renderer() == GrGLRenderer::kAdreno630 ||
4369 ctxInfo.renderer() == GrGLRenderer::kAdreno640 ||
4370 ctxInfo.renderer() == GrGLRenderer::kAdreno6xx_other) {
4371 shaderCaps->fRewriteMatrixComparisons = true;
4372 }
4373
4374 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
4375 // (rare) situations. It's sporadic, and mostly on older drivers. Additionally, old Adreno
4376 // compilers (see crbug.com/skia/4078) crash when accessing .zw of gl_FragCoord, so just bypass
4377 // using gl_FragCoord at all to get around it.
4378 if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4379 shaderCaps->fCanUseFragCoord = false;
4380 }
4381
4382 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
4383 if (ctxInfo.renderer() == GrGLRenderer::kTegra_PreK1) {
4384 shaderCaps->fCanUseFragCoord = false;
4385 }
4386
4387 if (fDriverBugWorkarounds.add_and_true_to_loop_condition) {
4388 shaderCaps->fAddAndTrueToLoopCondition = true;
4389 }
4390
4391 if (fDriverBugWorkarounds.unfold_short_circuit_as_ternary_operation) {
4392 shaderCaps->fUnfoldShortCircuitAsTernary = true;
4393 }
4394
4395 if (fDriverBugWorkarounds.emulate_abs_int_function) {
4396 shaderCaps->fEmulateAbsIntFunction = true;
4397 }
4398
4399 if (fDriverBugWorkarounds.rewrite_do_while_loops) {
4400 shaderCaps->fRewriteDoWhileLoops = true;
4401 }
4402
4403 if (fDriverBugWorkarounds.remove_pow_with_constant_exponent) {
4404 shaderCaps->fRemovePowWithConstantExponent = true;
4405 }
4406
4407 if (fDriverBugWorkarounds.disable_dual_source_blending_support) {
4408 shaderCaps->fDualSourceBlendingSupport = false;
4409 }
4410
4411 if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4412 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4413 shaderCaps->fMustWriteToFragColor = true;
4414 }
4415
4416 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
4417 // command buffer for now until its own denylists can be updated.
4418 if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4419 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
4420 ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4421 ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4422 ctxInfo.driver() == GrGLDriver::kIntel ||
4423 ctxInfo.angleVendor() == GrGLVendor::kIntel ||
4424 ctxInfo.isOverCommandBuffer() ||
4425 ctxInfo.vendor() == GrGLVendor::kARM /* http://skbug.com/11906 */) {
4426 fBlendEquationSupport = kBasic_BlendEquationSupport;
4427 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4428 }
4429
4430 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
4431 if (((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4432 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0)) ||
4433 (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4434 ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4435 ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(337, 00, 0))) &&
4436 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
4437 fBlendEquationSupport = kBasic_BlendEquationSupport;
4438 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4439 }
4440
4441 if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
4442 fBlendEquationSupport = kBasic_BlendEquationSupport;
4443 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
4444 }
4445
4446 if (this->advancedBlendEquationSupport()) {
4447 if ((ctxInfo.driver() == GrGLDriver::kNVIDIA &&
4448 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) ||
4449 (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL &&
4450 ctxInfo.angleDriver() == GrGLDriver::kNVIDIA &&
4451 ctxInfo.angleDriverVersion() < GR_GL_DRIVER_VER(355, 00, 0))) {
4452 // Disable color-dodge and color-burn on pre-355.00 NVIDIA.
4453 fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorDodge)) |
4454 (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4455 }
4456 if (ctxInfo.vendor() == GrGLVendor::kARM) {
4457 // Disable color-burn on ARM until the fix is released.
4458 fAdvBlendEqDisableFlags |= (1 << static_cast<int>(skgpu::BlendEquation::kColorBurn));
4459 }
4460 }
4461
4462 // On Adreno 5xx devices, there is a bug where we first draw using dual source blending. Thus
4463 // the dst blend func references the dst. Then the next draw we disable blending. However, on
4464 // the second draw the driver has a bug where it tries to access the second color output again.
4465 // This is fixed by reseting the blend function to anything that does not reference src2 when we
4466 // disable blending.
4467 if (ctxInfo.renderer() == GrGLRenderer::kAdreno530 ||
4468 ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
4469 ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4470 ctxInfo.renderer() == GrGLRenderer::kAdreno640) {
4471 fMustResetBlendFuncBetweenDualSourceAndDisable = true;
4472 }
4473
4474 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
4475 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
4476 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
4477 // skbug.com/7713
4478 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
4479 ctxInfo.glslGeneration() >= SkSL::GLSLGeneration::k330 &&
4480 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
4481 shaderCaps->fExternalTextureSupport = true;
4482 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
4483 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
4484 }
4485
4486 #ifdef SK_BUILD_FOR_IOS
4487 // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
4488 // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
4489 // is to just disable the feature.
4490 // https://github.com/flutter/flutter/issues/16718
4491 // https://bugreport.apple.com/web/?problemID=39948888
4492 fWritePixelsRowBytesSupport = false;
4493 // This affects all iOS devices for transfering from a PBO as well (presumably the issue is in
4494 // the GL->Metal layer).
4495 fTransferPixelsToRowBytesSupport = false;
4496 #endif
4497
4498 if (ctxInfo.vendor() == GrGLVendor::kIntel || // IntelIris640 drops draws completely.
4499 ctxInfo.webglVendor() == GrGLVendor::kIntel || // Disable if the webgl vendor is Intel
4500 ctxInfo.renderer() == GrGLRenderer::kMaliT || // Some curves appear flat on GalaxyS6.
4501 ctxInfo.renderer() == GrGLRenderer::kAdreno3xx ||
4502 ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4503 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other || // We get garbage on Adreno405.
4504 ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) { // D3D9 conic strokes fail.
4505 fDisableTessellationPathRenderer = true;
4506 }
4507 // We found that on Wembley devices (PowerVR GE8320) that using tessellation path renderer would
4508 // cause lots of rendering errors where it seemed like vertices were in the wrong place. This
4509 // led to lots of GMs drawing nothing (e.g. dashing4) or lots of garbage. The Wembley devices
4510 // were running Android 12 with a driver version of 1.13. We previously had TecnoSpark devices
4511 // with the same GPU running on Android P (driver 1.10) which did not have this issue. We don't
4512 // know when the bug appeared in the driver so for now we disable tessellation path renderer for
4513 // all matching gpus regardless of driver version.
4514 //
4515 // 2022-10-28 Update: Testing via Flutter found this is not a problem on driver version 1.15.
4516 // See https://github.com/flutter/flutter/issues/113596
4517 // GL_VERSION : OpenGL ES 3.1 build 1.15@6133109
4518 // GL_RENDERER: PowerVR Rogue AXE-1-16M
4519 // GL_VENDOR : Imagination Technologies
4520 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue &&
4521 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 15, 0)) {
4522 fDisableTessellationPathRenderer = true;
4523 }
4524
4525 // The Wembley device draws the mesh_update GM incorrectly when using transfer buffers. Buffer
4526 // to buffer transfers affect draws earlier in the GL command sequence.
4527 // Android API: 31
4528 // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4529 // GL_RENDERER: PowerVR Rogue GE8300
4530 // GL_VENDOR : Imagination Technologies
4531 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4532 fTransferFromBufferToBufferSupport = false;
4533 }
4534
4535 // The Wembley device fails shader compilations with no error message when there is a const
4536 // parameter. Given that we've already passed through SkSL compilation and enforced that the
4537 // parameter is never written, it is harmless to strip the const off when writing GLSL.
4538 // Android API: 31
4539 // GL_VERSION : OpenGL ES 3.2 build 1.13@5720833
4540 // GL_RENDERER: PowerVR Rogue GE8300
4541 // GL_VENDOR : Imagination Technologies
4542 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4543 fShaderCaps->fRemoveConstFromFunctionParameters = true;
4544 }
4545 #ifdef SK_BUILD_FOR_WIN
4546 // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
4547 if (ctxInfo.driver() == GrGLDriver::kIntel ||
4548 (ctxInfo.angleVendor() == GrGLVendor::kIntel &&
4549 ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL)) {
4550 fNativeDrawIndexedIndirectIsBroken = true;
4551 fUseClientSideIndirectBuffers = true;
4552 }
4553 #endif
4554
4555 // PowerVRGX6250 drops every pixel if we modify the sample mask while color writes are disabled.
4556 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue) {
4557 fNeverDisableColorWrites = true;
4558 shaderCaps->fMustWriteToFragColor = true;
4559 }
4560
4561 // It appears that Qualcomm drivers don't actually support
4562 // GL_NV_shader_noperspective_interpolation in ES 3.00 or 3.10 shaders, only 3.20.
4563 // https://crbug.com/986581
4564 if (ctxInfo.vendor() == GrGLVendor::kQualcomm &&
4565 SkSL::GLSLGeneration::k320es != ctxInfo.glslGeneration()) {
4566 shaderCaps->fNoPerspectiveInterpolationSupport = false;
4567 }
4568
4569 // We disable srgb write control for Adreno4xx devices.
4570 // see: https://bug.skia.org/5329
4571 if (ctxInfo.renderer() == GrGLRenderer::kAdreno430 ||
4572 ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other) {
4573 fSRGBWriteControl = false;
4574 }
4575
4576 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
4577 #if defined(SK_BUILD_FOR_MAC)
4578 if (ctxInfo.vendor() == GrGLVendor::kATI) {
4579 formatWorkarounds->fDisableSRGBRenderWithMSAAForMacAMD = true;
4580 }
4581 #endif
4582
4583 // Command buffer fails glTexSubImage2D with type == GL_HALF_FLOAT_OES if a GL_RGBA16F texture
4584 // is created with glTexStorage2D. See crbug.com/1008003.
4585 formatWorkarounds->fDisableRGBA16FTexStorageForCrBug1008003 =
4586 ctxInfo.isOverCommandBuffer() && ctxInfo.version() < GR_GL_VER(3, 0);
4587
4588 #if defined(SK_BUILD_FOR_WIN)
4589 // On Intel Windows ES contexts it seems that using texture storage with BGRA causes
4590 // problems with cross-context SkImages.
4591 formatWorkarounds->fDisableBGRATextureStorageForIntelWindowsES =
4592 ctxInfo.driver() == GrGLDriver::kIntel && GR_IS_GR_GL_ES(ctxInfo.standard());
4593 #endif
4594
4595 // On the Intel Iris 6100, interacting with LUM16F seems to confuse the driver. After
4596 // writing to/reading from a LUM16F texture reads from/writes to other formats behave
4597 // erratically.
4598 // All Adrenos claim to support LUM16F but don't appear to actually do so.
4599 // The failing devices/gpus were: Nexus5/Adreno330, Nexus5x/Adreno418, Pixel/Adreno530,
4600 // Pixel2XL/Adreno540 and Pixel3/Adreno630
4601 formatWorkarounds->fDisableLuminance16F =
4602 (ctxInfo.renderer() == GrGLRenderer::kIntelBroadwell ||
4603 ctxInfo.vendor() == GrGLVendor::kQualcomm) &&
4604 ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown;
4605
4606 #ifdef SK_BUILD_FOR_MAC
4607 // On a MacBookPro 11.5 running MacOS 10.13 with a Radeon M370X the TransferPixelsFrom test
4608 // fails when transferring out from a GL_RG8 texture using GL_RG/GL_UNSIGNED_BYTE.
4609 // The same error also occurs in MacOS 10.15 with a Radeon Pro 5300M.
4610 formatWorkarounds->fDisallowDirectRG8ReadPixels =
4611 ctxInfo.renderer() == GrGLRenderer::kAMDRadeonR9M3xx ||
4612 ctxInfo.renderer() == GrGLRenderer::kAMDRadeonPro5xxx ||
4613 ctxInfo.renderer() == GrGLRenderer::kAMDRadeonProVegaxx;
4614 #endif
4615
4616 #ifdef SK_BUILD_FOR_ANDROID
4617 // crbug.com/945506. Telemetry reported a memory usage regression for Android Go Chrome/WebView
4618 // when using glTexStorage2D. This appears to affect OOP-R (so not just over command buffer).
4619 // Update 10/2023, it looks like this may just effect chrome Android GO devices which are
4620 // running on Mali-T720. It does not seem to impact Qualcomm devices. We have no tests to verify
4621 // if newer ARM devices are impacted, so for now we keep this disabled on all ARM by default.
4622 //
4623 // We allow the client to pass in a GrContextOption flag to say they prefer having tex storage
4624 // support regadless of memory usage impacts. This is important for supporting Protected
4625 // textures as they require tex storage support.
4626 if (ctxInfo.vendor() == GrGLVendor::kARM &&
4627 !contextOptions.fAlwaysUseTexStorageWhenAvailable &&
4628 !fSupportsProtectedContent) {
4629 formatWorkarounds->fDisableTexStorage = true;
4630 }
4631 #endif
4632
4633 // https://github.com/flutter/flutter/issues/38700
4634 if (ctxInfo.driver() == GrGLDriver::kAndroidEmulator) {
4635 shaderCaps->fNoDefaultPrecisionForExternalSamplers = true;
4636 }
4637
4638 // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
4639 if (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx) {
4640 fTiledRenderingSupport = false;
4641 }
4642 // https://github.com/flutter/flutter/issues/47164
4643 // https://github.com/flutter/flutter/issues/47804
4644 if (fTiledRenderingSupport && (!glInterface->fFunctions.fStartTiling ||
4645 !glInterface->fFunctions.fEndTiling)) {
4646 // Some devices expose the QCOM tiled memory extension string but don't actually provide the
4647 // start and end tiling functions (see above flutter bugs). To work around this, the funcs
4648 // are marked optional in the interface generator, but we turn off the tiled rendering cap
4649 // if they aren't provided. This disabling is in driver workarounds so that SKQP will still
4650 // fail on devices that advertise the extension w/o the functions.
4651 fTiledRenderingSupport = false;
4652 }
4653
4654 if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9) {
4655 formatWorkarounds->fDisallowBGRA8ReadPixels = true;
4656 }
4657
4658 // We disable MSAA for older Intel GPUs. Before Gen9, performance was very bad. Even with Gen9,
4659 // we've seen driver crashes in the wild.
4660 // (crbug.com/527565, crbug.com/983926)
4661 if (ctxInfo.vendor() == GrGLVendor::kIntel || ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4662 // Gen11 seems mostly ok, except we avoid drawing lines with MSAA. (anglebug.com/7796)
4663 if (ctxInfo.renderer() >= GrGLRenderer::kIntelIceLake &&
4664 contextOptions.fAllowMSAAOnNewIntel) {
4665 if (fMSFBOType != kNone_MSFBOType) {
4666 fAvoidLineDraws = true;
4667 }
4668 } else {
4669 fMSFBOType = kNone_MSFBOType;
4670 }
4671 }
4672
4673 // ANGLE's D3D9 backend + AMD GPUs are flaky with program binary caching (skbug.com/10395)
4674 if (ctxInfo.angleBackend() == GrGLANGLEBackend::kD3D9 &&
4675 ctxInfo.angleVendor() == GrGLVendor::kATI) {
4676 fProgramBinarySupport = false;
4677 }
4678
4679 // skbug.com/11204. Avoid recursion issue in SurfaceContext::writePixels.
4680 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4681 fReuseScratchTextures = false;
4682 }
4683
4684 // skbug.com/11935. Don't reorder on these GPUs in GL on old drivers.
4685 if ((ctxInfo.renderer() == GrGLRenderer::kAdreno620 ||
4686 ctxInfo.renderer() == GrGLRenderer::kAdreno640) &&
4687 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(571, 0, 0)) {
4688 fAvoidReorderingRenderTasks = true;
4689 }
4690
4691 // http://crbug.com/1197152
4692 // http://b/187364475
4693 // We could limit this < 1.13 on ChromeOS but we don't really have a good way to detect
4694 // ChromeOS from here.
4695 if (ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue &&
4696 ctxInfo.driver() == GrGLDriver::kImagination &&
4697 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 16, 0)) {
4698 fShaderCaps->fShaderDerivativeSupport = false;
4699 }
4700
4701 if (ctxInfo.driver() == GrGLDriver::kFreedreno) {
4702 formatWorkarounds->fDisallowUnorm16Transfers = true;
4703 }
4704
4705 // If we keep rebind the same texture to an FBO's color attachment but changing between MSAA and
4706 // non-MSAA we get corruption in the texture contents. Binding texture 0 and then rebinding the
4707 // original texture avoids this.
4708 // This was found on Nexus 5, Android 6.0.1, build M4B30Z
4709 // GL_VENDOR : "Qualcomm"
4710 // GL_RENDERER: "Adreno (TM) 330"
4711 // GL_VERSION : "OpenGL ES 3.0 [email protected] AU@ (GIT@I96aee987eb)"
4712 //
4713 // We also so alpha blending issues on these GMs skbug_9819, p3_ovals, p3 on Mali-Gxx devices
4714 // The GM issues were observed on a Galaxy S9 running Android 10:
4715 // GL_VERSION : "OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###"
4716 // GL_RENDERER: "Mali-G72"
4717 // GL_VENDOR : "ARM"
4718 // and a P30 running Android 9:
4719 // GL_VERSION : "OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5"
4720 // GL_RENDERER: "Mali-G76"
4721 // GL_VENDOR : "ARM"
4722 // but *not* a Galaxy S20 running Android 10:
4723 // GL_VERSION : "OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###"
4724 // GL_RENDERER: "Mali-G77"
4725 // GL_VENDOR : "ARM"
4726 // It's unclear if the difference is driver version or Bifrost vs Valhall. The workaround is
4727 // fairly trivial so just applying to all Bifrost and Valhall.
4728 if ((ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
4729 ctxInfo.driver() == GrGLDriver::kQualcomm) ||
4730 (ctxInfo.renderer() == GrGLRenderer::kMaliG)) {
4731 fBindTexture0WhenChangingTextureFBOMultisampleCount = true;
4732 }
4733
4734 // skbug.com/12640
4735 // We found that on the Galaxy S7 the TransferPixelsTo test would fail after adding
4736 // glCheckFramebufferStatus() checks when making new FBOs. Note that the returned status was
4737 // GL_FRAMEBUFFER_COMPLETE. Switching the color binding to ID 0 and back to the original
4738 // afterwards works around the issue.
4739 // GL_VENDOR : "ARM"
4740 // GL_RENDERER: "Mali-T880"
4741 // GL_VERSION : "OpenGL ES 3.2 v1.r22p0-01rel0.f294e54ceb2cb2d81039204fa4b0402e"
4742 //
4743 // This *didn't* reproduce on a Kevin ChromeOS device:
4744 // GL_VENDOR : "ARM"
4745 // GL_RENDERER: "Mali-T860"
4746 // GL_VERSION : "OpenGL ES 3.2 v1.r26p0-01rel0.217d2597f6bd19b169343737782e56e3"
4747 if (ctxInfo.renderer() == GrGLRenderer::kMaliT &&
4748 ctxInfo.driver() == GrGLDriver::kARM &&
4749 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 26, 0)) {
4750 fRebindColorAttachmentAfterCheckFramebufferStatus = true;
4751 }
4752
4753 // skbug.com/13286
4754 // We found that the P30 produces a GL error when setting GL_TEXTURE_MAX_ANISOTROPY as a sampler
4755 // parameter but not as a texture parameter. We are disabling anisotropy on drivers that may
4756 // be affected.
4757 //
4758 // FAIL on P30
4759 // GL_VENDOR : ARM
4760 // GL_RENDERER: Mali-G76
4761 // GL_VERSION : OpenGL ES 3.2 v1.r16p0-01rel0.4aee637066427cbcd25297324dba15f5
4762 //
4763 // PASS on Pixel6
4764 // GL_VENDOR : ARM
4765 // GL_RENDERER: Mali-G78
4766 // GL_VERSION : OpenGL ES 3.2 v1.r32p1-00pxl0.b7e5868a59a273f4a9f58d1657ef99de
4767 //
4768 // PASS on Galaxy S30:
4769 // GL_VENDOR : ARM
4770 // GL_RENDERER: Mali-G77
4771 // GL_VERSION : OpenGL ES 3.2 v1.r20p0-01rel0.###other-sha0123456789ABCDEF0###
4772 //
4773 // PASS on Galaxy S9:
4774 // GL_VENDOR : ARM
4775 // GL_RENDERER: Mali-G72
4776 // GL_VENDOR : OpenGL ES 3.2 v1.r19p0-01rel0.###other-sha0123456789ABCDEF0###
4777 if (ctxInfo.renderer() == GrGLRenderer::kMaliG &&
4778 ctxInfo.driver() == GrGLDriver::kARM &&
4779 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(1, 19, 0)) {
4780 fAnisoSupport = false;
4781 }
4782
4783 // b/229626353
4784 // On certain classes of Adreno running WebGL, glTexSubImage2D() occasionally fails to upload
4785 // texels on time for sampling. The solution is to call glFlush() before glTexSubImage2D().
4786 // Seen on:
4787 // * Nexus 5x (Adreno 418)
4788 // * Nexus 6 (Adreno 420)
4789 // * Pixel 3 (Adreno 630)
4790 if (ctxInfo.renderer() == GrGLRenderer::kWebGL &&
4791 (ctxInfo.webglRenderer() == GrGLRenderer::kAdreno4xx_other ||
4792 ctxInfo.webglRenderer() == GrGLRenderer::kAdreno630)) {
4793 fFlushBeforeWritePixels = true;
4794 }
4795 // crbug.com/1395777
4796 // There appears to be a driver bug in GLSL program linking on Mali 400 and 450 devices with
4797 // driver version 2.1.199xx that causes the copy-as-draw programs in GrGLGpu to fail. The crash
4798 // rate increased when scaling copy support was added, so disallow scaling copy-as-draws on
4799 // these devices.
4800 if (ctxInfo.renderer() == GrGLRenderer::kMali4xx &&
4801 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(2, 1, 19900)) {
4802 fDisableScalingCopyAsDraws = true;
4803 }
4804 // skbug.com/14194
4805 // Setting the max level is technically unnecessary, but on Intel drivers it makes it
4806 // clear that a rendering feedback loop is not occurring, and avoids hitting a slow path.
4807 // When running on ANGLE, however, this triggers the validator because we can only use
4808 // levels between BASE_LEVEL and MAX_LEVEL for a framebuffer, and we're trying to use
4809 // MAX_LEVEL+1. So instead we set up sync points between each mipmap level render.
4810 if (ctxInfo.vendor() == GrGLVendor::kIntel &&
4811 ctxInfo.angleBackend() == GrGLANGLEBackend::kUnknown) {
4812 fRegenerateMipmapType = RegenerateMipmapType::kBasePlusMaxLevel;
4813 } else if (ctxInfo.angleVendor() == GrGLVendor::kIntel) {
4814 fRegenerateMipmapType = RegenerateMipmapType::kBasePlusSync;
4815 }
4816 #ifdef SK_BUILD_FOR_MAC
4817 // On Apple Silicon, RG88 requires 2-byte alignment for transfer buffer readback
4818 if (ctxInfo.vendor() == GrGLVendor::kApple) {
4819 fPadRG88TransferAlignment = true;
4820 }
4821 #endif
4822 }
4823
onApplyOptionsOverrides(const GrContextOptions & options)4824 void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
4825 if (options.fDisableDriverCorrectnessWorkarounds) {
4826 SkASSERT(!fDoManualMipmapping);
4827 SkASSERT(!fClearToBoundaryValuesIsBroken);
4828 SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
4829 SkASSERT(!fDrawArraysBaseVertexIsBroken);
4830 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
4831 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
4832 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
4833 SkASSERT(!fDontSetBaseOrMaxLevelForExternalTextures);
4834 SkASSERT(!fNeverDisableColorWrites);
4835 }
4836 if (options.fShaderCacheStrategy < GrContextOptions::ShaderCacheStrategy::kBackendBinary) {
4837 fProgramBinarySupport = false;
4838 }
4839
4840 switch (options.fSkipGLErrorChecks) {
4841 case GrContextOptions::Enable::kNo:
4842 fSkipErrorChecks = false;
4843 break;
4844 case GrContextOptions::Enable::kYes:
4845 fSkipErrorChecks = true;
4846 break;
4847 case GrContextOptions::Enable::kDefault:
4848 break;
4849 }
4850 }
4851
onSurfaceSupportsWritePixels(const GrSurface * surface) const4852 bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
4853 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
4854 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4855 if (tex->hasBaseLevelBeenBoundToFBO()) {
4856 return false;
4857 }
4858 }
4859 }
4860 if (auto rt = surface->asRenderTarget()) {
4861 if (fUseDrawInsteadOfAllRenderTargetWrites) {
4862 return false;
4863 }
4864 if (rt->numSamples() > 1 && this->usesMSAARenderBuffers()) {
4865 return false;
4866 }
4867 return SkToBool(surface->asTexture());
4868 }
4869 return true;
4870 }
4871
surfaceSupportsReadPixels(const GrSurface * surface) const4872 GrCaps::SurfaceReadPixelsSupport GrGLCaps::surfaceSupportsReadPixels(
4873 const GrSurface* surface) const {
4874 if (surface->isProtected()) {
4875 return SurfaceReadPixelsSupport::kUnsupported;
4876 }
4877 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
4878 // We don't support reading pixels directly from EXTERNAL textures as it would require
4879 // binding the texture to a FBO. For now we also disallow reading back directly
4880 // from compressed textures.
4881 if (tex->target() == GR_GL_TEXTURE_EXTERNAL || GrGLFormatIsCompressed(tex->format())) {
4882 return SurfaceReadPixelsSupport::kCopyToTexture2D;
4883 }
4884 } else if (auto rt = static_cast<const GrGLRenderTarget*>(surface->asRenderTarget())) {
4885 // glReadPixels does not allow reading back from a MSAA framebuffer. If the underlying
4886 // GrSurface doesn't have a second FBO to resolve to then we must make a copy.
4887 if (rt->numSamples() > 1 && !rt->asTexture()) {
4888 return SurfaceReadPixelsSupport::kCopyToTexture2D;
4889 }
4890 }
4891 return SurfaceReadPixelsSupport::kSupported;
4892 }
4893
offset_alignment_for_transfer_buffer(GrGLenum externalType)4894 size_t offset_alignment_for_transfer_buffer(GrGLenum externalType) {
4895 // This switch is derived from a table titled "Pixel data type parameter values and the
4896 // corresponding GL data types" in the OpenGL spec (Table 8.2 in OpenGL 4.5).
4897 switch (externalType) {
4898 case GR_GL_UNSIGNED_BYTE: return sizeof(GrGLubyte);
4899 case GR_GL_BYTE: return sizeof(GrGLbyte);
4900 case GR_GL_UNSIGNED_SHORT: return sizeof(GrGLushort);
4901 case GR_GL_SHORT: return sizeof(GrGLshort);
4902 case GR_GL_UNSIGNED_INT: return sizeof(GrGLuint);
4903 case GR_GL_INT: return sizeof(GrGLint);
4904 case GR_GL_HALF_FLOAT: return sizeof(GrGLhalf);
4905 case GR_GL_HALF_FLOAT_OES: return sizeof(GrGLhalf);
4906 case GR_GL_FLOAT: return sizeof(GrGLfloat);
4907 case GR_GL_UNSIGNED_SHORT_5_6_5: return sizeof(GrGLushort);
4908 case GR_GL_UNSIGNED_SHORT_4_4_4_4: return sizeof(GrGLushort);
4909 case GR_GL_UNSIGNED_SHORT_5_5_5_1: return sizeof(GrGLushort);
4910 case GR_GL_UNSIGNED_INT_2_10_10_10_REV: return sizeof(GrGLuint);
4911 #if 0 // GL types we currently don't use. Here for future reference.
4912 case GR_GL_UNSIGNED_BYTE_3_3_2: return sizeof(GrGLubyte);
4913 case GR_GL_UNSIGNED_BYTE_2_3_3_REV: return sizeof(GrGLubyte);
4914 case GR_GL_UNSIGNED_SHORT_5_6_5_REV: return sizeof(GrGLushort);
4915 case GR_GL_UNSIGNED_SHORT_4_4_4_4_REV: return sizeof(GrGLushort);
4916 case GR_GL_UNSIGNED_SHORT_1_5_5_5_REV: return sizeof(GrGLushort);
4917 case GR_GL_UNSIGNED_INT_8_8_8_8: return sizeof(GrGLuint);
4918 case GR_GL_UNSIGNED_INT_8_8_8_8_REV: return sizeof(GrGLuint);
4919 case GR_GL_UNSIGNED_INT_10_10_10_2: return sizeof(GrGLuint);
4920 case GR_GL_UNSIGNED_INT_24_8: return sizeof(GrGLuint);
4921 case GR_GL_UNSIGNED_INT_10F_11F_11F_REV: return sizeof(GrGLuint);
4922 case GR_GL_UNSIGNED_INT_5_9_9_9_REV: return sizeof(GrGLuint);
4923 // This one is not corresponding to a GL data type and the spec just says it is 4.
4924 case GR_GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return 4;
4925 #endif
4926 default: return 0;
4927 }
4928 }
4929
onSupportedReadPixelsColorType(GrColorType srcColorType,const GrBackendFormat & srcBackendFormat,GrColorType dstColorType) const4930 GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
4931 GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
4932 GrColorType dstColorType) const {
4933
4934 SkTextureCompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
4935 if (compression != SkTextureCompressionType::kNone) {
4936 return {SkTextureCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
4937 : GrColorType::kRGBA_8888,
4938 0};
4939 }
4940
4941 // We first try to find a supported read pixels GrColorType that matches the requested
4942 // dstColorType. If that doesn't exists we will use any valid read pixels GrColorType.
4943 GrCaps::SupportedRead fallbackRead = {GrColorType::kUnknown, 0};
4944 const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(srcBackendFormat));
4945 bool foundSrcCT = false;
4946 for (int i = 0; !foundSrcCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4947 if (formatInfo.fColorTypeInfos[i].fColorType == srcColorType) {
4948 const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4949 foundSrcCT = true;
4950 for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4951 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4952 if (ioInfo.fExternalReadFormat != 0) {
4953 if (formatInfo.fHaveQueriedImplementationReadSupport ||
4954 !ioInfo.fRequiresImplementationReadQuery) {
4955 GrGLenum transferOffsetAlignment = 0;
4956 if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4957 transferOffsetAlignment =
4958 offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
4959 if (dstColorType == GrColorType::kRG_88 && fPadRG88TransferAlignment) {
4960 transferOffsetAlignment = 2;
4961 }
4962 }
4963 if (ioInfo.fColorType == dstColorType) {
4964 return {dstColorType, transferOffsetAlignment};
4965 }
4966 // Currently we just pick the first supported format that we find as our
4967 // fallback.
4968 if (fallbackRead.fColorType == GrColorType::kUnknown) {
4969 fallbackRead = {ioInfo.fColorType, transferOffsetAlignment};
4970 }
4971 }
4972 }
4973 }
4974 }
4975 }
4976 return fallbackRead;
4977 }
4978
supportedWritePixelsColorType(GrColorType surfaceColorType,const GrBackendFormat & surfaceFormat,GrColorType srcColorType) const4979 GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfaceColorType,
4980 const GrBackendFormat& surfaceFormat,
4981 GrColorType srcColorType) const {
4982 // We first try to find a supported write pixels GrColorType that matches the data's
4983 // srcColorType. If that doesn't exists we will use any supported GrColorType.
4984 GrColorType fallbackCT = GrColorType::kUnknown;
4985 const auto& formatInfo = this->getFormatInfo(GrBackendFormats::AsGLFormat(surfaceFormat));
4986 bool foundSurfaceCT = false;
4987 size_t transferOffsetAlignment = 0;
4988 if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
4989 transferOffsetAlignment = 1;
4990 }
4991 for (int i = 0; !foundSurfaceCT && i < formatInfo.fColorTypeInfoCount; ++i) {
4992 if (formatInfo.fColorTypeInfos[i].fColorType == surfaceColorType) {
4993 const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
4994 foundSurfaceCT = true;
4995 for (int j = 0; j < ctInfo.fExternalIOFormatCount; ++j) {
4996 const auto& ioInfo = ctInfo.fExternalIOFormats[j];
4997 if (ioInfo.fExternalTexImageFormat != 0) {
4998 if (ioInfo.fColorType == srcColorType) {
4999 return {srcColorType, transferOffsetAlignment};
5000 }
5001 // Currently we just pick the first supported format that we find as our
5002 // fallback.
5003 if (fallbackCT == GrColorType::kUnknown) {
5004 fallbackCT = ioInfo.fColorType;
5005 }
5006 }
5007 }
5008 }
5009 }
5010 return {fallbackCT, transferOffsetAlignment};
5011 }
5012
programBinaryFormatIsValid(GrGLenum binaryFormat) const5013 bool GrGLCaps::programBinaryFormatIsValid(GrGLenum binaryFormat) const {
5014 return std::find(fProgramBinaryFormats.begin(), fProgramBinaryFormats.end(), binaryFormat) !=
5015 fProgramBinaryFormats.end();
5016 }
5017
onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget & backendRT) const5018 bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
5019 GrGLFramebufferInfo fbInfo;
5020 SkAssertResult(GrBackendRenderTargets::GetGLFramebufferInfo(backendRT, &fbInfo));
5021 // Window Rectangles are not supported for FBO 0;
5022 return fbInfo.fFBOID != 0;
5023 }
5024
isFormatSRGB(const GrBackendFormat & format) const5025 bool GrGLCaps::isFormatSRGB(const GrBackendFormat& format) const {
5026 return GrBackendFormats::AsGLFormat(format) == GrGLFormat::kSRGB8_ALPHA8;
5027 }
5028
isFormatTexturable(const GrBackendFormat & format,GrTextureType textureType) const5029 bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType textureType) const {
5030 if (textureType == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5031 return false;
5032 }
5033 return this->isFormatTexturable(GrBackendFormats::AsGLFormat(format));
5034 }
5035
isFormatTexturable(GrGLFormat format) const5036 bool GrGLCaps::isFormatTexturable(GrGLFormat format) const {
5037 const FormatInfo& info = this->getFormatInfo(format);
5038 return SkToBool(info.fFlags & FormatInfo::kTexturable_Flag);
5039 }
5040
isFormatAsColorTypeRenderable(GrColorType ct,const GrBackendFormat & format,int sampleCount) const5041 bool GrGLCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
5042 int sampleCount) const {
5043 if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5044 return false;
5045 }
5046 if (format.textureType() == GrTextureType::kExternal) {
5047 return false;
5048 }
5049 auto f = GrBackendFormats::AsGLFormat(format);
5050 const FormatInfo& info = this->getFormatInfo(f);
5051 if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
5052 return false;
5053 }
5054
5055 return this->isFormatRenderable(f, sampleCount);
5056 }
5057
isFormatRenderable(const GrBackendFormat & format,int sampleCount) const5058 bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
5059 if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
5060 return false;
5061 }
5062 if (format.textureType() == GrTextureType::kExternal) {
5063 return false;
5064 }
5065 return this->isFormatRenderable(GrBackendFormats::AsGLFormat(format), sampleCount);
5066 }
5067
getRenderTargetSampleCount(int requestedCount,GrGLFormat format) const5068 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrGLFormat format) const {
5069 const FormatInfo& info = this->getFormatInfo(format);
5070
5071 int count = info.fColorSampleCounts.size();
5072 if (!count) {
5073 return 0;
5074 }
5075
5076 requestedCount = std::max(1, requestedCount);
5077 if (1 == requestedCount) {
5078 return info.fColorSampleCounts[0] == 1 ? 1 : 0;
5079 }
5080
5081 for (int sampleCount : info.fColorSampleCounts) {
5082 if (sampleCount >= requestedCount) {
5083 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5084 sampleCount = std::min(sampleCount, 4);
5085 }
5086 return sampleCount;
5087 }
5088 }
5089 return 0;
5090 }
5091
maxRenderTargetSampleCount(GrGLFormat format) const5092 int GrGLCaps::maxRenderTargetSampleCount(GrGLFormat format) const {
5093 const FormatInfo& info = this->getFormatInfo(format);
5094 const auto& table = info.fColorSampleCounts;
5095 if (table.empty()) {
5096 return 0;
5097 }
5098 int count = table[table.size() - 1];
5099 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
5100 count = std::min(count, 4);
5101 }
5102 return count;
5103 }
5104
canFormatBeFBOColorAttachment(GrGLFormat format) const5105 bool GrGLCaps::canFormatBeFBOColorAttachment(GrGLFormat format) const {
5106 return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kFBOColorAttachment_Flag);
5107 }
5108
isFormatCopyable(const GrBackendFormat & format) const5109 bool GrGLCaps::isFormatCopyable(const GrBackendFormat& format) const {
5110 // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
5111 // requires the src to be an FBO attachment, blit requires both src and dst to be FBO
5112 // attachments, and draw requires the dst to be an FBO attachment. Thus to copy from and to
5113 // the same config, we need that config to be bindable to an FBO.
5114 return this->canFormatBeFBOColorAttachment(GrBackendFormats::AsGLFormat(format));
5115 }
5116
formatSupportsTexStorage(GrGLFormat format) const5117 bool GrGLCaps::formatSupportsTexStorage(GrGLFormat format) const {
5118 return SkToBool(this->getFormatInfo(format).fFlags & FormatInfo::kUseTexStorage_Flag);
5119 }
5120
shouldQueryImplementationReadSupport(GrGLFormat format) const5121 bool GrGLCaps::shouldQueryImplementationReadSupport(GrGLFormat format) const {
5122 const auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5123 if (!formatInfo.fHaveQueriedImplementationReadSupport) {
5124 // Check whether we will actually learn anything useful.
5125 bool needQuery = false;
5126 for (int i = 0; i < formatInfo.fColorTypeInfoCount && !needQuery; ++i) {
5127 const auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5128 for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5129 if (surfCTInfo.fExternalIOFormats[j].fRequiresImplementationReadQuery) {
5130 needQuery = true;
5131 break;
5132 }
5133 }
5134 }
5135 if (!needQuery) {
5136 // Pretend we already checked it.
5137 const_cast<FormatInfo&>(formatInfo).fHaveQueriedImplementationReadSupport = true;
5138 }
5139 }
5140 return !formatInfo.fHaveQueriedImplementationReadSupport;
5141 }
5142
didQueryImplementationReadSupport(GrGLFormat format,GrGLenum readFormat,GrGLenum readType) const5143 void GrGLCaps::didQueryImplementationReadSupport(GrGLFormat format,
5144 GrGLenum readFormat,
5145 GrGLenum readType) const {
5146 auto& formatInfo = const_cast<GrGLCaps*>(this)->getFormatInfo(format);
5147 for (int i = 0; i < formatInfo.fColorTypeInfoCount; ++i) {
5148 auto& surfCTInfo = formatInfo.fColorTypeInfos[i];
5149 for (int j = 0; j < surfCTInfo.fExternalIOFormatCount; ++j) {
5150 auto& readCTInfo = surfCTInfo.fExternalIOFormats[j];
5151 if (readCTInfo.fRequiresImplementationReadQuery) {
5152 if (readCTInfo.fExternalReadFormat != readFormat ||
5153 readCTInfo.fExternalType != readType) {
5154 // Don't zero out fExternalType. It's also used for writing data to the texture!
5155 readCTInfo.fExternalReadFormat = 0;
5156 }
5157 }
5158 }
5159 }
5160 formatInfo.fHaveQueriedImplementationReadSupport = true;
5161 }
5162
onAreColorTypeAndFormatCompatible(GrColorType ct,const GrBackendFormat & format) const5163 bool GrGLCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
5164 const GrBackendFormat& format) const {
5165 GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5166 const auto& info = this->getFormatInfo(glFormat);
5167 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5168 if (info.fColorTypeInfos[i].fColorType == ct) {
5169 return true;
5170 }
5171 }
5172 return false;
5173 }
5174
onGetDefaultBackendFormat(GrColorType ct) const5175 GrBackendFormat GrGLCaps::onGetDefaultBackendFormat(GrColorType ct) const {
5176 auto format = this->getFormatFromColorType(ct);
5177 if (format == GrGLFormat::kUnknown) {
5178 return {};
5179 }
5180 return GrBackendFormats::MakeGL(GrGLFormatToEnum(format), GR_GL_TEXTURE_2D);
5181 }
5182
getBackendFormatFromCompressionType(SkTextureCompressionType compressionType) const5183 GrBackendFormat GrGLCaps::getBackendFormatFromCompressionType(
5184 SkTextureCompressionType compressionType) const {
5185 switch (compressionType) {
5186 case SkTextureCompressionType::kNone:
5187 return {};
5188 case SkTextureCompressionType::kETC2_RGB8_UNORM:
5189 // if ETC2 is available default to that format
5190 if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_ETC2)) {
5191 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D);
5192 }
5193 if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_ETC1_RGB8)) {
5194 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D);
5195 }
5196 return {};
5197 case SkTextureCompressionType::kBC1_RGB8_UNORM:
5198 if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGB8_BC1)) {
5199 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
5200 GR_GL_TEXTURE_2D);
5201 }
5202 return {};
5203 case SkTextureCompressionType::kBC1_RGBA8_UNORM:
5204 if (this->isFormatTexturable(GrGLFormat::kCOMPRESSED_RGBA8_BC1)) {
5205 return GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
5206 GR_GL_TEXTURE_2D);
5207 }
5208 return {};
5209 }
5210
5211 SkUNREACHABLE;
5212 }
5213
onGetReadSwizzle(const GrBackendFormat & format,GrColorType colorType) const5214 skgpu::Swizzle GrGLCaps::onGetReadSwizzle(const GrBackendFormat& format,
5215 GrColorType colorType) const {
5216 GrGLFormat glFormat = GrBackendFormats::AsGLFormat(format);
5217 const auto& info = this->getFormatInfo(glFormat);
5218 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5219 const auto& ctInfo = info.fColorTypeInfos[i];
5220 if (ctInfo.fColorType == colorType) {
5221 return ctInfo.fReadSwizzle;
5222 }
5223 }
5224 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5225 (int)colorType, (int)glFormat);
5226 return {};
5227 }
5228
getWriteSwizzle(const GrBackendFormat & format,GrColorType colorType) const5229 skgpu::Swizzle GrGLCaps::getWriteSwizzle(const GrBackendFormat& format,
5230 GrColorType colorType) const {
5231 const auto& info = this->getFormatInfo(GrBackendFormats::AsGLFormat(format));
5232 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
5233 const auto& ctInfo = info.fColorTypeInfos[i];
5234 if (ctInfo.fColorType == colorType) {
5235 return ctInfo.fWriteSwizzle;
5236 }
5237 }
5238 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
5239 (int)colorType,
5240 (int)GrBackendFormats::AsGLFormat(format));
5241 return {};
5242 }
5243
onGetDstSampleFlagsForProxy(const GrRenderTargetProxy * rt) const5244 GrDstSampleFlags GrGLCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
5245 if (rt->asTextureProxy()) {
5246 return GrDstSampleFlags::kRequiresTextureBarrier;
5247 }
5248 return GrDstSampleFlags::kNone;
5249 }
5250
onSupportsDynamicMSAA(const GrRenderTargetProxy * rtProxy) const5251 bool GrGLCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
5252 return !fDisallowDynamicMSAA;
5253 }
5254
computeFormatKey(const GrBackendFormat & format) const5255 uint64_t GrGLCaps::computeFormatKey(const GrBackendFormat& format) const {
5256 auto glFormat = GrBackendFormats::AsGLFormat(format);
5257 return (uint64_t)(glFormat);
5258 }
5259
makeDesc(GrRenderTarget *,const GrProgramInfo & programInfo,ProgramDescOverrideFlags overrideFlags) const5260 GrProgramDesc GrGLCaps::makeDesc(GrRenderTarget* /* rt */,
5261 const GrProgramInfo& programInfo,
5262 ProgramDescOverrideFlags overrideFlags) const {
5263 SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
5264 GrProgramDesc desc;
5265 GrProgramDesc::Build(&desc, programInfo, *this);
5266 return desc;
5267 }
5268
5269 #if defined(GPU_TEST_UTILS)
getTestingCombinations() const5270 std::vector<GrTest::TestFormatColorTypeCombination> GrGLCaps::getTestingCombinations() const {
5271 std::vector<GrTest::TestFormatColorTypeCombination> combos = {
5272 { GrColorType::kAlpha_8,
5273 GrBackendFormats::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D) },
5274 { GrColorType::kAlpha_8,
5275 GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5276 { GrColorType::kBGR_565,
5277 GrBackendFormats::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D) },
5278 { GrColorType::kABGR_4444,
5279 GrBackendFormats::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D) },
5280 { GrColorType::kRGBA_8888,
5281 GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5282 { GrColorType::kRGBA_8888_SRGB,
5283 GrBackendFormats::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D) },
5284 { GrColorType::kRGB_888x,
5285 GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) },
5286 { GrColorType::kRGB_888x,
5287 GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) },
5288 { GrColorType::kRGB_888x,
5289 GrBackendFormats::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D) },
5290 { GrColorType::kRGB_888x,
5291 GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB8_ETC2, GR_GL_TEXTURE_2D) },
5292 { GrColorType::kRGB_888x,
5293 GrBackendFormats::MakeGL(GR_GL_COMPRESSED_ETC1_RGB8, GR_GL_TEXTURE_2D) },
5294 { GrColorType::kRGB_888x,
5295 GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5296 { GrColorType::kRGBA_8888,
5297 GrBackendFormats::MakeGL(GR_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GR_GL_TEXTURE_2D) },
5298 { GrColorType::kRG_88,
5299 GrBackendFormats::MakeGL(GR_GL_RG8, GR_GL_TEXTURE_2D) },
5300 { GrColorType::kRGBA_1010102,
5301 GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5302 { GrColorType::kRGB_101010x,
5303 GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) },
5304 { GrColorType::kGray_8,
5305 GrBackendFormats::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D) },
5306 { GrColorType::kGray_8,
5307 GrBackendFormats::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D) },
5308 { GrColorType::kGrayAlpha_88,
5309 GrBackendFormats::MakeGL(GR_GL_LUMINANCE8_ALPHA8, GR_GL_TEXTURE_2D) },
5310 { GrColorType::kAlpha_F16,
5311 GrBackendFormats::MakeGL(GR_GL_R16F, GR_GL_TEXTURE_2D) },
5312 { GrColorType::kAlpha_F16,
5313 GrBackendFormats::MakeGL(GR_GL_LUMINANCE16F, GR_GL_TEXTURE_2D) },
5314 { GrColorType::kRGBA_F16,
5315 GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5316 { GrColorType::kRGBA_F16_Clamped,
5317 GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5318 { GrColorType::kRGB_F16F16F16x,
5319 GrBackendFormats::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
5320 { GrColorType::kAlpha_16,
5321 GrBackendFormats::MakeGL(GR_GL_R16, GR_GL_TEXTURE_2D) },
5322 { GrColorType::kRG_1616,
5323 GrBackendFormats::MakeGL(GR_GL_RG16, GR_GL_TEXTURE_2D) },
5324 { GrColorType::kRGBA_16161616,
5325 GrBackendFormats::MakeGL(GR_GL_RGBA16, GR_GL_TEXTURE_2D) },
5326 { GrColorType::kRG_F16,
5327 GrBackendFormats::MakeGL(GR_GL_RG16F, GR_GL_TEXTURE_2D) },
5328 };
5329
5330 if (GR_IS_GR_GL(fStandard)) {
5331 combos.push_back({ GrColorType::kBGRA_8888,
5332 GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D) });
5333 combos.push_back({ GrColorType::kBGRA_1010102,
5334 GrBackendFormats::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D) });
5335 } else {
5336 SkASSERT(GR_IS_GR_GL_ES(fStandard) || GR_IS_GR_WEBGL(fStandard));
5337
5338 combos.push_back({ GrColorType::kBGRA_8888,
5339 GrBackendFormats::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D) });
5340 }
5341 if (this->rectangleTextureSupport()) {
5342 size_t count2D = combos.size();
5343 for (size_t i = 0; i < count2D; ++i) {
5344 auto combo2D = combos[i];
5345 GrGLenum formatEnum = GrBackendFormats::AsGLFormatEnum(combo2D.fFormat);
5346 combos.push_back({combo2D.fColorType,
5347 GrBackendFormats::MakeGL(formatEnum, GR_GL_TEXTURE_RECTANGLE)});
5348 }
5349 }
5350 return combos;
5351 }
5352 #endif
5353