blob: d1c1162a9e4c7316b6bd44f7736ec9d55e287c0f [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"
bsalomon1aa20292016-01-22 08:16:09 -080013#include "GrGLRenderTarget.h"
jvanverthcba99b82015-06-24 06:59:57 -070014#include "glsl/GrGLSLCaps.h"
csmartdaltone0d36292016-07-29 08:14:20 -070015#include "instanced/GLInstancedRendering.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000016#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000017#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000018
bsalomon682c2692015-05-22 14:01:46 -070019GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
20 const GrGLContextInfo& ctxInfo,
21 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080022 fStandard = ctxInfo.standard();
23
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000024 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000026 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000027 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080028 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000029 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000030 fUnpackRowLengthSupport = false;
31 fUnpackFlipYSupport = false;
32 fPackRowLengthSupport = false;
33 fPackFlipYSupport = false;
34 fTextureUsageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000035 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000036 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000037 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070038 fDirectStateAccessSupport = false;
39 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080040 fES2CompatibilitySupport = false;
csmartdalton4c18b622016-07-29 12:19:28 -070041 fDrawInstancedSupport = false;
cdalton06604b92016-02-05 10:09:51 -080042 fDrawIndirectSupport = false;
43 fMultiDrawIndirectSupport = false;
44 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000045 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070046 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080047 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080048 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070049 fRGBA8888PixelsOpsAreSlow = false;
50 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080051 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080052 fRGBAToBGRAReadbackConversionsAreSlow = false;
brianosman09563ce2016-06-02 08:59:34 -070053 fDoManualMipmapping = false;
piotaixre4b23142014-10-02 10:57:53 -070054
Brian Salomone5e7eb12016-10-14 16:18:33 -040055 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
bsalomon083617b2016-02-12 12:10:14 -080056
halcanary385fe4d2015-08-26 13:07:48 -070057 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070058
cdalton4cd67132015-06-10 19:23:46 -070059 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000060}
61
cdalton4cd67132015-06-10 19:23:46 -070062void GrGLCaps::init(const GrContextOptions& contextOptions,
63 const GrGLContextInfo& ctxInfo,
64 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000065 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000066 GrGLVersion version = ctxInfo.version();
67
bsalomon@google.combcce8922013-03-25 15:38:39 +000068 /**************************************************************************
69 * Caps specific to GrGLCaps
70 **************************************************************************/
71
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000072 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000073 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
74 &fMaxFragmentUniformVectors);
75 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000076 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000077 GrGLint max;
78 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
79 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000080 if (version >= GR_GL_VER(3, 2)) {
81 GrGLint profileMask;
82 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
83 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
84 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000085 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000086 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000087
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000088 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000089 fUnpackRowLengthSupport = true;
90 fUnpackFlipYSupport = false;
91 fPackRowLengthSupport = true;
92 fPackFlipYSupport = false;
93 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000094 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
95 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000096 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000097 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
98 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000099 fPackFlipYSupport =
100 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
101 }
102
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000103 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000104 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
105
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000106 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700107 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
108 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
109 ctxInfo.hasExtension("GL_NV_texture_barrier");
110 } else {
111 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
112 }
113
cdaltoneb79eea2016-02-26 10:39:34 -0800114 if (kGL_GrGLStandard == standard) {
115 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
116 ctxInfo.hasExtension("GL_ARB_texture_multisample");
117 } else {
118 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
119 }
120
halcanary9d524f22016-03-29 09:03:52 -0700121 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
hendrikwa0d5ad72014-12-02 07:30:30 -0800122 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700123 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800124 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000125 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
126 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800127 } else {
128 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
129 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000130 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000131 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000132 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000133 ctxInfo.hasExtension("GL_ARB_imaging");
134
egdaniel9250d242015-05-18 13:04:26 -0700135 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
136 // Thus we are blacklisting this extension for now on Adreno4xx devices.
137 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
138 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
139 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
140 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000141 fDiscardRenderTargetSupport = true;
142 fInvalidateFBType = kInvalidate_InvalidateFBType;
143 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
144 fDiscardRenderTargetSupport = true;
145 fInvalidateFBType = kDiscard_InvalidateFBType;
146 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000147
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000148 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
149 fFullClearIsFree = true;
150 }
151
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000152 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000153 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800154 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
155 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000156 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000157 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
158 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000159 }
160
cdalton626e1ff2015-06-12 13:56:46 -0700161 if (kGL_GrGLStandard == standard) {
162 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
163 } else {
164 fDirectStateAccessSupport = false;
165 }
166
167 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
168 fDebugSupport = true;
169 } else {
170 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
171 }
172
jvanverth3f801cb2014-12-16 09:49:38 -0800173 if (kGL_GrGLStandard == standard) {
174 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
175 }
176 else {
177 fES2CompatibilitySupport = true;
178 }
179
cdalton0edea2c2015-05-21 08:27:44 -0700180 if (kGL_GrGLStandard == standard) {
181 fMultisampleDisableSupport = true;
182 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700183 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700184 }
185
kkinnunend94708e2015-07-30 22:47:04 -0700186 if (kGL_GrGLStandard == standard) {
187 if (version >= GR_GL_VER(3, 0)) {
188 fBindFragDataLocationSupport = true;
189 }
190 } else {
191 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
192 fBindFragDataLocationSupport = true;
193 }
joshualittc1f56b52015-06-22 12:31:31 -0700194 }
195
joshualitt7bdd70a2015-10-01 06:28:11 -0700196 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
197
kkinnunene06ed252016-02-16 23:15:40 -0800198 if (kGL_GrGLStandard == standard) {
199 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
200 // We also require textureSize() support for rectangle 2D samplers which was added in
201 // GLSL 1.40.
202 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
203 fRectangleTextureSupport = true;
204 }
bsalomone179a912016-01-20 06:18:10 -0800205 }
kkinnunene06ed252016-02-16 23:15:40 -0800206 } else {
207 // Command buffer exposes this in GL ES context for Chromium reasons,
208 // but it should not be used. Also, at the time of writing command buffer
209 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800210 }
211
bsalomoncdee0092016-01-08 13:20:12 -0800212 if (kGL_GrGLStandard == standard) {
213 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
214 fTextureSwizzleSupport = true;
215 }
216 } else {
217 if (version >= GR_GL_VER(3,0)) {
218 fTextureSwizzleSupport = true;
219 }
220 }
221
cblume09bd2c02016-03-01 14:08:28 -0800222 if (kGL_GrGLStandard == standard) {
223 fMipMapLevelAndLodControlSupport = true;
224 } else if (kGLES_GrGLStandard == standard) {
225 if (version >= GR_GL_VER(3,0)) {
226 fMipMapLevelAndLodControlSupport = true;
227 }
228 }
229
bsalomon88c7b982015-07-31 11:20:16 -0700230#ifdef SK_BUILD_FOR_WIN
231 // We're assuming that on Windows Chromium we're using ANGLE.
232 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
233 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700234 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700235 fRGBA8888PixelsOpsAreSlow = isANGLE;
236 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
237 // check DX11 ANGLE.
238 fPartialFBOReadIsSlow = isANGLE;
239#endif
240
ericrkb4ecabd2016-03-11 15:18:20 -0800241 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
242 bool isMAC = false;
243#ifdef SK_BUILD_FOR_MAC
244 isMAC = true;
245#endif
246
247 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
248 // vis-versa.
249 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
250
cdalton4cd67132015-06-10 19:23:46 -0700251 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700252 * GrShaderCaps fields
253 **************************************************************************/
254
egdaniel0a482332015-10-26 08:59:10 -0700255 // This must be called after fCoreProfile is set on the GrGLCaps
256 this->initGLSL(ctxInfo);
257 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
258
egdaniel05ded892015-10-26 07:38:05 -0700259 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
260
261 // For now these two are equivalent but we could have dst read in shader via some other method.
262 // Before setting this, initGLSL() must have been called.
263 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
264
265 // Enable supported shader-related caps
266 if (kGL_GrGLStandard == standard) {
267 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
268 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
269 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
270 glslCaps->fShaderDerivativeSupport = true;
271 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
272 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
273 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
cdalton793dc262016-02-08 10:11:47 -0800274 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
275 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700276 }
277 else {
278 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
279
280 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
281 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800282
283 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
284 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700285 }
286
ethannicholas22793252016-01-30 09:59:10 -0800287 if (ctxInfo.hasExtension("GL_EXT_shader_pixel_local_storage")) {
288 #define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
halcanary9d524f22016-03-29 09:03:52 -0700289 GR_GL_GetIntegerv(gli, GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT,
ethannicholas22793252016-01-30 09:59:10 -0800290 &glslCaps->fPixelLocalStorageSize);
291 glslCaps->fPLSPathRenderingSupport = glslCaps->fFBFetchSupport;
292 }
293 else {
294 glslCaps->fPixelLocalStorageSize = 0;
295 glslCaps->fPLSPathRenderingSupport = false;
296 }
297
cdalton9c3f1432016-03-11 10:07:37 -0800298 // Protect ourselves against tracking huge amounts of texture state.
299 static const uint8_t kMaxSaneSamplers = 32;
300 GrGLint maxSamplers;
301 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
302 glslCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
303 if (glslCaps->fGeometryShaderSupport) {
304 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
305 glslCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
306 }
307 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
308 glslCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
309 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
310 glslCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
311
egdaniel05ded892015-10-26 07:38:05 -0700312 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700313 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000314 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700315
cdalton63f6c1f2015-11-06 07:09:43 -0800316 // We need dual source blending and the ability to disable multisample in order to support mixed
317 // samples in every corner case.
egdanieleed519e2016-01-15 11:36:18 -0800318 if (fMultisampleDisableSupport &&
319 glslCaps->dualSourceBlendingSupport() &&
320 fShaderCaps->pathRenderingSupport()) {
321 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
kkinnunenea409432015-12-10 01:21:59 -0800322 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800323 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
kkinnunen9f63b442016-01-25 00:31:49 -0800324 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
325 kChromium_GrGLDriver == ctxInfo.driver())) {
cdalton63f6c1f2015-11-06 07:09:43 -0800326 fDiscardRenderTargetSupport = false;
327 fInvalidateFBType = kNone_InvalidateFBType;
328 }
329 }
330
csmartdalton485a1202016-07-13 10:16:32 -0700331 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
332 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
333 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
334 // limit this decision to specific GPU families rather than basing it on the vendor alone.
335 if (!GR_GL_MUST_USE_VBO &&
336 !fIsCoreProfile &&
337 (kARM_GrGLVendor == ctxInfo.vendor() ||
338 kImagination_GrGLVendor == ctxInfo.vendor() ||
339 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
340 fPreferClientSideDynamicBuffers = true;
341 }
342
egdanieleed519e2016-01-15 11:36:18 -0800343 // fUsesMixedSamples must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700344 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700345 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700346 this->initStencilFormats(ctxInfo);
347
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000348 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000349 // we could also look for GL_ATI_separate_stencil extension or
350 // GL_EXT_stencil_two_side but they use different function signatures
351 // than GL2.0+ (and than each other).
352 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
353 // supported on GL 1.4 and higher or by extension
354 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
355 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
356 } else {
357 // ES 2 has two sided stencil and stencil wrap
358 fTwoSidedStencilSupport = true;
359 fStencilWrapOpsSupport = true;
360 }
361
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000362 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000363 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
364 // extension includes glMapBuffer.
365 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
366 fMapBufferFlags |= kSubset_MapFlag;
367 fMapBufferType = kMapBufferRange_MapBufferType;
368 } else {
369 fMapBufferType = kMapBuffer_MapBufferType;
370 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000371 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000372 // Unextended GLES2 doesn't have any buffer mapping.
373 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800374 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800375 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
376 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800377 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
378 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
379 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000380 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
381 fMapBufferFlags = kCanMap_MapFlag;
382 fMapBufferType = kMapBuffer_MapBufferType;
383 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000384 }
385
jvanverthd7a2c1f2015-12-07 07:36:44 -0800386 if (kGL_GrGLStandard == standard) {
387 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
388 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700389 }
jvanverthd7a2c1f2015-12-07 07:36:44 -0800390 } else {
391 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
392 fTransferBufferType = kPBO_TransferBufferType;
jvanverthc3d706f2016-04-20 10:33:27 -0700393 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
394 fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800395 }
396 }
397
joshualitte5b74c62015-06-01 14:17:47 -0700398 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
399 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700400 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700401 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
402 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
403 // a small subset.
404#if 0
cdalton397536c2016-03-25 12:15:03 -0700405 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700406#else
cdalton397536c2016-03-25 12:15:03 -0700407 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700408#endif
joshualitte5b74c62015-06-01 14:17:47 -0700409 }
410
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000411 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000412 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
413 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
414 fNPOTTextureTileSupport = true;
415 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000416 } else {
417 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000418 // ES3 has no limitations.
419 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
420 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000421 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
422 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
423 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
424 // to alllow arbitrary wrap modes, however.
425 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000426 }
427
bsalomone72bd022015-10-26 07:33:03 -0700428 // Using MIPs on this GPU seems to be a source of trouble.
429 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
430 fMipMapSupport = false;
431 }
432
bsalomon@google.combcce8922013-03-25 15:38:39 +0000433 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
434 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
435 // Our render targets are always created with textures as the color
436 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000437 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000438
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000439 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
440
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000441 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700442 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000443
robertphillips1b8e1b52015-06-24 06:54:10 -0700444#if 0
445 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
446 kQualcomm_GrGLVendor != ctxInfo.vendor();
447#endif
448
egdaniel05ded892015-10-26 07:38:05 -0700449 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000450 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800451 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000452 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800453 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000454 }
cdaltonaf8bc7d2016-02-05 09:35:20 -0800455 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
456 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
457 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
458 // This is to guard against platforms that may not support as many samples for
459 // glRasterSamples as they do for framebuffers.
460 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
461 }
462 fMaxColorSampleCount = fMaxStencilSampleCount;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000463
csmartdalton9bc11872016-08-09 12:42:47 -0700464 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
465 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700466 }
467
bsalomon63b21962014-11-05 07:05:34 -0800468 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800469 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800470 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800471 fUseDrawInsteadOfClear = true;
472 }
473
joshualitt83bc2292015-06-18 14:18:02 -0700474 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
475 fUseDrawInsteadOfPartialRenderTargetWrite = true;
476 }
477
bsalomonbabafcc2016-02-16 11:36:47 -0800478 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
479 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
480 fUseDrawInsteadOfPartialRenderTargetWrite = true;
481 fUseDrawInsteadOfAllRenderTargetWrites = true;
482 }
483
robertphillips63926682015-08-20 09:39:02 -0700484#ifdef SK_BUILD_FOR_WIN
485 // On ANGLE deferring flushes can lead to GPU starvation
486 fPreferVRAMUseOverFlushes = !isANGLE;
487#endif
488
bsalomon7dea7b72015-08-19 08:26:51 -0700489 if (kChromium_GrGLDriver == ctxInfo.driver()) {
490 fMustClearUploadedBufferData = true;
491 }
492
bsalomond08ea5f2015-02-20 06:58:13 -0800493 if (kGL_GrGLStandard == standard) {
494 // ARB allows mixed size FBO attachments, EXT does not.
495 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
496 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
497 fOversizedStencilSupport = true;
498 } else {
499 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
500 }
501 } else {
502 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
503 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
504 }
505
joshualitt58001552015-06-26 12:46:36 -0700506 if (kGL_GrGLStandard == standard) {
507 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
508 // instanced arrays, but we could make this more granular if we wanted
csmartdalton4c18b622016-07-29 12:19:28 -0700509 fDrawInstancedSupport =
joshualitt58001552015-06-26 12:46:36 -0700510 version >= GR_GL_VER(3, 2) ||
511 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
512 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
513 } else {
csmartdalton4c18b622016-07-29 12:19:28 -0700514 fDrawInstancedSupport =
joshualitt58001552015-06-26 12:46:36 -0700515 version >= GR_GL_VER(3, 0) ||
516 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
517 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
518 }
519
cdalton06604b92016-02-05 10:09:51 -0800520 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700521 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
522 ctxInfo.hasExtension("GL_ARB_draw_indirect");
523 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
524 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700525 (fDrawIndirectSupport &&
526 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700527 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700528 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800529 } else {
530 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700531 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
532 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
533 fBaseInstanceSupport = fDrawIndirectSupport &&
534 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700535 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800536 }
537
jvanverthcba99b82015-06-24 06:59:57 -0700538 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800539
540 if (contextOptions.fUseShaderSwizzling) {
541 fTextureSwizzleSupport = false;
542 }
543
ethannicholas28ef4452016-03-25 09:26:03 -0700544 if (kGL_GrGLStandard == standard) {
ethannicholas6536ae52016-05-02 12:16:49 -0700545 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
546 ctxInfo.vendor() != kIntel_GrGLVendor) {
ethannicholas28ef4452016-03-25 09:26:03 -0700547 fSampleShadingSupport = true;
548 }
549 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
550 fSampleShadingSupport = true;
551 }
552
jvanverth84741b32016-09-30 08:39:02 -0700553 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
554 if (kGL_GrGLStandard == standard) {
555 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
556 fFenceSyncSupport = true;
557 }
558 } else if (version >= GR_GL_VER(3, 0)) {
559 fFenceSyncSupport = true;
560 }
561
brianosman131ff132016-06-07 14:22:44 -0700562 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
563 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
564 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
565 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
brianosman09563ce2016-06-02 08:59:34 -0700566 if (fMipMapLevelAndLodControlSupport &&
brianosman9a3fbf72016-06-09 13:11:08 -0700567 (contextOptions.fDoManualMipmapping ||
568 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
brianosman131ff132016-06-07 14:22:44 -0700569 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
570 (kATI_GrGLVendor == ctxInfo.vendor()))) {
brianosman09563ce2016-06-02 08:59:34 -0700571 fDoManualMipmapping = true;
572 }
573
bsalomoncdee0092016-01-08 13:20:12 -0800574 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
575 // already been detected.
576 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700577
578 this->applyOptionsOverrides(contextOptions);
579 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000580}
581
egdaniel472d44e2015-10-22 08:20:00 -0700582const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
583 bool isCoreProfile) {
584 switch (generation) {
585 case k110_GrGLSLGeneration:
586 if (kGLES_GrGLStandard == standard) {
587 // ES2s shader language is based on version 1.20 but is version
588 // 1.00 of the ES language.
589 return "#version 100\n";
590 } else {
591 SkASSERT(kGL_GrGLStandard == standard);
592 return "#version 110\n";
593 }
594 case k130_GrGLSLGeneration:
595 SkASSERT(kGL_GrGLStandard == standard);
596 return "#version 130\n";
597 case k140_GrGLSLGeneration:
598 SkASSERT(kGL_GrGLStandard == standard);
599 return "#version 140\n";
600 case k150_GrGLSLGeneration:
601 SkASSERT(kGL_GrGLStandard == standard);
602 if (isCoreProfile) {
603 return "#version 150\n";
604 } else {
605 return "#version 150 compatibility\n";
606 }
607 case k330_GrGLSLGeneration:
608 if (kGLES_GrGLStandard == standard) {
609 return "#version 300 es\n";
610 } else {
611 SkASSERT(kGL_GrGLStandard == standard);
612 if (isCoreProfile) {
613 return "#version 330\n";
614 } else {
615 return "#version 330 compatibility\n";
616 }
617 }
cdalton33ad7012016-02-22 07:55:44 -0800618 case k400_GrGLSLGeneration:
619 SkASSERT(kGL_GrGLStandard == standard);
620 if (isCoreProfile) {
621 return "#version 400\n";
622 } else {
623 return "#version 400 compatibility\n";
624 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500625 case k420_GrGLSLGeneration:
626 SkASSERT(kGL_GrGLStandard == standard);
627 if (isCoreProfile) {
628 return "#version 420\n";
629 }
630 else {
631 return "#version 420 compatibility\n";
632 }
egdaniel472d44e2015-10-22 08:20:00 -0700633 case k310es_GrGLSLGeneration:
634 SkASSERT(kGLES_GrGLStandard == standard);
635 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800636 case k320es_GrGLSLGeneration:
637 SkASSERT(kGLES_GrGLStandard == standard);
638 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700639 }
640 return "<no version>";
641}
642
egdaniel05ded892015-10-26 07:38:05 -0700643void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700644 GrGLStandard standard = ctxInfo.standard();
645 GrGLVersion version = ctxInfo.version();
646
647 /**************************************************************************
648 * Caps specific to GrGLSLCaps
649 **************************************************************************/
650
651 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
652 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700653 if (kGLES_GrGLStandard == standard) {
654 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
655 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
656 glslCaps->fFBFetchSupport = true;
657 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
658 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
659 }
660 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
661 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
662 glslCaps->fFBFetchNeedsCustomOutput = false;
663 glslCaps->fFBFetchSupport = true;
664 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
665 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
666 }
667 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
668 // The arm extension also requires an additional flag which we will set onResetContext
669 glslCaps->fFBFetchNeedsCustomOutput = false;
670 glslCaps->fFBFetchSupport = true;
671 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
672 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
673 }
674 glslCaps->fUsesPrecisionModifiers = true;
675 }
676
egdaniel7517e452016-09-20 13:00:26 -0700677 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
678 // Galaxy S7.
679 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
680 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
681 glslCaps->fFBFetchSupport = false;
682 }
683
egdaniel472d44e2015-10-22 08:20:00 -0700684 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
685
cdaltonc08f1962016-02-12 12:14:06 -0800686 if (kGL_GrGLStandard == standard) {
687 glslCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
688 } else {
689 glslCaps->fFlatInterpolationSupport =
690 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
691 }
692
693 if (kGL_GrGLStandard == standard) {
694 glslCaps->fNoPerspectiveInterpolationSupport =
695 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
696 } else {
697 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
698 glslCaps->fNoPerspectiveInterpolationSupport = true;
699 glslCaps->fNoPerspectiveInterpolationExtensionString =
700 "GL_NV_shader_noperspective_interpolation";
701 }
702 }
703
cdalton33ad7012016-02-22 07:55:44 -0800704 if (kGL_GrGLStandard == standard) {
cdalton4a98cdb2016-03-01 12:12:20 -0800705 glslCaps->fMultisampleInterpolationSupport =
706 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
707 } else {
708 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
709 glslCaps->fMultisampleInterpolationSupport = true;
710 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
711 glslCaps->fMultisampleInterpolationSupport = true;
712 glslCaps->fMultisampleInterpolationExtensionString =
713 "GL_OES_shader_multisample_interpolation";
714 }
715 }
716
717 if (kGL_GrGLStandard == standard) {
cdalton33ad7012016-02-22 07:55:44 -0800718 glslCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
719 } else {
720 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
721 glslCaps->fSampleVariablesSupport = true;
722 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
723 glslCaps->fSampleVariablesSupport = true;
724 glslCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
725 }
726 }
727
csmartdaltonf848c9c2016-06-15 12:42:13 -0700728 if (glslCaps->fSampleVariablesSupport &&
729 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
730 // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
cdalton33ad7012016-02-22 07:55:44 -0800731 glslCaps->fSampleMaskOverrideCoverageSupport =
csmartdaltonf848c9c2016-06-15 12:42:13 -0700732 kNVIDIA_GrGLDriver != ctxInfo.driver() ||
733 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
cdalton33ad7012016-02-22 07:55:44 -0800734 }
735
egdaniel472d44e2015-10-22 08:20:00 -0700736 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
737 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
738
739 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
740 // function that may require a gradient calculation inside a conditional block may return
741 // undefined results". This appears to be an issue with the 'any' call since even the simple
742 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
743 // from our GrTextureDomain processor.
744 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
745
egdaniel472d44e2015-10-22 08:20:00 -0700746 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
747 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800748
749 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
750 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
751 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800752
753 // Frag Coords Convention support is not part of ES
754 // Known issue on at least some Intel platforms:
755 // http://code.google.com/p/skia/issues/detail?id=946
756 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
757 kGLES_GrGLStandard != standard &&
758 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
759 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
760 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
761 }
762
763 if (kGLES_GrGLStandard == standard) {
764 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
765 }
766
cdalton9c3f1432016-03-11 10:07:37 -0800767 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
768 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
769 glslCaps->fExternalTextureSupport = true;
770 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
771 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
772 // At least one driver has been found that has this extension without the "GL_" prefix.
773 glslCaps->fExternalTextureSupport = true;
774 }
775 }
776
777 if (glslCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800778 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
779 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
780 } else {
781 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
782 }
783 }
784
cdaltonc04ce672016-03-11 14:07:38 -0800785 if (kGL_GrGLStandard == standard) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700786 glslCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800787 } else {
cdaltonf8a6ce82016-04-11 13:02:05 -0700788 glslCaps->fTexelFetchSupport =
789 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
790 }
791
792 if (glslCaps->fTexelFetchSupport) {
793 if (kGL_GrGLStandard == standard) {
csmartdalton1897cfd2016-06-03 08:50:54 -0700794 glslCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700795 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
796 } else {
797 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
798 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
799 glslCaps->fTexelBufferSupport = true;
800 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
801 glslCaps->fTexelBufferSupport = true;
802 glslCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
803 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
804 glslCaps->fTexelBufferSupport = true;
805 glslCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
806 }
cdaltonc04ce672016-03-11 14:07:38 -0800807 }
808 }
809
egdaniel8dcdedc2015-11-11 06:27:20 -0800810 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
811 // the abs first in a separate expression.
812 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
813 glslCaps->fCanUseMinAndAbsTogether = false;
814 }
815
bsalomon7ea33f52015-11-22 14:51:00 -0800816 // 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 -0800817 // thus must us -1.0 * %s.x to work correctly
818 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
819 glslCaps->fMustForceNegatedAtanParamToFloat = true;
820 }
egdaniel138c2632016-08-17 10:59:00 -0700821
822 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
823 // the original dst color when reading the outColor even after being written to. By using a
824 // local outColor we can work around this bug.
825 if (glslCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
826 glslCaps->fRequiresLocalOutputColorForFBFetch = true;
827 }
egdaniel472d44e2015-10-22 08:20:00 -0700828}
829
kkinnunencfe62e32015-07-01 02:58:50 -0700830bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700831 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
832
833 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700834 return false;
835 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700836
kkinnunencfe62e32015-07-01 02:58:50 -0700837 if (kGL_GrGLStandard == ctxInfo.standard()) {
838 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
839 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
840 return false;
841 }
842 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700843 if (!hasChromiumPathRendering &&
844 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700845 return false;
846 }
847 }
848 // We only support v1.3+ of GL_NV_path_rendering which allows us to
849 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
850 // additions are detected by checking the existence of the function.
851 // We also use *Then* functions that not all drivers might have. Check
852 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800853 if (!gli->fFunctions.fStencilThenCoverFillPath ||
854 !gli->fFunctions.fStencilThenCoverStrokePath ||
855 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
856 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
857 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700858 return false;
859 }
860 return true;
861}
bsalomon1aa20292016-01-22 08:16:09 -0800862
Brian Salomon71d9d842016-11-03 13:42:00 -0400863bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800864 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800865 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800866 std::function<bool ()> bindRenderTarget,
867 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400868 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800869 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400870 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800871 return false;
872 }
bsalomon7928ef62016-01-05 10:26:39 -0800873
Brian Salomonbf7b6202016-11-11 16:08:03 -0500874 if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
875 return false;
876 }
877
bsalomon76148af2016-01-12 11:13:47 -0800878 GrGLenum readFormat;
879 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400880 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800881 return false;
882 }
883
bsalomon1aa20292016-01-22 08:16:09 -0800884 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800885 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
886 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
887 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
888 // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500889 // The manual does not seem to fully match the spec as the spec allows integer formats
890 // when the bound color buffer is an integer buffer. It doesn't specify which integer
891 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
bsalomone9573312016-01-25 14:33:25 -0800892 if (readFormat != GR_GL_RED && readFormat != GR_GL_RGB && readFormat != GR_GL_RGBA &&
Brian Salomonbf7b6202016-11-11 16:08:03 -0500893 readFormat != GR_GL_BGRA && readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800894 return false;
895 }
896 // There is also a set of allowed types, but all the types we use are in the set:
897 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
898 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
899 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
900 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
901 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
902 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
903 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800904 return true;
piotaixre4b23142014-10-02 10:57:53 -0700905 }
bsalomon7928ef62016-01-05 10:26:39 -0800906
bsalomon76148af2016-01-12 11:13:47 -0800907 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500908 switch (fConfigTable[surfaceConfig].fFormatType) {
909 case kNormalizedFixedPoint_FormatType:
910 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
911 return true;
912 }
913 break;
914 case kInteger_FormatType:
915 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
916 return true;
917 }
918 break;
919 case kFloat_FormatType:
920 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
921 return true;
922 }
923 break;
bsalomon7928ef62016-01-05 10:26:39 -0800924 }
925
Brian Salomon71d9d842016-11-03 13:42:00 -0400926 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800927 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400928 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800929 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800930 if (!bindRenderTarget()) {
931 return false;
932 }
933 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
934 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800935 rpFormat->fFormat = format;
936 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800937 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800938 }
939
Brian Salomon71d9d842016-11-03 13:42:00 -0400940 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
941 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700942}
943
robertphillips@google.com6177e692013-02-28 20:16:25 +0000944void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000945 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000946 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
947 // ES3 driver bugs on at least one device with a tiled GPU (N10).
948 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
949 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
950 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
951 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800952 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700953 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400954 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
Brian Salomonc5eceb02016-10-18 10:21:43 -0400955 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
956 ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400957 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000958 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
959 fMSFBOType = kES_Apple_MSFBOType;
960 }
bsalomon083617b2016-02-12 12:10:14 -0800961
962 // Above determined the preferred MSAA approach, now decide whether glBlitFramebuffer
963 // is available.
964 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
Brian Salomone5e7eb12016-10-14 16:18:33 -0400965 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
966 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
Brian Salomonc5eceb02016-10-18 10:21:43 -0400967 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
968 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
bsalomon083617b2016-02-12 12:10:14 -0800969 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
970 // limitations.
Brian Salomone5e7eb12016-10-14 16:18:33 -0400971 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
972 kResolveMustBeFull_BlitFrambufferFlag |
973 kNoMSAADst_BlitFramebufferFlag |
974 kNoFormatConversion_BlitFramebufferFlag;
bsalomon083617b2016-02-12 12:10:14 -0800975 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000976 } else {
egdanieleed519e2016-01-15 11:36:18 -0800977 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700978 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -0400979 fBlitFramebufferFlags = 0;
Brian Salomon00731b42016-10-14 11:30:51 -0400980 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
981 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
982 fMSFBOType = kStandard_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -0400983 fBlitFramebufferFlags = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000984 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
985 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400986 fMSFBOType = kEXT_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -0400987 fBlitFramebufferFlags = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000988 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000989 }
990}
991
cdalton1dd05422015-06-12 09:01:18 -0700992void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
993 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
994
995 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
996 // for now until its own blacklists can be updated.
997 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
Greg Daniel0ea7d432016-10-27 16:55:52 -0400998 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
cdalton1dd05422015-06-12 09:01:18 -0700999 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -07001000 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -07001001 return;
1002 }
1003
1004 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1005 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1006 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
1007 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
1008 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
1009 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
1010 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1011 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1012 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1013 return;
1014 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1015 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1016 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
1017 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
1018 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
1019 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
1020 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1021 // slow on a particular platform.
1022 } else {
1023 return; // No advanced blend support.
1024 }
1025
1026 SkASSERT(this->advancedBlendEquationSupport());
1027
csmartdalton3b88a032016-08-04 14:43:49 -07001028 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1029 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1030 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
cdalton1dd05422015-06-12 09:01:18 -07001031 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1032 (1 << kColorBurn_GrBlendEquation);
1033 }
joel.liang9764c402015-07-09 19:46:18 -07001034 if (kARM_GrGLVendor == ctxInfo.vendor()) {
1035 // Blacklist color-burn on ARM until the fix is released.
1036 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1037 }
cdalton1dd05422015-06-12 09:01:18 -07001038}
1039
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001040namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001041const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001042}
1043
1044void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
1045
1046 // Build up list of legal stencil formats (though perhaps not supported on
1047 // the particular gpu/driver) from most preferred to least.
1048
1049 // these consts are in order of most preferred to least preferred
1050 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1051
1052 static const StencilFormat
1053 // internal Format stencil bits total bits packed?
1054 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1055 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1056 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1057 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001058 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001059 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1060
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001061 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001062 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001063 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001064 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1065 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1066
1067 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1068 // require FBO support we can expect these are legal formats and don't
1069 // check. These also all support the unsized GL_STENCIL_INDEX.
1070 fStencilFormats.push_back() = gS8;
1071 fStencilFormats.push_back() = gS16;
1072 if (supportsPackedDS) {
1073 fStencilFormats.push_back() = gD24S8;
1074 }
1075 fStencilFormats.push_back() = gS4;
1076 if (supportsPackedDS) {
1077 fStencilFormats.push_back() = gDS;
1078 }
1079 } else {
1080 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1081 // for other formats.
1082 // ES doesn't support using the unsized format.
1083
1084 fStencilFormats.push_back() = gS8;
1085 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001086 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1087 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001088 fStencilFormats.push_back() = gD24S8;
1089 }
1090 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1091 fStencilFormats.push_back() = gS4;
1092 }
1093 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001094}
1095
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001096SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001097
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001098 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +00001099
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001100 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001101 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001102 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001103 i,
1104 fStencilFormats[i].fStencilBits,
1105 fStencilFormats[i].fTotalBits);
1106 }
1107
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001108 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001109 "None",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001110 "EXT",
Brian Salomon00731b42016-10-14 11:30:51 -04001111 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001112 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001113 "IMG MS To Texture",
1114 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001115 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001116 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001117 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Brian Salomon00731b42016-10-14 11:30:51 -04001118 GR_STATIC_ASSERT(1 == kEXT_MSFBOType);
1119 GR_STATIC_ASSERT(2 == kStandard_MSFBOType);
1120 GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
1121 GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
1122 GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
1123 GR_STATIC_ASSERT(6 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001124 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001125
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001126 static const char* kInvalidateFBTypeStr[] = {
1127 "None",
1128 "Discard",
1129 "Invalidate",
1130 };
1131 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1132 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1133 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1134 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001135
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001136 static const char* kMapBufferTypeStr[] = {
1137 "None",
1138 "MapBuffer",
1139 "MapBufferRange",
1140 "Chromium",
1141 };
1142 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1143 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1144 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1145 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1146 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1147
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001148 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001149 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001150 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001151 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001152 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001153 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
1154 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
1155 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
1156 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +00001157
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001158 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001159 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
1160 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001161 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -07001162 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
1163 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
csmartdalton4c18b622016-07-29 12:19:28 -07001164 r.appendf("Draw instanced support: %s\n", (fDrawInstancedSupport ? "YES" : "NO"));
cdalton06604b92016-02-05 10:09:51 -08001165 r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
1166 r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
1167 r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -07001168 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
1169 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -07001170 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -08001171 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -08001172 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
halcanary9d524f22016-03-29 09:03:52 -07001173 r.appendf("BGRA to RGBA readback conversions are slow: %s\n",
ericrkb4ecabd2016-03-11 15:18:20 -08001174 (fRGBAToBGRAReadbackConversionsAreSlow ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -08001175
1176 r.append("Configs\n-------\n");
1177 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1178 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -08001179 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
1180 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -08001181 i,
1182 fConfigTable[i].fFlags,
1183 fConfigTable[i].fFormats.fBaseInternalFormat,
1184 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -08001185 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
1186 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -08001187 fConfigTable[i].fFormats.fExternalType,
1188 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -08001189 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -08001190 }
1191
jvanverthe9c0fc62015-04-29 11:18:05 -07001192 return r;
1193}
1194
jvanverthe9c0fc62015-04-29 11:18:05 -07001195static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1196 switch (p) {
1197 case kLow_GrSLPrecision:
1198 return GR_GL_LOW_FLOAT;
1199 case kMedium_GrSLPrecision:
1200 return GR_GL_MEDIUM_FLOAT;
1201 case kHigh_GrSLPrecision:
1202 return GR_GL_HIGH_FLOAT;
1203 }
1204 SkFAIL("Unknown precision.");
1205 return -1;
1206}
1207
1208static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1209 switch (type) {
1210 case kVertex_GrShaderType:
1211 return GR_GL_VERTEX_SHADER;
1212 case kGeometry_GrShaderType:
1213 return GR_GL_GEOMETRY_SHADER;
1214 case kFragment_GrShaderType:
1215 return GR_GL_FRAGMENT_SHADER;
1216 }
1217 SkFAIL("Unknown shader type.");
1218 return -1;
1219}
1220
jvanverthcba99b82015-06-24 06:59:57 -07001221void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
halcanary9d524f22016-03-29 09:03:52 -07001222 const GrGLInterface* intf,
jvanverthcba99b82015-06-24 06:59:57 -07001223 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001224 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1225 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1226 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1227 if (kGeometry_GrShaderType != s) {
1228 GrShaderType shaderType = static_cast<GrShaderType>(s);
1229 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001230 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -07001231 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001232 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1233 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1234 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1235 GrGLint range[2];
1236 GrGLint bits;
1237 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1238 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -07001239 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1240 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1241 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001242 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -07001243 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001244 }
jvanverthcba99b82015-06-24 06:59:57 -07001245 else if (!glslCaps->fShaderPrecisionVaries) {
halcanary9d524f22016-03-29 09:03:52 -07001246 glslCaps->fShaderPrecisionVaries =
jvanverthcba99b82015-06-24 06:59:57 -07001247 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001248 }
1249 }
1250 }
1251 }
1252 }
1253 }
1254 else {
1255 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -07001256 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001257 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1258 if (kGeometry_GrShaderType != s) {
1259 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001260 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1261 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1262 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001263 }
1264 }
1265 }
1266 }
1267 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1268 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1269 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1270 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -07001271 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001272 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
halcanary9d524f22016-03-29 09:03:52 -07001273 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
jvanverthcba99b82015-06-24 06:59:57 -07001274 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001275 }
1276 }
cdaltona6b92ad2016-04-11 12:03:08 -07001277 glslCaps->initSamplerPrecisionTable();
jvanverthe9c0fc62015-04-29 11:18:05 -07001278}
1279
bsalomon41e4384e2016-01-08 09:12:44 -08001280bool GrGLCaps::bgraIsInternalFormat() const {
1281 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1282}
1283
bsalomon76148af2016-01-12 11:13:47 -08001284bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1285 GrGLenum* internalFormat, GrGLenum* externalFormat,
1286 GrGLenum* externalType) const {
1287 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1288 externalFormat, externalType)) {
1289 return false;
1290 }
1291 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1292 return true;
1293}
1294
1295bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1296 GrGLenum* internalFormat) const {
1297 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1298 return false;
1299 }
1300 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1301 return true;
1302}
1303
1304bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1305 GrGLenum* externalFormat, GrGLenum* externalType) const {
1306 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1307 externalFormat, externalType)) {
1308 return false;
1309 }
1310 return true;
1311}
1312
1313bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1314 if (GrPixelConfigIsCompressed(config)) {
1315 return false;
1316 }
1317 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1318 return true;
1319}
1320
1321bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1322 ExternalFormatUsage usage, GrGLenum* externalFormat,
1323 GrGLenum* externalType) const {
1324 SkASSERT(externalFormat && externalType);
sylvestre.ledruf0cbfb32016-09-01 08:17:02 -07001325 if (GrPixelConfigIsCompressed(memoryConfig)) {
bsalomon76148af2016-01-12 11:13:47 -08001326 return false;
1327 }
1328
1329 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1330 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1331
1332 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1333 // made to work in many cases using glPixelStore and what not but is not needed currently.
1334 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1335 return false;
1336 }
1337
1338 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1339 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1340
bsalomone9573312016-01-25 14:33:25 -08001341 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1342 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1343 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1344 // texture, not the red component.
1345 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1346 if (this->textureRedSupport()) {
1347 SkASSERT(GR_GL_RED == *externalFormat);
1348 *externalFormat = GR_GL_ALPHA;
1349 }
1350 }
1351
bsalomon76148af2016-01-12 11:13:47 -08001352 return true;
1353}
1354
bsalomoncdee0092016-01-08 13:20:12 -08001355void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1356 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001357 /*
1358 Comments on renderability of configs on various GL versions.
1359 OpenGL < 3.0:
1360 no built in support for render targets.
1361 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1362 format RGB, RGBA and NV float formats we don't use.
1363 This is the following:
1364 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1365 RGB10_A2, RGBA12,RGBA16
1366 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1367 since they aren't required by later standards and the driver can simply return
1368 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1369 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1370 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1371 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1372 This adds a lot of additional renderable sized formats, including ALPHA8.
1373 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1374 16F, 32I, 32UI, and 32F variants).
1375 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1376
1377 For both the above extensions we limit ourselves to those that are also required by
1378 OpenGL 3.0.
1379
1380 OpenGL 3.0:
1381 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1382 but are not required to be supported as renderable textures/renderbuffer.
1383 Required renderable color formats:
1384 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1385 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1386 RGB10_A2.
1387 - R11F_G11F_B10F.
1388 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1389 and RG8UI.
1390 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1391 - ALPHA8
1392
1393 OpenGL 3.1, 3.2, 3.3
1394 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1395 OpengGL 3.3, 4.0, 4.1
1396 Adds RGB10_A2UI.
1397 OpengGL 4.2
1398 Adds
1399 - RGB5_A1, RGBA4
1400 - RGB565
1401 OpenGL 4.4
1402 Does away with the separate list and adds a column to the sized internal color format
1403 table. However, no new formats become required color renderable.
1404
1405 ES 2.0
1406 color renderable: RGBA4, RGB5_A1, RGB565
1407 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1408 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1409 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1410 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1411 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1412 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1413
1414 ES 3.0
1415 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1416 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1417 RGB5_A1.
1418 - RGB8 and RGB565.
1419 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1420 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1421 ES 3.1
1422 Adds RGB10_A2, RGB10_A2UI,
1423 ES 3.2
1424 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1425 */
Brian Salomon71d9d842016-11-03 13:42:00 -04001426 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1427 ConfigInfo::kFBOColorAttachment_Flag;
1428 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001429 if (kNone_MSFBOType != fMSFBOType) {
1430 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1431 }
bsalomon41e4384e2016-01-08 09:12:44 -08001432 GrGLStandard standard = ctxInfo.standard();
1433 GrGLVersion version = ctxInfo.version();
1434
cblume790d5132016-02-29 11:13:29 -08001435 bool texStorageSupported = false;
1436 if (kGL_GrGLStandard == standard) {
1437 // The EXT version can apply to either GL or GLES.
1438 texStorageSupported = version >= GR_GL_VER(4,2) ||
1439 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1440 ctxInfo.hasExtension("GL_EXT_texture_storage");
1441 } else {
1442 // Qualcomm Adreno drivers appear to have issues with texture storage.
1443 texStorageSupported = (version >= GR_GL_VER(3,0) &&
1444 kQualcomm_GrGLVendor != ctxInfo.vendor()) &&
1445 ctxInfo.hasExtension("GL_EXT_texture_storage");
1446 }
1447
1448 // TODO: remove after command buffer supports full ES 3.0
1449 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1450 kChromium_GrGLDriver == ctxInfo.driver()) {
1451 texStorageSupported = false;
1452 }
1453
cdalton74b8d322016-04-11 14:47:28 -07001454 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1455
bsalomon30447372015-12-21 09:03:05 -08001456 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1457 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001458 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001459 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001460 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001461 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001462
1463 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1464 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001465 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1466 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001467 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001468 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001469 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1470 if (kGL_GrGLStandard == standard) {
1471 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1472 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001473 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001474 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1475 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1476 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1477 }
egdaniel4999df82016-01-07 17:06:04 -08001478 }
cblume790d5132016-02-29 11:13:29 -08001479 if (texStorageSupported) {
1480 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1481 }
cdalton74b8d322016-04-11 14:47:28 -07001482 if (texelBufferSupport) {
1483 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1484 }
bsalomoncdee0092016-01-08 13:20:12 -08001485 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001486
bsalomon76148af2016-01-12 11:13:47 -08001487 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1488 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001489 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001490 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001491 if (kGL_GrGLStandard == standard) {
1492 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1493 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1494 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1495 // Since the internal format is RGBA8, it is also renderable.
1496 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1497 allRenderFlags;
1498 }
1499 } else {
1500 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1501 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1502 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1503 // The APPLE extension doesn't make this renderable.
1504 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1505 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1506 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1507 // Though, that seems to not be the case if the texture storage extension is
1508 // present. The specs don't exactly make that clear.
1509 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1510 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1511 }
1512 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1513 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001514 nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001515 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001516 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001517 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1518 ConfigInfo::kRenderableWithMSAA_Flag;
1519 }
1520 }
1521 }
cblume790d5132016-02-29 11:13:29 -08001522 if (texStorageSupported) {
1523 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1524 }
bsalomoncdee0092016-01-08 13:20:12 -08001525 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001526
brianosmana6359362016-03-21 06:55:37 -07001527 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001528 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001529 if (kGL_GrGLStandard == standard) {
1530 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001531 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001532 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1533 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1534 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001535 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001536 }
1537 }
1538 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001539 if (fSRGBSupport) {
1540 fSRGBWriteControl = true;
1541 }
bsalomon41e4384e2016-01-08 09:12:44 -08001542 } else {
1543 // See https://bug.skia.org/4148 for PowerVR issue.
brianosmana6359362016-03-21 06:55:37 -07001544 fSRGBSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
bsalomon41e4384e2016-01-08 09:12:44 -08001545 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1546 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1547 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001548 // See https://bug.skia.org/5329 for Adreno4xx issue.
1549 fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1550 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001551 }
brianosmana6359362016-03-21 06:55:37 -07001552 if (!ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode")) {
1553 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode:
1554 fSRGBSupport = false;
1555 }
bsalomon30447372015-12-21 09:03:05 -08001556 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1557 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1558 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1559 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001560 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1561 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001562 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001563 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001564 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001565 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1566 allRenderFlags;
1567 }
cblume790d5132016-02-29 11:13:29 -08001568 if (texStorageSupported) {
1569 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1570 }
bsalomoncdee0092016-01-08 13:20:12 -08001571 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001572
brianosmana6359362016-03-21 06:55:37 -07001573 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1574 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1575 // is in this format, for example).
1576 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1577 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1578 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1579 // external format is GL_BGRA.
1580 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1581 GR_GL_BGRA;
1582 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1583 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1584 if (fSRGBSupport) {
1585 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1586 allRenderFlags;
1587 }
1588 if (texStorageSupported) {
1589 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1590 }
1591 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1592
Brian Salomonbf7b6202016-11-11 16:08:03 -05001593 bool hasIntegerTextures;
1594 if (standard == kGL_GrGLStandard) {
1595 hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1596 ctxInfo.hasExtension("GL_EXT_texture_integer");
1597 } else {
1598 hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1599 }
1600 // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1601 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1602 hasIntegerTextures = false;
1603 }
1604 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1605 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1606 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1607 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1608 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1609 // We currently only support using integer textures as srcs, not for rendering (even though GL
1610 // allows it).
1611 if (hasIntegerTextures) {
1612 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1613 ConfigInfo::kFBOColorAttachment_Flag;
1614 if (texStorageSupported) {
1615 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1616 ConfigInfo::kCanUseTexStorage_Flag;
1617 }
1618 }
1619
bsalomon30447372015-12-21 09:03:05 -08001620 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1621 if (this->ES2CompatibilitySupport()) {
1622 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1623 } else {
1624 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1625 }
bsalomon76148af2016-01-12 11:13:47 -08001626 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1627 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001628 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001629 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001630 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1631 if (kGL_GrGLStandard == standard) {
1632 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1633 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1634 }
1635 } else {
1636 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1637 }
cblume790d5132016-02-29 11:13:29 -08001638 // 565 is not a sized internal format on desktop GL. So on desktop with
1639 // 565 we always use an unsized internal format to let the system pick
1640 // the best sized format to convert the 565 data to. Since TexStorage
1641 // only allows sized internal formats we disallow it.
1642 //
1643 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1644 // update.
1645 if (texStorageSupported && kGL_GrGLStandard != standard) {
1646 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1647 }
bsalomoncdee0092016-01-08 13:20:12 -08001648 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001649
1650 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1651 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001652 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1653 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001654 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001655 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001656 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1657 if (kGL_GrGLStandard == standard) {
1658 if (version >= GR_GL_VER(4, 2)) {
1659 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1660 }
1661 } else {
1662 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1663 }
cblume790d5132016-02-29 11:13:29 -08001664 if (texStorageSupported) {
1665 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1666 }
bsalomoncdee0092016-01-08 13:20:12 -08001667 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001668
1669 if (this->textureRedSupport()) {
1670 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1671 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001672 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1673 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001674 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001675 if (texelBufferSupport) {
1676 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1677 }
bsalomon30447372015-12-21 09:03:05 -08001678 } else {
1679 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1680 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001681 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1682 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001683 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001684 }
1685 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001686 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001687 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon40170072016-05-05 14:40:03 -07001688 if (this->textureRedSupport() ||
Brian Salomon00731b42016-10-14 11:30:51 -04001689 (kStandard_MSFBOType == this->msFBOType() && ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1690 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
bsalomon40170072016-05-05 14:40:03 -07001691 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
bsalomon41e4384e2016-01-08 09:12:44 -08001692 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1693 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1694 }
cblume790d5132016-02-29 11:13:29 -08001695 if (texStorageSupported) {
1696 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1697 }
bsalomon41e4384e2016-01-08 09:12:44 -08001698
1699 // Check for [half] floating point texture support
1700 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1701 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1702 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1703 bool hasFPTextures = false;
1704 bool hasHalfFPTextures = false;
1705 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001706 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001707
1708 if (kGL_GrGLStandard == standard) {
1709 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1710 hasFPTextures = true;
1711 hasHalfFPTextures = true;
1712 }
1713 } else {
1714 if (version >= GR_GL_VER(3, 1)) {
1715 hasFPTextures = true;
1716 hasHalfFPTextures = true;
1717 } else {
1718 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1719 ctxInfo.hasExtension("GL_OES_texture_float")) {
1720 hasFPTextures = true;
1721 }
1722 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1723 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1724 hasHalfFPTextures = true;
1725 }
1726 }
1727 }
bsalomon30447372015-12-21 09:03:05 -08001728
1729 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1730 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001731 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1732 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001733 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001734 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001735 if (hasFPTextures) {
1736 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1737 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1738 // many precision issues and no clients actually want this yet.
1739 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1740 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1741 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1742 }
1743 }
cblume790d5132016-02-29 11:13:29 -08001744 if (texStorageSupported) {
1745 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1746 }
cdalton74b8d322016-04-11 14:47:28 -07001747 if (texelBufferSupport) {
1748 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1749 }
bsalomoncdee0092016-01-08 13:20:12 -08001750 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001751
1752 if (this->textureRedSupport()) {
1753 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1754 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001755 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1756 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001757 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001758 if (texelBufferSupport) {
1759 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |=
1760 ConfigInfo::kCanUseWithTexelBuffer_Flag;
1761 }
bsalomon30447372015-12-21 09:03:05 -08001762 } else {
1763 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1764 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001765 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1766 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001767 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001768 }
brianosmanaa92afb2016-08-29 06:46:07 -07001769 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001770 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1771 } else {
1772 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1773 }
bsalomon7928ef62016-01-05 10:26:39 -08001774 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001775 if (hasHalfFPTextures) {
1776 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1777 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1778 // GL_RED internal format.
1779 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1780 (this->textureRedSupport() &&
1781 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1782 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1783 }
1784 }
cblume790d5132016-02-29 11:13:29 -08001785 if (texStorageSupported) {
1786 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1787 }
bsalomon30447372015-12-21 09:03:05 -08001788
1789 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1790 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001791 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1792 GR_GL_RGBA;
brianosmanaa92afb2016-08-29 06:46:07 -07001793 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001794 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1795 } else {
1796 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1797 }
bsalomon7928ef62016-01-05 10:26:39 -08001798 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001799 if (hasHalfFPTextures) {
1800 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1801 // ES requires 3.2 or EXT_color_buffer_half_float.
1802 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1803 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1804 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1805 }
1806 }
cblume790d5132016-02-29 11:13:29 -08001807 if (texStorageSupported) {
1808 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1809 }
cdalton74b8d322016-04-11 14:47:28 -07001810 if (texelBufferSupport) {
1811 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1812 }
bsalomoncdee0092016-01-08 13:20:12 -08001813 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001814
1815 // Compressed texture support
1816
1817 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1818 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1819
1820 // TODO: Fix command buffer bindings and remove this.
1821 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001822
1823 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001824 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001825
1826 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1827 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001828 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001829 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001830 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001831 // Disable this for now, while we investigate https://bug.skia.org/4333
Brian Salomoneaabe002016-10-11 14:40:33 -07001832 if ((false)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001833 // Check for 8-bit palette..
1834 GrGLint numFormats;
1835 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1836 if (numFormats) {
1837 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1838 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1839 for (int i = 0; i < numFormats; ++i) {
1840 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1841 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1842 break;
1843 }
1844 }
1845 }
1846 }
bsalomoncdee0092016-01-08 13:20:12 -08001847 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001848
bsalomon41e4384e2016-01-08 09:12:44 -08001849 // May change the internal format based on extensions.
1850 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1851 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1852 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1853 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1854 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1855 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1856 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1857 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1858 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1859 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1860 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1861 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1862 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1863 GR_GL_COMPRESSED_RED_RGTC1;
1864 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1865 GR_GL_COMPRESSED_RED_RGTC1;
1866 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1867 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1868 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1869 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1870 GR_GL_COMPRESSED_3DC_X;
1871
bsalomon30447372015-12-21 09:03:05 -08001872 }
bsalomon76148af2016-01-12 11:13:47 -08001873 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001874 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001875 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001876 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001877
1878 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1879 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001880 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001881 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001882 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001883 if (kGL_GrGLStandard == standard) {
1884 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1885 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1886 }
1887 } else {
1888 if (version >= GR_GL_VER(3, 0) ||
1889 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1890 // ETC2 is a superset of ETC1, so we can just check for that, too.
1891 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1892 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1893 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1894 }
1895 }
bsalomoncdee0092016-01-08 13:20:12 -08001896 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001897
1898 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1899 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001900 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001901 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001902 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001903 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1904 // decompressing the textures in the driver, and is generally slower.
1905 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1906 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1907 }
bsalomoncdee0092016-01-08 13:20:12 -08001908 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001909
1910 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1911 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1912 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1913 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001914 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1915 0;
bsalomon30447372015-12-21 09:03:05 -08001916 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001917 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001918 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1919 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1920 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1921 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1922 }
bsalomoncdee0092016-01-08 13:20:12 -08001923 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001924
1925 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1926
1927 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001928 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1929 ctxInfo.version() >= GR_GL_VER(3,0));
1930 // All ES versions (thus far) require sized internal formats for render buffers.
1931 // TODO: Always use sized internal format?
1932 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1933
bsalomon30447372015-12-21 09:03:05 -08001934 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001935 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1936 // param to glTex[Sub]Image.
1937 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1938 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1939 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1940 fConfigTable[i].fFormats.fSizedInternalFormat :
1941 fConfigTable[i].fFormats.fBaseInternalFormat;
1942 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001943 fConfigTable[i].fFormats.fSizedInternalFormat :
1944 fConfigTable[i].fFormats.fBaseInternalFormat;
1945 }
1946 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1947 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1948 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1949 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1950 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001951 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001952 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001953
1954 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1955 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1956 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1957 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001958 }
1959
1960 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1961 // as a base format.
1962 // GL_EXT_texture_format_BGRA8888:
1963 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1964 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1965 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001966 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001967 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1968 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1969 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001970 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001971 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1972 }
1973
bsalomoncdee0092016-01-08 13:20:12 -08001974 // If we don't have texture swizzle support then the shader generator must insert the
1975 // swizzle into shader code.
1976 if (!this->textureSwizzleSupport()) {
1977 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1978 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1979 }
1980 }
1981
bsalomon7f9b2e42016-01-12 13:29:26 -08001982 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1983 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1984 // gets written to the single component.
1985 if (this->textureRedSupport()) {
1986 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1987 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1988 if (GrPixelConfigIsAlphaOnly(config) &&
1989 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1990 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1991 }
1992 }
1993 }
1994
bsalomon30447372015-12-21 09:03:05 -08001995#ifdef SK_DEBUG
1996 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001997 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001998 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04001999 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2000 // renderable.
2001 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2002 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002003 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2004 fConfigTable[i].fFormats.fBaseInternalFormat);
2005 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002006 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002007 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2008 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2009 fConfigTable[i].fFormats.fExternalFormat[j]);
2010 }
2011 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002012 }
2013#endif
2014}
2015
csmartdaltone0d36292016-07-29 08:14:20 -07002016void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
2017 if (options.fEnableInstancedRendering) {
2018 fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
2019#ifndef SK_BUILD_FOR_MAC
2020 // OS X doesn't seem to write correctly to floating point textures when using
2021 // glDraw*Indirect, regardless of the underlying GPU.
2022 fAvoidInstancedDrawsToFPTargets = true;
2023#endif
2024 }
2025}