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