blob: 63fe074d79cca45c10e2c21d1966eb92e8ef8807 [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
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00008#include "GrGLCaps.h"
egdanielb7e7d572015-11-04 04:23:53 -08009#include "GrContextOptions.h"
robertphillips@google.com6177e692013-02-28 20:16:25 +000010#include "GrGLContext.h"
bsalomon1aa20292016-01-22 08:16:09 -080011#include "GrGLRenderTarget.h"
Brian Salomon467921e2017-03-06 16:17:12 -050012#include "GrGLTexture.h"
Brian Salomon94efbf52016-11-29 13:43:05 -050013#include "GrShaderCaps.h"
Robert Phillipsbf25d432017-04-07 10:08:53 -040014#include "GrSurfaceProxyPriv.h"
Brian Osman71a18892017-08-10 10:23:25 -040015#include "SkJSONWriter.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"
Brian Salomon467921e2017-03-06 16:17:12 -050018#include "instanced/GLInstancedRendering.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000019
bsalomon682c2692015-05-22 14:01:46 -070020GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
21 const GrGLContextInfo& ctxInfo,
22 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080023 fStandard = ctxInfo.standard();
24
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000026 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000027 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000028 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080029 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000030 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000031 fUnpackRowLengthSupport = false;
32 fUnpackFlipYSupport = false;
33 fPackRowLengthSupport = false;
34 fPackFlipYSupport = false;
35 fTextureUsageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000036 fTextureRedSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040037 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000038 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000039 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070040 fDirectStateAccessSupport = false;
41 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080042 fES2CompatibilitySupport = false;
cdalton06604b92016-02-05 10:09:51 -080043 fDrawIndirectSupport = false;
44 fMultiDrawIndirectSupport = false;
45 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000046 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070047 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080048 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080049 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070050 fRGBA8888PixelsOpsAreSlow = false;
51 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080052 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080053 fRGBAToBGRAReadbackConversionsAreSlow = false;
brianosman09563ce2016-06-02 08:59:34 -070054 fDoManualMipmapping = false;
brianosman851c2382016-12-07 10:03:25 -080055 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070056 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040057 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060058 fDrawArraysBaseVertexIsBroken = false;
Mike Klein31550db2017-06-06 23:29:53 +000059 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040060 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
61 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040062 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
piotaixre4b23142014-10-02 10:57:53 -070063
Brian Salomone5e7eb12016-10-14 16:18:33 -040064 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060065 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080066
Brian Salomon94efbf52016-11-29 13:43:05 -050067 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070068
cdalton4cd67132015-06-10 19:23:46 -070069 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000070}
71
cdalton4cd67132015-06-10 19:23:46 -070072void GrGLCaps::init(const GrContextOptions& contextOptions,
73 const GrGLContextInfo& ctxInfo,
74 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000075 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000076 GrGLVersion version = ctxInfo.version();
77
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000078 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000079 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
80 &fMaxFragmentUniformVectors);
81 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000082 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000083 GrGLint max;
84 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
85 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000086 if (version >= GR_GL_VER(3, 2)) {
87 GrGLint profileMask;
88 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
89 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
90 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000091 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000092 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000093
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000094 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000095 fUnpackRowLengthSupport = true;
96 fUnpackFlipYSupport = false;
97 fPackRowLengthSupport = true;
98 fPackFlipYSupport = false;
99 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000100 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
101 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000102 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000103 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
104 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000105 fPackFlipYSupport =
106 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
107 }
108
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000109 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000110 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
111
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000112 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700113 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
114 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
115 ctxInfo.hasExtension("GL_NV_texture_barrier");
116 } else {
117 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
118 }
119
cdaltoneb79eea2016-02-26 10:39:34 -0800120 if (kGL_GrGLStandard == standard) {
121 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
122 ctxInfo.hasExtension("GL_ARB_texture_multisample");
123 } else {
124 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
125 }
126
Brian Salomon0ee6f952017-01-19 15:52:24 -0500127 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
hendrikwa0d5ad72014-12-02 07:30:30 -0800128 // and GL_RG on FBO textures.
Brian Salomon0ee6f952017-01-19 15:52:24 -0500129 if (kOSMesa_GrGLRenderer != ctxInfo.renderer()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800130 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000131 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
132 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800133 } else {
134 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
135 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000136 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000137 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000138 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000139 ctxInfo.hasExtension("GL_ARB_imaging");
140
egdaniel9250d242015-05-18 13:04:26 -0700141 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
142 // Thus we are blacklisting this extension for now on Adreno4xx devices.
143 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
144 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
145 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
146 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000147 fDiscardRenderTargetSupport = true;
148 fInvalidateFBType = kInvalidate_InvalidateFBType;
149 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
150 fDiscardRenderTargetSupport = true;
151 fInvalidateFBType = kDiscard_InvalidateFBType;
152 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000153
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000154 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
155 fFullClearIsFree = true;
156 }
157
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000158 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000159 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800160 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
161 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000162 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000163 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
164 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000165 }
166
cdalton626e1ff2015-06-12 13:56:46 -0700167 if (kGL_GrGLStandard == standard) {
168 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
169 } else {
170 fDirectStateAccessSupport = false;
171 }
172
173 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
174 fDebugSupport = true;
175 } else {
176 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
177 }
178
jvanverth3f801cb2014-12-16 09:49:38 -0800179 if (kGL_GrGLStandard == standard) {
180 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
181 }
182 else {
183 fES2CompatibilitySupport = true;
184 }
185
cdalton0edea2c2015-05-21 08:27:44 -0700186 if (kGL_GrGLStandard == standard) {
187 fMultisampleDisableSupport = true;
188 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700189 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700190 }
191
kkinnunend94708e2015-07-30 22:47:04 -0700192 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600193 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
194 // instanced arrays, but we could make this more granular if we wanted
195 fInstanceAttribSupport =
196 version >= GR_GL_VER(3, 2) ||
197 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
198 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
199 } else {
200 fInstanceAttribSupport =
201 version >= GR_GL_VER(3, 0) ||
202 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
203 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
204 }
205
206 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700207 if (version >= GR_GL_VER(3, 0)) {
208 fBindFragDataLocationSupport = true;
209 }
210 } else {
211 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
212 fBindFragDataLocationSupport = true;
213 }
joshualittc1f56b52015-06-22 12:31:31 -0700214 }
215
joshualitt7bdd70a2015-10-01 06:28:11 -0700216 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
217
kkinnunene06ed252016-02-16 23:15:40 -0800218 if (kGL_GrGLStandard == standard) {
219 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
220 // We also require textureSize() support for rectangle 2D samplers which was added in
221 // GLSL 1.40.
222 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
223 fRectangleTextureSupport = true;
224 }
bsalomone179a912016-01-20 06:18:10 -0800225 }
kkinnunene06ed252016-02-16 23:15:40 -0800226 } else {
227 // Command buffer exposes this in GL ES context for Chromium reasons,
228 // but it should not be used. Also, at the time of writing command buffer
229 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800230 }
231
bsalomoncdee0092016-01-08 13:20:12 -0800232 if (kGL_GrGLStandard == standard) {
233 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
234 fTextureSwizzleSupport = true;
235 }
236 } else {
237 if (version >= GR_GL_VER(3,0)) {
238 fTextureSwizzleSupport = true;
239 }
240 }
241
cblume09bd2c02016-03-01 14:08:28 -0800242 if (kGL_GrGLStandard == standard) {
243 fMipMapLevelAndLodControlSupport = true;
244 } else if (kGLES_GrGLStandard == standard) {
245 if (version >= GR_GL_VER(3,0)) {
246 fMipMapLevelAndLodControlSupport = true;
247 }
248 }
249
bsalomon88c7b982015-07-31 11:20:16 -0700250#ifdef SK_BUILD_FOR_WIN
251 // We're assuming that on Windows Chromium we're using ANGLE.
252 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
253 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700254 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700255 fRGBA8888PixelsOpsAreSlow = isANGLE;
256 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
257 // check DX11 ANGLE.
258 fPartialFBOReadIsSlow = isANGLE;
259#endif
260
ericrkb4ecabd2016-03-11 15:18:20 -0800261 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
262 bool isMAC = false;
263#ifdef SK_BUILD_FOR_MAC
264 isMAC = true;
265#endif
266
267 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
268 // vis-versa.
269 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
270
Brian Salomond17b4a62017-05-23 16:53:47 -0400271 if (kGL_GrGLStandard == standard) {
272 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
273 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
274 // 340.96 and 367.57.
275 if (ctxInfo.driver() != kNVIDIA_GrGLDriver ||
276 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(367, 57)) {
277 fClearTextureSupport = true;
278 }
279 }
280 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
281 // Calling glClearTexImage crashes on the NexusPlayer.
282 if (kPowerVRRogue_GrGLRenderer != ctxInfo.renderer()) {
283 fClearTextureSupport = true;
284 }
285 }
286
cdalton4cd67132015-06-10 19:23:46 -0700287 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700288 * GrShaderCaps fields
289 **************************************************************************/
290
egdaniel0a482332015-10-26 08:59:10 -0700291 // This must be called after fCoreProfile is set on the GrGLCaps
292 this->initGLSL(ctxInfo);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500293 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700294
Brian Osman195c05b2017-08-30 15:14:04 -0400295 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
296#if GR_TEST_UTILS
297 if (contextOptions.fSuppressPathRendering) {
298 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700299 }
Brian Osman195c05b2017-08-30 15:14:04 -0400300#endif
egdaniel05ded892015-10-26 07:38:05 -0700301
302 // For now these two are equivalent but we could have dst read in shader via some other method.
303 // Before setting this, initGLSL() must have been called.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500304 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
egdaniel05ded892015-10-26 07:38:05 -0700305
306 // Enable supported shader-related caps
307 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500308 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700309 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
310 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600311
Brian Salomon1edc5b92016-11-29 13:43:46 -0500312 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600313
egdaniel05ded892015-10-26 07:38:05 -0700314 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500315 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700316 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600317 if (shaderCaps->fGeometryShaderSupport) {
318 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
319#ifndef SK_BUILD_FOR_MAC
320 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
321 shaderCaps->fGSInvocationsSupport = true;
322 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
323 shaderCaps->fGSInvocationsSupport = true;
324 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
325 }
326#endif
327 }
328
Brian Salomon1edc5b92016-11-29 13:43:46 -0500329 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800330 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700331 }
332 else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500333 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700334
Brian Salomon1edc5b92016-11-29 13:43:46 -0500335 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700336 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800337
csmartdalton1d2aed02017-02-15 21:43:20 -0700338 shaderCaps->fGeometryShaderSupport = ctxInfo.hasExtension("GL_EXT_geometry_shader");
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600339 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
csmartdalton1d2aed02017-02-15 21:43:20 -0700340
Brian Salomon1edc5b92016-11-29 13:43:46 -0500341 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800342 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700343 }
344
cdalton9c3f1432016-03-11 10:07:37 -0800345 // Protect ourselves against tracking huge amounts of texture state.
346 static const uint8_t kMaxSaneSamplers = 32;
347 GrGLint maxSamplers;
348 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500349 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
350 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800351 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500352 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800353 }
354 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500355 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800356 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500357 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800358
Brian Salomonf26f7a02016-11-15 14:05:01 -0500359 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500360 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(4, 2);
361 if (!shaderCaps->fImageLoadStoreSupport &&
Brian Salomonf26f7a02016-11-15 14:05:01 -0500362 ctxInfo.hasExtension("GL_ARB_shader_image_load_store")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500363 shaderCaps->fImageLoadStoreSupport = true;
364 shaderCaps->fImageLoadStoreExtensionString = "GL_ARB_shader_image_load_store";
Brian Salomonf26f7a02016-11-15 14:05:01 -0500365 }
366 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500367 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500368 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500369 if (shaderCaps->fImageLoadStoreSupport) {
Brian Salomonf26f7a02016-11-15 14:05:01 -0500370 // Protect ourselves against tracking huge amounts of image state.
371 static constexpr int kMaxSaneImages = 4;
372 GrGLint maxUnits;
373 GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
Brian Salomonf9f45122016-11-29 11:59:17 -0500374 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500375 &shaderCaps->fMaxVertexImageStorages);
376 if (shaderCaps->fGeometryShaderSupport) {
Brian Salomonf9f45122016-11-29 11:59:17 -0500377 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500378 &shaderCaps->fMaxGeometryImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500379 }
380 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500381 &shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500382 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500383 &shaderCaps->fMaxCombinedImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500384 // We use one unit for every image uniform
Brian Salomon1edc5b92016-11-29 13:43:46 -0500385 shaderCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(shaderCaps->fMaxCombinedImageStorages,
386 maxUnits), kMaxSaneImages);
387 shaderCaps->fMaxVertexImageStorages = SkTMin(maxUnits,
388 shaderCaps->fMaxVertexImageStorages);
389 shaderCaps->fMaxGeometryImageStorages = SkTMin(maxUnits,
390 shaderCaps->fMaxGeometryImageStorages);
391 shaderCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
392 shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500393 }
394
csmartdalton485a1202016-07-13 10:16:32 -0700395 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
396 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
397 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
398 // limit this decision to specific GPU families rather than basing it on the vendor alone.
399 if (!GR_GL_MUST_USE_VBO &&
400 !fIsCoreProfile &&
401 (kARM_GrGLVendor == ctxInfo.vendor() ||
402 kImagination_GrGLVendor == ctxInfo.vendor() ||
403 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
404 fPreferClientSideDynamicBuffers = true;
405 }
406
Chris Daltone4679fa2017-09-29 13:58:26 -0600407 if (kARM_GrGLVendor == ctxInfo.vendor()) {
Chris Dalton06cd6662017-10-07 14:37:57 -0600408 // Mali GPUs have rendering issues with CCPR. Blacklisting until we look into workarounds.
Chris Daltone4679fa2017-09-29 13:58:26 -0600409 fBlacklistCoverageCounting = true;
410 }
411
Chris Dalton06cd6662017-10-07 14:37:57 -0600412 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Chris Dalton4cad3102017-10-08 11:40:03 -0600413#ifndef SK_BUILD_FOR_MAC
Chris Dalton06cd6662017-10-07 14:37:57 -0600414 if (kIntel_GrGLDriver == ctxInfo.driver()) {
Chris Dalton4cad3102017-10-08 11:40:03 -0600415 // Every Windows Intel bot either crashes with CCPR or does not draw properly. Hopefully
416 // this issue resolves itself when we move away from geometry shaders.
417 fBlacklistCoverageCounting = true;
418 }
419#endif
420 if (kMesa_GrGLDriver == ctxInfo.driver()) {
Chris Dalton06cd6662017-10-07 14:37:57 -0600421 // Blocking old Intel/Mesa setups while we investigate
422 // https://bugs.chromium.org/p/skia/issues/detail?id=7134.
423 fBlacklistCoverageCounting = version < GR_GL_VER(4,0);
424 }
Chris Dalton4a6a7322017-10-06 14:28:11 -0600425 }
426
Eric Karl5c779752017-05-08 12:02:07 -0700427 if (!contextOptions.fAvoidStencilBuffers) {
428 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
429 this->initFSAASupport(contextOptions, ctxInfo, gli);
430 this->initStencilSupport(ctxInfo);
431 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400432
433 // Setup blit framebuffer
434 if (kGL_GrGLStandard != ctxInfo.standard()) {
435 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
436 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
437 kNoMSAADst_BlitFramebufferFlag |
438 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
439 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
440 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
441 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
442 // limitations.
443 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
444 kResolveMustBeFull_BlitFrambufferFlag |
445 kNoMSAADst_BlitFramebufferFlag |
446 kNoFormatConversion_BlitFramebufferFlag |
447 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
448 }
449 } else {
450 if (fUsesMixedSamples ||
451 ctxInfo.version() >= GR_GL_VER(3,0) ||
452 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
453 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
454 fBlitFramebufferFlags = 0;
455 }
456 }
457
cdalton1dd05422015-06-12 09:01:18 -0700458 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000459
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000460 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000461 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
462 // extension includes glMapBuffer.
463 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
464 fMapBufferFlags |= kSubset_MapFlag;
465 fMapBufferType = kMapBufferRange_MapBufferType;
466 } else {
467 fMapBufferType = kMapBuffer_MapBufferType;
468 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000469 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000470 // Unextended GLES2 doesn't have any buffer mapping.
471 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800472 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800473 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
474 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800475 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
476 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
477 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000478 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
479 fMapBufferFlags = kCanMap_MapFlag;
480 fMapBufferType = kMapBuffer_MapBufferType;
481 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000482 }
483
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400484#if defined(__has_feature)
485#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
486 // See skbug.com/7058
487 fMapBufferType = kNone_MapBufferType;
488 fMapBufferFlags = kNone_MapFlags;
489#endif
490#endif
491
Brian Salomone03a7292017-06-08 11:00:50 -0400492 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
493 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
494 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
495 // unclear whether this really affects a wide range of devices.
496 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer && ctxInfo.driver() == kQualcomm_GrGLDriver &&
497 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0)) {
498 fMapBufferType = kNone_MapBufferType;
499 fMapBufferFlags = kNone_MapFlags;
500 }
501
jvanverthd7a2c1f2015-12-07 07:36:44 -0800502 if (kGL_GrGLStandard == standard) {
503 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
504 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700505 }
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400506 } else if (kANGLE_GrGLDriver != ctxInfo.driver()) { // TODO: re-enable for ANGLE
507 if (version >= GR_GL_VER(3, 0) ||
508 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
509 // GL_EXT_unpack_subimage needed to support subtexture rectangles
510 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800511 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400512// TODO: get transfer buffers working in Chrome
513// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
514// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800515 }
516 }
517
joshualitte5b74c62015-06-01 14:17:47 -0700518 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
519 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700520 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700521#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500522 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
523 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
524 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700525 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700526#else
cdalton397536c2016-03-25 12:15:03 -0700527 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700528#endif
joshualitte5b74c62015-06-01 14:17:47 -0700529 }
530
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000531 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000532 fNPOTTextureTileSupport = true;
533 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000534 } else {
535 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000536 // ES3 has no limitations.
537 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
538 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000539 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
540 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
541 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
542 // to alllow arbitrary wrap modes, however.
543 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000544 }
545
bsalomone72bd022015-10-26 07:33:03 -0700546 // Using MIPs on this GPU seems to be a source of trouble.
547 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
548 fMipMapSupport = false;
549 }
550
bsalomon@google.combcce8922013-03-25 15:38:39 +0000551 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
552 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
553 // Our render targets are always created with textures as the color
554 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000555 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000556
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000557 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
558
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000559 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700560 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000561
robertphillips1b8e1b52015-06-24 06:54:10 -0700562#if 0
563 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
564 kQualcomm_GrGLVendor != ctxInfo.vendor();
565#endif
566
csmartdalton9bc11872016-08-09 12:42:47 -0700567 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
568 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700569 }
570
bsalomon63b21962014-11-05 07:05:34 -0800571 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800572 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
Brian Salomon1b52df32017-03-24 18:49:09 -0400573 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
574 ctxInfo.driver() != kChromium_GrGLDriver)) {
bsalomon63b21962014-11-05 07:05:34 -0800575 fUseDrawInsteadOfClear = true;
576 }
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400577
578#ifdef SK_BUILD_FOR_MAC
579 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
580 // full screen clears
581 if (kIntelIrisPro_GrGLRenderer == ctxInfo.renderer()) {
582 fUseDrawInsteadOfClear = true;
583 }
584#endif
585
Brian Salomon266ef6d2017-09-22 11:27:42 -0400586 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
587 // bugs seems to involve clearing too much and not skipping the clear.
Ben Wagner63fd7602017-10-09 15:45:33 -0400588 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
Robert Phillips3a930532017-10-04 18:03:24 -0400589 // but only for D3D11 ANGLE.
590 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
Brian Salomon266ef6d2017-09-22 11:27:42 -0400591 fUseDrawInsteadOfClear = true;
592 }
bsalomon63b21962014-11-05 07:05:34 -0800593
joshualitt83bc2292015-06-18 14:18:02 -0700594 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomonb52fa022017-06-07 09:42:52 -0400595 // This is known to be fixed sometime between driver 145.0 and 219.0
596 if (ctxInfo.driver() == kQualcomm_GrGLDriver &&
597 ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0)) {
598 fUseDrawToClearStencilClip = true;
599 }
Brian Salomon9bada542017-06-12 12:09:30 -0400600 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
joshualitt83bc2292015-06-18 14:18:02 -0700601 }
602
Brian Salomonaf971de2017-06-08 16:11:33 -0400603 // This was reproduced on the following configurations:
604 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
605 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
606 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400607 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
Brian Salomonaf971de2017-06-08 16:11:33 -0400608 // and not produced on:
609 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400610 // The particular lines that get dropped from test images varies across different devices.
Brian Salomonaf971de2017-06-08 16:11:33 -0400611 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() && kQualcomm_GrGLDriver == ctxInfo.driver() &&
612 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0)) {
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400613 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
Brian Salomonaf971de2017-06-08 16:11:33 -0400614 }
615
Chris Daltoncc604e52017-10-06 16:27:32 -0600616 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
617 // given 1 << 15 or more instances.
618 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
619 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
620 }
621
bsalomonbabafcc2016-02-16 11:36:47 -0800622 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
623 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon9bada542017-06-12 12:09:30 -0400624 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
bsalomonbabafcc2016-02-16 11:36:47 -0800625 fUseDrawInsteadOfAllRenderTargetWrites = true;
626 }
627
robertphillips63926682015-08-20 09:39:02 -0700628#ifdef SK_BUILD_FOR_WIN
629 // On ANGLE deferring flushes can lead to GPU starvation
630 fPreferVRAMUseOverFlushes = !isANGLE;
631#endif
632
bsalomon7dea7b72015-08-19 08:26:51 -0700633 if (kChromium_GrGLDriver == ctxInfo.driver()) {
634 fMustClearUploadedBufferData = true;
635 }
636
bsalomond08ea5f2015-02-20 06:58:13 -0800637 if (kGL_GrGLStandard == standard) {
638 // ARB allows mixed size FBO attachments, EXT does not.
639 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
640 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
641 fOversizedStencilSupport = true;
642 } else {
643 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
644 }
645 } else {
646 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
647 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
648 }
649
joshualitt58001552015-06-26 12:46:36 -0700650 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700651 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
652 ctxInfo.hasExtension("GL_ARB_draw_indirect");
653 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
654 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700655 (fDrawIndirectSupport &&
656 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700657 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700658 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800659 } else {
660 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700661 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
662 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
663 fBaseInstanceSupport = fDrawIndirectSupport &&
664 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700665 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800666 }
667
Brian Salomon1edc5b92016-11-29 13:43:46 -0500668 this->initShaderPrecisionTable(ctxInfo, gli, shaderCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800669
ethannicholas28ef4452016-03-25 09:26:03 -0700670 if (kGL_GrGLStandard == standard) {
Greg Daniela5cb7812017-06-16 09:45:32 -0400671 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
ethannicholas6536ae52016-05-02 12:16:49 -0700672 ctxInfo.vendor() != kIntel_GrGLVendor) {
ethannicholas28ef4452016-03-25 09:26:03 -0700673 fSampleShadingSupport = true;
674 }
675 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
676 fSampleShadingSupport = true;
677 }
678
jvanverth84741b32016-09-30 08:39:02 -0700679 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
680 if (kGL_GrGLStandard == standard) {
681 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
682 fFenceSyncSupport = true;
683 }
Brian Osman93a23462017-06-21 15:13:39 -0400684 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700685 fFenceSyncSupport = true;
686 }
687
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400688 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500689 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500690
brianosman131ff132016-06-07 14:22:44 -0700691 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
692 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
693 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
694 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
brianosman09563ce2016-06-02 08:59:34 -0700695 if (fMipMapLevelAndLodControlSupport &&
brianosman9a3fbf72016-06-09 13:11:08 -0700696 (contextOptions.fDoManualMipmapping ||
697 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
brianosman131ff132016-06-07 14:22:44 -0700698 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
699 (kATI_GrGLVendor == ctxInfo.vendor()))) {
brianosman09563ce2016-06-02 08:59:34 -0700700 fDoManualMipmapping = true;
701 }
702
brianosman20471892016-12-02 06:43:32 -0800703 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
brianosman851c2382016-12-07 10:03:25 -0800704 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
705 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800706
Brian Salomon028a9a52017-05-11 11:39:08 -0400707 // See http://crbug.com/710443
708#ifdef SK_BUILD_FOR_MAC
709 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
Eric Karlaeaf22b2017-05-18 15:08:09 -0700710 fClearToBoundaryValuesIsBroken = true;
Brian Salomon028a9a52017-05-11 11:39:08 -0400711 }
712#endif
Chris Dalton9926f4b2017-05-17 15:15:50 -0600713 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
714 fDrawArraysBaseVertexIsBroken = true;
715 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400716
bsalomoncdee0092016-01-08 13:20:12 -0800717 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
718 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800719 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700720
721 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500722 shaderCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000723}
724
egdaniel472d44e2015-10-22 08:20:00 -0700725const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
726 bool isCoreProfile) {
727 switch (generation) {
728 case k110_GrGLSLGeneration:
729 if (kGLES_GrGLStandard == standard) {
730 // ES2s shader language is based on version 1.20 but is version
731 // 1.00 of the ES language.
732 return "#version 100\n";
733 } else {
734 SkASSERT(kGL_GrGLStandard == standard);
735 return "#version 110\n";
736 }
737 case k130_GrGLSLGeneration:
738 SkASSERT(kGL_GrGLStandard == standard);
739 return "#version 130\n";
740 case k140_GrGLSLGeneration:
741 SkASSERT(kGL_GrGLStandard == standard);
742 return "#version 140\n";
743 case k150_GrGLSLGeneration:
744 SkASSERT(kGL_GrGLStandard == standard);
745 if (isCoreProfile) {
746 return "#version 150\n";
747 } else {
748 return "#version 150 compatibility\n";
749 }
750 case k330_GrGLSLGeneration:
751 if (kGLES_GrGLStandard == standard) {
752 return "#version 300 es\n";
753 } else {
754 SkASSERT(kGL_GrGLStandard == standard);
755 if (isCoreProfile) {
756 return "#version 330\n";
757 } else {
758 return "#version 330 compatibility\n";
759 }
760 }
cdalton33ad7012016-02-22 07:55:44 -0800761 case k400_GrGLSLGeneration:
762 SkASSERT(kGL_GrGLStandard == standard);
763 if (isCoreProfile) {
764 return "#version 400\n";
765 } else {
766 return "#version 400 compatibility\n";
767 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500768 case k420_GrGLSLGeneration:
769 SkASSERT(kGL_GrGLStandard == standard);
770 if (isCoreProfile) {
771 return "#version 420\n";
772 }
773 else {
774 return "#version 420 compatibility\n";
775 }
egdaniel472d44e2015-10-22 08:20:00 -0700776 case k310es_GrGLSLGeneration:
777 SkASSERT(kGLES_GrGLStandard == standard);
778 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800779 case k320es_GrGLSLGeneration:
780 SkASSERT(kGLES_GrGLStandard == standard);
781 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700782 }
783 return "<no version>";
784}
785
egdaniel05ded892015-10-26 07:38:05 -0700786void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700787 GrGLStandard standard = ctxInfo.standard();
788 GrGLVersion version = ctxInfo.version();
789
790 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500791 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700792 **************************************************************************/
793
Brian Salomon1edc5b92016-11-29 13:43:46 -0500794 GrShaderCaps* shaderCaps = fShaderCaps.get();
795 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700796 if (kGLES_GrGLStandard == standard) {
797 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500798 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
799 shaderCaps->fFBFetchSupport = true;
800 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
801 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700802 }
803 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
804 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
Brian Salomon1edc5b92016-11-29 13:43:46 -0500805 shaderCaps->fFBFetchNeedsCustomOutput = false;
806 shaderCaps->fFBFetchSupport = true;
807 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
808 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700809 }
810 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
811 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500812 shaderCaps->fFBFetchNeedsCustomOutput = false;
813 shaderCaps->fFBFetchSupport = true;
814 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
815 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700816 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500817 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700818 }
819
egdaniel7517e452016-09-20 13:00:26 -0700820 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
821 // Galaxy S7.
822 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
823 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500824 shaderCaps->fFBFetchSupport = false;
egdaniel7517e452016-09-20 13:00:26 -0700825 }
826
Brian Salomon1edc5b92016-11-29 13:43:46 -0500827 shaderCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
egdaniel472d44e2015-10-22 08:20:00 -0700828
cdaltonc08f1962016-02-12 12:14:06 -0800829 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500830 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800831 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500832 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800833 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
834 }
Brian Salomon41274562017-09-15 09:40:03 -0700835 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
836 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
837 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800838 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500839 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800840 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
841 } else {
842 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500843 shaderCaps->fNoPerspectiveInterpolationSupport = true;
844 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800845 "GL_NV_shader_noperspective_interpolation";
846 }
847 }
848
cdalton33ad7012016-02-22 07:55:44 -0800849 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500850 shaderCaps->fMultisampleInterpolationSupport =
cdalton4a98cdb2016-03-01 12:12:20 -0800851 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
852 } else {
853 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500854 shaderCaps->fMultisampleInterpolationSupport = true;
cdalton4a98cdb2016-03-01 12:12:20 -0800855 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500856 shaderCaps->fMultisampleInterpolationSupport = true;
857 shaderCaps->fMultisampleInterpolationExtensionString =
cdalton4a98cdb2016-03-01 12:12:20 -0800858 "GL_OES_shader_multisample_interpolation";
859 }
860 }
861
862 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500863 shaderCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
cdalton33ad7012016-02-22 07:55:44 -0800864 } else {
865 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500866 shaderCaps->fSampleVariablesSupport = true;
cdalton33ad7012016-02-22 07:55:44 -0800867 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500868 shaderCaps->fSampleVariablesSupport = true;
869 shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
cdalton33ad7012016-02-22 07:55:44 -0800870 }
871 }
872
Brian Salomon1edc5b92016-11-29 13:43:46 -0500873 if (shaderCaps->fSampleVariablesSupport &&
csmartdaltonf848c9c2016-06-15 12:42:13 -0700874 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
875 // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500876 shaderCaps->fSampleMaskOverrideCoverageSupport =
csmartdaltonf848c9c2016-06-15 12:42:13 -0700877 kNVIDIA_GrGLDriver != ctxInfo.driver() ||
878 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
cdalton33ad7012016-02-22 07:55:44 -0800879 }
880
egdaniel472d44e2015-10-22 08:20:00 -0700881 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
Brian Salomon1edc5b92016-11-29 13:43:46 -0500882 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700883
884 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
885 // function that may require a gradient calculation inside a conditional block may return
886 // undefined results". This appears to be an issue with the 'any' call since even the simple
887 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
888 // from our GrTextureDomain processor.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500889 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700890
Brian Salomon1edc5b92016-11-29 13:43:46 -0500891 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
892 shaderCaps->fGLSLGeneration,
893 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800894
Brian Salomon1edc5b92016-11-29 13:43:46 -0500895 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
896 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800897 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800898
899 // Frag Coords Convention support is not part of ES
900 // Known issue on at least some Intel platforms:
901 // http://code.google.com/p/skia/issues/detail?id=946
902 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
903 kGLES_GrGLStandard != standard &&
904 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
905 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500906 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800907 }
908
909 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500910 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800911 }
912
cdalton9c3f1432016-03-11 10:07:37 -0800913 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
914 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500915 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800916 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
917 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
918 // At least one driver has been found that has this extension without the "GL_" prefix.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500919 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800920 }
921 }
922
Brian Salomon1edc5b92016-11-29 13:43:46 -0500923 if (shaderCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800924 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500925 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
bsalomon7ea33f52015-11-22 14:51:00 -0800926 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500927 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800928 }
929 }
930
cdaltonc04ce672016-03-11 14:07:38 -0800931 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500932 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800933 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500934 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700935 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
936 }
937
Brian Salomon1edc5b92016-11-29 13:43:46 -0500938 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700939 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500940 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700941 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
942 } else {
943 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
944 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500945 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700946 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500947 shaderCaps->fTexelBufferSupport = true;
948 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700949 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500950 shaderCaps->fTexelBufferSupport = true;
951 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700952 }
cdaltonc04ce672016-03-11 14:07:38 -0800953 }
954 }
955
Chris Dalton1d616352017-05-31 12:51:23 -0600956 if (kGL_GrGLStandard == standard) {
957 shaderCaps->fVertexIDSupport = true;
958 } else {
959 // Desktop GLSL 3.30 == ES GLSL 3.00.
960 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
961 }
962
egdaniel8dcdedc2015-11-11 06:27:20 -0800963 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Florin Malita8a0044f2017-08-07 14:38:22 -0400964 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
965 // so we must do the abs first in a separate expression.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500966 shaderCaps->fCanUseMinAndAbsTogether = false;
Florin Malita8a0044f2017-08-07 14:38:22 -0400967
968 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
969 // must avoid this condition.
970 shaderCaps->fCanUseFractForNegativeValues = false;
egdaniel8dcdedc2015-11-11 06:27:20 -0800971 }
972
bsalomon7ea33f52015-11-22 14:51:00 -0800973 // 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 -0800974 // thus must us -1.0 * %s.x to work correctly
975 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500976 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
egdaniel8dcdedc2015-11-11 06:27:20 -0800977 }
egdaniel138c2632016-08-17 10:59:00 -0700978
979 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
980 // the original dst color when reading the outColor even after being written to. By using a
981 // local outColor we can work around this bug.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500982 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
983 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
egdaniel138c2632016-08-17 10:59:00 -0700984 }
csmartdalton2e777ea2017-02-15 10:41:27 -0700985
Brian Osmanac1e4962017-05-25 11:34:38 -0400986 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
987 // color, and that uniform contains an opaque color, and the output of the shader is only based
988 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
989 // that the shader always outputs opaque values. In that case, it appears to remove the shader
990 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
991 // insert an extra bit of math on the uniform that confuses the compiler just enough...
992 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
993 shaderCaps->fMustObfuscateUniformColor = true;
994 }
Brian Osmandff5d432017-08-01 14:46:18 -0400995
996#ifdef SK_BUILD_FOR_WIN
997 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
998 //
999 // Basically, if a shader has a construct like:
1000 //
1001 // float x = someCondition ? someValue : 0;
1002 // float2 result = (0 == x) ? float2(x, x)
1003 // : float2(2 * x / x, 0);
1004 //
1005 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
1006 // we've explicitly guarded the division with a check against zero. This manifests in much
1007 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
1008 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
1009 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
1010 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
1011 }
1012#endif
egdaniel472d44e2015-10-22 08:20:00 -07001013}
1014
kkinnunencfe62e32015-07-01 02:58:50 -07001015bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -07001016 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
1017
1018 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -07001019 return false;
1020 }
kkinnunen6bb6d402015-07-14 10:59:23 -07001021
kkinnunencfe62e32015-07-01 02:58:50 -07001022 if (kGL_GrGLStandard == ctxInfo.standard()) {
1023 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
1024 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
1025 return false;
1026 }
1027 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -07001028 if (!hasChromiumPathRendering &&
1029 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -07001030 return false;
1031 }
1032 }
1033 // We only support v1.3+ of GL_NV_path_rendering which allows us to
1034 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
1035 // additions are detected by checking the existence of the function.
1036 // We also use *Then* functions that not all drivers might have. Check
1037 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -08001038 if (!gli->fFunctions.fStencilThenCoverFillPath ||
1039 !gli->fFunctions.fStencilThenCoverStrokePath ||
1040 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
1041 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
1042 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -07001043 return false;
1044 }
1045 return true;
1046}
bsalomon1aa20292016-01-22 08:16:09 -08001047
Brian Salomon71d9d842016-11-03 13:42:00 -04001048bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -08001049 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -08001050 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -08001051 std::function<bool ()> bindRenderTarget,
1052 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -04001053 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -08001054 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -04001055 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -08001056 return false;
1057 }
bsalomon7928ef62016-01-05 10:26:39 -08001058
Brian Salomonbf7b6202016-11-11 16:08:03 -05001059 if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
1060 return false;
1061 }
1062
bsalomon76148af2016-01-12 11:13:47 -08001063 GrGLenum readFormat;
1064 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -04001065 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -08001066 return false;
1067 }
1068
bsalomon1aa20292016-01-22 08:16:09 -08001069 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -08001070 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
1071 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
1072 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
1073 // 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 -05001074 // The manual does not seem to fully match the spec as the spec allows integer formats
1075 // when the bound color buffer is an integer buffer. It doesn't specify which integer
1076 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -05001077 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
1078 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
1079 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -08001080 return false;
1081 }
1082 // There is also a set of allowed types, but all the types we use are in the set:
1083 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
1084 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
1085 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
1086 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
1087 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
1088 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
1089 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -08001090 return true;
piotaixre4b23142014-10-02 10:57:53 -07001091 }
bsalomon7928ef62016-01-05 10:26:39 -08001092
bsalomon76148af2016-01-12 11:13:47 -08001093 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -05001094 switch (fConfigTable[surfaceConfig].fFormatType) {
1095 case kNormalizedFixedPoint_FormatType:
1096 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
1097 return true;
1098 }
1099 break;
1100 case kInteger_FormatType:
1101 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
1102 return true;
1103 }
1104 break;
1105 case kFloat_FormatType:
1106 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
1107 return true;
1108 }
1109 break;
bsalomon7928ef62016-01-05 10:26:39 -08001110 }
1111
Brian Salomon71d9d842016-11-03 13:42:00 -04001112 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -08001113 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -04001114 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -08001115 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -08001116 if (!bindRenderTarget()) {
1117 return false;
1118 }
1119 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
1120 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -08001121 rpFormat->fFormat = format;
1122 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -08001123 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -08001124 }
1125
Brian Salomon71d9d842016-11-03 13:42:00 -04001126 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
1127 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -07001128}
1129
Eric Karl5c779752017-05-08 12:02:07 -07001130void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
1131 const GrGLInterface* gli) {
1132 // We need dual source blending and the ability to disable multisample in order to support mixed
1133 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
1134 // renderer is available and enabled; no other path renderers support this feature.
1135 if (fMultisampleDisableSupport &&
1136 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -04001137 this->shaderCaps()->pathRenderingSupport()
1138#if GR_TEST_UTILS
1139 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
1140#endif
1141 ) {
Eric Karl5c779752017-05-08 12:02:07 -07001142 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -04001143 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -07001144 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
1145 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
1146 kChromium_GrGLDriver == ctxInfo.driver())) {
1147 fDiscardRenderTargetSupport = false;
1148 fInvalidateFBType = kNone_InvalidateFBType;
1149 }
1150 }
1151
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001152 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001153 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
1154 // ES3 driver bugs on at least one device with a tiled GPU (N10).
1155 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1156 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1157 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1158 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -08001159 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001160 fMSFBOType = kMixedSamples_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001161 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1162 fMSFBOType = kStandard_MSFBOType;
1163 fAlpha8IsRenderable = true;
1164 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -04001165 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001166 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001167 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001168 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1169 fMSFBOType = kES_Apple_MSFBOType;
1170 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001171 } else {
egdanieleed519e2016-01-15 11:36:18 -08001172 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001173 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -04001174 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1175 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001176
Brian Salomon00731b42016-10-14 11:30:51 -04001177 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001178 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
1179 // Core profile removes ALPHA8 support.
1180 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1181 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
1182 // present.
1183 fAlpha8IsRenderable = true;
1184 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001185 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1186 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001187 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001188 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001189 }
Eric Karl5c779752017-05-08 12:02:07 -07001190
Robert Phillips3b3307f2017-05-24 07:44:02 -04001191 // We disable MSAA across the board for Intel GPUs
1192 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1193 fMSFBOType = kNone_MSFBOType;
1194 }
1195
Eric Karl5c779752017-05-08 12:02:07 -07001196 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
1197 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
1198 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
1199 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
1200 }
1201 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1202 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1203 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
1204 // This is to guard against platforms that may not support as many samples for
1205 // glRasterSamples as they do for framebuffers.
1206 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
1207 }
1208 fMaxColorSampleCount = fMaxStencilSampleCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001209}
1210
cdalton1dd05422015-06-12 09:01:18 -07001211void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001212 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001213
1214 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
1215 // for now until its own blacklists can be updated.
1216 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
Greg Daniel0ea7d432016-10-27 16:55:52 -04001217 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
cdalton1dd05422015-06-12 09:01:18 -07001218 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -07001219 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -07001220 return;
1221 }
1222
1223 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1224 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001225 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001226 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
1227 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001228 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001229 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1230 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1231 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1232 return;
1233 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1234 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001235 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001236 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
1237 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001238 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001239 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1240 // slow on a particular platform.
1241 } else {
1242 return; // No advanced blend support.
1243 }
1244
1245 SkASSERT(this->advancedBlendEquationSupport());
1246
csmartdalton3b88a032016-08-04 14:43:49 -07001247 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1248 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1249 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
cdalton1dd05422015-06-12 09:01:18 -07001250 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1251 (1 << kColorBurn_GrBlendEquation);
1252 }
joel.liang9764c402015-07-09 19:46:18 -07001253 if (kARM_GrGLVendor == ctxInfo.vendor()) {
1254 // Blacklist color-burn on ARM until the fix is released.
1255 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1256 }
cdalton1dd05422015-06-12 09:01:18 -07001257}
1258
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001259namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001260const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001261}
1262
Eric Karl5c779752017-05-08 12:02:07 -07001263void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001264
1265 // Build up list of legal stencil formats (though perhaps not supported on
1266 // the particular gpu/driver) from most preferred to least.
1267
1268 // these consts are in order of most preferred to least preferred
1269 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1270
1271 static const StencilFormat
1272 // internal Format stencil bits total bits packed?
1273 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1274 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1275 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1276 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001277 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001278 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1279
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001280 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001281 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001282 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001283 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1284 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1285
1286 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1287 // require FBO support we can expect these are legal formats and don't
1288 // check. These also all support the unsized GL_STENCIL_INDEX.
1289 fStencilFormats.push_back() = gS8;
1290 fStencilFormats.push_back() = gS16;
1291 if (supportsPackedDS) {
1292 fStencilFormats.push_back() = gD24S8;
1293 }
1294 fStencilFormats.push_back() = gS4;
1295 if (supportsPackedDS) {
1296 fStencilFormats.push_back() = gDS;
1297 }
1298 } else {
1299 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1300 // for other formats.
1301 // ES doesn't support using the unsized format.
1302
1303 fStencilFormats.push_back() = gS8;
1304 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001305 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1306 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001307 fStencilFormats.push_back() = gD24S8;
1308 }
1309 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1310 fStencilFormats.push_back() = gS4;
1311 }
1312 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001313}
1314
Brian Osman71a18892017-08-10 10:23:25 -04001315void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001316
Brian Osman71a18892017-08-10 10:23:25 -04001317 // We are called by the base class, which has already called beginObject(). We choose to nest
1318 // all of our caps information in a named sub-object.
1319 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001320
Brian Osman71a18892017-08-10 10:23:25 -04001321 writer->beginArray("Stencil Formats");
1322
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001323 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001324 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001325 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1326 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1327 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001328 }
1329
Brian Osman71a18892017-08-10 10:23:25 -04001330 writer->endArray();
1331
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001332 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001333 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001334 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001335 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001336 "IMG MS To Texture",
1337 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001338 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001339 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001340 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001341 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1342 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1343 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1344 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1345 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001346 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001347
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001348 static const char* kInvalidateFBTypeStr[] = {
1349 "None",
1350 "Discard",
1351 "Invalidate",
1352 };
1353 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1354 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1355 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1356 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001357
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001358 static const char* kMapBufferTypeStr[] = {
1359 "None",
1360 "MapBuffer",
1361 "MapBufferRange",
1362 "Chromium",
1363 };
1364 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1365 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1366 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1367 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1368 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1369
Brian Osman71a18892017-08-10 10:23:25 -04001370 writer->appendBool("Core Profile", fIsCoreProfile);
1371 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1372 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1373 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1374 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1375 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1376 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1377 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1378 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001379
Brian Osman71a18892017-08-10 10:23:25 -04001380 writer->appendBool("Texture Usage support", fTextureUsageSupport);
1381 writer->appendBool("GL_R support", fTextureRedSupport);
1382 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1383 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1384 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
1385 writer->appendBool("Direct state access support", fDirectStateAccessSupport);
1386 writer->appendBool("Debug support", fDebugSupport);
1387 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1388 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1389 writer->appendBool("Base instance support", fBaseInstanceSupport);
1390 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1391 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1392 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1393 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1394 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1395 writer->appendBool("BGRA to RGBA readback conversions are slow",
1396 fRGBAToBGRAReadbackConversionsAreSlow);
1397 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1398 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1399 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1400 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001401 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1402 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001403
Brian Osman71a18892017-08-10 10:23:25 -04001404 writer->beginArray("configs");
1405
bsalomon41e4384e2016-01-08 09:12:44 -08001406 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001407 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001408 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1409 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1410 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
1411 writer->appendHexU32("e_format",
1412 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage]);
1413 writer->appendHexU32(
1414 "e_format_teximage",
1415 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1416 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1417 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1418 writer->appendHexU32("i_for_renderbuffer",
1419 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1420 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001421 }
1422
Brian Osman71a18892017-08-10 10:23:25 -04001423 writer->endArray();
1424 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001425}
1426
jvanverthe9c0fc62015-04-29 11:18:05 -07001427static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1428 switch (p) {
1429 case kLow_GrSLPrecision:
1430 return GR_GL_LOW_FLOAT;
1431 case kMedium_GrSLPrecision:
1432 return GR_GL_MEDIUM_FLOAT;
1433 case kHigh_GrSLPrecision:
1434 return GR_GL_HIGH_FLOAT;
Brian Osman33aa2c72017-04-05 09:26:15 -04001435 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -04001436 SK_ABORT("Unexpected precision type.");
Brian Osman33aa2c72017-04-05 09:26:15 -04001437 return -1;
jvanverthe9c0fc62015-04-29 11:18:05 -07001438 }
jvanverthe9c0fc62015-04-29 11:18:05 -07001439}
1440
1441static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1442 switch (type) {
1443 case kVertex_GrShaderType:
1444 return GR_GL_VERTEX_SHADER;
1445 case kGeometry_GrShaderType:
1446 return GR_GL_GEOMETRY_SHADER;
1447 case kFragment_GrShaderType:
1448 return GR_GL_FRAGMENT_SHADER;
1449 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -04001450 SK_ABORT("Unknown shader type.");
jvanverthe9c0fc62015-04-29 11:18:05 -07001451 return -1;
1452}
1453
jvanverthcba99b82015-06-24 06:59:57 -07001454void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
halcanary9d524f22016-03-29 09:03:52 -07001455 const GrGLInterface* intf,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001456 GrShaderCaps* shaderCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001457 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1458 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1459 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1460 if (kGeometry_GrShaderType != s) {
1461 GrShaderType shaderType = static_cast<GrShaderType>(s);
1462 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001463 GrShaderCaps::PrecisionInfo* first = nullptr;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001464 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001465 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1466 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1467 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1468 GrGLint range[2];
1469 GrGLint bits;
1470 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1471 if (bits) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001472 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1473 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1474 shaderCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001475 if (!first) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001476 first = &shaderCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001477 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001478 else if (!shaderCaps->fShaderPrecisionVaries) {
1479 shaderCaps->fShaderPrecisionVaries =
1480 (*first != shaderCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001481 }
1482 }
1483 }
1484 }
1485 }
1486 }
1487 else {
1488 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001489 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001490 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1491 if (kGeometry_GrShaderType != s) {
1492 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001493 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1494 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1495 shaderCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001496 }
1497 }
1498 }
1499 }
1500 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1501 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1502 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1503 // are recommended against.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001504 if (shaderCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001505 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001506 shaderCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1507 shaderCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001508 }
1509 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001510 shaderCaps->initSamplerPrecisionTable();
jvanverthe9c0fc62015-04-29 11:18:05 -07001511}
1512
bsalomon41e4384e2016-01-08 09:12:44 -08001513bool GrGLCaps::bgraIsInternalFormat() const {
1514 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1515}
1516
bsalomon76148af2016-01-12 11:13:47 -08001517bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1518 GrGLenum* internalFormat, GrGLenum* externalFormat,
1519 GrGLenum* externalType) const {
1520 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1521 externalFormat, externalType)) {
1522 return false;
1523 }
1524 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1525 return true;
1526}
1527
bsalomon76148af2016-01-12 11:13:47 -08001528bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1529 GrGLenum* externalFormat, GrGLenum* externalType) const {
1530 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1531 externalFormat, externalType)) {
1532 return false;
1533 }
1534 return true;
1535}
1536
1537bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001538 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1539 return true;
1540}
1541
1542bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1543 ExternalFormatUsage usage, GrGLenum* externalFormat,
1544 GrGLenum* externalType) const {
1545 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001546
1547 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1548 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1549
1550 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1551 // made to work in many cases using glPixelStore and what not but is not needed currently.
1552 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1553 return false;
1554 }
1555
1556 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1557 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1558
bsalomone9573312016-01-25 14:33:25 -08001559 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1560 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1561 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1562 // texture, not the red component.
1563 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1564 if (this->textureRedSupport()) {
1565 SkASSERT(GR_GL_RED == *externalFormat);
1566 *externalFormat = GR_GL_ALPHA;
1567 }
1568 }
1569
bsalomon76148af2016-01-12 11:13:47 -08001570 return true;
1571}
1572
brianosman20471892016-12-02 06:43:32 -08001573void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1574 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001575 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001576 /*
1577 Comments on renderability of configs on various GL versions.
1578 OpenGL < 3.0:
1579 no built in support for render targets.
1580 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1581 format RGB, RGBA and NV float formats we don't use.
1582 This is the following:
1583 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1584 RGB10_A2, RGBA12,RGBA16
1585 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1586 since they aren't required by later standards and the driver can simply return
1587 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1588 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1589 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1590 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1591 This adds a lot of additional renderable sized formats, including ALPHA8.
1592 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1593 16F, 32I, 32UI, and 32F variants).
1594 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1595
1596 For both the above extensions we limit ourselves to those that are also required by
1597 OpenGL 3.0.
1598
1599 OpenGL 3.0:
1600 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1601 but are not required to be supported as renderable textures/renderbuffer.
1602 Required renderable color formats:
1603 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1604 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1605 RGB10_A2.
1606 - R11F_G11F_B10F.
1607 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1608 and RG8UI.
1609 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1610 - ALPHA8
1611
1612 OpenGL 3.1, 3.2, 3.3
1613 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1614 OpengGL 3.3, 4.0, 4.1
1615 Adds RGB10_A2UI.
1616 OpengGL 4.2
1617 Adds
1618 - RGB5_A1, RGBA4
1619 - RGB565
1620 OpenGL 4.4
1621 Does away with the separate list and adds a column to the sized internal color format
1622 table. However, no new formats become required color renderable.
1623
1624 ES 2.0
1625 color renderable: RGBA4, RGB5_A1, RGB565
1626 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1627 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1628 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1629 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1630 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1631 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1632
1633 ES 3.0
1634 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1635 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1636 RGB5_A1.
1637 - RGB8 and RGB565.
1638 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1639 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1640 ES 3.1
1641 Adds RGB10_A2, RGB10_A2UI,
1642 ES 3.2
1643 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1644 */
Brian Salomon71d9d842016-11-03 13:42:00 -04001645 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1646 ConfigInfo::kFBOColorAttachment_Flag;
1647 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001648 if (kNone_MSFBOType != fMSFBOType) {
1649 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1650 }
bsalomon41e4384e2016-01-08 09:12:44 -08001651 GrGLStandard standard = ctxInfo.standard();
1652 GrGLVersion version = ctxInfo.version();
1653
cblume790d5132016-02-29 11:13:29 -08001654 bool texStorageSupported = false;
1655 if (kGL_GrGLStandard == standard) {
1656 // The EXT version can apply to either GL or GLES.
1657 texStorageSupported = version >= GR_GL_VER(4,2) ||
1658 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1659 ctxInfo.hasExtension("GL_EXT_texture_storage");
1660 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001661 texStorageSupported = version >= GR_GL_VER(3,0) ||
1662 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001663 }
1664
1665 // TODO: remove after command buffer supports full ES 3.0
1666 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1667 kChromium_GrGLDriver == ctxInfo.driver()) {
1668 texStorageSupported = false;
1669 }
1670
cdalton74b8d322016-04-11 14:47:28 -07001671 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1672
bsalomon30447372015-12-21 09:03:05 -08001673 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1674 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001675 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001676 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001677 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001678 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001679
1680 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1681 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001682 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1683 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001684 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001685 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001686 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1687 if (kGL_GrGLStandard == standard) {
1688 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1689 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001690 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001691 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1692 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1693 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1694 }
egdaniel4999df82016-01-07 17:06:04 -08001695 }
cblume790d5132016-02-29 11:13:29 -08001696 if (texStorageSupported) {
1697 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1698 }
cdalton74b8d322016-04-11 14:47:28 -07001699 if (texelBufferSupport) {
1700 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1701 }
bsalomoncdee0092016-01-08 13:20:12 -08001702 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001703
bsalomon76148af2016-01-12 11:13:47 -08001704 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1705 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001706 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001707 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001708 if (kGL_GrGLStandard == standard) {
1709 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1710 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1711 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1712 // Since the internal format is RGBA8, it is also renderable.
1713 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1714 allRenderFlags;
1715 }
1716 } else {
1717 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1718 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1719 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001720 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1721 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1722 // driver remembers the external format when the texture is created (with TexImage).
1723 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1724 // We could work around this, but it adds even more state tracking to code that is
1725 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1726 // This also side-steps some ambiguous interactions with the texture storage extension.
1727 if (version >= GR_GL_VER(3,0)) {
1728 // The APPLE extension doesn't make this renderable.
1729 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon41e4384e2016-01-08 09:12:44 -08001730 }
1731 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1732 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001733 nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001734 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001735 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001736 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1737 ConfigInfo::kRenderableWithMSAA_Flag;
1738 }
1739 }
1740 }
Brian Osman48c99192017-06-02 08:45:06 -04001741
1742 bool isX86PowerVR = false;
1743#if defined(SK_CPU_X86)
1744 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1745 isX86PowerVR = true;
1746 }
1747#endif
1748
1749 // Adreno 3xx, 4xx, 5xx, and NexusPlayer all fail if we try to use TexStorage with BGRA
1750 if (texStorageSupported &&
1751 kAdreno3xx_GrGLRenderer != ctxInfo.renderer() &&
1752 kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1753 kAdreno5xx_GrGLRenderer != ctxInfo.renderer() &&
1754 !isX86PowerVR) {
1755 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001756 }
bsalomoncdee0092016-01-08 13:20:12 -08001757 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001758
brianosmana6359362016-03-21 06:55:37 -07001759 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001760 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001761 if (kGL_GrGLStandard == standard) {
1762 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001763 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001764 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1765 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1766 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001767 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001768 }
1769 }
1770 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001771 if (fSRGBSupport) {
1772 fSRGBWriteControl = true;
1773 }
bsalomon41e4384e2016-01-08 09:12:44 -08001774 } else {
brianosman20471892016-12-02 06:43:32 -08001775 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Osman48c99192017-06-02 08:45:06 -04001776 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1777 // blacklist that device (and any others that might be sharing the same driver).
1778 if (isX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001779 fSRGBSupport = false;
1780 }
bsalomon41e4384e2016-01-08 09:12:44 -08001781 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1782 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001783 // See https://bug.skia.org/5329 for Adreno4xx issue.
1784 fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1785 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001786 }
brianosman20471892016-12-02 06:43:32 -08001787 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1788 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1789 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001790 fSRGBSupport = false;
1791 }
brianosman20471892016-12-02 06:43:32 -08001792
1793 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1794 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1795 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1796 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1797 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1798 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1799 // affects Windows.
1800 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1801 fSRGBSupport = false;
1802 }
1803
Brian Osman48c99192017-06-02 08:45:06 -04001804 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1805 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1806 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1807
Brian Osman67999392017-05-31 16:19:34 -04001808 uint32_t srgbRenderFlags = allRenderFlags;
1809 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers
1810#if defined(SK_BUILD_FOR_MAC)
1811 if (kATI_GrGLVendor == ctxInfo.vendor()) {
1812 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1813 }
1814#endif
1815
bsalomon30447372015-12-21 09:03:05 -08001816 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1817 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1818 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1819 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001820 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1821 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001822 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001823 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001824 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001825 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001826 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001827 }
Brian Osman48c99192017-06-02 08:45:06 -04001828 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1829 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001830 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1831 }
bsalomoncdee0092016-01-08 13:20:12 -08001832 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001833 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1834 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1835 // is in this format, for example).
1836 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1837 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1838 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1839 // external format is GL_BGRA.
1840 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1841 GR_GL_BGRA;
1842 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1843 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001844 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001845 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001846 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001847 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001848
brianosmana6359362016-03-21 06:55:37 -07001849 if (texStorageSupported) {
1850 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1851 }
1852 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1853
Brian Salomonbf7b6202016-11-11 16:08:03 -05001854 bool hasIntegerTextures;
1855 if (standard == kGL_GrGLStandard) {
1856 hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1857 ctxInfo.hasExtension("GL_EXT_texture_integer");
1858 } else {
1859 hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1860 }
1861 // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1862 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1863 hasIntegerTextures = false;
1864 }
1865 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1866 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1867 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1868 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1869 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1870 // We currently only support using integer textures as srcs, not for rendering (even though GL
1871 // allows it).
1872 if (hasIntegerTextures) {
1873 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1874 ConfigInfo::kFBOColorAttachment_Flag;
1875 if (texStorageSupported) {
1876 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1877 ConfigInfo::kCanUseTexStorage_Flag;
1878 }
1879 }
1880
bsalomon30447372015-12-21 09:03:05 -08001881 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1882 if (this->ES2CompatibilitySupport()) {
1883 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1884 } else {
1885 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1886 }
bsalomon76148af2016-01-12 11:13:47 -08001887 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1888 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001889 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001890 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001891 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1892 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001893 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001894 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1895 }
1896 } else {
1897 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1898 }
cblume790d5132016-02-29 11:13:29 -08001899 // 565 is not a sized internal format on desktop GL. So on desktop with
1900 // 565 we always use an unsized internal format to let the system pick
1901 // the best sized format to convert the 565 data to. Since TexStorage
1902 // only allows sized internal formats we disallow it.
1903 //
1904 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1905 // update.
1906 if (texStorageSupported && kGL_GrGLStandard != standard) {
1907 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1908 }
bsalomoncdee0092016-01-08 13:20:12 -08001909 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001910
1911 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1912 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001913 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1914 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001915 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001916 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001917 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1918 if (kGL_GrGLStandard == standard) {
1919 if (version >= GR_GL_VER(4, 2)) {
1920 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1921 }
1922 } else {
1923 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1924 }
cblume790d5132016-02-29 11:13:29 -08001925 if (texStorageSupported) {
1926 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1927 }
bsalomoncdee0092016-01-08 13:20:12 -08001928 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001929
Brian Osmanf4faccd2017-01-10 16:53:58 -05001930 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1931 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1932 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001933 if (this->textureRedSupport()) {
1934 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1935 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001936 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1937 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001938 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001939 if (texelBufferSupport) {
1940 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1941 }
Robert Phillips5ab72762017-06-07 12:04:18 -04001942 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
bsalomon30447372015-12-21 09:03:05 -08001943 } else {
1944 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1945 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001946 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1947 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001948 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
Robert Phillips5ab72762017-06-07 12:04:18 -04001949 if (fAlpha8IsRenderable) {
1950 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1951 }
bsalomon30447372015-12-21 09:03:05 -08001952 }
Robert Phillips5ab72762017-06-07 12:04:18 -04001953
Brian Osman48c99192017-06-02 08:45:06 -04001954 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1955 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001956 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1957 }
bsalomon41e4384e2016-01-08 09:12:44 -08001958
Brian Osmanf4faccd2017-01-10 16:53:58 -05001959 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1960 fConfigTable[kGray_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1961 fConfigTable[kGray_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001962 if (this->textureRedSupport()) {
1963 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1964 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1965 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1966 GR_GL_RED;
1967 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRA();
1968 if (texelBufferSupport) {
1969 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1970 }
1971 } else {
1972 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1973 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1974 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1975 GR_GL_LUMINANCE;
1976 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1977 }
Brian Osman986563b2017-01-10 14:20:02 -05001978#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster
1979 if (this->textureRedSupport() ||
1980 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1981 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1982 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1983 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1984 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1985 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1986 }
1987#endif
Brian Osman48c99192017-06-02 08:45:06 -04001988 if (texStorageSupported && !isCommandBufferES2) {
Brian Osman986563b2017-01-10 14:20:02 -05001989 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1990 }
1991
bsalomon41e4384e2016-01-08 09:12:44 -08001992 // Check for [half] floating point texture support
1993 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1994 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1995 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1996 bool hasFPTextures = false;
1997 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001998 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001999 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04002000 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08002001
2002 if (kGL_GrGLStandard == standard) {
2003 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
2004 hasFPTextures = true;
2005 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002006 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08002007 }
2008 } else {
2009 if (version >= GR_GL_VER(3, 1)) {
2010 hasFPTextures = true;
2011 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002012 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08002013 } else {
2014 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
2015 ctxInfo.hasExtension("GL_OES_texture_float")) {
2016 hasFPTextures = true;
2017 }
2018 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
2019 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
2020 hasHalfFPTextures = true;
2021 }
2022 }
2023 }
bsalomon30447372015-12-21 09:03:05 -08002024
csmartdalton6aa0e112017-02-08 16:14:11 -05002025 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
2026 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
2027 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
2028 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
2029 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
2030 fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
2031 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
2032 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
2033 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002034 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05002035 // For now we only enable rendering to float on desktop, because on ES we'd have to
2036 // solve many precision issues and no clients actually want this yet.
2037 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
2038 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
2039 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
2040 }
bsalomon41e4384e2016-01-08 09:12:44 -08002041 }
csmartdalton6aa0e112017-02-08 16:14:11 -05002042 if (texStorageSupported) {
2043 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2044 }
2045 if (texelBufferSupport) {
2046 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
2047 }
2048 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08002049 }
bsalomon30447372015-12-21 09:03:05 -08002050
2051 if (this->textureRedSupport()) {
2052 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
2053 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08002054 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
2055 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08002056 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07002057 if (texelBufferSupport) {
2058 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |=
2059 ConfigInfo::kCanUseWithTexelBuffer_Flag;
2060 }
bsalomon30447372015-12-21 09:03:05 -08002061 } else {
2062 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
2063 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08002064 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
2065 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08002066 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08002067 }
Geoff Lang4b050002017-09-28 15:16:50 -04002068
2069 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08002070 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
2071 } else {
2072 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
2073 }
bsalomon7928ef62016-01-05 10:26:39 -08002074 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
cblume790d5132016-02-29 11:13:29 -08002075 if (texStorageSupported) {
2076 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2077 }
csmartdalton6aa0e112017-02-08 16:14:11 -05002078 if (hasHalfFPTextures) {
2079 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
2080 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
2081 // GL_RED internal format.
2082 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
2083 (this->textureRedSupport() &&
2084 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
2085 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
2086 }
2087 }
bsalomon30447372015-12-21 09:03:05 -08002088
2089 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
2090 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08002091 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
2092 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04002093 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08002094 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
2095 } else {
2096 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
2097 }
bsalomon7928ef62016-01-05 10:26:39 -08002098 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08002099 if (hasHalfFPTextures) {
2100 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
2101 // ES requires 3.2 or EXT_color_buffer_half_float.
2102 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
2103 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
2104 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
2105 }
2106 }
cblume790d5132016-02-29 11:13:29 -08002107 if (texStorageSupported) {
2108 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2109 }
cdalton74b8d322016-04-11 14:47:28 -07002110 if (texelBufferSupport) {
2111 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
2112 }
bsalomoncdee0092016-01-08 13:20:12 -08002113 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08002114
bsalomon30447372015-12-21 09:03:05 -08002115 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
2116
2117 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08002118 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
2119 ctxInfo.version() >= GR_GL_VER(3,0));
2120 // All ES versions (thus far) require sized internal formats for render buffers.
2121 // TODO: Always use sized internal format?
2122 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
2123
bsalomon30447372015-12-21 09:03:05 -08002124 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08002125 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
2126 // param to glTex[Sub]Image.
2127 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
2128 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
2129 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
2130 fConfigTable[i].fFormats.fSizedInternalFormat :
2131 fConfigTable[i].fFormats.fBaseInternalFormat;
2132 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08002133 fConfigTable[i].fFormats.fSizedInternalFormat :
2134 fConfigTable[i].fFormats.fBaseInternalFormat;
2135 }
2136 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
2137 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
2138 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
2139 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
2140 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08002141 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08002142 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07002143
2144 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
2145 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
2146 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
2147 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08002148 }
2149
2150 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2151 // as a base format.
2152 // GL_EXT_texture_format_BGRA8888:
2153 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
2154 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
2155 // formats.
halcanary9d524f22016-03-29 09:03:52 -07002156 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08002157 // ES 2.0: the extension makes BGRA an external format but not an internal format.
2158 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
2159 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08002160 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08002161 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
2162 }
2163
bsalomoncdee0092016-01-08 13:20:12 -08002164 // If we don't have texture swizzle support then the shader generator must insert the
2165 // swizzle into shader code.
2166 if (!this->textureSwizzleSupport()) {
2167 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002168 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08002169 }
2170 }
2171
bsalomon7f9b2e42016-01-12 13:29:26 -08002172 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
2173 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
2174 // gets written to the single component.
2175 if (this->textureRedSupport()) {
2176 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2177 GrPixelConfig config = static_cast<GrPixelConfig>(i);
2178 if (GrPixelConfigIsAlphaOnly(config) &&
2179 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002180 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08002181 }
2182 }
2183 }
2184
Brian Salomonf9f45122016-11-29 11:59:17 -05002185 // We currently only support images on rgba textures formats. We could add additional formats
2186 // if desired. The shader builder would have to be updated to add swizzles where appropriate
2187 // (e.g. where we use GL_RED textures to implement alpha configs).
2188 if (this->shaderCaps()->imageLoadStoreSupport()) {
2189 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
2190 ConfigInfo::kCanUseAsImageStorage_Flag;
2191 // In OpenGL ES a texture may only be used with BindImageTexture if it has been made
2192 // immutable via TexStorage. We create non-integer textures as mutable textures using
2193 // TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
2194 // storage support for non-integer textures.
2195 if (kGL_GrGLStandard == ctxInfo.standard()) {
2196 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2197 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
2198 ConfigInfo::kCanUseAsImageStorage_Flag;
2199 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2200 }
2201 }
2202
Greg Daniel81e7bf82017-07-19 14:47:42 -04002203 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2204 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Greg Daniel6bd729d2017-07-31 09:38:23 -04002205 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04002206 (ctxInfo.version() >= GR_GL_VER(4,2) ||
2207 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04002208 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002209 int count;
2210 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
2211 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
2212 1, &count);
2213 if (count) {
2214 int* temp = new int[count];
2215 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
2216 temp);
2217 fConfigTable[i].fColorSampleCounts.setCount(count+1);
2218 // We initialize our supported values with 0 (no msaa) and reverse the order
2219 // returned by GL so that the array is ascending.
2220 fConfigTable[i].fColorSampleCounts[0] = 0;
2221 for (int j = 0; j < count; ++j) {
2222 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2223 }
2224 delete[] temp;
2225 }
2226 } else {
2227 static const int kDefaultSamples[] = {0,1,2,4,8};
2228 int count = SK_ARRAY_COUNT(kDefaultSamples);
2229 for (; count > 0; --count) {
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00002230 if (kDefaultSamples[count-1] <= fMaxColorSampleCount) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002231 break;
2232 }
2233 }
2234 if (count > 0) {
2235 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2236 }
2237 }
2238 }
2239 }
2240
bsalomon30447372015-12-21 09:03:05 -08002241#ifdef SK_DEBUG
2242 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002243 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002244 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002245 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2246 // renderable.
2247 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2248 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002249 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2250 fConfigTable[i].fFormats.fBaseInternalFormat);
2251 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002252 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002253 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2254 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2255 fConfigTable[i].fFormats.fExternalFormat[j]);
2256 }
2257 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002258 }
2259#endif
2260}
2261
Robert Phillipsbf25d432017-04-07 10:08:53 -04002262bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Eric Karl74480882017-04-03 14:49:05 -07002263 bool* rectsMustMatch, bool* disallowSubrect) const {
2264 // By default, we don't require rects to match.
2265 *rectsMustMatch = false;
2266
2267 // By default, we allow subrects.
2268 *disallowSubrect = false;
2269
Brian Salomon467921e2017-03-06 16:17:12 -05002270 // If the src is a texture, we can implement the blit as a draw assuming the config is
2271 // renderable.
Robert Phillipsbf25d432017-04-07 10:08:53 -04002272 if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
2273 desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002274 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2275 desc->fConfig = src->config();
2276 return true;
2277 }
2278
Robert Phillipsbf25d432017-04-07 10:08:53 -04002279 {
2280 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2281 // wrapped. In that case the proxy would already be instantiated.
2282 const GrTexture* srcTexture = src->priv().peekTexture();
2283 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2284 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2285 // Not supported for FBO blit or CopyTexSubImage
2286 return false;
2287 }
Brian Salomon467921e2017-03-06 16:17:12 -05002288 }
2289
2290 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2291 // possible and we return false to fallback to creating a render target dst for render-to-
2292 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2293 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002294 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002295 bool rectsMustMatchForBlitFramebuffer = false;
2296 bool disallowSubrectForBlitFramebuffer = false;
2297 if (src->numColorSamples() &&
2298 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2299 rectsMustMatchForBlitFramebuffer = true;
2300 disallowSubrectForBlitFramebuffer = true;
2301 // Mirroring causes rects to mismatch later, don't allow it.
2302 originForBlitFramebuffer = src->origin();
2303 } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() &
2304 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
2305 rectsMustMatchForBlitFramebuffer = true;
2306 // Mirroring causes rects to mismatch later, don't allow it.
2307 originForBlitFramebuffer = src->origin();
2308 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002309 originForBlitFramebuffer = src->origin();
2310 }
2311
2312 // Check for format issues with glCopyTexSubImage2D
2313 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2314 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2315 // then we set up for that, otherwise fail.
2316 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2317 desc->fOrigin = originForBlitFramebuffer;
2318 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002319 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2320 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002321 return true;
2322 }
2323 return false;
2324 }
2325
Robert Phillipsbf25d432017-04-07 10:08:53 -04002326 {
Brian Salomon63e79732017-05-15 21:23:13 -04002327 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2328 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002329 if (srcIsMSAARenderbuffer) {
2330 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2331 // blit or fail.
2332 if (this->canConfigBeFBOColorAttachment(src->config())) {
2333 desc->fOrigin = originForBlitFramebuffer;
2334 desc->fConfig = src->config();
2335 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2336 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2337 return true;
2338 }
2339 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002340 }
Brian Salomon467921e2017-03-06 16:17:12 -05002341 }
2342
2343 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2344 desc->fConfig = src->config();
2345 desc->fOrigin = src->origin();
2346 desc->fFlags = kNone_GrSurfaceFlags;
2347 return true;
2348}
2349
csmartdaltone0d36292016-07-29 08:14:20 -07002350void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
2351 if (options.fEnableInstancedRendering) {
2352 fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
2353#ifndef SK_BUILD_FOR_MAC
2354 // OS X doesn't seem to write correctly to floating point textures when using
2355 // glDraw*Indirect, regardless of the underlying GPU.
2356 fAvoidInstancedDrawsToFPTargets = true;
2357#endif
2358 }
Brian Salomon9bada542017-06-12 12:09:30 -04002359 if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
2360 fUseDrawInsteadOfAllRenderTargetWrites = true;
2361 }
csmartdaltone0d36292016-07-29 08:14:20 -07002362}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002363
2364int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
2365 int count = fConfigTable[config].fColorSampleCounts.count();
2366 if (!count || !this->isConfigRenderable(config, true)) {
2367 return 0;
2368 }
2369
2370 for (int i = 0; i < count; ++i) {
2371 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2372 return fConfigTable[config].fColorSampleCounts[i];
2373 }
2374 }
2375 return fConfigTable[config].fColorSampleCounts[count-1];
2376}
2377