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