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