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