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