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