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