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