blob: 5605babcec8f9cd7cf12d5a865bd85f4ee8e343e [file] [log] [blame]
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001/*
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
9#include "GrGLCaps.h"
joshualittb4384b92014-10-21 12:53:15 -070010
egdanielb7e7d572015-11-04 04:23:53 -080011#include "GrContextOptions.h"
robertphillips@google.com6177e692013-02-28 20:16:25 +000012#include "GrGLContext.h"
jvanverthcba99b82015-06-24 06:59:57 -070013#include "glsl/GrGLSLCaps.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000014#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000015#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000016
bsalomon682c2692015-05-22 14:01:46 -070017GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
18 const GrGLContextInfo& ctxInfo,
19 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000020 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000021 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000022 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000023 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080024 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fMaxFragmentUniformVectors = 0;
bsalomon@google.com60da4172012-06-01 19:25:00 +000026 fMaxVertexAttributes = 0;
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000027 fMaxFragmentTextureUnits = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000028 fUnpackRowLengthSupport = false;
29 fUnpackFlipYSupport = false;
30 fPackRowLengthSupport = false;
31 fPackFlipYSupport = false;
32 fTextureUsageSupport = false;
33 fTexStorageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000034 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000035 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000036 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070037 fDirectStateAccessSupport = false;
38 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080039 fES2CompatibilitySupport = false;
cdaltond4727922015-11-10 12:49:06 -080040 fMultisampleDisableSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000041 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000042 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070043 fBindFragDataLocationSupport = false;
bsalomon7ea33f52015-11-22 14:51:00 -080044 fExternalTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080045 fTextureSwizzleSupport = false;
bsalomon16921ec2015-07-30 15:34:56 -070046 fSRGBWriteControl = false;
bsalomon88c7b982015-07-31 11:20:16 -070047 fRGBA8888PixelsOpsAreSlow = false;
48 fPartialFBOReadIsSlow = false;
piotaixre4b23142014-10-02 10:57:53 -070049
halcanary385fe4d2015-08-26 13:07:48 -070050 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070051
cdalton4cd67132015-06-10 19:23:46 -070052 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000053}
54
cdalton4cd67132015-06-10 19:23:46 -070055void GrGLCaps::init(const GrContextOptions& contextOptions,
56 const GrGLContextInfo& ctxInfo,
57 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000058 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000059 GrGLVersion version = ctxInfo.version();
60
bsalomon@google.combcce8922013-03-25 15:38:39 +000061 /**************************************************************************
62 * Caps specific to GrGLCaps
63 **************************************************************************/
64
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000065 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000066 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
67 &fMaxFragmentUniformVectors);
68 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000069 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000070 GrGLint max;
71 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
72 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000073 if (version >= GR_GL_VER(3, 2)) {
74 GrGLint profileMask;
75 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
76 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
77 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000078 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000079 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000080 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000081
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000082 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000083 fUnpackRowLengthSupport = true;
84 fUnpackFlipYSupport = false;
85 fPackRowLengthSupport = true;
86 fPackFlipYSupport = false;
87 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000088 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
89 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000090 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000091 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
92 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000093 fPackFlipYSupport =
94 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
95 }
96
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000097 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000098 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
99
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000100 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000101 // The EXT version can apply to either GL or GLES.
102 fTexStorageSupport = version >= GR_GL_VER(4,2) ||
103 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
104 ctxInfo.hasExtension("GL_EXT_texture_storage");
105 } else {
106 // Qualcomm Adreno drivers appear to have issues with texture storage.
107 fTexStorageSupport = (version >= GR_GL_VER(3,0) &&
108 kQualcomm_GrGLVendor != ctxInfo.vendor()) ||
109 ctxInfo.hasExtension("GL_EXT_texture_storage");
110 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000111
cdaltonfd4167d2015-04-21 11:45:56 -0700112 if (kGL_GrGLStandard == standard) {
113 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
114 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
115 ctxInfo.hasExtension("GL_NV_texture_barrier");
116 } else {
117 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
118 }
119
hendrikwa0d5ad72014-12-02 07:30:30 -0800120 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
121 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700122 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800123 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000124 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
125 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800126 } else {
127 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
128 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000129 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000130 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000131 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000132 ctxInfo.hasExtension("GL_ARB_imaging");
133
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000134 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
135 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
136 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
137 // limit this decision to specific GPU families rather than basing it on the vendor alone.
138 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700139 (kARM_GrGLVendor == ctxInfo.vendor() ||
140 kImagination_GrGLVendor == ctxInfo.vendor() ||
141 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000142 fUseNonVBOVertexAndIndexDynamicData = true;
143 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000144
egdaniel9250d242015-05-18 13:04:26 -0700145 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
146 // Thus we are blacklisting this extension for now on Adreno4xx devices.
147 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
148 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
149 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
150 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000151 fDiscardRenderTargetSupport = true;
152 fInvalidateFBType = kInvalidate_InvalidateFBType;
153 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
154 fDiscardRenderTargetSupport = true;
155 fInvalidateFBType = kDiscard_InvalidateFBType;
156 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000157
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000158 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
159 fFullClearIsFree = true;
160 }
161
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000162 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000163 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800164 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
165 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000166 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000167 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
168 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000169 }
170
cdalton626e1ff2015-06-12 13:56:46 -0700171 if (kGL_GrGLStandard == standard) {
172 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
173 } else {
174 fDirectStateAccessSupport = false;
175 }
176
177 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
178 fDebugSupport = true;
179 } else {
180 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
181 }
182
jvanverth3f801cb2014-12-16 09:49:38 -0800183 if (kGL_GrGLStandard == standard) {
184 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
185 }
186 else {
187 fES2CompatibilitySupport = true;
188 }
189
cdalton0edea2c2015-05-21 08:27:44 -0700190 if (kGL_GrGLStandard == standard) {
191 fMultisampleDisableSupport = true;
192 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700193 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700194 }
195
kkinnunend94708e2015-07-30 22:47:04 -0700196 if (kGL_GrGLStandard == standard) {
197 if (version >= GR_GL_VER(3, 0)) {
198 fBindFragDataLocationSupport = true;
199 }
200 } else {
201 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
202 fBindFragDataLocationSupport = true;
203 }
joshualittc1f56b52015-06-22 12:31:31 -0700204 }
205
halcanary6950de62015-11-07 05:29:00 -0800206#if 0 // Disabled due to https://bug.skia.org/4454
joshualitt7bdd70a2015-10-01 06:28:11 -0700207 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
kkinnunen177519e2015-10-28 06:18:35 -0700208#else
209 fBindUniformLocationSupport = false;
210#endif
joshualitt7bdd70a2015-10-01 06:28:11 -0700211
bsalomon7ea33f52015-11-22 14:51:00 -0800212 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
213 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
214 fExternalTextureSupport = true;
215 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
216 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
217 // At least one driver has been found that has this extension without the "GL_" prefix.
218 fExternalTextureSupport = true;
219 }
220 }
221
bsalomoncdee0092016-01-08 13:20:12 -0800222 if (kGL_GrGLStandard == standard) {
223 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
224 fTextureSwizzleSupport = true;
225 }
226 } else {
227 if (version >= GR_GL_VER(3,0)) {
228 fTextureSwizzleSupport = true;
229 }
230 }
231
bsalomon88c7b982015-07-31 11:20:16 -0700232#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
cdalton4cd67132015-06-10 19:23:46 -0700243 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700244 * GrShaderCaps fields
245 **************************************************************************/
246
egdaniel0a482332015-10-26 08:59:10 -0700247 // This must be called after fCoreProfile is set on the GrGLCaps
248 this->initGLSL(ctxInfo);
249 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
250
egdaniel05ded892015-10-26 07:38:05 -0700251 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
252
253 // For now these two are equivalent but we could have dst read in shader via some other method.
254 // Before setting this, initGLSL() must have been called.
255 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
256
257 // Enable supported shader-related caps
258 if (kGL_GrGLStandard == standard) {
259 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
260 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
261 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
262 glslCaps->fShaderDerivativeSupport = true;
263 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
264 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
265 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
266 }
267 else {
268 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
269
270 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
271 ctxInfo.hasExtension("GL_OES_standard_derivatives");
272 }
273
egdaniel05ded892015-10-26 07:38:05 -0700274 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700275 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000276 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700277
cdalton63f6c1f2015-11-06 07:09:43 -0800278 // We need dual source blending and the ability to disable multisample in order to support mixed
279 // samples in every corner case.
280 if (fMultisampleDisableSupport && glslCaps->dualSourceBlendingSupport()) {
kkinnunenea409432015-12-10 01:21:59 -0800281 fMixedSamplesSupport = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
282 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800283 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
284 if (fMixedSamplesSupport && kNVIDIA_GrGLDriver == ctxInfo.driver()) {
285 fDiscardRenderTargetSupport = false;
286 fInvalidateFBType = kNone_InvalidateFBType;
287 }
288 }
289
290 // fPathRenderingSupport and fMixedSamplesSupport must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700291 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700292 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700293 this->initStencilFormats(ctxInfo);
294
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000295 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000296 // we could also look for GL_ATI_separate_stencil extension or
297 // GL_EXT_stencil_two_side but they use different function signatures
298 // than GL2.0+ (and than each other).
299 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
300 // supported on GL 1.4 and higher or by extension
301 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
302 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
303 } else {
304 // ES 2 has two sided stencil and stencil wrap
305 fTwoSidedStencilSupport = true;
306 fStencilWrapOpsSupport = true;
307 }
308
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000309 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000310 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
311 // extension includes glMapBuffer.
312 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
313 fMapBufferFlags |= kSubset_MapFlag;
314 fMapBufferType = kMapBufferRange_MapBufferType;
315 } else {
316 fMapBufferType = kMapBuffer_MapBufferType;
317 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000318 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000319 // Unextended GLES2 doesn't have any buffer mapping.
320 fMapBufferFlags = kNone_MapBufferType;
321 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
322 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
323 fMapBufferType = kChromium_MapBufferType;
324 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
325 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
326 fMapBufferType = kMapBufferRange_MapBufferType;
327 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
328 fMapBufferFlags = kCanMap_MapFlag;
329 fMapBufferType = kMapBuffer_MapBufferType;
330 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000331 }
332
jvanverthd7a2c1f2015-12-07 07:36:44 -0800333 if (kGL_GrGLStandard == standard) {
334 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
335 fTransferBufferType = kPBO_TransferBufferType;
336 }
337 } else {
338 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
339 fTransferBufferType = kPBO_TransferBufferType;
340 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
341 fTransferBufferType = kChromium_TransferBufferType;
342 }
343 }
344
joshualitte5b74c62015-06-01 14:17:47 -0700345 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
346 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
347 if (fGeometryBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700348 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
349 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
350 // a small subset.
351#if 0
cdalton1acea862015-06-02 13:05:52 -0700352 fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700353#else
354 fGeometryBufferMapThreshold = SK_MaxS32;
355#endif
joshualitte5b74c62015-06-01 14:17:47 -0700356 }
357
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000358 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000359 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
360 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
361 fNPOTTextureTileSupport = true;
362 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000363 } else {
364 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000365 // ES3 has no limitations.
366 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
367 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000368 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
369 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
370 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
371 // to alllow arbitrary wrap modes, however.
372 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000373 }
374
bsalomone72bd022015-10-26 07:33:03 -0700375 // Using MIPs on this GPU seems to be a source of trouble.
376 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
377 fMipMapSupport = false;
378 }
379
bsalomon@google.combcce8922013-03-25 15:38:39 +0000380 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
381 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
382 // Our render targets are always created with textures as the color
383 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000384 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000385
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000386 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
387
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000388 // Disable scratch texture reuse on Mali and Adreno devices
389 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
390 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000391
robertphillips1b8e1b52015-06-24 06:54:10 -0700392#if 0
393 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
394 kQualcomm_GrGLVendor != ctxInfo.vendor();
395#endif
396
egdaniel05ded892015-10-26 07:38:05 -0700397 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000398 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000399 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount);
400 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
401 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
402 }
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000403
bsalomon63b21962014-11-05 07:05:34 -0800404 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800405 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800406 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800407 fUseDrawInsteadOfClear = true;
408 }
409
joshualitt83bc2292015-06-18 14:18:02 -0700410 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
411 fUseDrawInsteadOfPartialRenderTargetWrite = true;
412 }
413
robertphillips63926682015-08-20 09:39:02 -0700414#ifdef SK_BUILD_FOR_WIN
415 // On ANGLE deferring flushes can lead to GPU starvation
416 fPreferVRAMUseOverFlushes = !isANGLE;
417#endif
418
bsalomon7dea7b72015-08-19 08:26:51 -0700419 if (kChromium_GrGLDriver == ctxInfo.driver()) {
420 fMustClearUploadedBufferData = true;
421 }
422
bsalomond08ea5f2015-02-20 06:58:13 -0800423 if (kGL_GrGLStandard == standard) {
424 // ARB allows mixed size FBO attachments, EXT does not.
425 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
426 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
427 fOversizedStencilSupport = true;
428 } else {
429 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
430 }
431 } else {
432 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
433 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
434 }
435
joshualitt58001552015-06-26 12:46:36 -0700436 if (kGL_GrGLStandard == standard) {
437 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
438 // instanced arrays, but we could make this more granular if we wanted
439 fSupportsInstancedDraws =
440 version >= GR_GL_VER(3, 2) ||
441 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
442 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
443 } else {
444 fSupportsInstancedDraws =
445 version >= GR_GL_VER(3, 0) ||
446 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
447 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
448 }
449
jvanverthcba99b82015-06-24 06:59:57 -0700450 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800451
452 if (contextOptions.fUseShaderSwizzling) {
453 fTextureSwizzleSupport = false;
454 }
455
456 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
457 // already been detected.
458 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700459
460 this->applyOptionsOverrides(contextOptions);
461 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000462}
463
egdaniel472d44e2015-10-22 08:20:00 -0700464const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
465 bool isCoreProfile) {
466 switch (generation) {
467 case k110_GrGLSLGeneration:
468 if (kGLES_GrGLStandard == standard) {
469 // ES2s shader language is based on version 1.20 but is version
470 // 1.00 of the ES language.
471 return "#version 100\n";
472 } else {
473 SkASSERT(kGL_GrGLStandard == standard);
474 return "#version 110\n";
475 }
476 case k130_GrGLSLGeneration:
477 SkASSERT(kGL_GrGLStandard == standard);
478 return "#version 130\n";
479 case k140_GrGLSLGeneration:
480 SkASSERT(kGL_GrGLStandard == standard);
481 return "#version 140\n";
482 case k150_GrGLSLGeneration:
483 SkASSERT(kGL_GrGLStandard == standard);
484 if (isCoreProfile) {
485 return "#version 150\n";
486 } else {
487 return "#version 150 compatibility\n";
488 }
489 case k330_GrGLSLGeneration:
490 if (kGLES_GrGLStandard == standard) {
491 return "#version 300 es\n";
492 } else {
493 SkASSERT(kGL_GrGLStandard == standard);
494 if (isCoreProfile) {
495 return "#version 330\n";
496 } else {
497 return "#version 330 compatibility\n";
498 }
499 }
500 case k310es_GrGLSLGeneration:
501 SkASSERT(kGLES_GrGLStandard == standard);
502 return "#version 310 es\n";
503 }
504 return "<no version>";
505}
506
egdaniel05ded892015-10-26 07:38:05 -0700507void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700508 GrGLStandard standard = ctxInfo.standard();
509 GrGLVersion version = ctxInfo.version();
510
511 /**************************************************************************
512 * Caps specific to GrGLSLCaps
513 **************************************************************************/
514
515 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
516 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
517
518 if (kGLES_GrGLStandard == standard) {
519 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
520 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
521 glslCaps->fFBFetchSupport = true;
522 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
523 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
524 }
525 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
526 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
527 glslCaps->fFBFetchNeedsCustomOutput = false;
528 glslCaps->fFBFetchSupport = true;
529 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
530 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
531 }
532 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
533 // The arm extension also requires an additional flag which we will set onResetContext
534 glslCaps->fFBFetchNeedsCustomOutput = false;
535 glslCaps->fFBFetchSupport = true;
536 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
537 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
538 }
539 glslCaps->fUsesPrecisionModifiers = true;
540 }
541
542 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
543
544 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
545 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
546
547 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
548 // function that may require a gradient calculation inside a conditional block may return
549 // undefined results". This appears to be an issue with the 'any' call since even the simple
550 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
551 // from our GrTextureDomain processor.
552 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
553
egdaniel472d44e2015-10-22 08:20:00 -0700554 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
555 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800556
557 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
558 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
559 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800560
561 // Frag Coords Convention support is not part of ES
562 // Known issue on at least some Intel platforms:
563 // http://code.google.com/p/skia/issues/detail?id=946
564 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
565 kGLES_GrGLStandard != standard &&
566 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
567 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
568 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
569 }
570
571 if (kGLES_GrGLStandard == standard) {
572 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
573 }
574
bsalomon7ea33f52015-11-22 14:51:00 -0800575 if (fExternalTextureSupport) {
576 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
577 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
578 } else {
579 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
580 }
581 }
582
egdaniel8dcdedc2015-11-11 06:27:20 -0800583 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
584 // the abs first in a separate expression.
585 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
586 glslCaps->fCanUseMinAndAbsTogether = false;
587 }
588
bsalomon7ea33f52015-11-22 14:51:00 -0800589 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
egdaniel8dcdedc2015-11-11 06:27:20 -0800590 // thus must us -1.0 * %s.x to work correctly
591 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
592 glslCaps->fMustForceNegatedAtanParamToFloat = true;
593 }
egdaniel472d44e2015-10-22 08:20:00 -0700594}
595
kkinnunencfe62e32015-07-01 02:58:50 -0700596bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700597 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
598
599 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700600 return false;
601 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700602
kkinnunencfe62e32015-07-01 02:58:50 -0700603 if (kGL_GrGLStandard == ctxInfo.standard()) {
604 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
605 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
606 return false;
607 }
608 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700609 if (!hasChromiumPathRendering &&
610 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700611 return false;
612 }
613 }
614 // We only support v1.3+ of GL_NV_path_rendering which allows us to
615 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
616 // additions are detected by checking the existence of the function.
617 // We also use *Then* functions that not all drivers might have. Check
618 // them for consistency.
halcanary96fcdcc2015-08-27 07:41:13 -0700619 if (nullptr == gli->fFunctions.fStencilThenCoverFillPath ||
620 nullptr == gli->fFunctions.fStencilThenCoverStrokePath ||
621 nullptr == gli->fFunctions.fStencilThenCoverFillPathInstanced ||
622 nullptr == gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
623 nullptr == gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700624 return false;
625 }
626 return true;
627}
piotaixre4b23142014-10-02 10:57:53 -0700628bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf,
bsalomon7928ef62016-01-05 10:26:39 -0800629 GrPixelConfig readConfig,
630 GrPixelConfig currFBOConfig) const {
631 SkASSERT(this->isConfigRenderable(currFBOConfig, false));
632
bsalomon76148af2016-01-12 11:13:47 -0800633 GrGLenum readFormat;
634 GrGLenum readType;
635 if (!this->getReadPixelsFormat(currFBOConfig, readConfig, &readFormat, &readType)) {
636 return false;
637 }
638
bsalomon7928ef62016-01-05 10:26:39 -0800639 if (kGL_GrGLStandard == intf->fStandard) {
640 // All of our renderable configs can be converted to each other by glReadPixels in OpenGL.
641 return true;
piotaixre4b23142014-10-02 10:57:53 -0700642 }
bsalomon7928ef62016-01-05 10:26:39 -0800643
bsalomon76148af2016-01-12 11:13:47 -0800644 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800645
646 if (kNormalizedFixedPoint_FormatType == fConfigTable[currFBOConfig].fFormatType) {
647 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
648 return true;
649 }
650 } else {
651 SkASSERT(kFloat_FormatType == fConfigTable[currFBOConfig].fFormatType);
652 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
653 return true;
654 }
655 }
656
657 if (0 == fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat) {
658 ReadPixelsFormat* rpFormat =
659 const_cast<ReadPixelsFormat*>(&fConfigTable[currFBOConfig].fSecondReadPixelsFormat);
660 GrGLint format = 0, type = 0;
661 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
662 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
663 rpFormat->fFormat = format;
664 rpFormat->fType = type;
665 }
666
667 return fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
668 fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700669}
670
robertphillips@google.com6177e692013-02-28 20:16:25 +0000671void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000672
673 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000674 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000675 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
676 // ES3 driver bugs on at least one device with a tiled GPU (N10).
677 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
678 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
679 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
680 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
cdalton63f6c1f2015-11-06 07:09:43 -0800681 } else if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700682 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000683 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000684 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
685 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
686 // chrome's extension is equivalent to the EXT msaa
687 // and fbo_blit extensions.
688 fMSFBOType = kDesktop_EXT_MSFBOType;
689 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
690 fMSFBOType = kES_Apple_MSFBOType;
691 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000692 } else {
cdalton63f6c1f2015-11-06 07:09:43 -0800693 if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700694 fMSFBOType = kMixedSamples_MSFBOType;
695 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000696 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000697 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000698 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
699 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000700 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000701 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000702 }
703}
704
cdalton1dd05422015-06-12 09:01:18 -0700705void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
706 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
707
708 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
709 // for now until its own blacklists can be updated.
710 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
711 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700712 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700713 return;
714 }
715
716 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
717 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
718 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
719 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
720 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
721 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
722 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
723 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
724 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
725 return;
726 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
727 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
728 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
729 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
730 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
731 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
732 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
733 // slow on a particular platform.
734 } else {
735 return; // No advanced blend support.
736 }
737
738 SkASSERT(this->advancedBlendEquationSupport());
739
740 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
741 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
742 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
743 (1 << kColorBurn_GrBlendEquation);
744 }
joel.liang9764c402015-07-09 19:46:18 -0700745 if (kARM_GrGLVendor == ctxInfo.vendor()) {
746 // Blacklist color-burn on ARM until the fix is released.
747 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
748 }
cdalton1dd05422015-06-12 09:01:18 -0700749}
750
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000751namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700752const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000753}
754
755void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
756
757 // Build up list of legal stencil formats (though perhaps not supported on
758 // the particular gpu/driver) from most preferred to least.
759
760 // these consts are in order of most preferred to least preferred
761 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
762
763 static const StencilFormat
764 // internal Format stencil bits total bits packed?
765 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
766 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
767 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
768 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000769 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000770 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
771
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000772 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000773 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000774 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000775 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
776 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
777
778 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
779 // require FBO support we can expect these are legal formats and don't
780 // check. These also all support the unsized GL_STENCIL_INDEX.
781 fStencilFormats.push_back() = gS8;
782 fStencilFormats.push_back() = gS16;
783 if (supportsPackedDS) {
784 fStencilFormats.push_back() = gD24S8;
785 }
786 fStencilFormats.push_back() = gS4;
787 if (supportsPackedDS) {
788 fStencilFormats.push_back() = gDS;
789 }
790 } else {
791 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
792 // for other formats.
793 // ES doesn't support using the unsized format.
794
795 fStencilFormats.push_back() = gS8;
796 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000797 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
798 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000799 fStencilFormats.push_back() = gD24S8;
800 }
801 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
802 fStencilFormats.push_back() = gS4;
803 }
804 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000805}
806
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000807SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000808
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000809 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000810
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000811 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000812 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000813 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000814 i,
815 fStencilFormats[i].fStencilBits,
816 fStencilFormats[i].fTotalBits);
817 }
818
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000819 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000820 "None",
821 "ARB",
822 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000823 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000824 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000825 "IMG MS To Texture",
826 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700827 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000828 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000829 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
830 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
831 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000832 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
833 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
834 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
835 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700836 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000837 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000838
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000839 static const char* kInvalidateFBTypeStr[] = {
840 "None",
841 "Discard",
842 "Invalidate",
843 };
844 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
845 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
846 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
847 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000848
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000849 static const char* kMapBufferTypeStr[] = {
850 "None",
851 "MapBuffer",
852 "MapBufferRange",
853 "Chromium",
854 };
855 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
856 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
857 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
858 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
859 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
860
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000861 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000862 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000863 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000864 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000865 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
866 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000867 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000868 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
869 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
870 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
871 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000872
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000873 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
874 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
875 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
876 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000877 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700878 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
879 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800880 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000881 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000882 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700883 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700884 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
885 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700886 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800887 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
888 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800889
890 r.append("Configs\n-------\n");
891 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
892 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -0800893 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
894 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -0800895 i,
896 fConfigTable[i].fFlags,
897 fConfigTable[i].fFormats.fBaseInternalFormat,
898 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -0800899 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
900 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -0800901 fConfigTable[i].fFormats.fExternalType,
902 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -0800903 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -0800904 }
905
jvanverthe9c0fc62015-04-29 11:18:05 -0700906 return r;
907}
908
jvanverthe9c0fc62015-04-29 11:18:05 -0700909static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
910 switch (p) {
911 case kLow_GrSLPrecision:
912 return GR_GL_LOW_FLOAT;
913 case kMedium_GrSLPrecision:
914 return GR_GL_MEDIUM_FLOAT;
915 case kHigh_GrSLPrecision:
916 return GR_GL_HIGH_FLOAT;
917 }
918 SkFAIL("Unknown precision.");
919 return -1;
920}
921
922static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
923 switch (type) {
924 case kVertex_GrShaderType:
925 return GR_GL_VERTEX_SHADER;
926 case kGeometry_GrShaderType:
927 return GR_GL_GEOMETRY_SHADER;
928 case kFragment_GrShaderType:
929 return GR_GL_FRAGMENT_SHADER;
930 }
931 SkFAIL("Unknown shader type.");
932 return -1;
933}
934
jvanverthcba99b82015-06-24 06:59:57 -0700935void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
936 const GrGLInterface* intf,
937 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700938 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
939 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
940 for (int s = 0; s < kGrShaderTypeCount; ++s) {
941 if (kGeometry_GrShaderType != s) {
942 GrShaderType shaderType = static_cast<GrShaderType>(s);
943 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -0700944 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -0700945 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700946 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
947 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
948 GrGLenum glPrecision = precision_to_gl_float_type(precision);
949 GrGLint range[2];
950 GrGLint bits;
951 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
952 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -0700953 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
954 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
955 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -0700956 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -0700957 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700958 }
jvanverthcba99b82015-06-24 06:59:57 -0700959 else if (!glslCaps->fShaderPrecisionVaries) {
960 glslCaps->fShaderPrecisionVaries =
961 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -0700962 }
963 }
964 }
965 }
966 }
967 }
968 else {
969 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -0700970 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700971 for (int s = 0; s < kGrShaderTypeCount; ++s) {
972 if (kGeometry_GrShaderType != s) {
973 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700974 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
975 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
976 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -0700977 }
978 }
979 }
980 }
981 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
982 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
983 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
984 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -0700985 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700986 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700987 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
988 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700989 }
990 }
991}
992
bsalomon41e4384e2016-01-08 09:12:44 -0800993bool GrGLCaps::bgraIsInternalFormat() const {
994 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
995}
996
bsalomon76148af2016-01-12 11:13:47 -0800997bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
998 GrGLenum* internalFormat, GrGLenum* externalFormat,
999 GrGLenum* externalType) const {
1000 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1001 externalFormat, externalType)) {
1002 return false;
1003 }
1004 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1005 return true;
1006}
1007
1008bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1009 GrGLenum* internalFormat) const {
1010 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1011 return false;
1012 }
1013 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1014 return true;
1015}
1016
1017bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1018 GrGLenum* externalFormat, GrGLenum* externalType) const {
1019 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1020 externalFormat, externalType)) {
1021 return false;
1022 }
1023 return true;
1024}
1025
1026bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1027 if (GrPixelConfigIsCompressed(config)) {
1028 return false;
1029 }
1030 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1031 return true;
1032}
1033
1034bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1035 ExternalFormatUsage usage, GrGLenum* externalFormat,
1036 GrGLenum* externalType) const {
1037 SkASSERT(externalFormat && externalType);
1038 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1039 return false;
1040 }
1041
1042 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1043 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1044
1045 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1046 // made to work in many cases using glPixelStore and what not but is not needed currently.
1047 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1048 return false;
1049 }
1050
1051 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1052 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1053
1054 return true;
1055}
1056
bsalomoncdee0092016-01-08 13:20:12 -08001057void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1058 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001059 /*
1060 Comments on renderability of configs on various GL versions.
1061 OpenGL < 3.0:
1062 no built in support for render targets.
1063 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1064 format RGB, RGBA and NV float formats we don't use.
1065 This is the following:
1066 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1067 RGB10_A2, RGBA12,RGBA16
1068 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1069 since they aren't required by later standards and the driver can simply return
1070 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1071 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1072 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1073 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1074 This adds a lot of additional renderable sized formats, including ALPHA8.
1075 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1076 16F, 32I, 32UI, and 32F variants).
1077 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1078
1079 For both the above extensions we limit ourselves to those that are also required by
1080 OpenGL 3.0.
1081
1082 OpenGL 3.0:
1083 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1084 but are not required to be supported as renderable textures/renderbuffer.
1085 Required renderable color formats:
1086 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1087 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1088 RGB10_A2.
1089 - R11F_G11F_B10F.
1090 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1091 and RG8UI.
1092 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1093 - ALPHA8
1094
1095 OpenGL 3.1, 3.2, 3.3
1096 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1097 OpengGL 3.3, 4.0, 4.1
1098 Adds RGB10_A2UI.
1099 OpengGL 4.2
1100 Adds
1101 - RGB5_A1, RGBA4
1102 - RGB565
1103 OpenGL 4.4
1104 Does away with the separate list and adds a column to the sized internal color format
1105 table. However, no new formats become required color renderable.
1106
1107 ES 2.0
1108 color renderable: RGBA4, RGB5_A1, RGB565
1109 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1110 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1111 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1112 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1113 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1114 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1115
1116 ES 3.0
1117 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1118 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1119 RGB5_A1.
1120 - RGB8 and RGB565.
1121 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1122 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1123 ES 3.1
1124 Adds RGB10_A2, RGB10_A2UI,
1125 ES 3.2
1126 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1127 */
1128 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1129 if (kNone_MSFBOType != fMSFBOType) {
1130 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1131 }
1132
1133 GrGLStandard standard = ctxInfo.standard();
1134 GrGLVersion version = ctxInfo.version();
1135
bsalomon30447372015-12-21 09:03:05 -08001136 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1137 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001138 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001139 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001140 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001141 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001142
1143 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1144 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001145 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1146 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001147 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001148 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001149 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1150 if (kGL_GrGLStandard == standard) {
1151 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1152 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001153 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001154 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1155 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1156 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1157 }
egdaniel4999df82016-01-07 17:06:04 -08001158 }
bsalomoncdee0092016-01-08 13:20:12 -08001159 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001160
bsalomon76148af2016-01-12 11:13:47 -08001161 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1162 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001163 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001164 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001165 if (kGL_GrGLStandard == standard) {
1166 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1167 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1168 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1169 // Since the internal format is RGBA8, it is also renderable.
1170 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1171 allRenderFlags;
1172 }
1173 } else {
1174 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1175 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1176 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1177 // The APPLE extension doesn't make this renderable.
1178 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1179 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1180 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1181 // Though, that seems to not be the case if the texture storage extension is
1182 // present. The specs don't exactly make that clear.
1183 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1184 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1185 }
1186 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1187 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1188 ConfigInfo::kRenderable_Flag;
1189 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1190 this->usesMSAARenderBuffers()) {
1191 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1192 ConfigInfo::kRenderableWithMSAA_Flag;
1193 }
1194 }
1195 }
bsalomoncdee0092016-01-08 13:20:12 -08001196 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001197
bsalomon41e4384e2016-01-08 09:12:44 -08001198 // We only enable srgb support if both textures and FBOs support srgb.
1199 bool srgbSupport = false;
1200 if (kGL_GrGLStandard == standard) {
1201 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1202 srgbSupport = true;
1203 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1204 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1205 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1206 srgbSupport = true;
1207 }
1208 }
1209 // All the above srgb extensions support toggling srgb writes
1210 fSRGBWriteControl = srgbSupport;
1211 } else {
1212 // See https://bug.skia.org/4148 for PowerVR issue.
1213 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1214 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1215 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1216 // sRGB writing for destinations.
1217 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1218 }
bsalomon30447372015-12-21 09:03:05 -08001219 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1220 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1221 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1222 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001223 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1224 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001225 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001226 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001227 if (srgbSupport) {
1228 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1229 allRenderFlags;
1230 }
bsalomoncdee0092016-01-08 13:20:12 -08001231 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001232
1233 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1234 if (this->ES2CompatibilitySupport()) {
1235 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1236 } else {
1237 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1238 }
bsalomon76148af2016-01-12 11:13:47 -08001239 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1240 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001241 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001242 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001243 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1244 if (kGL_GrGLStandard == standard) {
1245 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1246 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1247 }
1248 } else {
1249 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1250 }
bsalomoncdee0092016-01-08 13:20:12 -08001251 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001252
1253 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1254 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001255 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1256 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001257 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001258 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001259 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1260 if (kGL_GrGLStandard == standard) {
1261 if (version >= GR_GL_VER(4, 2)) {
1262 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1263 }
1264 } else {
1265 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1266 }
bsalomoncdee0092016-01-08 13:20:12 -08001267 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001268
1269 if (this->textureRedSupport()) {
1270 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1271 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001272 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1273 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001274 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001275 } else {
1276 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1277 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001278 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1279 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001280 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001281 }
1282 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001283 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001284 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1285 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1286 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1287 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1288 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1289 }
1290
1291 // Check for [half] floating point texture support
1292 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1293 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1294 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1295 bool hasFPTextures = false;
1296 bool hasHalfFPTextures = false;
1297 // for now we don't support floating point MSAA on ES
1298 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1299 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1300
1301 if (kGL_GrGLStandard == standard) {
1302 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1303 hasFPTextures = true;
1304 hasHalfFPTextures = true;
1305 }
1306 } else {
1307 if (version >= GR_GL_VER(3, 1)) {
1308 hasFPTextures = true;
1309 hasHalfFPTextures = true;
1310 } else {
1311 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1312 ctxInfo.hasExtension("GL_OES_texture_float")) {
1313 hasFPTextures = true;
1314 }
1315 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1316 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1317 hasHalfFPTextures = true;
1318 }
1319 }
1320 }
bsalomon30447372015-12-21 09:03:05 -08001321
1322 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1323 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001324 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1325 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001326 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001327 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001328 if (hasFPTextures) {
1329 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1330 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1331 // many precision issues and no clients actually want this yet.
1332 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1333 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1334 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1335 }
1336 }
bsalomoncdee0092016-01-08 13:20:12 -08001337 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001338
1339 if (this->textureRedSupport()) {
1340 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1341 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001342 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1343 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001344 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001345 } else {
1346 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1347 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001348 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1349 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001350 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001351 }
1352 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1353 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1354 } else {
1355 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1356 }
bsalomon7928ef62016-01-05 10:26:39 -08001357 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001358 if (hasHalfFPTextures) {
1359 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1360 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1361 // GL_RED internal format.
1362 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1363 (this->textureRedSupport() &&
1364 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1365 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1366 }
1367 }
bsalomon30447372015-12-21 09:03:05 -08001368
1369 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1370 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001371 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1372 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001373 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1374 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1375 } else {
1376 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1377 }
bsalomon7928ef62016-01-05 10:26:39 -08001378 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001379 if (hasHalfFPTextures) {
1380 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1381 // ES requires 3.2 or EXT_color_buffer_half_float.
1382 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1383 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1384 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1385 }
1386 }
bsalomoncdee0092016-01-08 13:20:12 -08001387 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001388
1389 // Compressed texture support
1390
1391 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1392 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1393
1394 // TODO: Fix command buffer bindings and remove this.
1395 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001396
1397 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001398 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001399
1400 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1401 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001402 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001403 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001404 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001405 // Disable this for now, while we investigate https://bug.skia.org/4333
1406 if (false) {
1407 // Check for 8-bit palette..
1408 GrGLint numFormats;
1409 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1410 if (numFormats) {
1411 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1412 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1413 for (int i = 0; i < numFormats; ++i) {
1414 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1415 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1416 break;
1417 }
1418 }
1419 }
1420 }
bsalomoncdee0092016-01-08 13:20:12 -08001421 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001422
bsalomon41e4384e2016-01-08 09:12:44 -08001423 // May change the internal format based on extensions.
1424 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1425 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1426 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1427 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1428 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1429 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1430 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1431 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1432 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1433 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1434 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1435 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1436 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1437 GR_GL_COMPRESSED_RED_RGTC1;
1438 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1439 GR_GL_COMPRESSED_RED_RGTC1;
1440 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1441 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1442 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1443 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1444 GR_GL_COMPRESSED_3DC_X;
1445
bsalomon30447372015-12-21 09:03:05 -08001446 }
bsalomon76148af2016-01-12 11:13:47 -08001447 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001448 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001449 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001450 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001451
1452 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1453 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001454 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001455 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001456 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001457 if (kGL_GrGLStandard == standard) {
1458 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1459 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1460 }
1461 } else {
1462 if (version >= GR_GL_VER(3, 0) ||
1463 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1464 // ETC2 is a superset of ETC1, so we can just check for that, too.
1465 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1466 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1467 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1468 }
1469 }
bsalomoncdee0092016-01-08 13:20:12 -08001470 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001471
1472 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1473 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001474 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001475 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001476 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001477 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1478 // decompressing the textures in the driver, and is generally slower.
1479 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1480 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1481 }
bsalomoncdee0092016-01-08 13:20:12 -08001482 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001483
1484 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1485 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1486 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1487 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001488 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1489 0;
bsalomon30447372015-12-21 09:03:05 -08001490 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001491 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001492 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1493 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1494 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1495 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1496 }
bsalomoncdee0092016-01-08 13:20:12 -08001497 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001498
1499 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1500
1501 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001502 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1503 ctxInfo.version() >= GR_GL_VER(3,0));
1504 // All ES versions (thus far) require sized internal formats for render buffers.
1505 // TODO: Always use sized internal format?
1506 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1507
bsalomon30447372015-12-21 09:03:05 -08001508 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001509 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1510 // param to glTex[Sub]Image.
1511 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1512 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1513 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1514 fConfigTable[i].fFormats.fSizedInternalFormat :
1515 fConfigTable[i].fFormats.fBaseInternalFormat;
1516 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001517 fConfigTable[i].fFormats.fSizedInternalFormat :
1518 fConfigTable[i].fFormats.fBaseInternalFormat;
1519 }
1520 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1521 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1522 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1523 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1524 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001525 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001526 GR_GL_SRGB_ALPHA;
1527 }
1528
1529 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1530 // as a base format.
1531 // GL_EXT_texture_format_BGRA8888:
1532 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1533 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1534 // formats.
1535 // GL_APPLE_texture_format_BGRA8888:
1536 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1537 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1538 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001539 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001540 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1541 }
1542
bsalomoncdee0092016-01-08 13:20:12 -08001543 // If we don't have texture swizzle support then the shader generator must insert the
1544 // swizzle into shader code.
1545 if (!this->textureSwizzleSupport()) {
1546 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1547 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1548 }
1549 }
1550
bsalomon30447372015-12-21 09:03:05 -08001551#ifdef SK_DEBUG
1552 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001553 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001554 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001555 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1556 fConfigTable[i].fFormats.fBaseInternalFormat);
1557 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001558 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001559 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1560 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1561 fConfigTable[i].fFormats.fExternalFormat[j]);
1562 }
1563 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001564 }
1565#endif
1566}
1567
egdanielb7e7d572015-11-04 04:23:53 -08001568void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}