blob: 99ed042139da4524cf1b43775835d21e84cf733f [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
633 if (kGL_GrGLStandard == intf->fStandard) {
634 // All of our renderable configs can be converted to each other by glReadPixels in OpenGL.
635 return true;
piotaixre4b23142014-10-02 10:57:53 -0700636 }
bsalomon7928ef62016-01-05 10:26:39 -0800637 // See Section 16.1.2 in the ES 3.2 specification.
638
639 GrGLenum readFormat = fConfigTable[readConfig].fFormats.fExternalFormat;
640 GrGLenum readType = fConfigTable[readConfig].fFormats.fExternalType;
641
642 if (kNormalizedFixedPoint_FormatType == fConfigTable[currFBOConfig].fFormatType) {
643 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
644 return true;
645 }
646 } else {
647 SkASSERT(kFloat_FormatType == fConfigTable[currFBOConfig].fFormatType);
648 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
649 return true;
650 }
651 }
652
653 if (0 == fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat) {
654 ReadPixelsFormat* rpFormat =
655 const_cast<ReadPixelsFormat*>(&fConfigTable[currFBOConfig].fSecondReadPixelsFormat);
656 GrGLint format = 0, type = 0;
657 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
658 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
659 rpFormat->fFormat = format;
660 rpFormat->fType = type;
661 }
662
663 return fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
664 fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700665}
666
robertphillips@google.com6177e692013-02-28 20:16:25 +0000667void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000668
669 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000670 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000671 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
672 // ES3 driver bugs on at least one device with a tiled GPU (N10).
673 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
674 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
675 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
676 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
cdalton63f6c1f2015-11-06 07:09:43 -0800677 } else if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700678 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000679 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000680 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
681 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
682 // chrome's extension is equivalent to the EXT msaa
683 // and fbo_blit extensions.
684 fMSFBOType = kDesktop_EXT_MSFBOType;
685 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
686 fMSFBOType = kES_Apple_MSFBOType;
687 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000688 } else {
cdalton63f6c1f2015-11-06 07:09:43 -0800689 if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700690 fMSFBOType = kMixedSamples_MSFBOType;
691 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000692 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000693 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000694 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
695 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000696 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000697 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000698 }
699}
700
cdalton1dd05422015-06-12 09:01:18 -0700701void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
702 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
703
704 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
705 // for now until its own blacklists can be updated.
706 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
707 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700708 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700709 return;
710 }
711
712 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
713 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
714 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
715 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
716 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
717 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
718 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
719 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
720 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
721 return;
722 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
723 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
724 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
725 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
726 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
727 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
728 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
729 // slow on a particular platform.
730 } else {
731 return; // No advanced blend support.
732 }
733
734 SkASSERT(this->advancedBlendEquationSupport());
735
736 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
737 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
738 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
739 (1 << kColorBurn_GrBlendEquation);
740 }
joel.liang9764c402015-07-09 19:46:18 -0700741 if (kARM_GrGLVendor == ctxInfo.vendor()) {
742 // Blacklist color-burn on ARM until the fix is released.
743 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
744 }
cdalton1dd05422015-06-12 09:01:18 -0700745}
746
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000747namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700748const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000749}
750
751void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
752
753 // Build up list of legal stencil formats (though perhaps not supported on
754 // the particular gpu/driver) from most preferred to least.
755
756 // these consts are in order of most preferred to least preferred
757 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
758
759 static const StencilFormat
760 // internal Format stencil bits total bits packed?
761 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
762 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
763 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
764 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000765 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000766 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
767
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000768 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000769 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000770 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000771 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
772 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
773
774 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
775 // require FBO support we can expect these are legal formats and don't
776 // check. These also all support the unsized GL_STENCIL_INDEX.
777 fStencilFormats.push_back() = gS8;
778 fStencilFormats.push_back() = gS16;
779 if (supportsPackedDS) {
780 fStencilFormats.push_back() = gD24S8;
781 }
782 fStencilFormats.push_back() = gS4;
783 if (supportsPackedDS) {
784 fStencilFormats.push_back() = gDS;
785 }
786 } else {
787 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
788 // for other formats.
789 // ES doesn't support using the unsized format.
790
791 fStencilFormats.push_back() = gS8;
792 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000793 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
794 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000795 fStencilFormats.push_back() = gD24S8;
796 }
797 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
798 fStencilFormats.push_back() = gS4;
799 }
800 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000801}
802
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000803SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000804
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000805 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000806
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000807 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000808 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000809 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000810 i,
811 fStencilFormats[i].fStencilBits,
812 fStencilFormats[i].fTotalBits);
813 }
814
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000815 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000816 "None",
817 "ARB",
818 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000819 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000820 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000821 "IMG MS To Texture",
822 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700823 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000824 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000825 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
826 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
827 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000828 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
829 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
830 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
831 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700832 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000833 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000834
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000835 static const char* kInvalidateFBTypeStr[] = {
836 "None",
837 "Discard",
838 "Invalidate",
839 };
840 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
841 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
842 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
843 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000844
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000845 static const char* kMapBufferTypeStr[] = {
846 "None",
847 "MapBuffer",
848 "MapBufferRange",
849 "Chromium",
850 };
851 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
852 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
853 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
854 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
855 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
856
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000857 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000858 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000859 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000860 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000861 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
862 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000863 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000864 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
865 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
866 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
867 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000868
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000869 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
870 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
871 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
872 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000873 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700874 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
875 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800876 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000877 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000878 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700879 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700880 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
881 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700882 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800883 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
884 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800885
886 r.append("Configs\n-------\n");
887 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
888 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
889 "0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, e_for_teximage: 0x%08x\n",
890 i,
891 fConfigTable[i].fFlags,
892 fConfigTable[i].fFormats.fBaseInternalFormat,
893 fConfigTable[i].fFormats.fSizedInternalFormat,
894 fConfigTable[i].fFormats.fExternalFormat,
895 fConfigTable[i].fFormats.fExternalType,
896 fConfigTable[i].fFormats.fInternalFormatTexImage,
897 fConfigTable[i].fFormats.fExternalFormatForTexImage);
898 }
899
jvanverthe9c0fc62015-04-29 11:18:05 -0700900 return r;
901}
902
jvanverthe9c0fc62015-04-29 11:18:05 -0700903static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
904 switch (p) {
905 case kLow_GrSLPrecision:
906 return GR_GL_LOW_FLOAT;
907 case kMedium_GrSLPrecision:
908 return GR_GL_MEDIUM_FLOAT;
909 case kHigh_GrSLPrecision:
910 return GR_GL_HIGH_FLOAT;
911 }
912 SkFAIL("Unknown precision.");
913 return -1;
914}
915
916static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
917 switch (type) {
918 case kVertex_GrShaderType:
919 return GR_GL_VERTEX_SHADER;
920 case kGeometry_GrShaderType:
921 return GR_GL_GEOMETRY_SHADER;
922 case kFragment_GrShaderType:
923 return GR_GL_FRAGMENT_SHADER;
924 }
925 SkFAIL("Unknown shader type.");
926 return -1;
927}
928
jvanverthcba99b82015-06-24 06:59:57 -0700929void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
930 const GrGLInterface* intf,
931 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700932 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
933 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
934 for (int s = 0; s < kGrShaderTypeCount; ++s) {
935 if (kGeometry_GrShaderType != s) {
936 GrShaderType shaderType = static_cast<GrShaderType>(s);
937 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -0700938 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -0700939 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700940 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
941 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
942 GrGLenum glPrecision = precision_to_gl_float_type(precision);
943 GrGLint range[2];
944 GrGLint bits;
945 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
946 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -0700947 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
948 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
949 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -0700950 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -0700951 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700952 }
jvanverthcba99b82015-06-24 06:59:57 -0700953 else if (!glslCaps->fShaderPrecisionVaries) {
954 glslCaps->fShaderPrecisionVaries =
955 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -0700956 }
957 }
958 }
959 }
960 }
961 }
962 else {
963 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -0700964 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700965 for (int s = 0; s < kGrShaderTypeCount; ++s) {
966 if (kGeometry_GrShaderType != s) {
967 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700968 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
969 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
970 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -0700971 }
972 }
973 }
974 }
975 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
976 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
977 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
978 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -0700979 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700980 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700981 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
982 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700983 }
984 }
985}
986
bsalomon41e4384e2016-01-08 09:12:44 -0800987bool GrGLCaps::bgraIsInternalFormat() const {
988 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
989}
990
bsalomoncdee0092016-01-08 13:20:12 -0800991void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
992 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -0800993 /*
994 Comments on renderability of configs on various GL versions.
995 OpenGL < 3.0:
996 no built in support for render targets.
997 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
998 format RGB, RGBA and NV float formats we don't use.
999 This is the following:
1000 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1001 RGB10_A2, RGBA12,RGBA16
1002 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1003 since they aren't required by later standards and the driver can simply return
1004 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1005 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1006 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1007 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1008 This adds a lot of additional renderable sized formats, including ALPHA8.
1009 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1010 16F, 32I, 32UI, and 32F variants).
1011 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1012
1013 For both the above extensions we limit ourselves to those that are also required by
1014 OpenGL 3.0.
1015
1016 OpenGL 3.0:
1017 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1018 but are not required to be supported as renderable textures/renderbuffer.
1019 Required renderable color formats:
1020 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1021 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1022 RGB10_A2.
1023 - R11F_G11F_B10F.
1024 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1025 and RG8UI.
1026 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1027 - ALPHA8
1028
1029 OpenGL 3.1, 3.2, 3.3
1030 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1031 OpengGL 3.3, 4.0, 4.1
1032 Adds RGB10_A2UI.
1033 OpengGL 4.2
1034 Adds
1035 - RGB5_A1, RGBA4
1036 - RGB565
1037 OpenGL 4.4
1038 Does away with the separate list and adds a column to the sized internal color format
1039 table. However, no new formats become required color renderable.
1040
1041 ES 2.0
1042 color renderable: RGBA4, RGB5_A1, RGB565
1043 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1044 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1045 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1046 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1047 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1048 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1049
1050 ES 3.0
1051 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1052 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1053 RGB5_A1.
1054 - RGB8 and RGB565.
1055 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1056 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1057 ES 3.1
1058 Adds RGB10_A2, RGB10_A2UI,
1059 ES 3.2
1060 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1061 */
1062 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1063 if (kNone_MSFBOType != fMSFBOType) {
1064 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1065 }
1066
1067 GrGLStandard standard = ctxInfo.standard();
1068 GrGLVersion version = ctxInfo.version();
1069
bsalomon30447372015-12-21 09:03:05 -08001070 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1071 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
1072 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat = 0;
1073 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001074 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001075 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001076
1077 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1078 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1079 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGBA;
1080 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001081 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001082 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1083 if (kGL_GrGLStandard == standard) {
1084 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1085 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001086 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001087 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1088 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1089 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1090 }
egdaniel4999df82016-01-07 17:06:04 -08001091 }
bsalomoncdee0092016-01-08 13:20:12 -08001092 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001093
bsalomon30447372015-12-21 09:03:05 -08001094 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat= GR_GL_BGRA;
1095 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001096 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001097 if (kGL_GrGLStandard == standard) {
1098 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1099 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1100 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1101 // Since the internal format is RGBA8, it is also renderable.
1102 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1103 allRenderFlags;
1104 }
1105 } else {
1106 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1107 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1108 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1109 // The APPLE extension doesn't make this renderable.
1110 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1111 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1112 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1113 // Though, that seems to not be the case if the texture storage extension is
1114 // present. The specs don't exactly make that clear.
1115 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1116 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1117 }
1118 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1119 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1120 ConfigInfo::kRenderable_Flag;
1121 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1122 this->usesMSAARenderBuffers()) {
1123 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1124 ConfigInfo::kRenderableWithMSAA_Flag;
1125 }
1126 }
1127 }
bsalomoncdee0092016-01-08 13:20:12 -08001128 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001129
bsalomon41e4384e2016-01-08 09:12:44 -08001130 // We only enable srgb support if both textures and FBOs support srgb.
1131 bool srgbSupport = false;
1132 if (kGL_GrGLStandard == standard) {
1133 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1134 srgbSupport = true;
1135 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1136 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1137 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1138 srgbSupport = true;
1139 }
1140 }
1141 // All the above srgb extensions support toggling srgb writes
1142 fSRGBWriteControl = srgbSupport;
1143 } else {
1144 // See https://bug.skia.org/4148 for PowerVR issue.
1145 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1146 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1147 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1148 // sRGB writing for destinations.
1149 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1150 }
bsalomon30447372015-12-21 09:03:05 -08001151 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1152 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1153 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1154 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
1155 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGBA;
1156 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001157 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001158 if (srgbSupport) {
1159 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1160 allRenderFlags;
1161 }
bsalomoncdee0092016-01-08 13:20:12 -08001162 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001163
1164 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1165 if (this->ES2CompatibilitySupport()) {
1166 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1167 } else {
1168 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1169 }
1170 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGB;
1171 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001172 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001173 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1174 if (kGL_GrGLStandard == standard) {
1175 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1176 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1177 }
1178 } else {
1179 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1180 }
bsalomoncdee0092016-01-08 13:20:12 -08001181 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001182
1183 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1184 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
1185 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGBA;
1186 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001187 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001188 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1189 if (kGL_GrGLStandard == standard) {
1190 if (version >= GR_GL_VER(4, 2)) {
1191 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1192 }
1193 } else {
1194 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1195 }
bsalomoncdee0092016-01-08 13:20:12 -08001196 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001197
1198 if (this->textureRedSupport()) {
1199 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1200 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1201 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001202 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001203 } else {
1204 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1205 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
1206 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001207 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001208 }
1209 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001210 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001211 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1212 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1213 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1214 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1215 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1216 }
1217
1218 // Check for [half] floating point texture support
1219 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1220 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1221 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1222 bool hasFPTextures = false;
1223 bool hasHalfFPTextures = false;
1224 // for now we don't support floating point MSAA on ES
1225 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1226 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1227
1228 if (kGL_GrGLStandard == standard) {
1229 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1230 hasFPTextures = true;
1231 hasHalfFPTextures = true;
1232 }
1233 } else {
1234 if (version >= GR_GL_VER(3, 1)) {
1235 hasFPTextures = true;
1236 hasHalfFPTextures = true;
1237 } else {
1238 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1239 ctxInfo.hasExtension("GL_OES_texture_float")) {
1240 hasFPTextures = true;
1241 }
1242 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1243 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1244 hasHalfFPTextures = true;
1245 }
1246 }
1247 }
bsalomon30447372015-12-21 09:03:05 -08001248
1249 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1250 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
1251 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGBA;
1252 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001253 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001254 if (hasFPTextures) {
1255 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1256 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1257 // many precision issues and no clients actually want this yet.
1258 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1259 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1260 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1261 }
1262 }
bsalomoncdee0092016-01-08 13:20:12 -08001263 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001264
1265 if (this->textureRedSupport()) {
1266 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1267 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
1268 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001269 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001270 } else {
1271 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1272 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
1273 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001274 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001275 }
1276 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1277 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1278 } else {
1279 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1280 }
bsalomon7928ef62016-01-05 10:26:39 -08001281 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001282 if (hasHalfFPTextures) {
1283 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1284 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1285 // GL_RED internal format.
1286 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1287 (this->textureRedSupport() &&
1288 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1289 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1290 }
1291 }
bsalomon30447372015-12-21 09:03:05 -08001292
1293 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1294 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
1295 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RGBA;
1296 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1297 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1298 } else {
1299 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1300 }
bsalomon7928ef62016-01-05 10:26:39 -08001301 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001302 if (hasHalfFPTextures) {
1303 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1304 // ES requires 3.2 or EXT_color_buffer_half_float.
1305 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1306 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1307 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1308 }
1309 }
bsalomoncdee0092016-01-08 13:20:12 -08001310 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001311
1312 // Compressed texture support
1313
1314 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1315 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1316
1317 // TODO: Fix command buffer bindings and remove this.
1318 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001319
1320 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001321 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001322
1323 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1324 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
1325 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat = 0;
1326 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001327 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001328 // Disable this for now, while we investigate https://bug.skia.org/4333
1329 if (false) {
1330 // Check for 8-bit palette..
1331 GrGLint numFormats;
1332 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1333 if (numFormats) {
1334 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1335 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1336 for (int i = 0; i < numFormats; ++i) {
1337 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1338 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1339 break;
1340 }
1341 }
1342 }
1343 }
bsalomoncdee0092016-01-08 13:20:12 -08001344 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001345
bsalomon41e4384e2016-01-08 09:12:44 -08001346 // May change the internal format based on extensions.
1347 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1348 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1349 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1350 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1351 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1352 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1353 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1354 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1355 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1356 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1357 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1358 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1359 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1360 GR_GL_COMPRESSED_RED_RGTC1;
1361 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1362 GR_GL_COMPRESSED_RED_RGTC1;
1363 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1364 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1365 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1366 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1367 GR_GL_COMPRESSED_3DC_X;
1368
bsalomon30447372015-12-21 09:03:05 -08001369 }
1370 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat = 0;
1371 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001372 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001373 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001374
1375 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1376 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1377 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat = 0;
1378 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001379 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001380 if (kGL_GrGLStandard == standard) {
1381 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1382 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1383 }
1384 } else {
1385 if (version >= GR_GL_VER(3, 0) ||
1386 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1387 // ETC2 is a superset of ETC1, so we can just check for that, too.
1388 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1389 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1390 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1391 }
1392 }
bsalomoncdee0092016-01-08 13:20:12 -08001393 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001394
1395 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1396 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1397 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat = 0;
1398 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001399 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001400 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1401 // decompressing the textures in the driver, and is generally slower.
1402 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1403 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1404 }
bsalomoncdee0092016-01-08 13:20:12 -08001405 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001406
1407 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1408 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1409 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1410 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1411 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat = 0;
1412 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001413 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001414 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1415 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1416 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1417 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1418 }
bsalomoncdee0092016-01-08 13:20:12 -08001419 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001420
1421 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1422
1423 // ES 2.0 requires that the internal/external formats match.
1424 bool useSizedFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1425 ctxInfo.version() >= GR_GL_VER(3,0));
1426 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1427 // Almost always we want to pass fExternalFormat as the <format> param to glTex[Sub]Image.
1428 fConfigTable[i].fFormats.fExternalFormatForTexImage =
1429 fConfigTable[i].fFormats.fExternalFormat;
1430 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedFormats ?
1431 fConfigTable[i].fFormats.fSizedInternalFormat :
1432 fConfigTable[i].fFormats.fBaseInternalFormat;
1433 }
1434 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1435 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1436 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1437 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1438 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
1439 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormatForTexImage =
1440 GR_GL_SRGB_ALPHA;
1441 }
1442
1443 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1444 // as a base format.
1445 // GL_EXT_texture_format_BGRA8888:
1446 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1447 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1448 // formats.
1449 // GL_APPLE_texture_format_BGRA8888:
1450 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1451 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1452 // glTexImage (just for glTexStorage).
1453 if (useSizedFormats && this->bgraIsInternalFormat()) {
1454 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1455 }
1456
bsalomoncdee0092016-01-08 13:20:12 -08001457 // If we don't have texture swizzle support then the shader generator must insert the
1458 // swizzle into shader code.
1459 if (!this->textureSwizzleSupport()) {
1460 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1461 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1462 }
1463 }
1464
bsalomon30447372015-12-21 09:03:05 -08001465#ifdef SK_DEBUG
1466 // Make sure we initialized everything.
1467 ConfigFormats defaultEntry;
1468 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1469 SkASSERT(defaultEntry.fBaseInternalFormat != fConfigTable[i].fFormats.fBaseInternalFormat);
1470 SkASSERT(defaultEntry.fSizedInternalFormat !=
1471 fConfigTable[i].fFormats.fSizedInternalFormat);
1472 SkASSERT(defaultEntry.fExternalFormat != fConfigTable[i].fFormats.fExternalFormat);
1473 SkASSERT(defaultEntry.fExternalType != fConfigTable[i].fFormats.fExternalType);
1474 }
1475#endif
1476}
1477
egdanielb7e7d572015-11-04 04:23:53 -08001478void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}
jvanverthe9c0fc62015-04-29 11:18:05 -07001479
1480