Line data Source code
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 "GrGLCaps.h"
9 : #include "GrContextOptions.h"
10 : #include "GrGLContext.h"
11 : #include "GrGLRenderTarget.h"
12 : #include "GrGLTexture.h"
13 : #include "GrShaderCaps.h"
14 : #include "GrSurfaceProxyPriv.h"
15 : #include "SkTSearch.h"
16 : #include "SkTSort.h"
17 : #include "instanced/GLInstancedRendering.h"
18 :
19 0 : GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
20 : const GrGLContextInfo& ctxInfo,
21 0 : const GrGLInterface* glInterface) : INHERITED(contextOptions) {
22 0 : fStandard = ctxInfo.standard();
23 :
24 0 : fStencilFormats.reset();
25 0 : fMSFBOType = kNone_MSFBOType;
26 0 : fInvalidateFBType = kNone_InvalidateFBType;
27 0 : fMapBufferType = kNone_MapBufferType;
28 0 : fTransferBufferType = kNone_TransferBufferType;
29 0 : fMaxFragmentUniformVectors = 0;
30 0 : fUnpackRowLengthSupport = false;
31 0 : fUnpackFlipYSupport = false;
32 0 : fPackRowLengthSupport = false;
33 0 : fPackFlipYSupport = false;
34 0 : fTextureUsageSupport = false;
35 0 : fTextureRedSupport = false;
36 0 : fImagingSupport = false;
37 0 : fVertexArrayObjectSupport = false;
38 0 : fDirectStateAccessSupport = false;
39 0 : fDebugSupport = false;
40 0 : fES2CompatibilitySupport = false;
41 0 : fDrawInstancedSupport = false;
42 0 : fDrawIndirectSupport = false;
43 0 : fMultiDrawIndirectSupport = false;
44 0 : fBaseInstanceSupport = false;
45 0 : fIsCoreProfile = false;
46 0 : fBindFragDataLocationSupport = false;
47 0 : fRectangleTextureSupport = false;
48 0 : fTextureSwizzleSupport = false;
49 0 : fRGBA8888PixelsOpsAreSlow = false;
50 0 : fPartialFBOReadIsSlow = false;
51 0 : fMipMapLevelAndLodControlSupport = false;
52 0 : fRGBAToBGRAReadbackConversionsAreSlow = false;
53 0 : fDoManualMipmapping = false;
54 0 : fSRGBDecodeDisableSupport = false;
55 0 : fSRGBDecodeDisableAffectsMipmaps = false;
56 :
57 0 : fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
58 :
59 0 : fShaderCaps.reset(new GrShaderCaps(contextOptions));
60 :
61 0 : this->init(contextOptions, ctxInfo, glInterface);
62 0 : }
63 :
64 0 : void GrGLCaps::init(const GrContextOptions& contextOptions,
65 : const GrGLContextInfo& ctxInfo,
66 : const GrGLInterface* gli) {
67 0 : GrGLStandard standard = ctxInfo.standard();
68 0 : GrGLVersion version = ctxInfo.version();
69 :
70 : /**************************************************************************
71 : * Caps specific to GrGLCaps
72 : **************************************************************************/
73 :
74 0 : if (kGLES_GrGLStandard == standard) {
75 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
76 : &fMaxFragmentUniformVectors);
77 : } else {
78 0 : SkASSERT(kGL_GrGLStandard == standard);
79 : GrGLint max;
80 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
81 0 : fMaxFragmentUniformVectors = max / 4;
82 0 : if (version >= GR_GL_VER(3, 2)) {
83 : GrGLint profileMask;
84 0 : GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
85 0 : fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
86 : }
87 : }
88 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
89 :
90 0 : if (kGL_GrGLStandard == standard) {
91 0 : fUnpackRowLengthSupport = true;
92 0 : fUnpackFlipYSupport = false;
93 0 : fPackRowLengthSupport = true;
94 0 : fPackFlipYSupport = false;
95 : } else {
96 0 : fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
97 0 : ctxInfo.hasExtension("GL_EXT_unpack_subimage");
98 0 : fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
99 0 : fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
100 0 : ctxInfo.hasExtension("GL_NV_pack_subimage");
101 0 : fPackFlipYSupport =
102 0 : ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
103 : }
104 :
105 0 : fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
106 0 : ctxInfo.hasExtension("GL_ANGLE_texture_usage");
107 :
108 0 : if (kGL_GrGLStandard == standard) {
109 0 : fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
110 0 : ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
111 0 : ctxInfo.hasExtension("GL_NV_texture_barrier");
112 : } else {
113 0 : fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
114 : }
115 :
116 0 : if (kGL_GrGLStandard == standard) {
117 0 : fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
118 0 : ctxInfo.hasExtension("GL_ARB_texture_multisample");
119 : } else {
120 0 : fSampleLocationsSupport = version >= GR_GL_VER(3,1);
121 : }
122 :
123 : // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
124 : // and GL_RG on FBO textures.
125 0 : if (kOSMesa_GrGLRenderer != ctxInfo.renderer()) {
126 0 : if (kGL_GrGLStandard == standard) {
127 0 : fTextureRedSupport = version >= GR_GL_VER(3,0) ||
128 0 : ctxInfo.hasExtension("GL_ARB_texture_rg");
129 : } else {
130 0 : fTextureRedSupport = version >= GR_GL_VER(3,0) ||
131 0 : ctxInfo.hasExtension("GL_EXT_texture_rg");
132 : }
133 : }
134 0 : fImagingSupport = kGL_GrGLStandard == standard &&
135 0 : ctxInfo.hasExtension("GL_ARB_imaging");
136 :
137 : // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
138 : // Thus we are blacklisting this extension for now on Adreno4xx devices.
139 0 : if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
140 0 : ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
141 0 : (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
142 0 : ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
143 0 : fDiscardRenderTargetSupport = true;
144 0 : fInvalidateFBType = kInvalidate_InvalidateFBType;
145 0 : } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
146 0 : fDiscardRenderTargetSupport = true;
147 0 : fInvalidateFBType = kDiscard_InvalidateFBType;
148 : }
149 :
150 0 : if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
151 0 : fFullClearIsFree = true;
152 : }
153 :
154 0 : if (kGL_GrGLStandard == standard) {
155 0 : fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
156 0 : ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
157 0 : ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
158 : } else {
159 0 : fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
160 0 : ctxInfo.hasExtension("GL_OES_vertex_array_object");
161 : }
162 :
163 0 : if (kGL_GrGLStandard == standard) {
164 0 : fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
165 : } else {
166 0 : fDirectStateAccessSupport = false;
167 : }
168 :
169 0 : if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
170 0 : fDebugSupport = true;
171 : } else {
172 0 : fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
173 : }
174 :
175 0 : if (kGL_GrGLStandard == standard) {
176 0 : fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
177 : }
178 : else {
179 0 : fES2CompatibilitySupport = true;
180 : }
181 :
182 0 : if (kGL_GrGLStandard == standard) {
183 0 : fMultisampleDisableSupport = true;
184 : } else {
185 0 : fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
186 : }
187 :
188 0 : if (kGL_GrGLStandard == standard) {
189 0 : if (version >= GR_GL_VER(3, 0)) {
190 0 : fBindFragDataLocationSupport = true;
191 : }
192 : } else {
193 0 : if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
194 0 : fBindFragDataLocationSupport = true;
195 : }
196 : }
197 :
198 0 : fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
199 :
200 0 : if (kGL_GrGLStandard == standard) {
201 0 : if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
202 : // We also require textureSize() support for rectangle 2D samplers which was added in
203 : // GLSL 1.40.
204 0 : if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
205 0 : fRectangleTextureSupport = true;
206 : }
207 : }
208 : } else {
209 : // Command buffer exposes this in GL ES context for Chromium reasons,
210 : // but it should not be used. Also, at the time of writing command buffer
211 : // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
212 : }
213 :
214 0 : if (kGL_GrGLStandard == standard) {
215 0 : if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
216 0 : fTextureSwizzleSupport = true;
217 : }
218 : } else {
219 0 : if (version >= GR_GL_VER(3,0)) {
220 0 : fTextureSwizzleSupport = true;
221 : }
222 : }
223 :
224 0 : if (kGL_GrGLStandard == standard) {
225 0 : fMipMapLevelAndLodControlSupport = true;
226 0 : } else if (kGLES_GrGLStandard == standard) {
227 0 : if (version >= GR_GL_VER(3,0)) {
228 0 : fMipMapLevelAndLodControlSupport = true;
229 : }
230 : }
231 :
232 : #ifdef SK_BUILD_FOR_WIN
233 : // We're assuming that on Windows Chromium we're using ANGLE.
234 : bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
235 : kChromium_GrGLDriver == ctxInfo.driver();
236 : // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
237 : fRGBA8888PixelsOpsAreSlow = isANGLE;
238 : // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
239 : // check DX11 ANGLE.
240 : fPartialFBOReadIsSlow = isANGLE;
241 : #endif
242 :
243 0 : bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
244 0 : bool isMAC = false;
245 : #ifdef SK_BUILD_FOR_MAC
246 : isMAC = true;
247 : #endif
248 :
249 : // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
250 : // vis-versa.
251 0 : fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
252 :
253 : /**************************************************************************
254 : * GrShaderCaps fields
255 : **************************************************************************/
256 :
257 : // This must be called after fCoreProfile is set on the GrGLCaps
258 0 : this->initGLSL(ctxInfo);
259 0 : GrShaderCaps* shaderCaps = fShaderCaps.get();
260 :
261 0 : if (!contextOptions.fSuppressPathRendering) {
262 0 : shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
263 : }
264 :
265 : // For now these two are equivalent but we could have dst read in shader via some other method.
266 : // Before setting this, initGLSL() must have been called.
267 0 : shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
268 :
269 : // Enable supported shader-related caps
270 0 : if (kGL_GrGLStandard == standard) {
271 0 : shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
272 0 : ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
273 0 : GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
274 0 : shaderCaps->fShaderDerivativeSupport = true;
275 : // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
276 0 : shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
277 0 : ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
278 0 : shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
279 0 : ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
280 : }
281 : else {
282 0 : shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
283 :
284 0 : shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
285 0 : ctxInfo.hasExtension("GL_OES_standard_derivatives");
286 :
287 0 : shaderCaps->fGeometryShaderSupport = ctxInfo.hasExtension("GL_EXT_geometry_shader");
288 :
289 0 : shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
290 0 : ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
291 : }
292 :
293 : // Protect ourselves against tracking huge amounts of texture state.
294 : static const uint8_t kMaxSaneSamplers = 32;
295 : GrGLint maxSamplers;
296 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
297 0 : shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
298 0 : if (shaderCaps->fGeometryShaderSupport) {
299 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
300 0 : shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
301 : }
302 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
303 0 : shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
304 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
305 0 : shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
306 :
307 0 : if (kGL_GrGLStandard == standard) {
308 0 : shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(4, 2);
309 0 : if (!shaderCaps->fImageLoadStoreSupport &&
310 0 : ctxInfo.hasExtension("GL_ARB_shader_image_load_store")) {
311 0 : shaderCaps->fImageLoadStoreSupport = true;
312 0 : shaderCaps->fImageLoadStoreExtensionString = "GL_ARB_shader_image_load_store";
313 : }
314 : } else {
315 0 : shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
316 : }
317 0 : if (shaderCaps->fImageLoadStoreSupport) {
318 : // Protect ourselves against tracking huge amounts of image state.
319 : static constexpr int kMaxSaneImages = 4;
320 : GrGLint maxUnits;
321 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
322 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
323 : &shaderCaps->fMaxVertexImageStorages);
324 0 : if (shaderCaps->fGeometryShaderSupport) {
325 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
326 : &shaderCaps->fMaxGeometryImageStorages);
327 : }
328 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
329 : &shaderCaps->fMaxFragmentImageStorages);
330 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
331 : &shaderCaps->fMaxCombinedImageStorages);
332 : // We use one unit for every image uniform
333 0 : shaderCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(shaderCaps->fMaxCombinedImageStorages,
334 0 : maxUnits), kMaxSaneImages);
335 0 : shaderCaps->fMaxVertexImageStorages = SkTMin(maxUnits,
336 0 : shaderCaps->fMaxVertexImageStorages);
337 0 : shaderCaps->fMaxGeometryImageStorages = SkTMin(maxUnits,
338 0 : shaderCaps->fMaxGeometryImageStorages);
339 0 : shaderCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
340 0 : shaderCaps->fMaxFragmentImageStorages);
341 : }
342 :
343 : /**************************************************************************
344 : * GrCaps fields
345 : **************************************************************************/
346 :
347 : // We need dual source blending and the ability to disable multisample in order to support mixed
348 : // samples in every corner case. We only use mixed samples if the stencil-and-cover path
349 : // renderer is available and enabled; no other path renderers support this feature.
350 0 : if (fMultisampleDisableSupport &&
351 0 : shaderCaps->dualSourceBlendingSupport() &&
352 0 : fShaderCaps->pathRenderingSupport() &&
353 0 : (contextOptions.fGpuPathRenderers & GrContextOptions::GpuPathRenderers::kStencilAndCover)) {
354 0 : fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
355 0 : ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
356 : // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
357 0 : if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
358 0 : kChromium_GrGLDriver == ctxInfo.driver())) {
359 0 : fDiscardRenderTargetSupport = false;
360 0 : fInvalidateFBType = kNone_InvalidateFBType;
361 : }
362 : }
363 :
364 : // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
365 : // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
366 : // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
367 : // limit this decision to specific GPU families rather than basing it on the vendor alone.
368 0 : if (!GR_GL_MUST_USE_VBO &&
369 0 : !fIsCoreProfile &&
370 0 : (kARM_GrGLVendor == ctxInfo.vendor() ||
371 0 : kImagination_GrGLVendor == ctxInfo.vendor() ||
372 0 : kQualcomm_GrGLVendor == ctxInfo.vendor())) {
373 0 : fPreferClientSideDynamicBuffers = true;
374 : }
375 :
376 : // fUsesMixedSamples must be set before calling initFSAASupport.
377 0 : this->initFSAASupport(ctxInfo, gli);
378 0 : this->initBlendEqationSupport(ctxInfo);
379 0 : this->initStencilFormats(ctxInfo);
380 :
381 0 : if (kGL_GrGLStandard == standard) {
382 : // we could also look for GL_ATI_separate_stencil extension or
383 : // GL_EXT_stencil_two_side but they use different function signatures
384 : // than GL2.0+ (and than each other).
385 0 : fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
386 : // supported on GL 1.4 and higher or by extension
387 0 : fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
388 0 : ctxInfo.hasExtension("GL_EXT_stencil_wrap");
389 : } else {
390 : // ES 2 has two sided stencil and stencil wrap
391 0 : fTwoSidedStencilSupport = true;
392 0 : fStencilWrapOpsSupport = true;
393 : }
394 :
395 0 : if (kGL_GrGLStandard == standard) {
396 0 : fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
397 : // extension includes glMapBuffer.
398 0 : if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
399 0 : fMapBufferFlags |= kSubset_MapFlag;
400 0 : fMapBufferType = kMapBufferRange_MapBufferType;
401 : } else {
402 0 : fMapBufferType = kMapBuffer_MapBufferType;
403 : }
404 : } else {
405 : // Unextended GLES2 doesn't have any buffer mapping.
406 0 : fMapBufferFlags = kNone_MapBufferType;
407 0 : if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
408 0 : fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
409 0 : fMapBufferType = kChromium_MapBufferType;
410 0 : } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
411 0 : fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
412 0 : fMapBufferType = kMapBufferRange_MapBufferType;
413 0 : } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
414 0 : fMapBufferFlags = kCanMap_MapFlag;
415 0 : fMapBufferType = kMapBuffer_MapBufferType;
416 : }
417 : }
418 :
419 0 : if (kGL_GrGLStandard == standard) {
420 0 : if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
421 0 : fTransferBufferType = kPBO_TransferBufferType;
422 : }
423 : } else {
424 0 : if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
425 0 : fTransferBufferType = kPBO_TransferBufferType;
426 0 : } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
427 0 : fTransferBufferType = kChromium_TransferBufferType;
428 : }
429 : }
430 :
431 : // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
432 : // threshold to the maximum unless the client gives us a hint that map memory is cheap.
433 0 : if (fBufferMapThreshold < 0) {
434 : #if 0
435 : // We think mapping on Chromium will be cheaper once we know ahead of time how much space
436 : // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
437 : // using a small subset.
438 : fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
439 : #else
440 0 : fBufferMapThreshold = SK_MaxS32;
441 : #endif
442 : }
443 :
444 0 : if (kGL_GrGLStandard == standard) {
445 0 : SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
446 : ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
447 0 : fNPOTTextureTileSupport = true;
448 0 : fMipMapSupport = true;
449 : } else {
450 : // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
451 : // ES3 has no limitations.
452 0 : fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
453 0 : ctxInfo.hasExtension("GL_OES_texture_npot");
454 : // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
455 : // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
456 : // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
457 : // to alllow arbitrary wrap modes, however.
458 0 : fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
459 : }
460 :
461 : // Using MIPs on this GPU seems to be a source of trouble.
462 0 : if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
463 0 : fMipMapSupport = false;
464 : }
465 :
466 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
467 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
468 : // Our render targets are always created with textures as the color
469 : // attachment, hence this min:
470 0 : fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
471 :
472 0 : fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
473 :
474 : // Disable scratch texture reuse on Mali and Adreno devices
475 0 : fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
476 :
477 : #if 0
478 : fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
479 : kQualcomm_GrGLVendor != ctxInfo.vendor();
480 : #endif
481 :
482 : // initFSAASupport() must have been called before this point
483 0 : if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
484 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
485 0 : } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
486 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
487 : }
488 : // We only have a use for raster multisample if there is coverage modulation from mixed samples.
489 0 : if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
490 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
491 : // This is to guard against platforms that may not support as many samples for
492 : // glRasterSamples as they do for framebuffers.
493 0 : fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
494 : }
495 0 : fMaxColorSampleCount = fMaxStencilSampleCount;
496 :
497 0 : if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
498 0 : GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
499 : }
500 :
501 0 : if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
502 0 : kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
503 0 : (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
504 0 : ctxInfo.driver() != kChromium_GrGLDriver)) {
505 0 : fUseDrawInsteadOfClear = true;
506 : }
507 :
508 0 : if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
509 0 : fUseDrawInsteadOfPartialRenderTargetWrite = true;
510 : }
511 :
512 : // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
513 0 : if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
514 0 : fUseDrawInsteadOfPartialRenderTargetWrite = true;
515 0 : fUseDrawInsteadOfAllRenderTargetWrites = true;
516 : }
517 :
518 : #ifdef SK_BUILD_FOR_WIN
519 : // On ANGLE deferring flushes can lead to GPU starvation
520 : fPreferVRAMUseOverFlushes = !isANGLE;
521 : #endif
522 :
523 0 : if (kChromium_GrGLDriver == ctxInfo.driver()) {
524 0 : fMustClearUploadedBufferData = true;
525 : }
526 :
527 0 : if (kGL_GrGLStandard == standard) {
528 : // ARB allows mixed size FBO attachments, EXT does not.
529 0 : if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
530 0 : ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
531 0 : fOversizedStencilSupport = true;
532 : } else {
533 0 : SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
534 : }
535 : } else {
536 : // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
537 0 : fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
538 : }
539 :
540 0 : if (kGL_GrGLStandard == standard) {
541 : // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
542 : // instanced arrays, but we could make this more granular if we wanted
543 0 : fDrawInstancedSupport =
544 0 : version >= GR_GL_VER(3, 2) ||
545 0 : (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
546 0 : ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
547 : } else {
548 0 : fDrawInstancedSupport =
549 0 : version >= GR_GL_VER(3, 0) ||
550 0 : (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
551 0 : ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
552 : }
553 :
554 0 : if (kGL_GrGLStandard == standard) {
555 0 : fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
556 0 : ctxInfo.hasExtension("GL_ARB_draw_indirect");
557 0 : fBaseInstanceSupport = version >= GR_GL_VER(4,2);
558 0 : fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
559 0 : (fDrawIndirectSupport &&
560 0 : !fBaseInstanceSupport && // The ARB extension has no base inst.
561 0 : ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
562 0 : fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
563 : } else {
564 0 : fDrawIndirectSupport = version >= GR_GL_VER(3,1);
565 0 : fMultiDrawIndirectSupport = fDrawIndirectSupport &&
566 0 : ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
567 0 : fBaseInstanceSupport = fDrawIndirectSupport &&
568 0 : ctxInfo.hasExtension("GL_EXT_base_instance");
569 0 : fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
570 : }
571 :
572 0 : this->initShaderPrecisionTable(ctxInfo, gli, shaderCaps);
573 :
574 0 : if (contextOptions.fUseShaderSwizzling) {
575 0 : fTextureSwizzleSupport = false;
576 : }
577 :
578 0 : if (kGL_GrGLStandard == standard) {
579 0 : if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
580 0 : ctxInfo.vendor() != kIntel_GrGLVendor) {
581 0 : fSampleShadingSupport = true;
582 : }
583 0 : } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
584 0 : fSampleShadingSupport = true;
585 : }
586 :
587 : // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
588 0 : if (kGL_GrGLStandard == standard) {
589 0 : if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
590 0 : fFenceSyncSupport = true;
591 : }
592 0 : } else if (version >= GR_GL_VER(3, 0)) {
593 0 : fFenceSyncSupport = true;
594 : }
595 :
596 : // Safely moving textures between contexts requires fences. The Windows Intel driver has a
597 : // bug with deleting and reusing texture IDs across contexts, so disallow this feature.
598 0 : fCrossContextTextureSupport = fFenceSyncSupport;
599 : #ifdef SK_BUILD_FOR_WIN
600 : if (kIntel_GrGLVendor == ctxInfo.vendor()) {
601 : fCrossContextTextureSupport = false;
602 : }
603 : #endif
604 :
605 : // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
606 : // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
607 : // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
608 : // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
609 0 : if (fMipMapLevelAndLodControlSupport &&
610 0 : (contextOptions.fDoManualMipmapping ||
611 0 : (kIntel_GrGLVendor == ctxInfo.vendor()) ||
612 0 : (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
613 0 : (kATI_GrGLVendor == ctxInfo.vendor()))) {
614 0 : fDoManualMipmapping = true;
615 : }
616 :
617 0 : fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
618 0 : fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
619 0 : kChromium_GrGLDriver != ctxInfo.driver();
620 :
621 : // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
622 : // already been detected.
623 0 : this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
624 :
625 0 : this->applyOptionsOverrides(contextOptions);
626 0 : shaderCaps->applyOptionsOverrides(contextOptions);
627 0 : }
628 :
629 0 : const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
630 : bool isCoreProfile) {
631 0 : switch (generation) {
632 : case k110_GrGLSLGeneration:
633 0 : if (kGLES_GrGLStandard == standard) {
634 : // ES2s shader language is based on version 1.20 but is version
635 : // 1.00 of the ES language.
636 0 : return "#version 100\n";
637 : } else {
638 0 : SkASSERT(kGL_GrGLStandard == standard);
639 0 : return "#version 110\n";
640 : }
641 : case k130_GrGLSLGeneration:
642 0 : SkASSERT(kGL_GrGLStandard == standard);
643 0 : return "#version 130\n";
644 : case k140_GrGLSLGeneration:
645 0 : SkASSERT(kGL_GrGLStandard == standard);
646 0 : return "#version 140\n";
647 : case k150_GrGLSLGeneration:
648 0 : SkASSERT(kGL_GrGLStandard == standard);
649 0 : if (isCoreProfile) {
650 0 : return "#version 150\n";
651 : } else {
652 0 : return "#version 150 compatibility\n";
653 : }
654 : case k330_GrGLSLGeneration:
655 0 : if (kGLES_GrGLStandard == standard) {
656 0 : return "#version 300 es\n";
657 : } else {
658 0 : SkASSERT(kGL_GrGLStandard == standard);
659 0 : if (isCoreProfile) {
660 0 : return "#version 330\n";
661 : } else {
662 0 : return "#version 330 compatibility\n";
663 : }
664 : }
665 : case k400_GrGLSLGeneration:
666 0 : SkASSERT(kGL_GrGLStandard == standard);
667 0 : if (isCoreProfile) {
668 0 : return "#version 400\n";
669 : } else {
670 0 : return "#version 400 compatibility\n";
671 : }
672 : case k420_GrGLSLGeneration:
673 0 : SkASSERT(kGL_GrGLStandard == standard);
674 0 : if (isCoreProfile) {
675 0 : return "#version 420\n";
676 : }
677 : else {
678 0 : return "#version 420 compatibility\n";
679 : }
680 : case k310es_GrGLSLGeneration:
681 0 : SkASSERT(kGLES_GrGLStandard == standard);
682 0 : return "#version 310 es\n";
683 : case k320es_GrGLSLGeneration:
684 0 : SkASSERT(kGLES_GrGLStandard == standard);
685 0 : return "#version 320 es\n";
686 : }
687 0 : return "<no version>";
688 : }
689 :
690 0 : void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
691 0 : GrGLStandard standard = ctxInfo.standard();
692 0 : GrGLVersion version = ctxInfo.version();
693 :
694 : /**************************************************************************
695 : * Caps specific to GrShaderCaps
696 : **************************************************************************/
697 :
698 0 : GrShaderCaps* shaderCaps = fShaderCaps.get();
699 0 : shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
700 0 : if (kGLES_GrGLStandard == standard) {
701 0 : if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
702 0 : shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
703 0 : shaderCaps->fFBFetchSupport = true;
704 0 : shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
705 0 : shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
706 : }
707 0 : else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
708 : // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
709 0 : shaderCaps->fFBFetchNeedsCustomOutput = false;
710 0 : shaderCaps->fFBFetchSupport = true;
711 0 : shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
712 0 : shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
713 : }
714 0 : else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
715 : // The arm extension also requires an additional flag which we will set onResetContext
716 0 : shaderCaps->fFBFetchNeedsCustomOutput = false;
717 0 : shaderCaps->fFBFetchSupport = true;
718 0 : shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
719 0 : shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
720 : }
721 0 : shaderCaps->fUsesPrecisionModifiers = true;
722 : }
723 :
724 : // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
725 : // Galaxy S7.
726 : // TODO: Once this is fixed we can update the check here to look at a driver version number too.
727 0 : if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
728 0 : shaderCaps->fFBFetchSupport = false;
729 : }
730 :
731 0 : shaderCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
732 :
733 0 : if (kGL_GrGLStandard == standard) {
734 0 : shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
735 : } else {
736 0 : shaderCaps->fFlatInterpolationSupport =
737 0 : ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
738 : }
739 :
740 0 : if (kGL_GrGLStandard == standard) {
741 0 : shaderCaps->fNoPerspectiveInterpolationSupport =
742 0 : ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
743 : } else {
744 0 : if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
745 0 : shaderCaps->fNoPerspectiveInterpolationSupport = true;
746 0 : shaderCaps->fNoPerspectiveInterpolationExtensionString =
747 : "GL_NV_shader_noperspective_interpolation";
748 : }
749 : }
750 :
751 0 : if (kGL_GrGLStandard == standard) {
752 0 : shaderCaps->fMultisampleInterpolationSupport =
753 0 : ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
754 : } else {
755 0 : if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
756 0 : shaderCaps->fMultisampleInterpolationSupport = true;
757 0 : } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
758 0 : shaderCaps->fMultisampleInterpolationSupport = true;
759 0 : shaderCaps->fMultisampleInterpolationExtensionString =
760 : "GL_OES_shader_multisample_interpolation";
761 : }
762 : }
763 :
764 0 : if (kGL_GrGLStandard == standard) {
765 0 : shaderCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
766 : } else {
767 0 : if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
768 0 : shaderCaps->fSampleVariablesSupport = true;
769 0 : } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
770 0 : shaderCaps->fSampleVariablesSupport = true;
771 0 : shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
772 : }
773 : }
774 :
775 0 : if (shaderCaps->fSampleVariablesSupport &&
776 0 : ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
777 : // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
778 0 : shaderCaps->fSampleMaskOverrideCoverageSupport =
779 0 : kNVIDIA_GrGLDriver != ctxInfo.driver() ||
780 0 : ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
781 : }
782 :
783 : // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
784 0 : shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
785 :
786 : // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
787 : // function that may require a gradient calculation inside a conditional block may return
788 : // undefined results". This appears to be an issue with the 'any' call since even the simple
789 : // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
790 : // from our GrTextureDomain processor.
791 0 : shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
792 :
793 0 : shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
794 : shaderCaps->fGLSLGeneration,
795 0 : fIsCoreProfile);
796 :
797 0 : if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
798 0 : shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
799 : }
800 :
801 : // Frag Coords Convention support is not part of ES
802 : // Known issue on at least some Intel platforms:
803 : // http://code.google.com/p/skia/issues/detail?id=946
804 0 : if (kIntel_GrGLVendor != ctxInfo.vendor() &&
805 0 : kGLES_GrGLStandard != standard &&
806 0 : (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
807 0 : ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
808 0 : shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
809 : }
810 :
811 0 : if (kGLES_GrGLStandard == standard) {
812 0 : shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
813 : }
814 :
815 0 : if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
816 0 : if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
817 0 : shaderCaps->fExternalTextureSupport = true;
818 0 : } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
819 0 : ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
820 : // At least one driver has been found that has this extension without the "GL_" prefix.
821 0 : shaderCaps->fExternalTextureSupport = true;
822 : }
823 : }
824 :
825 0 : if (shaderCaps->fExternalTextureSupport) {
826 0 : if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
827 0 : shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
828 : } else {
829 0 : shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
830 : }
831 : }
832 :
833 0 : if (kGL_GrGLStandard == standard) {
834 0 : shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
835 : } else {
836 0 : shaderCaps->fTexelFetchSupport =
837 0 : ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
838 : }
839 :
840 0 : if (shaderCaps->fTexelFetchSupport) {
841 0 : if (kGL_GrGLStandard == standard) {
842 0 : shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
843 0 : ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
844 : } else {
845 0 : if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
846 0 : ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
847 0 : shaderCaps->fTexelBufferSupport = true;
848 0 : } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
849 0 : shaderCaps->fTexelBufferSupport = true;
850 0 : shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
851 0 : } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
852 0 : shaderCaps->fTexelBufferSupport = true;
853 0 : shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
854 : }
855 : }
856 : }
857 :
858 : // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
859 : // the abs first in a separate expression.
860 0 : if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
861 0 : shaderCaps->fCanUseMinAndAbsTogether = false;
862 : }
863 :
864 : // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
865 : // thus must us -1.0 * %s.x to work correctly
866 0 : if (kIntel_GrGLVendor == ctxInfo.vendor()) {
867 0 : shaderCaps->fMustForceNegatedAtanParamToFloat = true;
868 : }
869 :
870 : // On Adreno devices with framebuffer fetch support, there is a bug where they always return
871 : // the original dst color when reading the outColor even after being written to. By using a
872 : // local outColor we can work around this bug.
873 0 : if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
874 0 : shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
875 : }
876 :
877 : #ifdef SK_BUILD_FOR_MAC
878 : // On at least some MacBooks, geometry shaders fall apart if we use more than one invocation. To
879 : // work around this, we always use a single invocation and wrap the shader in a loop. The long-
880 : // term plan for this WAR is for it to eventually be baked into SkSL.
881 : shaderCaps->fMustImplementGSInvocationsWithLoop = true;
882 : #endif
883 0 : }
884 :
885 0 : bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
886 0 : bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
887 :
888 0 : if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
889 0 : return false;
890 : }
891 :
892 0 : if (kGL_GrGLStandard == ctxInfo.standard()) {
893 0 : if (ctxInfo.version() < GR_GL_VER(4, 3) &&
894 0 : !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
895 0 : return false;
896 : }
897 : } else {
898 0 : if (!hasChromiumPathRendering &&
899 0 : ctxInfo.version() < GR_GL_VER(3, 1)) {
900 0 : return false;
901 : }
902 : }
903 : // We only support v1.3+ of GL_NV_path_rendering which allows us to
904 : // set individual fragment inputs with ProgramPathFragmentInputGen. The API
905 : // additions are detected by checking the existence of the function.
906 : // We also use *Then* functions that not all drivers might have. Check
907 : // them for consistency.
908 0 : if (!gli->fFunctions.fStencilThenCoverFillPath ||
909 0 : !gli->fFunctions.fStencilThenCoverStrokePath ||
910 0 : !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
911 0 : !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
912 0 : !gli->fFunctions.fProgramPathFragmentInputGen) {
913 0 : return false;
914 : }
915 0 : return true;
916 : }
917 :
918 0 : bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
919 : GrPixelConfig readConfig,
920 : std::function<void (GrGLenum, GrGLint*)> getIntegerv,
921 : std::function<bool ()> bindRenderTarget,
922 : std::function<void ()> unbindRenderTarget) const {
923 : // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
924 : // not supported regardless of readConfig.
925 0 : if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
926 0 : return false;
927 : }
928 :
929 0 : if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
930 0 : return false;
931 : }
932 :
933 : GrGLenum readFormat;
934 : GrGLenum readType;
935 0 : if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
936 0 : return false;
937 : }
938 :
939 0 : if (kGL_GrGLStandard == fStandard) {
940 : // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
941 : // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
942 : // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
943 : // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
944 : // The manual does not seem to fully match the spec as the spec allows integer formats
945 : // when the bound color buffer is an integer buffer. It doesn't specify which integer
946 : // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
947 0 : if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
948 0 : readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
949 0 : readFormat != GR_GL_RGBA_INTEGER) {
950 0 : return false;
951 : }
952 : // There is also a set of allowed types, but all the types we use are in the set:
953 : // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
954 : // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
955 : // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
956 : // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
957 : // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
958 : // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
959 : // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
960 0 : return true;
961 : }
962 :
963 : // See Section 16.1.2 in the ES 3.2 specification.
964 0 : switch (fConfigTable[surfaceConfig].fFormatType) {
965 : case kNormalizedFixedPoint_FormatType:
966 0 : if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
967 0 : return true;
968 : }
969 0 : break;
970 : case kInteger_FormatType:
971 0 : if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
972 0 : return true;
973 : }
974 0 : break;
975 : case kFloat_FormatType:
976 0 : if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
977 0 : return true;
978 : }
979 0 : break;
980 : }
981 :
982 0 : if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
983 : ReadPixelsFormat* rpFormat =
984 0 : const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
985 0 : GrGLint format = 0, type = 0;
986 0 : if (!bindRenderTarget()) {
987 0 : return false;
988 : }
989 0 : getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
990 0 : getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
991 0 : rpFormat->fFormat = format;
992 0 : rpFormat->fType = type;
993 0 : unbindRenderTarget();
994 : }
995 :
996 0 : return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
997 0 : fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
998 : }
999 :
1000 0 : void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
1001 0 : if (kGL_GrGLStandard != ctxInfo.standard()) {
1002 : // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
1003 : // ES3 driver bugs on at least one device with a tiled GPU (N10).
1004 0 : if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1005 0 : fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1006 0 : } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1007 0 : fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
1008 0 : } else if (fUsesMixedSamples) {
1009 0 : fMSFBOType = kMixedSamples_MSFBOType;
1010 0 : } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1011 0 : ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
1012 0 : ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
1013 0 : fMSFBOType = kStandard_MSFBOType;
1014 0 : } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1015 0 : fMSFBOType = kES_Apple_MSFBOType;
1016 : }
1017 :
1018 : // Above determined the preferred MSAA approach, now decide whether glBlitFramebuffer
1019 : // is available.
1020 0 : if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
1021 0 : fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
1022 : kNoMSAADst_BlitFramebufferFlag |
1023 : kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
1024 0 : } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
1025 0 : ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
1026 : // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
1027 : // limitations.
1028 0 : fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
1029 : kResolveMustBeFull_BlitFrambufferFlag |
1030 : kNoMSAADst_BlitFramebufferFlag |
1031 : kNoFormatConversion_BlitFramebufferFlag |
1032 : kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
1033 : }
1034 : } else {
1035 0 : if (fUsesMixedSamples) {
1036 0 : fMSFBOType = kMixedSamples_MSFBOType;
1037 0 : fBlitFramebufferFlags = 0;
1038 0 : } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1039 0 : ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
1040 0 : fMSFBOType = kStandard_MSFBOType;
1041 0 : fBlitFramebufferFlags = 0;
1042 0 : } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1043 0 : ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
1044 0 : fMSFBOType = kEXT_MSFBOType;
1045 0 : fBlitFramebufferFlags = 0;
1046 : }
1047 : }
1048 0 : }
1049 :
1050 0 : void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
1051 0 : GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
1052 :
1053 : // Disabling advanced blend on various platforms with major known issues. We also block Chrome
1054 : // for now until its own blacklists can be updated.
1055 0 : if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
1056 0 : kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
1057 0 : kIntel_GrGLDriver == ctxInfo.driver() ||
1058 0 : kChromium_GrGLDriver == ctxInfo.driver()) {
1059 0 : return;
1060 : }
1061 :
1062 0 : if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1063 0 : fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1064 0 : shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1065 0 : } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
1066 0 : fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1067 0 : shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1068 0 : } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1069 0 : ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1070 : // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1071 0 : return;
1072 0 : } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1073 0 : fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1074 0 : shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
1075 0 : } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
1076 0 : fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1077 0 : shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
1078 : // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1079 : // slow on a particular platform.
1080 : } else {
1081 0 : return; // No advanced blend support.
1082 : }
1083 :
1084 0 : SkASSERT(this->advancedBlendEquationSupport());
1085 :
1086 0 : if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1087 0 : ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1088 : // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
1089 0 : fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1090 0 : (1 << kColorBurn_GrBlendEquation);
1091 : }
1092 0 : if (kARM_GrGLVendor == ctxInfo.vendor()) {
1093 : // Blacklist color-burn on ARM until the fix is released.
1094 0 : fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1095 : }
1096 : }
1097 :
1098 : namespace {
1099 : const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
1100 : }
1101 :
1102 0 : void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
1103 :
1104 : // Build up list of legal stencil formats (though perhaps not supported on
1105 : // the particular gpu/driver) from most preferred to least.
1106 :
1107 : // these consts are in order of most preferred to least preferred
1108 : // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1109 :
1110 : static const StencilFormat
1111 : // internal Format stencil bits total bits packed?
1112 : gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1113 : gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1114 : gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1115 : gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
1116 : // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
1117 : gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1118 :
1119 0 : if (kGL_GrGLStandard == ctxInfo.standard()) {
1120 : bool supportsPackedDS =
1121 0 : ctxInfo.version() >= GR_GL_VER(3,0) ||
1122 0 : ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1123 0 : ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1124 :
1125 : // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1126 : // require FBO support we can expect these are legal formats and don't
1127 : // check. These also all support the unsized GL_STENCIL_INDEX.
1128 0 : fStencilFormats.push_back() = gS8;
1129 0 : fStencilFormats.push_back() = gS16;
1130 0 : if (supportsPackedDS) {
1131 0 : fStencilFormats.push_back() = gD24S8;
1132 : }
1133 0 : fStencilFormats.push_back() = gS4;
1134 0 : if (supportsPackedDS) {
1135 0 : fStencilFormats.push_back() = gDS;
1136 : }
1137 : } else {
1138 : // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1139 : // for other formats.
1140 : // ES doesn't support using the unsized format.
1141 :
1142 0 : fStencilFormats.push_back() = gS8;
1143 : //fStencilFormats.push_back() = gS16;
1144 0 : if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1145 0 : ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
1146 0 : fStencilFormats.push_back() = gD24S8;
1147 : }
1148 0 : if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1149 0 : fStencilFormats.push_back() = gS4;
1150 : }
1151 : }
1152 0 : }
1153 :
1154 0 : SkString GrGLCaps::dump() const {
1155 :
1156 0 : SkString r = INHERITED::dump();
1157 :
1158 0 : r.appendf("--- GL-Specific ---\n");
1159 0 : for (int i = 0; i < fStencilFormats.count(); ++i) {
1160 : r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
1161 : i,
1162 0 : fStencilFormats[i].fStencilBits,
1163 0 : fStencilFormats[i].fTotalBits);
1164 : }
1165 :
1166 : static const char* kMSFBOExtStr[] = {
1167 : "None",
1168 : "EXT",
1169 : "Standard",
1170 : "Apple",
1171 : "IMG MS To Texture",
1172 : "EXT MS To Texture",
1173 : "MixedSamples",
1174 : };
1175 : GR_STATIC_ASSERT(0 == kNone_MSFBOType);
1176 : GR_STATIC_ASSERT(1 == kEXT_MSFBOType);
1177 : GR_STATIC_ASSERT(2 == kStandard_MSFBOType);
1178 : GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
1179 : GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
1180 : GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
1181 : GR_STATIC_ASSERT(6 == kMixedSamples_MSFBOType);
1182 : GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
1183 :
1184 : static const char* kInvalidateFBTypeStr[] = {
1185 : "None",
1186 : "Discard",
1187 : "Invalidate",
1188 : };
1189 : GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1190 : GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1191 : GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1192 : GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
1193 :
1194 : static const char* kMapBufferTypeStr[] = {
1195 : "None",
1196 : "MapBuffer",
1197 : "MapBufferRange",
1198 : "Chromium",
1199 : };
1200 : GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1201 : GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1202 : GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1203 : GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1204 : GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1205 :
1206 0 : r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
1207 0 : r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
1208 0 : r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
1209 0 : r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
1210 0 : r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
1211 0 : r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
1212 0 : r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
1213 0 : r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
1214 0 : r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
1215 :
1216 0 : r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
1217 0 : r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
1218 0 : r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
1219 0 : r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
1220 0 : r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
1221 0 : r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
1222 0 : r.appendf("Draw instanced support: %s\n", (fDrawInstancedSupport ? "YES" : "NO"));
1223 0 : r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
1224 0 : r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
1225 0 : r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
1226 0 : r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
1227 0 : r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
1228 0 : r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
1229 0 : r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
1230 0 : r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
1231 0 : r.appendf("BGRA to RGBA readback conversions are slow: %s\n",
1232 0 : (fRGBAToBGRAReadbackConversionsAreSlow ? "YES" : "NO"));
1233 :
1234 0 : r.append("Configs\n-------\n");
1235 0 : for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1236 : r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
1237 : "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
1238 : "i_for_renderbuffer: 0x%08x\n",
1239 : i,
1240 0 : fConfigTable[i].fFlags,
1241 0 : fConfigTable[i].fFormats.fBaseInternalFormat,
1242 0 : fConfigTable[i].fFormats.fSizedInternalFormat,
1243 0 : fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
1244 0 : fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
1245 0 : fConfigTable[i].fFormats.fExternalType,
1246 0 : fConfigTable[i].fFormats.fInternalFormatTexImage,
1247 0 : fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1248 : }
1249 :
1250 0 : return r;
1251 : }
1252 :
1253 0 : static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1254 0 : switch (p) {
1255 : case kLow_GrSLPrecision:
1256 0 : return GR_GL_LOW_FLOAT;
1257 : case kMedium_GrSLPrecision:
1258 0 : return GR_GL_MEDIUM_FLOAT;
1259 : case kHigh_GrSLPrecision:
1260 0 : return GR_GL_HIGH_FLOAT;
1261 : default:
1262 0 : SkFAIL("Unexpected precision type.");
1263 0 : return -1;
1264 : }
1265 : }
1266 :
1267 0 : static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1268 0 : switch (type) {
1269 : case kVertex_GrShaderType:
1270 0 : return GR_GL_VERTEX_SHADER;
1271 : case kGeometry_GrShaderType:
1272 0 : return GR_GL_GEOMETRY_SHADER;
1273 : case kFragment_GrShaderType:
1274 0 : return GR_GL_FRAGMENT_SHADER;
1275 : }
1276 0 : SkFAIL("Unknown shader type.");
1277 0 : return -1;
1278 : }
1279 :
1280 0 : void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
1281 : const GrGLInterface* intf,
1282 : GrShaderCaps* shaderCaps) {
1283 0 : if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1284 0 : ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1285 0 : for (int s = 0; s < kGrShaderTypeCount; ++s) {
1286 0 : if (kGeometry_GrShaderType != s) {
1287 0 : GrShaderType shaderType = static_cast<GrShaderType>(s);
1288 0 : GrGLenum glShader = shader_type_to_gl_shader(shaderType);
1289 0 : GrShaderCaps::PrecisionInfo* first = nullptr;
1290 0 : shaderCaps->fShaderPrecisionVaries = false;
1291 0 : for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1292 0 : GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1293 0 : GrGLenum glPrecision = precision_to_gl_float_type(precision);
1294 : GrGLint range[2];
1295 : GrGLint bits;
1296 0 : GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1297 0 : if (bits) {
1298 0 : shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1299 0 : shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1300 0 : shaderCaps->fFloatPrecisions[s][p].fBits = bits;
1301 0 : if (!first) {
1302 0 : first = &shaderCaps->fFloatPrecisions[s][p];
1303 : }
1304 0 : else if (!shaderCaps->fShaderPrecisionVaries) {
1305 0 : shaderCaps->fShaderPrecisionVaries =
1306 0 : (*first != shaderCaps->fFloatPrecisions[s][p]);
1307 : }
1308 : }
1309 : }
1310 : }
1311 : }
1312 : }
1313 : else {
1314 : // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
1315 0 : shaderCaps->fShaderPrecisionVaries = false;
1316 0 : for (int s = 0; s < kGrShaderTypeCount; ++s) {
1317 0 : if (kGeometry_GrShaderType != s) {
1318 0 : for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1319 0 : shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1320 0 : shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1321 0 : shaderCaps->fFloatPrecisions[s][p].fBits = 23;
1322 : }
1323 : }
1324 : }
1325 : }
1326 : // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1327 : // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1328 : // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1329 : // are recommended against.
1330 0 : if (shaderCaps->fGeometryShaderSupport) {
1331 0 : for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1332 0 : shaderCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1333 : shaderCaps->fFloatPrecisions[kVertex_GrShaderType][p];
1334 : }
1335 : }
1336 0 : shaderCaps->initSamplerPrecisionTable();
1337 0 : }
1338 :
1339 0 : bool GrGLCaps::bgraIsInternalFormat() const {
1340 0 : return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1341 : }
1342 :
1343 0 : bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1344 : GrGLenum* internalFormat, GrGLenum* externalFormat,
1345 : GrGLenum* externalType) const {
1346 0 : if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1347 : externalFormat, externalType)) {
1348 0 : return false;
1349 : }
1350 0 : *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1351 0 : return true;
1352 : }
1353 :
1354 0 : bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1355 : GrGLenum* internalFormat) const {
1356 0 : if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1357 0 : return false;
1358 : }
1359 0 : *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1360 0 : return true;
1361 : }
1362 :
1363 0 : bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1364 : GrGLenum* externalFormat, GrGLenum* externalType) const {
1365 0 : if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1366 : externalFormat, externalType)) {
1367 0 : return false;
1368 : }
1369 0 : return true;
1370 : }
1371 :
1372 0 : bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1373 0 : if (GrPixelConfigIsCompressed(config)) {
1374 0 : return false;
1375 : }
1376 0 : *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1377 0 : return true;
1378 : }
1379 :
1380 0 : bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1381 : ExternalFormatUsage usage, GrGLenum* externalFormat,
1382 : GrGLenum* externalType) const {
1383 0 : SkASSERT(externalFormat && externalType);
1384 0 : if (GrPixelConfigIsCompressed(memoryConfig)) {
1385 0 : return false;
1386 : }
1387 :
1388 0 : bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1389 0 : bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1390 :
1391 : // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1392 : // made to work in many cases using glPixelStore and what not but is not needed currently.
1393 0 : if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1394 0 : return false;
1395 : }
1396 :
1397 0 : *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1398 0 : *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1399 :
1400 : // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1401 : // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1402 : // surface is not alpha-only and we want alpha to really mean the alpha component of the
1403 : // texture, not the red component.
1404 0 : if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1405 0 : if (this->textureRedSupport()) {
1406 0 : SkASSERT(GR_GL_RED == *externalFormat);
1407 0 : *externalFormat = GR_GL_ALPHA;
1408 : }
1409 : }
1410 :
1411 0 : return true;
1412 : }
1413 :
1414 0 : void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1415 : const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1416 : GrShaderCaps* shaderCaps) {
1417 : /*
1418 : Comments on renderability of configs on various GL versions.
1419 : OpenGL < 3.0:
1420 : no built in support for render targets.
1421 : GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1422 : format RGB, RGBA and NV float formats we don't use.
1423 : This is the following:
1424 : R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1425 : RGB10_A2, RGBA12,RGBA16
1426 : Though, it is hard to believe the more obscure formats such as RGBA12 would work
1427 : since they aren't required by later standards and the driver can simply return
1428 : FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1429 : GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1430 : any sized internal format with a base internal format of ALPHA, LUMINANCE,
1431 : LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1432 : This adds a lot of additional renderable sized formats, including ALPHA8.
1433 : The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1434 : 16F, 32I, 32UI, and 32F variants).
1435 : Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1436 :
1437 : For both the above extensions we limit ourselves to those that are also required by
1438 : OpenGL 3.0.
1439 :
1440 : OpenGL 3.0:
1441 : Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1442 : but are not required to be supported as renderable textures/renderbuffer.
1443 : Required renderable color formats:
1444 : - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1445 : RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1446 : RGB10_A2.
1447 : - R11F_G11F_B10F.
1448 : - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1449 : and RG8UI.
1450 : - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1451 : - ALPHA8
1452 :
1453 : OpenGL 3.1, 3.2, 3.3
1454 : Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1455 : OpengGL 3.3, 4.0, 4.1
1456 : Adds RGB10_A2UI.
1457 : OpengGL 4.2
1458 : Adds
1459 : - RGB5_A1, RGBA4
1460 : - RGB565
1461 : OpenGL 4.4
1462 : Does away with the separate list and adds a column to the sized internal color format
1463 : table. However, no new formats become required color renderable.
1464 :
1465 : ES 2.0
1466 : color renderable: RGBA4, RGB5_A1, RGB565
1467 : GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1468 : GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1469 : GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1470 : GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1471 : GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1472 : GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1473 :
1474 : ES 3.0
1475 : - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1476 : RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1477 : RGB5_A1.
1478 : - RGB8 and RGB565.
1479 : - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1480 : - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1481 : ES 3.1
1482 : Adds RGB10_A2, RGB10_A2UI,
1483 : ES 3.2
1484 : Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1485 : */
1486 : uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1487 0 : ConfigInfo::kFBOColorAttachment_Flag;
1488 0 : uint32_t allRenderFlags = nonMSAARenderFlags;
1489 0 : if (kNone_MSFBOType != fMSFBOType) {
1490 0 : allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1491 : }
1492 0 : GrGLStandard standard = ctxInfo.standard();
1493 0 : GrGLVersion version = ctxInfo.version();
1494 :
1495 0 : bool texStorageSupported = false;
1496 0 : if (kGL_GrGLStandard == standard) {
1497 : // The EXT version can apply to either GL or GLES.
1498 0 : texStorageSupported = version >= GR_GL_VER(4,2) ||
1499 0 : ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1500 0 : ctxInfo.hasExtension("GL_EXT_texture_storage");
1501 : } else {
1502 0 : texStorageSupported = version >= GR_GL_VER(3,0) ||
1503 0 : ctxInfo.hasExtension("GL_EXT_texture_storage");
1504 : }
1505 :
1506 : // TODO: remove after command buffer supports full ES 3.0
1507 0 : if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1508 0 : kChromium_GrGLDriver == ctxInfo.driver()) {
1509 0 : texStorageSupported = false;
1510 : }
1511 :
1512 0 : bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1513 :
1514 0 : fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1515 0 : fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
1516 0 : fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
1517 0 : fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
1518 0 : fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1519 0 : fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1520 :
1521 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1522 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1523 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1524 : GR_GL_RGBA;
1525 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1526 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1527 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1528 0 : if (kGL_GrGLStandard == standard) {
1529 : // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1530 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1531 : } else {
1532 0 : if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1533 0 : ctxInfo.hasExtension("GL_ARM_rgba8")) {
1534 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1535 : }
1536 : }
1537 0 : if (texStorageSupported) {
1538 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1539 : }
1540 0 : if (texelBufferSupport) {
1541 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1542 : }
1543 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1544 :
1545 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1546 : GR_GL_BGRA;
1547 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1548 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1549 0 : if (kGL_GrGLStandard == standard) {
1550 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1551 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1552 0 : if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1553 : // Since the internal format is RGBA8, it is also renderable.
1554 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1555 : allRenderFlags;
1556 : }
1557 : } else {
1558 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1559 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1560 0 : if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1561 : // The APPLE extension doesn't make this renderable.
1562 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1563 0 : if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1564 : // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1565 : // Though, that seems to not be the case if the texture storage extension is
1566 : // present. The specs don't exactly make that clear.
1567 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1568 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1569 : }
1570 0 : } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1571 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1572 : nonMSAARenderFlags;
1573 0 : if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1574 0 : (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1575 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1576 0 : ConfigInfo::kRenderableWithMSAA_Flag;
1577 : }
1578 : }
1579 : }
1580 0 : if (texStorageSupported) {
1581 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1582 : }
1583 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1584 :
1585 : // We only enable srgb support if both textures and FBOs support srgb,
1586 : // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
1587 0 : if (kGL_GrGLStandard == standard) {
1588 0 : if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1589 0 : fSRGBSupport = true;
1590 0 : } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1591 0 : if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1592 0 : ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1593 0 : fSRGBSupport = true;
1594 : }
1595 : }
1596 : // All the above srgb extensions support toggling srgb writes
1597 0 : if (fSRGBSupport) {
1598 0 : fSRGBWriteControl = true;
1599 : }
1600 : } else {
1601 0 : fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
1602 : #if defined(SK_CPU_X86)
1603 0 : if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1604 : // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1605 : // blacklist that device (and any others that might be sharing the same driver).
1606 0 : fSRGBSupport = false;
1607 : }
1608 : #endif
1609 : // ES through 3.1 requires EXT_srgb_write_control to support toggling
1610 : // sRGB writing for destinations.
1611 : // See https://bug.skia.org/5329 for Adreno4xx issue.
1612 0 : fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1613 0 : ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1614 : }
1615 0 : if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1616 : // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1617 : // can opt-out of that requirement, if they intend to always do linear blending.
1618 0 : fSRGBSupport = false;
1619 : }
1620 :
1621 : // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1622 : // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1623 : // and sBGRA is basically impossible to support on any version of ES (with our current code).
1624 : // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1625 : // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1626 : // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1627 : // affects Windows.
1628 0 : if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1629 0 : fSRGBSupport = false;
1630 : }
1631 :
1632 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1633 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1634 : // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1635 : // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
1636 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1637 : GR_GL_RGBA;
1638 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1639 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1640 0 : if (fSRGBSupport) {
1641 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1642 : allRenderFlags;
1643 : }
1644 0 : if (texStorageSupported) {
1645 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1646 : }
1647 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1648 :
1649 : // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1650 : // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1651 : // is in this format, for example).
1652 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1653 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1654 : // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1655 : // external format is GL_BGRA.
1656 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1657 : GR_GL_BGRA;
1658 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1659 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1660 0 : if (fSRGBSupport) {
1661 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1662 : allRenderFlags;
1663 : }
1664 0 : if (texStorageSupported) {
1665 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1666 : }
1667 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1668 :
1669 : bool hasIntegerTextures;
1670 0 : if (standard == kGL_GrGLStandard) {
1671 0 : hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1672 0 : ctxInfo.hasExtension("GL_EXT_texture_integer");
1673 : } else {
1674 0 : hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1675 : }
1676 : // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1677 0 : if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1678 0 : hasIntegerTextures = false;
1679 : }
1680 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1681 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1682 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1683 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1684 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1685 : // We currently only support using integer textures as srcs, not for rendering (even though GL
1686 : // allows it).
1687 0 : if (hasIntegerTextures) {
1688 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1689 : ConfigInfo::kFBOColorAttachment_Flag;
1690 0 : if (texStorageSupported) {
1691 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1692 0 : ConfigInfo::kCanUseTexStorage_Flag;
1693 : }
1694 : }
1695 :
1696 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1697 0 : if (this->ES2CompatibilitySupport()) {
1698 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1699 : } else {
1700 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1701 : }
1702 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1703 : GR_GL_RGB;
1704 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
1705 0 : fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1706 0 : fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1707 0 : if (kGL_GrGLStandard == standard) {
1708 0 : if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1709 0 : fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1710 : }
1711 : } else {
1712 0 : fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1713 : }
1714 : // 565 is not a sized internal format on desktop GL. So on desktop with
1715 : // 565 we always use an unsized internal format to let the system pick
1716 : // the best sized format to convert the 565 data to. Since TexStorage
1717 : // only allows sized internal formats we disallow it.
1718 : //
1719 : // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1720 : // update.
1721 0 : if (texStorageSupported && kGL_GrGLStandard != standard) {
1722 0 : fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1723 : }
1724 0 : fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1725 :
1726 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1727 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
1728 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1729 : GR_GL_RGBA;
1730 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
1731 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1732 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1733 0 : if (kGL_GrGLStandard == standard) {
1734 0 : if (version >= GR_GL_VER(4, 2)) {
1735 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1736 : }
1737 : } else {
1738 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1739 : }
1740 0 : if (texStorageSupported) {
1741 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1742 : }
1743 0 : fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1744 :
1745 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1746 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1747 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1748 0 : if (this->textureRedSupport()) {
1749 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1750 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1751 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1752 : GR_GL_RED;
1753 0 : fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
1754 0 : if (texelBufferSupport) {
1755 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1756 : }
1757 : } else {
1758 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1759 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
1760 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1761 : GR_GL_ALPHA;
1762 0 : fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
1763 : }
1764 0 : if (this->textureRedSupport() ||
1765 0 : (kStandard_MSFBOType == this->msFBOType() && ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1766 : // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1767 : // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1768 : // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1769 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1770 : }
1771 0 : if (texStorageSupported) {
1772 0 : fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1773 : }
1774 :
1775 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1776 0 : fConfigTable[kGray_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1777 0 : fConfigTable[kGray_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1778 0 : if (this->textureRedSupport()) {
1779 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1780 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1781 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1782 : GR_GL_RED;
1783 0 : fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRA();
1784 0 : if (texelBufferSupport) {
1785 0 : fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1786 : }
1787 : } else {
1788 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1789 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1790 0 : fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1791 : GR_GL_LUMINANCE;
1792 0 : fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1793 : }
1794 : #if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster
1795 : if (this->textureRedSupport() ||
1796 : (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1797 : ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1798 : // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1799 : // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1800 : // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1801 : fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1802 : }
1803 : #endif
1804 0 : if (texStorageSupported) {
1805 0 : fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1806 : }
1807 :
1808 : // Check for [half] floating point texture support
1809 : // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1810 : // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1811 : // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1812 0 : bool hasFPTextures = false;
1813 0 : bool hasHalfFPTextures = false;
1814 : // for now we don't support floating point MSAA on ES
1815 0 : uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
1816 :
1817 0 : if (kGL_GrGLStandard == standard) {
1818 0 : if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1819 0 : hasFPTextures = true;
1820 0 : hasHalfFPTextures = true;
1821 : }
1822 : } else {
1823 0 : if (version >= GR_GL_VER(3, 1)) {
1824 0 : hasFPTextures = true;
1825 0 : hasHalfFPTextures = true;
1826 : } else {
1827 0 : if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1828 0 : ctxInfo.hasExtension("GL_OES_texture_float")) {
1829 0 : hasFPTextures = true;
1830 : }
1831 0 : if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1832 0 : ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1833 0 : hasHalfFPTextures = true;
1834 : }
1835 : }
1836 : }
1837 :
1838 0 : for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1839 0 : const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1840 0 : fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1841 0 : fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1842 0 : kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
1843 0 : fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
1844 0 : fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1845 0 : fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1846 0 : if (hasFPTextures) {
1847 0 : fConfigTable[fpconfig].fFlags = ConfigInfo::kTextureable_Flag;
1848 : // For now we only enable rendering to float on desktop, because on ES we'd have to
1849 : // solve many precision issues and no clients actually want this yet.
1850 0 : if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1851 : ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1852 0 : fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1853 : }
1854 : }
1855 0 : if (texStorageSupported) {
1856 0 : fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1857 : }
1858 0 : if (texelBufferSupport) {
1859 0 : fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1860 : }
1861 0 : fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
1862 : }
1863 :
1864 0 : if (this->textureRedSupport()) {
1865 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1866 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
1867 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1868 0 : = GR_GL_RED;
1869 0 : fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
1870 0 : if (texelBufferSupport) {
1871 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFlags |=
1872 0 : ConfigInfo::kCanUseWithTexelBuffer_Flag;
1873 : }
1874 : } else {
1875 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1876 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
1877 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1878 0 : = GR_GL_ALPHA;
1879 0 : fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
1880 : }
1881 : // ANGLE always returns GL_HALF_FLOAT_OES for GL_IMPLEMENTATION_COLOR_READ_TYPE, even though
1882 : // ES3 would typically return GL_HALF_FLOAT. The correct fix is for us to respect the value
1883 : // returned when we query, but that turns into a bigger refactor, so just work around it.
1884 0 : if (kGL_GrGLStandard == ctxInfo.standard() ||
1885 0 : (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
1886 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1887 : } else {
1888 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1889 : }
1890 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
1891 0 : if (texStorageSupported) {
1892 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1893 : }
1894 0 : if (hasHalfFPTextures) {
1895 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1896 : // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1897 : // GL_RED internal format.
1898 0 : if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
1899 0 : (this->textureRedSupport() &&
1900 0 : ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1901 0 : fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1902 : }
1903 : }
1904 :
1905 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1906 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
1907 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1908 : GR_GL_RGBA;
1909 : // See comment above, re: ANGLE and ES3.
1910 0 : if (kGL_GrGLStandard == ctxInfo.standard() ||
1911 0 : (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
1912 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1913 : } else {
1914 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1915 : }
1916 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
1917 0 : if (hasHalfFPTextures) {
1918 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1919 : // ES requires 3.2 or EXT_color_buffer_half_float.
1920 0 : if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1921 0 : ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1922 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1923 : }
1924 : }
1925 0 : if (texStorageSupported) {
1926 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1927 : }
1928 0 : if (texelBufferSupport) {
1929 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1930 : }
1931 0 : fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1932 :
1933 : // Compressed texture support
1934 :
1935 : // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1936 : // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1937 :
1938 : // TODO: Fix command buffer bindings and remove this.
1939 0 : fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
1940 :
1941 : // No sized/unsized internal format distinction for compressed formats, no external format.
1942 : // Below we set the external formats and types to 0.
1943 : {
1944 0 : fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1945 0 : fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat =
1946 : GR_GL_COMPRESSED_ETC1_RGB8;
1947 0 : fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
1948 0 : fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
1949 0 : fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1950 0 : if (kGL_GrGLStandard == standard) {
1951 0 : if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1952 0 : fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1953 : }
1954 : } else {
1955 0 : if (version >= GR_GL_VER(3, 0) ||
1956 0 : ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1957 : // ETC2 is a superset of ETC1, so we can just check for that, too.
1958 0 : (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1959 0 : ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1960 0 : fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1961 : }
1962 : }
1963 0 : fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1964 : }
1965 :
1966 : // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1967 :
1968 : // ES 2.0 requires that the internal/external formats match.
1969 0 : bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1970 0 : ctxInfo.version() >= GR_GL_VER(3,0));
1971 : // All ES versions (thus far) require sized internal formats for render buffers.
1972 : // TODO: Always use sized internal format?
1973 0 : bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1974 :
1975 0 : for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1976 : // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1977 : // param to glTex[Sub]Image.
1978 0 : fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1979 0 : fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1980 0 : fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1981 : fConfigTable[i].fFormats.fSizedInternalFormat :
1982 : fConfigTable[i].fFormats.fBaseInternalFormat;
1983 0 : fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
1984 : fConfigTable[i].fFormats.fSizedInternalFormat :
1985 : fConfigTable[i].fFormats.fBaseInternalFormat;
1986 : }
1987 : // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1988 : // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1989 : // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1990 : // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1991 0 : if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
1992 0 : fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1993 : GR_GL_SRGB_ALPHA;
1994 :
1995 : // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1996 : // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1997 : // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1998 0 : fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
1999 : }
2000 :
2001 : // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2002 : // as a base format.
2003 : // GL_EXT_texture_format_BGRA8888:
2004 : // This extension GL_BGRA as an unsized internal format. However, it is written against ES
2005 : // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
2006 : // formats.
2007 : // GL_APPLE_texture_format_BGRA8888:
2008 : // ES 2.0: the extension makes BGRA an external format but not an internal format.
2009 : // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
2010 : // glTexImage (just for glTexStorage).
2011 0 : if (useSizedTexFormats && this->bgraIsInternalFormat()) {
2012 0 : fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
2013 : }
2014 :
2015 : // If we don't have texture swizzle support then the shader generator must insert the
2016 : // swizzle into shader code.
2017 0 : if (!this->textureSwizzleSupport()) {
2018 0 : for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2019 0 : shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
2020 : }
2021 : }
2022 :
2023 : // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
2024 : // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
2025 : // gets written to the single component.
2026 0 : if (this->textureRedSupport()) {
2027 0 : for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2028 0 : GrPixelConfig config = static_cast<GrPixelConfig>(i);
2029 0 : if (GrPixelConfigIsAlphaOnly(config) &&
2030 0 : fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
2031 0 : shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
2032 : }
2033 : }
2034 : }
2035 :
2036 : // We currently only support images on rgba textures formats. We could add additional formats
2037 : // if desired. The shader builder would have to be updated to add swizzles where appropriate
2038 : // (e.g. where we use GL_RED textures to implement alpha configs).
2039 0 : if (this->shaderCaps()->imageLoadStoreSupport()) {
2040 0 : fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
2041 0 : ConfigInfo::kCanUseAsImageStorage_Flag;
2042 : // In OpenGL ES a texture may only be used with BindImageTexture if it has been made
2043 : // immutable via TexStorage. We create non-integer textures as mutable textures using
2044 : // TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
2045 : // storage support for non-integer textures.
2046 0 : if (kGL_GrGLStandard == ctxInfo.standard()) {
2047 0 : fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2048 0 : fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
2049 0 : ConfigInfo::kCanUseAsImageStorage_Flag;
2050 0 : fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2051 : }
2052 : }
2053 :
2054 : #ifdef SK_DEBUG
2055 : // Make sure we initialized everything.
2056 0 : ConfigInfo defaultEntry;
2057 0 : for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2058 : // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2059 : // renderable.
2060 : SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2061 : SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
2062 0 : SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2063 : fConfigTable[i].fFormats.fBaseInternalFormat);
2064 0 : SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
2065 : fConfigTable[i].fFormats.fSizedInternalFormat);
2066 0 : for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2067 0 : SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2068 : fConfigTable[i].fFormats.fExternalFormat[j]);
2069 : }
2070 0 : SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
2071 : }
2072 : #endif
2073 0 : }
2074 :
2075 0 : bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
2076 : bool* rectsMustMatch, bool* disallowSubrect) const {
2077 : // By default, we don't require rects to match.
2078 0 : *rectsMustMatch = false;
2079 :
2080 : // By default, we allow subrects.
2081 0 : *disallowSubrect = false;
2082 :
2083 : // If the src is a texture, we can implement the blit as a draw assuming the config is
2084 : // renderable.
2085 0 : if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
2086 0 : desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
2087 0 : desc->fFlags = kRenderTarget_GrSurfaceFlag;
2088 0 : desc->fConfig = src->config();
2089 0 : return true;
2090 : }
2091 :
2092 : {
2093 : // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2094 : // wrapped. In that case the proxy would already be instantiated.
2095 0 : const GrTexture* srcTexture = src->priv().peekTexture();
2096 0 : const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2097 0 : if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2098 : // Not supported for FBO blit or CopyTexSubImage
2099 0 : return false;
2100 : }
2101 : }
2102 :
2103 : // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2104 : // possible and we return false to fallback to creating a render target dst for render-to-
2105 : // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2106 : // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
2107 0 : GrSurfaceOrigin originForBlitFramebuffer = kDefault_GrSurfaceOrigin;
2108 0 : bool rectsMustMatchForBlitFramebuffer = false;
2109 0 : bool disallowSubrectForBlitFramebuffer = false;
2110 0 : if (src->numColorSamples() &&
2111 0 : (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2112 0 : rectsMustMatchForBlitFramebuffer = true;
2113 0 : disallowSubrectForBlitFramebuffer = true;
2114 : // Mirroring causes rects to mismatch later, don't allow it.
2115 0 : originForBlitFramebuffer = src->origin();
2116 0 : } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() &
2117 : kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
2118 0 : rectsMustMatchForBlitFramebuffer = true;
2119 : // Mirroring causes rects to mismatch later, don't allow it.
2120 0 : originForBlitFramebuffer = src->origin();
2121 0 : } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
2122 0 : originForBlitFramebuffer = src->origin();
2123 : }
2124 :
2125 : // Check for format issues with glCopyTexSubImage2D
2126 0 : if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2127 : // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2128 : // then we set up for that, otherwise fail.
2129 0 : if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2130 0 : desc->fOrigin = originForBlitFramebuffer;
2131 0 : desc->fConfig = kBGRA_8888_GrPixelConfig;
2132 0 : *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2133 0 : *disallowSubrect = disallowSubrectForBlitFramebuffer;
2134 0 : return true;
2135 : }
2136 0 : return false;
2137 : }
2138 :
2139 : {
2140 0 : bool srcIsMSAARenderbuffer = src->desc().fSampleCnt > 0 && this->usesMSAARenderBuffers();
2141 0 : if (srcIsMSAARenderbuffer) {
2142 : // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2143 : // blit or fail.
2144 0 : if (this->canConfigBeFBOColorAttachment(src->config())) {
2145 0 : desc->fOrigin = originForBlitFramebuffer;
2146 0 : desc->fConfig = src->config();
2147 0 : *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2148 0 : *disallowSubrect = disallowSubrectForBlitFramebuffer;
2149 0 : return true;
2150 : }
2151 0 : return false;
2152 : }
2153 : }
2154 :
2155 : // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2156 0 : desc->fConfig = src->config();
2157 0 : desc->fOrigin = src->origin();
2158 0 : desc->fFlags = kNone_GrSurfaceFlags;
2159 0 : return true;
2160 : }
2161 :
2162 0 : void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
2163 0 : if (options.fEnableInstancedRendering) {
2164 0 : fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
2165 : #ifndef SK_BUILD_FOR_MAC
2166 : // OS X doesn't seem to write correctly to floating point textures when using
2167 : // glDraw*Indirect, regardless of the underlying GPU.
2168 0 : fAvoidInstancedDrawsToFPTargets = true;
2169 : #endif
2170 : }
2171 0 : }
|