blob: 0c2ed73d7cb237597d1f99f19d2767028209531d [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) {
bsalomonb76afed2016-01-13 12:19:15 -0800640 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
641 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
642 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
643 // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
644 if (readFormat != GR_GL_RED && readFormat != GR_GL_RGB && readFormat != GR_GL_RGBA &&
645 readFormat != GR_GL_BGRA) {
646 return false;
647 }
648 // There is also a set of allowed types, but all the types we use are in the set:
649 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
650 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
651 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
652 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
653 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
654 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
655 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800656 return true;
piotaixre4b23142014-10-02 10:57:53 -0700657 }
bsalomon7928ef62016-01-05 10:26:39 -0800658
bsalomon76148af2016-01-12 11:13:47 -0800659 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800660
661 if (kNormalizedFixedPoint_FormatType == fConfigTable[currFBOConfig].fFormatType) {
662 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
663 return true;
664 }
665 } else {
666 SkASSERT(kFloat_FormatType == fConfigTable[currFBOConfig].fFormatType);
667 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
668 return true;
669 }
670 }
671
672 if (0 == fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat) {
673 ReadPixelsFormat* rpFormat =
674 const_cast<ReadPixelsFormat*>(&fConfigTable[currFBOConfig].fSecondReadPixelsFormat);
675 GrGLint format = 0, type = 0;
676 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
677 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
678 rpFormat->fFormat = format;
679 rpFormat->fType = type;
680 }
681
682 return fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
683 fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700684}
685
robertphillips@google.com6177e692013-02-28 20:16:25 +0000686void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000687
688 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000689 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000690 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
691 // ES3 driver bugs on at least one device with a tiled GPU (N10).
692 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
693 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
694 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
695 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
cdalton63f6c1f2015-11-06 07:09:43 -0800696 } else if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700697 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000698 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000699 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
700 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
701 // chrome's extension is equivalent to the EXT msaa
702 // and fbo_blit extensions.
703 fMSFBOType = kDesktop_EXT_MSFBOType;
704 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
705 fMSFBOType = kES_Apple_MSFBOType;
706 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000707 } else {
cdalton63f6c1f2015-11-06 07:09:43 -0800708 if (fMixedSamplesSupport && fShaderCaps->pathRenderingSupport()) {
vbuzinovdded6962015-06-12 08:59:45 -0700709 fMSFBOType = kMixedSamples_MSFBOType;
710 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000711 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000712 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000713 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
714 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000715 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000716 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000717 }
718}
719
cdalton1dd05422015-06-12 09:01:18 -0700720void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
721 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
722
723 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
724 // for now until its own blacklists can be updated.
725 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
726 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700727 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700728 return;
729 }
730
731 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
732 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
733 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
734 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
735 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
736 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
737 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
738 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
739 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
740 return;
741 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
742 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
743 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
744 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
745 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
746 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
747 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
748 // slow on a particular platform.
749 } else {
750 return; // No advanced blend support.
751 }
752
753 SkASSERT(this->advancedBlendEquationSupport());
754
755 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
756 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
757 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
758 (1 << kColorBurn_GrBlendEquation);
759 }
joel.liang9764c402015-07-09 19:46:18 -0700760 if (kARM_GrGLVendor == ctxInfo.vendor()) {
761 // Blacklist color-burn on ARM until the fix is released.
762 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
763 }
cdalton1dd05422015-06-12 09:01:18 -0700764}
765
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000766namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700767const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000768}
769
770void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
771
772 // Build up list of legal stencil formats (though perhaps not supported on
773 // the particular gpu/driver) from most preferred to least.
774
775 // these consts are in order of most preferred to least preferred
776 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
777
778 static const StencilFormat
779 // internal Format stencil bits total bits packed?
780 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
781 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
782 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
783 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000784 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000785 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
786
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000787 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000788 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000789 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000790 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
791 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
792
793 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
794 // require FBO support we can expect these are legal formats and don't
795 // check. These also all support the unsized GL_STENCIL_INDEX.
796 fStencilFormats.push_back() = gS8;
797 fStencilFormats.push_back() = gS16;
798 if (supportsPackedDS) {
799 fStencilFormats.push_back() = gD24S8;
800 }
801 fStencilFormats.push_back() = gS4;
802 if (supportsPackedDS) {
803 fStencilFormats.push_back() = gDS;
804 }
805 } else {
806 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
807 // for other formats.
808 // ES doesn't support using the unsized format.
809
810 fStencilFormats.push_back() = gS8;
811 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000812 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
813 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000814 fStencilFormats.push_back() = gD24S8;
815 }
816 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
817 fStencilFormats.push_back() = gS4;
818 }
819 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000820}
821
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000822SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000823
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000824 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000825
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000826 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000827 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000828 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000829 i,
830 fStencilFormats[i].fStencilBits,
831 fStencilFormats[i].fTotalBits);
832 }
833
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000834 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000835 "None",
836 "ARB",
837 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000838 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000839 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000840 "IMG MS To Texture",
841 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700842 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000843 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000844 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
845 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
846 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000847 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
848 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
849 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
850 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700851 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000852 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000853
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000854 static const char* kInvalidateFBTypeStr[] = {
855 "None",
856 "Discard",
857 "Invalidate",
858 };
859 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
860 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
861 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
862 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000863
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000864 static const char* kMapBufferTypeStr[] = {
865 "None",
866 "MapBuffer",
867 "MapBufferRange",
868 "Chromium",
869 };
870 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
871 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
872 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
873 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
874 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
875
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000876 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000877 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000878 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000879 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000880 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
881 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000882 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000883 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
884 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
885 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
886 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000887
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000888 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
889 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
890 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
891 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000892 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700893 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
894 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800895 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000896 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000897 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700898 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700899 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
900 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700901 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800902 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
903 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800904
905 r.append("Configs\n-------\n");
906 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
907 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -0800908 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
909 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -0800910 i,
911 fConfigTable[i].fFlags,
912 fConfigTable[i].fFormats.fBaseInternalFormat,
913 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -0800914 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
915 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -0800916 fConfigTable[i].fFormats.fExternalType,
917 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -0800918 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -0800919 }
920
jvanverthe9c0fc62015-04-29 11:18:05 -0700921 return r;
922}
923
jvanverthe9c0fc62015-04-29 11:18:05 -0700924static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
925 switch (p) {
926 case kLow_GrSLPrecision:
927 return GR_GL_LOW_FLOAT;
928 case kMedium_GrSLPrecision:
929 return GR_GL_MEDIUM_FLOAT;
930 case kHigh_GrSLPrecision:
931 return GR_GL_HIGH_FLOAT;
932 }
933 SkFAIL("Unknown precision.");
934 return -1;
935}
936
937static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
938 switch (type) {
939 case kVertex_GrShaderType:
940 return GR_GL_VERTEX_SHADER;
941 case kGeometry_GrShaderType:
942 return GR_GL_GEOMETRY_SHADER;
943 case kFragment_GrShaderType:
944 return GR_GL_FRAGMENT_SHADER;
945 }
946 SkFAIL("Unknown shader type.");
947 return -1;
948}
949
jvanverthcba99b82015-06-24 06:59:57 -0700950void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
951 const GrGLInterface* intf,
952 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700953 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
954 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
955 for (int s = 0; s < kGrShaderTypeCount; ++s) {
956 if (kGeometry_GrShaderType != s) {
957 GrShaderType shaderType = static_cast<GrShaderType>(s);
958 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -0700959 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -0700960 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700961 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
962 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
963 GrGLenum glPrecision = precision_to_gl_float_type(precision);
964 GrGLint range[2];
965 GrGLint bits;
966 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
967 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -0700968 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
969 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
970 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -0700971 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -0700972 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700973 }
jvanverthcba99b82015-06-24 06:59:57 -0700974 else if (!glslCaps->fShaderPrecisionVaries) {
975 glslCaps->fShaderPrecisionVaries =
976 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -0700977 }
978 }
979 }
980 }
981 }
982 }
983 else {
984 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -0700985 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700986 for (int s = 0; s < kGrShaderTypeCount; ++s) {
987 if (kGeometry_GrShaderType != s) {
988 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700989 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
990 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
991 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -0700992 }
993 }
994 }
995 }
996 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
997 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
998 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
999 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -07001000 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001001 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001002 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1003 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001004 }
1005 }
1006}
1007
bsalomon41e4384e2016-01-08 09:12:44 -08001008bool GrGLCaps::bgraIsInternalFormat() const {
1009 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1010}
1011
bsalomon76148af2016-01-12 11:13:47 -08001012bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1013 GrGLenum* internalFormat, GrGLenum* externalFormat,
1014 GrGLenum* externalType) const {
1015 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1016 externalFormat, externalType)) {
1017 return false;
1018 }
1019 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1020 return true;
1021}
1022
1023bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1024 GrGLenum* internalFormat) const {
1025 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1026 return false;
1027 }
1028 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1029 return true;
1030}
1031
1032bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1033 GrGLenum* externalFormat, GrGLenum* externalType) const {
1034 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1035 externalFormat, externalType)) {
1036 return false;
1037 }
1038 return true;
1039}
1040
1041bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1042 if (GrPixelConfigIsCompressed(config)) {
1043 return false;
1044 }
1045 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1046 return true;
1047}
1048
1049bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1050 ExternalFormatUsage usage, GrGLenum* externalFormat,
1051 GrGLenum* externalType) const {
1052 SkASSERT(externalFormat && externalType);
1053 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1054 return false;
1055 }
1056
1057 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1058 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1059
1060 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1061 // made to work in many cases using glPixelStore and what not but is not needed currently.
1062 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1063 return false;
1064 }
1065
1066 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1067 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1068
bsalomonb76afed2016-01-13 12:19:15 -08001069 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1070 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1071 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1072 // texture, not the red component.
1073 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1074 if (this->textureRedSupport()) {
1075 SkASSERT(GR_GL_RED == *externalFormat);
1076 *externalFormat = GR_GL_ALPHA;
1077 }
1078 }
1079
bsalomon76148af2016-01-12 11:13:47 -08001080 return true;
1081}
1082
bsalomoncdee0092016-01-08 13:20:12 -08001083void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1084 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001085 /*
1086 Comments on renderability of configs on various GL versions.
1087 OpenGL < 3.0:
1088 no built in support for render targets.
1089 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1090 format RGB, RGBA and NV float formats we don't use.
1091 This is the following:
1092 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1093 RGB10_A2, RGBA12,RGBA16
1094 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1095 since they aren't required by later standards and the driver can simply return
1096 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1097 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1098 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1099 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1100 This adds a lot of additional renderable sized formats, including ALPHA8.
1101 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1102 16F, 32I, 32UI, and 32F variants).
1103 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1104
1105 For both the above extensions we limit ourselves to those that are also required by
1106 OpenGL 3.0.
1107
1108 OpenGL 3.0:
1109 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1110 but are not required to be supported as renderable textures/renderbuffer.
1111 Required renderable color formats:
1112 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1113 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1114 RGB10_A2.
1115 - R11F_G11F_B10F.
1116 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1117 and RG8UI.
1118 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1119 - ALPHA8
1120
1121 OpenGL 3.1, 3.2, 3.3
1122 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1123 OpengGL 3.3, 4.0, 4.1
1124 Adds RGB10_A2UI.
1125 OpengGL 4.2
1126 Adds
1127 - RGB5_A1, RGBA4
1128 - RGB565
1129 OpenGL 4.4
1130 Does away with the separate list and adds a column to the sized internal color format
1131 table. However, no new formats become required color renderable.
1132
1133 ES 2.0
1134 color renderable: RGBA4, RGB5_A1, RGB565
1135 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1136 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1137 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1138 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1139 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1140 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1141
1142 ES 3.0
1143 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1144 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1145 RGB5_A1.
1146 - RGB8 and RGB565.
1147 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1148 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1149 ES 3.1
1150 Adds RGB10_A2, RGB10_A2UI,
1151 ES 3.2
1152 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1153 */
1154 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1155 if (kNone_MSFBOType != fMSFBOType) {
1156 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1157 }
1158
1159 GrGLStandard standard = ctxInfo.standard();
1160 GrGLVersion version = ctxInfo.version();
1161
bsalomon30447372015-12-21 09:03:05 -08001162 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1163 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001164 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001165 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001166 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001167 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001168
1169 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1170 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001171 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1172 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001173 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001174 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001175 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1176 if (kGL_GrGLStandard == standard) {
1177 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1178 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001179 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001180 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1181 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1182 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1183 }
egdaniel4999df82016-01-07 17:06:04 -08001184 }
bsalomoncdee0092016-01-08 13:20:12 -08001185 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001186
bsalomon76148af2016-01-12 11:13:47 -08001187 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1188 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001189 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001190 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001191 if (kGL_GrGLStandard == standard) {
1192 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1193 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1194 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1195 // Since the internal format is RGBA8, it is also renderable.
1196 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1197 allRenderFlags;
1198 }
1199 } else {
1200 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1201 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1202 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1203 // The APPLE extension doesn't make this renderable.
1204 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1205 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1206 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1207 // Though, that seems to not be the case if the texture storage extension is
1208 // present. The specs don't exactly make that clear.
1209 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1210 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1211 }
1212 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1213 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1214 ConfigInfo::kRenderable_Flag;
1215 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1216 this->usesMSAARenderBuffers()) {
1217 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1218 ConfigInfo::kRenderableWithMSAA_Flag;
1219 }
1220 }
1221 }
bsalomoncdee0092016-01-08 13:20:12 -08001222 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001223
bsalomon41e4384e2016-01-08 09:12:44 -08001224 // We only enable srgb support if both textures and FBOs support srgb.
1225 bool srgbSupport = false;
1226 if (kGL_GrGLStandard == standard) {
1227 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1228 srgbSupport = true;
1229 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1230 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1231 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1232 srgbSupport = true;
1233 }
1234 }
1235 // All the above srgb extensions support toggling srgb writes
1236 fSRGBWriteControl = srgbSupport;
1237 } else {
1238 // See https://bug.skia.org/4148 for PowerVR issue.
1239 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1240 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1241 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1242 // sRGB writing for destinations.
1243 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1244 }
bsalomon30447372015-12-21 09:03:05 -08001245 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1246 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1247 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1248 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001249 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1250 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001251 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001252 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001253 if (srgbSupport) {
1254 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1255 allRenderFlags;
1256 }
bsalomoncdee0092016-01-08 13:20:12 -08001257 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001258
1259 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1260 if (this->ES2CompatibilitySupport()) {
1261 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1262 } else {
1263 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1264 }
bsalomon76148af2016-01-12 11:13:47 -08001265 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1266 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001267 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001268 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001269 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1270 if (kGL_GrGLStandard == standard) {
1271 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1272 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1273 }
1274 } else {
1275 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1276 }
bsalomoncdee0092016-01-08 13:20:12 -08001277 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001278
1279 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1280 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001281 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1282 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001283 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001284 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001285 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1286 if (kGL_GrGLStandard == standard) {
1287 if (version >= GR_GL_VER(4, 2)) {
1288 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1289 }
1290 } else {
1291 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1292 }
bsalomoncdee0092016-01-08 13:20:12 -08001293 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001294
1295 if (this->textureRedSupport()) {
1296 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1297 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001298 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1299 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001300 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001301 } else {
1302 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1303 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001304 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1305 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001306 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001307 }
1308 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001309 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001310 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1311 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1312 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1313 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1314 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1315 }
1316
1317 // Check for [half] floating point texture support
1318 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1319 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1320 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1321 bool hasFPTextures = false;
1322 bool hasHalfFPTextures = false;
1323 // for now we don't support floating point MSAA on ES
1324 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1325 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1326
1327 if (kGL_GrGLStandard == standard) {
1328 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1329 hasFPTextures = true;
1330 hasHalfFPTextures = true;
1331 }
1332 } else {
1333 if (version >= GR_GL_VER(3, 1)) {
1334 hasFPTextures = true;
1335 hasHalfFPTextures = true;
1336 } else {
1337 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1338 ctxInfo.hasExtension("GL_OES_texture_float")) {
1339 hasFPTextures = true;
1340 }
1341 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1342 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1343 hasHalfFPTextures = true;
1344 }
1345 }
1346 }
bsalomon30447372015-12-21 09:03:05 -08001347
1348 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1349 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001350 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1351 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001352 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001353 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001354 if (hasFPTextures) {
1355 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1356 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1357 // many precision issues and no clients actually want this yet.
1358 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1359 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1360 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1361 }
1362 }
bsalomoncdee0092016-01-08 13:20:12 -08001363 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001364
1365 if (this->textureRedSupport()) {
1366 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1367 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001368 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1369 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001370 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001371 } else {
1372 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1373 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001374 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1375 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001376 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001377 }
1378 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1379 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1380 } else {
1381 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1382 }
bsalomon7928ef62016-01-05 10:26:39 -08001383 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001384 if (hasHalfFPTextures) {
1385 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1386 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1387 // GL_RED internal format.
1388 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1389 (this->textureRedSupport() &&
1390 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1391 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1392 }
1393 }
bsalomon30447372015-12-21 09:03:05 -08001394
1395 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1396 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001397 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1398 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001399 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1400 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1401 } else {
1402 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1403 }
bsalomon7928ef62016-01-05 10:26:39 -08001404 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001405 if (hasHalfFPTextures) {
1406 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1407 // ES requires 3.2 or EXT_color_buffer_half_float.
1408 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1409 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1410 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1411 }
1412 }
bsalomoncdee0092016-01-08 13:20:12 -08001413 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001414
1415 // Compressed texture support
1416
1417 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1418 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1419
1420 // TODO: Fix command buffer bindings and remove this.
1421 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001422
1423 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001424 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001425
1426 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1427 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001428 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001429 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001430 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001431 // Disable this for now, while we investigate https://bug.skia.org/4333
1432 if (false) {
1433 // Check for 8-bit palette..
1434 GrGLint numFormats;
1435 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1436 if (numFormats) {
1437 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1438 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1439 for (int i = 0; i < numFormats; ++i) {
1440 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1441 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1442 break;
1443 }
1444 }
1445 }
1446 }
bsalomoncdee0092016-01-08 13:20:12 -08001447 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001448
bsalomon41e4384e2016-01-08 09:12:44 -08001449 // May change the internal format based on extensions.
1450 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1451 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1452 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1453 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1454 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1455 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1456 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1457 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1458 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1459 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1460 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1461 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1462 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1463 GR_GL_COMPRESSED_RED_RGTC1;
1464 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1465 GR_GL_COMPRESSED_RED_RGTC1;
1466 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1467 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1468 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1469 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1470 GR_GL_COMPRESSED_3DC_X;
1471
bsalomon30447372015-12-21 09:03:05 -08001472 }
bsalomon76148af2016-01-12 11:13:47 -08001473 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001474 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001475 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001476 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001477
1478 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1479 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001480 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001481 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001482 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001483 if (kGL_GrGLStandard == standard) {
1484 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1485 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1486 }
1487 } else {
1488 if (version >= GR_GL_VER(3, 0) ||
1489 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1490 // ETC2 is a superset of ETC1, so we can just check for that, too.
1491 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1492 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1493 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1494 }
1495 }
bsalomoncdee0092016-01-08 13:20:12 -08001496 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001497
1498 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1499 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001500 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001501 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001502 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001503 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1504 // decompressing the textures in the driver, and is generally slower.
1505 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1506 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1507 }
bsalomoncdee0092016-01-08 13:20:12 -08001508 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001509
1510 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1511 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1512 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1513 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001514 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1515 0;
bsalomon30447372015-12-21 09:03:05 -08001516 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001517 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001518 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1519 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1520 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1521 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1522 }
bsalomoncdee0092016-01-08 13:20:12 -08001523 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001524
1525 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1526
1527 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001528 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1529 ctxInfo.version() >= GR_GL_VER(3,0));
1530 // All ES versions (thus far) require sized internal formats for render buffers.
1531 // TODO: Always use sized internal format?
1532 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1533
bsalomon30447372015-12-21 09:03:05 -08001534 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001535 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1536 // param to glTex[Sub]Image.
1537 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1538 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1539 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1540 fConfigTable[i].fFormats.fSizedInternalFormat :
1541 fConfigTable[i].fFormats.fBaseInternalFormat;
1542 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001543 fConfigTable[i].fFormats.fSizedInternalFormat :
1544 fConfigTable[i].fFormats.fBaseInternalFormat;
1545 }
1546 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1547 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1548 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1549 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1550 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001551 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001552 GR_GL_SRGB_ALPHA;
1553 }
1554
1555 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1556 // as a base format.
1557 // GL_EXT_texture_format_BGRA8888:
1558 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1559 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1560 // formats.
1561 // GL_APPLE_texture_format_BGRA8888:
1562 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1563 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1564 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001565 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001566 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1567 }
1568
bsalomoncdee0092016-01-08 13:20:12 -08001569 // If we don't have texture swizzle support then the shader generator must insert the
1570 // swizzle into shader code.
1571 if (!this->textureSwizzleSupport()) {
1572 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1573 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1574 }
1575 }
1576
bsalomon7f9b2e42016-01-12 13:29:26 -08001577 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1578 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1579 // gets written to the single component.
1580 if (this->textureRedSupport()) {
1581 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1582 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1583 if (GrPixelConfigIsAlphaOnly(config) &&
1584 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1585 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1586 }
1587 }
1588 }
1589
bsalomon30447372015-12-21 09:03:05 -08001590#ifdef SK_DEBUG
1591 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001592 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001593 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001594 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1595 fConfigTable[i].fFormats.fBaseInternalFormat);
1596 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001597 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001598 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1599 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1600 fConfigTable[i].fFormats.fExternalFormat[j]);
1601 }
1602 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001603 }
1604#endif
1605}
1606
egdanielb7e7d572015-11-04 04:23:53 -08001607void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}