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