blob: d71194ed6fd9c92cd23ddf0ca2ff3be2b669fcb7 [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"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000018
bsalomon682c2692015-05-22 14:01:46 -070019GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
20 const GrGLContextInfo& ctxInfo,
21 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080022 fStandard = ctxInfo.standard();
23
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000024 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000026 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000027 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080028 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000029 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000030 fUnpackRowLengthSupport = false;
31 fUnpackFlipYSupport = false;
32 fPackRowLengthSupport = false;
33 fPackFlipYSupport = false;
34 fTextureUsageSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040035 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000036 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000037 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070038 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080039 fES2CompatibilitySupport = false;
cdalton06604b92016-02-05 10:09:51 -080040 fDrawIndirectSupport = false;
41 fMultiDrawIndirectSupport = false;
42 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000043 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070044 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080045 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080046 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070047 fRGBA8888PixelsOpsAreSlow = false;
48 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080049 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080050 fRGBAToBGRAReadbackConversionsAreSlow = false;
brianosman09563ce2016-06-02 08:59:34 -070051 fDoManualMipmapping = false;
brianosman851c2382016-12-07 10:03:25 -080052 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070053 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040054 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060055 fDrawArraysBaseVertexIsBroken = false;
Brian Salomon43f8bf02017-10-18 08:33:29 -040056 fUseDrawToClearColor = false;
Mike Klein31550db2017-06-06 23:29:53 +000057 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040058 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
59 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040060 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050061 fProgramBinarySupport = false;
piotaixre4b23142014-10-02 10:57:53 -070062
Brian Salomone5e7eb12016-10-14 16:18:33 -040063 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060064 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080065
Brian Salomon94efbf52016-11-29 13:43:05 -050066 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070067
cdalton4cd67132015-06-10 19:23:46 -070068 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000069}
70
cdalton4cd67132015-06-10 19:23:46 -070071void GrGLCaps::init(const GrContextOptions& contextOptions,
72 const GrGLContextInfo& ctxInfo,
73 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000074 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000075 GrGLVersion version = ctxInfo.version();
76
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000077 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000078 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
79 &fMaxFragmentUniformVectors);
80 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000081 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000082 GrGLint max;
83 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
84 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000085 if (version >= GR_GL_VER(3, 2)) {
86 GrGLint profileMask;
87 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
88 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
89 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000090 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000091 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000092
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000093 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094 fUnpackRowLengthSupport = true;
95 fUnpackFlipYSupport = false;
96 fPackRowLengthSupport = true;
97 fPackFlipYSupport = false;
98 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000099 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
100 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000101 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000102 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
103 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000104 fPackFlipYSupport =
105 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
106 }
107
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000108 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000109 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
110
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000111 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700112 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
113 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
114 ctxInfo.hasExtension("GL_NV_texture_barrier");
115 } else {
116 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
117 }
118
Robert Phillips7f861922018-01-30 13:13:42 +0000119 if (kGL_GrGLStandard == standard) {
120 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
121 ctxInfo.hasExtension("GL_ARB_texture_multisample");
122 } else {
123 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
124 }
125
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000126 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000127 ctxInfo.hasExtension("GL_ARB_imaging");
128
Brian Salomon01b476a2018-01-23 11:06:41 -0500129 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700130 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
131 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000132 fDiscardRenderTargetSupport = true;
133 fInvalidateFBType = kInvalidate_InvalidateFBType;
134 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
135 fDiscardRenderTargetSupport = true;
136 fInvalidateFBType = kDiscard_InvalidateFBType;
137 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000138
Chris Dalton27059d32018-01-23 14:06:50 -0700139 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
140 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
141 if (kGLES_GrGLStandard == standard) {
142 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
143 // TODO: Evaluate on PowerVR.
144 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
145 if (kARM_GrGLVendor == ctxInfo.vendor()) {
146 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
147 }
148 }
149
Chris Dalton344e9032017-12-11 15:42:09 -0700150 if (kARM_GrGLVendor == ctxInfo.vendor() ||
151 kImagination_GrGLVendor == ctxInfo.vendor() ||
152 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
153 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000154 }
155
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000156 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000157 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800158 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
159 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000160 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000161 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
162 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000163 }
164
cdalton626e1ff2015-06-12 13:56:46 -0700165 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
166 fDebugSupport = true;
167 } else {
168 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
169 }
170
jvanverth3f801cb2014-12-16 09:49:38 -0800171 if (kGL_GrGLStandard == standard) {
172 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
173 }
174 else {
175 fES2CompatibilitySupport = true;
176 }
177
cdalton0edea2c2015-05-21 08:27:44 -0700178 if (kGL_GrGLStandard == standard) {
179 fMultisampleDisableSupport = true;
180 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700181 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700182 }
183
kkinnunend94708e2015-07-30 22:47:04 -0700184 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600185 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
186 // instanced arrays, but we could make this more granular if we wanted
187 fInstanceAttribSupport =
188 version >= GR_GL_VER(3, 2) ||
189 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
190 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
191 } else {
192 fInstanceAttribSupport =
193 version >= GR_GL_VER(3, 0) ||
194 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
195 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
196 }
197
198 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700199 if (version >= GR_GL_VER(3, 0)) {
200 fBindFragDataLocationSupport = true;
201 }
202 } else {
203 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
204 fBindFragDataLocationSupport = true;
205 }
joshualittc1f56b52015-06-22 12:31:31 -0700206 }
207
joshualitt7bdd70a2015-10-01 06:28:11 -0700208 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
209
kkinnunene06ed252016-02-16 23:15:40 -0800210 if (kGL_GrGLStandard == standard) {
211 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
212 // We also require textureSize() support for rectangle 2D samplers which was added in
213 // GLSL 1.40.
214 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
215 fRectangleTextureSupport = true;
216 }
bsalomone179a912016-01-20 06:18:10 -0800217 }
kkinnunene06ed252016-02-16 23:15:40 -0800218 } else {
219 // Command buffer exposes this in GL ES context for Chromium reasons,
220 // but it should not be used. Also, at the time of writing command buffer
221 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800222 }
223
bsalomoncdee0092016-01-08 13:20:12 -0800224 if (kGL_GrGLStandard == standard) {
225 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
226 fTextureSwizzleSupport = true;
227 }
228 } else {
229 if (version >= GR_GL_VER(3,0)) {
230 fTextureSwizzleSupport = true;
231 }
232 }
233
cblume09bd2c02016-03-01 14:08:28 -0800234 if (kGL_GrGLStandard == standard) {
235 fMipMapLevelAndLodControlSupport = true;
236 } else if (kGLES_GrGLStandard == standard) {
237 if (version >= GR_GL_VER(3,0)) {
238 fMipMapLevelAndLodControlSupport = true;
239 }
240 }
241
bsalomon88c7b982015-07-31 11:20:16 -0700242#ifdef SK_BUILD_FOR_WIN
243 // We're assuming that on Windows Chromium we're using ANGLE.
244 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
245 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700246 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700247 fRGBA8888PixelsOpsAreSlow = isANGLE;
248 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
249 // check DX11 ANGLE.
250 fPartialFBOReadIsSlow = isANGLE;
251#endif
252
ericrkb4ecabd2016-03-11 15:18:20 -0800253 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
254 bool isMAC = false;
255#ifdef SK_BUILD_FOR_MAC
256 isMAC = true;
257#endif
258
259 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
260 // vis-versa.
261 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
262
Brian Salomond17b4a62017-05-23 16:53:47 -0400263 if (kGL_GrGLStandard == standard) {
264 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400265 fClearTextureSupport = true;
266 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500267 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
268 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400269 }
270
cdalton4cd67132015-06-10 19:23:46 -0700271 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700272 * GrShaderCaps fields
273 **************************************************************************/
274
egdaniel0a482332015-10-26 08:59:10 -0700275 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700276 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500277 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700278
Brian Osman195c05b2017-08-30 15:14:04 -0400279 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
280#if GR_TEST_UTILS
281 if (contextOptions.fSuppressPathRendering) {
282 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700283 }
Brian Osman195c05b2017-08-30 15:14:04 -0400284#endif
egdaniel05ded892015-10-26 07:38:05 -0700285
egdaniel05ded892015-10-26 07:38:05 -0700286 // Enable supported shader-related caps
287 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500288 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700289 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
290 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600291
Brian Salomon1edc5b92016-11-29 13:43:46 -0500292 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600293
egdaniel05ded892015-10-26 07:38:05 -0700294 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500295 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700296 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600297 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600298 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
299 shaderCaps->fGSInvocationsSupport = true;
300 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
301 shaderCaps->fGSInvocationsSupport = true;
302 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
303 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600304 }
305
Brian Salomon1edc5b92016-11-29 13:43:46 -0500306 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800307 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500308 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500309 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700310
Brian Salomon1edc5b92016-11-29 13:43:46 -0500311 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700312 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800313
Chris Daltonfaca00d2018-01-19 15:56:07 -0700314 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
315 // backup impl that only uses vertex shaders.
316 if (kARM_GrGLVendor != ctxInfo.vendor()) {
317 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
318 shaderCaps->fGeometryShaderSupport = true;
319 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
320 shaderCaps->fGeometryShaderSupport = true;
321 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
322 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700323 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500324 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700325
Brian Salomon1edc5b92016-11-29 13:43:46 -0500326 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800327 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700328 }
329
cdalton9c3f1432016-03-11 10:07:37 -0800330 // Protect ourselves against tracking huge amounts of texture state.
331 static const uint8_t kMaxSaneSamplers = 32;
332 GrGLint maxSamplers;
333 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500334 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
335 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800336 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500337 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800338 }
339 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500340 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800341 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500342 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800343
Brian Salomonbbf05752017-11-30 11:30:48 -0500344 // This is all *very* approximate.
345 switch (ctxInfo.vendor()) {
346 case kNVIDIA_GrGLVendor:
347 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
348 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
349 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
350 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500351 case kImagination_GrGLVendor:
352 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
353 // it is always a win to use multitexturing.
354 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
355 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
356 std::numeric_limits<size_t>::max();
357 }
358 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500359 case kATI_GrGLVendor:
360 // So far no AMD GPU shows a performance difference. A tie goes to disabling
361 // multitexturing for simplicity's sake.
362 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
363 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500364 default:
365 break;
366 }
367
csmartdalton485a1202016-07-13 10:16:32 -0700368 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
369 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
370 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
371 // limit this decision to specific GPU families rather than basing it on the vendor alone.
372 if (!GR_GL_MUST_USE_VBO &&
373 !fIsCoreProfile &&
374 (kARM_GrGLVendor == ctxInfo.vendor() ||
375 kImagination_GrGLVendor == ctxInfo.vendor() ||
376 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
377 fPreferClientSideDynamicBuffers = true;
378 }
379
Eric Karl5c779752017-05-08 12:02:07 -0700380 if (!contextOptions.fAvoidStencilBuffers) {
381 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
382 this->initFSAASupport(contextOptions, ctxInfo, gli);
383 this->initStencilSupport(ctxInfo);
384 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400385
386 // Setup blit framebuffer
387 if (kGL_GrGLStandard != ctxInfo.standard()) {
388 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
389 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
390 kNoMSAADst_BlitFramebufferFlag |
391 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
392 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
393 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
394 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
395 // limitations.
396 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
397 kResolveMustBeFull_BlitFrambufferFlag |
398 kNoMSAADst_BlitFramebufferFlag |
399 kNoFormatConversion_BlitFramebufferFlag |
400 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
401 }
402 } else {
403 if (fUsesMixedSamples ||
404 ctxInfo.version() >= GR_GL_VER(3,0) ||
405 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
406 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
407 fBlitFramebufferFlags = 0;
408 }
409 }
410
cdalton1dd05422015-06-12 09:01:18 -0700411 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000412
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000413 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000414 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
415 // extension includes glMapBuffer.
416 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
417 fMapBufferFlags |= kSubset_MapFlag;
418 fMapBufferType = kMapBufferRange_MapBufferType;
419 } else {
420 fMapBufferType = kMapBuffer_MapBufferType;
421 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000422 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000423 // Unextended GLES2 doesn't have any buffer mapping.
424 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800425 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800426 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
427 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800428 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
429 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
430 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000431 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
432 fMapBufferFlags = kCanMap_MapFlag;
433 fMapBufferType = kMapBuffer_MapBufferType;
434 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000435 }
436
jvanverthd7a2c1f2015-12-07 07:36:44 -0800437 if (kGL_GrGLStandard == standard) {
438 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
439 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700440 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500441 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400442 if (version >= GR_GL_VER(3, 0) ||
443 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
444 // GL_EXT_unpack_subimage needed to support subtexture rectangles
445 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800446 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400447// TODO: get transfer buffers working in Chrome
448// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
449// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800450 }
451 }
452
joshualitte5b74c62015-06-01 14:17:47 -0700453 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
454 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700455 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700456#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500457 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
458 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
459 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700460 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700461#else
cdalton397536c2016-03-25 12:15:03 -0700462 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700463#endif
joshualitte5b74c62015-06-01 14:17:47 -0700464 }
465
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000466 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000467 fNPOTTextureTileSupport = true;
468 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000469 } else {
470 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000471 // ES3 has no limitations.
472 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
473 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000474 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
475 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
476 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
477 // to alllow arbitrary wrap modes, however.
478 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000479 }
480
bsalomon@google.combcce8922013-03-25 15:38:39 +0000481 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
482 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
483 // Our render targets are always created with textures as the color
484 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000485 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000486
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000487 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
488
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000489 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700490 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000491
robertphillips1b8e1b52015-06-24 06:54:10 -0700492#if 0
493 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
494 kQualcomm_GrGLVendor != ctxInfo.vendor();
495#endif
496
csmartdalton9bc11872016-08-09 12:42:47 -0700497 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
498 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700499 }
500
robertphillips63926682015-08-20 09:39:02 -0700501#ifdef SK_BUILD_FOR_WIN
502 // On ANGLE deferring flushes can lead to GPU starvation
503 fPreferVRAMUseOverFlushes = !isANGLE;
504#endif
505
bsalomon7dea7b72015-08-19 08:26:51 -0700506 if (kChromium_GrGLDriver == ctxInfo.driver()) {
507 fMustClearUploadedBufferData = true;
508 }
509
bsalomond08ea5f2015-02-20 06:58:13 -0800510 if (kGL_GrGLStandard == standard) {
511 // ARB allows mixed size FBO attachments, EXT does not.
512 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
513 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
514 fOversizedStencilSupport = true;
515 } else {
516 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
517 }
518 } else {
519 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
520 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
521 }
522
joshualitt58001552015-06-26 12:46:36 -0700523 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700524 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
525 ctxInfo.hasExtension("GL_ARB_draw_indirect");
526 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
527 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700528 (fDrawIndirectSupport &&
529 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700530 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700531 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800532 } else {
533 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700534 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
535 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
536 fBaseInstanceSupport = fDrawIndirectSupport &&
537 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700538 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800539 }
540
ethannicholas28ef4452016-03-25 09:26:03 -0700541 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500542 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700543 fSampleShadingSupport = true;
544 }
545 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
546 fSampleShadingSupport = true;
547 }
548
jvanverth84741b32016-09-30 08:39:02 -0700549 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
550 if (kGL_GrGLStandard == standard) {
551 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
552 fFenceSyncSupport = true;
553 }
Brian Osman93a23462017-06-21 15:13:39 -0400554 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700555 fFenceSyncSupport = true;
556 }
557
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400558 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500559 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500560
brianosman20471892016-12-02 06:43:32 -0800561 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500562
brianosman851c2382016-12-07 10:03:25 -0800563 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
564 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800565
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400566 if (kGL_GrGLStandard == standard) {
567 if (version >= GR_GL_VER(4, 1)) {
568 fProgramBinarySupport = true;
569 }
570 } else if (version >= GR_GL_VER(3, 0)) {
571 fProgramBinarySupport = true;
572 }
573
bsalomoncdee0092016-01-08 13:20:12 -0800574 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
575 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800576 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700577
Brian Salomon01b476a2018-01-23 11:06:41 -0500578 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
579 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
580 }
581
cdalton4cd67132015-06-10 19:23:46 -0700582 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500583 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700584
Brian Salomon01b476a2018-01-23 11:06:41 -0500585 // For now these two are equivalent but we could have dst read in shader via some other method.
586 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000587}
588
egdaniel472d44e2015-10-22 08:20:00 -0700589const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
590 bool isCoreProfile) {
591 switch (generation) {
592 case k110_GrGLSLGeneration:
593 if (kGLES_GrGLStandard == standard) {
594 // ES2s shader language is based on version 1.20 but is version
595 // 1.00 of the ES language.
596 return "#version 100\n";
597 } else {
598 SkASSERT(kGL_GrGLStandard == standard);
599 return "#version 110\n";
600 }
601 case k130_GrGLSLGeneration:
602 SkASSERT(kGL_GrGLStandard == standard);
603 return "#version 130\n";
604 case k140_GrGLSLGeneration:
605 SkASSERT(kGL_GrGLStandard == standard);
606 return "#version 140\n";
607 case k150_GrGLSLGeneration:
608 SkASSERT(kGL_GrGLStandard == standard);
609 if (isCoreProfile) {
610 return "#version 150\n";
611 } else {
612 return "#version 150 compatibility\n";
613 }
614 case k330_GrGLSLGeneration:
615 if (kGLES_GrGLStandard == standard) {
616 return "#version 300 es\n";
617 } else {
618 SkASSERT(kGL_GrGLStandard == standard);
619 if (isCoreProfile) {
620 return "#version 330\n";
621 } else {
622 return "#version 330 compatibility\n";
623 }
624 }
cdalton33ad7012016-02-22 07:55:44 -0800625 case k400_GrGLSLGeneration:
626 SkASSERT(kGL_GrGLStandard == standard);
627 if (isCoreProfile) {
628 return "#version 400\n";
629 } else {
630 return "#version 400 compatibility\n";
631 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500632 case k420_GrGLSLGeneration:
633 SkASSERT(kGL_GrGLStandard == standard);
634 if (isCoreProfile) {
635 return "#version 420\n";
636 }
637 else {
638 return "#version 420 compatibility\n";
639 }
egdaniel472d44e2015-10-22 08:20:00 -0700640 case k310es_GrGLSLGeneration:
641 SkASSERT(kGLES_GrGLStandard == standard);
642 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800643 case k320es_GrGLSLGeneration:
644 SkASSERT(kGLES_GrGLStandard == standard);
645 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700646 }
647 return "<no version>";
648}
649
Chris Dalton47c8ed32017-11-15 18:27:09 -0700650bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
651 if (kGLES_GrGLStandard != ctxInfo.standard() &&
652 ctxInfo.version() < GR_GL_VER(4,1) &&
653 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
654 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
655 return true;
656 }
657 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
658 // geometry shaders don't have lower precision than vertex and fragment.
659 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
660 GrGLint range[2];
661 GrGLint bits;
662 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
663 if (range[0] < 127 || range[1] < 127 || bits < 23) {
664 return false;
665 }
666 }
667 return true;
668}
669
670void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700671 GrGLStandard standard = ctxInfo.standard();
672 GrGLVersion version = ctxInfo.version();
673
674 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500675 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700676 **************************************************************************/
677
Brian Salomon1edc5b92016-11-29 13:43:46 -0500678 GrShaderCaps* shaderCaps = fShaderCaps.get();
679 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700680 if (kGLES_GrGLStandard == standard) {
681 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500682 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
683 shaderCaps->fFBFetchSupport = true;
684 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
685 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700686 }
687 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
688 // 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 -0500689 shaderCaps->fFBFetchNeedsCustomOutput = false;
690 shaderCaps->fFBFetchSupport = true;
691 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
692 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700693 }
694 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
695 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500696 shaderCaps->fFBFetchNeedsCustomOutput = false;
697 shaderCaps->fFBFetchSupport = true;
698 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
699 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700700 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500701 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700702 }
703
cdaltonc08f1962016-02-12 12:14:06 -0800704 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500705 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800706 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500707 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800708 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
709 }
Brian Salomon41274562017-09-15 09:40:03 -0700710 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
711 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
712 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800713 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500714 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800715 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
716 } else {
717 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500718 shaderCaps->fNoPerspectiveInterpolationSupport = true;
719 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800720 "GL_NV_shader_noperspective_interpolation";
721 }
722 }
723
Brian Salomon1edc5b92016-11-29 13:43:46 -0500724 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
725 shaderCaps->fGLSLGeneration,
726 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800727
Brian Salomon1edc5b92016-11-29 13:43:46 -0500728 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
729 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800730 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800731
732 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500733 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800734 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
735 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500736 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800737 }
738
739 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500740 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800741 }
742
cdalton9c3f1432016-03-11 10:07:37 -0800743 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
744 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500745 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800746 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
747 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
748 // At least one driver has been found that has this extension without the "GL_" prefix.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500749 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800750 }
751 }
752
Brian Salomon1edc5b92016-11-29 13:43:46 -0500753 if (shaderCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800754 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500755 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
bsalomon7ea33f52015-11-22 14:51:00 -0800756 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500757 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800758 }
759 }
760
cdaltonc04ce672016-03-11 14:07:38 -0800761 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500762 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800763 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500764 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700765 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
766 }
767
Brian Salomon1edc5b92016-11-29 13:43:46 -0500768 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700769 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500770 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700771 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
772 } else {
773 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
774 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500775 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700776 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500777 shaderCaps->fTexelBufferSupport = true;
778 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700779 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500780 shaderCaps->fTexelBufferSupport = true;
781 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700782 }
cdaltonc04ce672016-03-11 14:07:38 -0800783 }
784 }
785
Chris Dalton1d616352017-05-31 12:51:23 -0600786 if (kGL_GrGLStandard == standard) {
787 shaderCaps->fVertexIDSupport = true;
788 } else {
789 // Desktop GLSL 3.30 == ES GLSL 3.00.
790 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
791 }
792
Chris Dalton47c8ed32017-11-15 18:27:09 -0700793 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
794 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700795}
796
kkinnunencfe62e32015-07-01 02:58:50 -0700797bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700798 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
799
800 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700801 return false;
802 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700803
kkinnunencfe62e32015-07-01 02:58:50 -0700804 if (kGL_GrGLStandard == ctxInfo.standard()) {
805 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
806 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
807 return false;
808 }
809 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700810 if (!hasChromiumPathRendering &&
811 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700812 return false;
813 }
814 }
815 // We only support v1.3+ of GL_NV_path_rendering which allows us to
816 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
817 // additions are detected by checking the existence of the function.
818 // We also use *Then* functions that not all drivers might have. Check
819 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800820 if (!gli->fFunctions.fStencilThenCoverFillPath ||
821 !gli->fFunctions.fStencilThenCoverStrokePath ||
822 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
823 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
824 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700825 return false;
826 }
827 return true;
828}
bsalomon1aa20292016-01-22 08:16:09 -0800829
Brian Salomon71d9d842016-11-03 13:42:00 -0400830bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800831 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800832 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800833 std::function<bool ()> bindRenderTarget,
834 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400835 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800836 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400837 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800838 return false;
839 }
bsalomon7928ef62016-01-05 10:26:39 -0800840
bsalomon76148af2016-01-12 11:13:47 -0800841 GrGLenum readFormat;
842 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400843 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800844 return false;
845 }
846
bsalomon1aa20292016-01-22 08:16:09 -0800847 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800848 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
849 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
850 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
851 // 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 -0500852 // The manual does not seem to fully match the spec as the spec allows integer formats
853 // when the bound color buffer is an integer buffer. It doesn't specify which integer
854 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500855 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
856 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
857 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800858 return false;
859 }
860 // There is also a set of allowed types, but all the types we use are in the set:
861 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
862 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
863 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
864 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
865 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
866 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
867 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800868 return true;
piotaixre4b23142014-10-02 10:57:53 -0700869 }
bsalomon7928ef62016-01-05 10:26:39 -0800870
bsalomon76148af2016-01-12 11:13:47 -0800871 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500872 switch (fConfigTable[surfaceConfig].fFormatType) {
873 case kNormalizedFixedPoint_FormatType:
874 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
875 return true;
876 }
877 break;
878 case kInteger_FormatType:
879 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
880 return true;
881 }
882 break;
883 case kFloat_FormatType:
884 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
885 return true;
886 }
887 break;
bsalomon7928ef62016-01-05 10:26:39 -0800888 }
889
Brian Salomon71d9d842016-11-03 13:42:00 -0400890 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800891 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400892 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800893 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800894 if (!bindRenderTarget()) {
895 return false;
896 }
897 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
898 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800899 rpFormat->fFormat = format;
900 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800901 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800902 }
903
Brian Salomon71d9d842016-11-03 13:42:00 -0400904 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
905 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700906}
907
Eric Karl5c779752017-05-08 12:02:07 -0700908void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
909 const GrGLInterface* gli) {
910 // We need dual source blending and the ability to disable multisample in order to support mixed
911 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
912 // renderer is available and enabled; no other path renderers support this feature.
913 if (fMultisampleDisableSupport &&
914 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400915 this->shaderCaps()->pathRenderingSupport()
916#if GR_TEST_UTILS
917 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
918#endif
919 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700920 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400921 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700922 }
923
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000924 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400925 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
926 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
927 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
928 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
929 fAlpha8IsRenderable = true;
930 }
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000931 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
932 // ES3 driver bugs on at least one device with a tiled GPU (N10).
933 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
934 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
935 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
936 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800937 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700938 fMSFBOType = kMixedSamples_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400939 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
940 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400941 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400942 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400943 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400944 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000945 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
946 fMSFBOType = kES_Apple_MSFBOType;
947 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000948 } else {
egdanieleed519e2016-01-15 11:36:18 -0800949 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700950 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400951 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
952 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400953
Brian Salomon00731b42016-10-14 11:30:51 -0400954 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400955 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
956 // Core profile removes ALPHA8 support.
957 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
958 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
959 // present.
960 fAlpha8IsRenderable = true;
961 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000962 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
963 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400964 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000965 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000966 }
Eric Karl5c779752017-05-08 12:02:07 -0700967
Brian Salomon01b476a2018-01-23 11:06:41 -0500968 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400969 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
970 fMSFBOType = kNone_MSFBOType;
971 }
972
Eric Karl5c779752017-05-08 12:02:07 -0700973 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
974 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
975 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700976 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000977}
978
cdalton1dd05422015-06-12 09:01:18 -0700979void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500980 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -0700981
Greg Daniel210883c2017-11-27 15:14:01 -0500982 bool layoutQualifierSupport = false;
983 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
984 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
985 layoutQualifierSupport = true;
986 }
987
cdalton1dd05422015-06-12 09:01:18 -0700988 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
989 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500990 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -0500991 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
992 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -0700993 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500994 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -0700995 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
996 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500997 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -0500998 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -0700999 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001000 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001001 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1002 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001003 }
cdalton1dd05422015-06-12 09:01:18 -07001004}
1005
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001006namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001007const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001008}
1009
Eric Karl5c779752017-05-08 12:02:07 -07001010void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001011
1012 // Build up list of legal stencil formats (though perhaps not supported on
1013 // the particular gpu/driver) from most preferred to least.
1014
1015 // these consts are in order of most preferred to least preferred
1016 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1017
1018 static const StencilFormat
1019 // internal Format stencil bits total bits packed?
1020 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1021 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1022 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1023 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001024 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001025 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1026
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001027 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001028 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001029 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001030 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1031 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1032
1033 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1034 // require FBO support we can expect these are legal formats and don't
1035 // check. These also all support the unsized GL_STENCIL_INDEX.
1036 fStencilFormats.push_back() = gS8;
1037 fStencilFormats.push_back() = gS16;
1038 if (supportsPackedDS) {
1039 fStencilFormats.push_back() = gD24S8;
1040 }
1041 fStencilFormats.push_back() = gS4;
1042 if (supportsPackedDS) {
1043 fStencilFormats.push_back() = gDS;
1044 }
1045 } else {
1046 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1047 // for other formats.
1048 // ES doesn't support using the unsized format.
1049
1050 fStencilFormats.push_back() = gS8;
1051 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001052 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1053 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001054 fStencilFormats.push_back() = gD24S8;
1055 }
1056 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1057 fStencilFormats.push_back() = gS4;
1058 }
1059 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001060}
1061
Brian Osman71a18892017-08-10 10:23:25 -04001062void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001063
Brian Osman71a18892017-08-10 10:23:25 -04001064 // We are called by the base class, which has already called beginObject(). We choose to nest
1065 // all of our caps information in a named sub-object.
1066 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001067
Brian Osman71a18892017-08-10 10:23:25 -04001068 writer->beginArray("Stencil Formats");
1069
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001070 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001071 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001072 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1073 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1074 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001075 }
1076
Brian Osman71a18892017-08-10 10:23:25 -04001077 writer->endArray();
1078
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001079 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001080 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001081 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001082 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001083 "IMG MS To Texture",
1084 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001085 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001086 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001087 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001088 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1089 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1090 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1091 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1092 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001093 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001094
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001095 static const char* kInvalidateFBTypeStr[] = {
1096 "None",
1097 "Discard",
1098 "Invalidate",
1099 };
1100 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1101 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1102 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1103 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001104
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001105 static const char* kMapBufferTypeStr[] = {
1106 "None",
1107 "MapBuffer",
1108 "MapBufferRange",
1109 "Chromium",
1110 };
1111 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1112 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1113 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1114 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1115 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1116
Brian Osman71a18892017-08-10 10:23:25 -04001117 writer->appendBool("Core Profile", fIsCoreProfile);
1118 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1119 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1120 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1121 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1122 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1123 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1124 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1125 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001126
Brian Osman71a18892017-08-10 10:23:25 -04001127 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001128 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1129 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1130 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001131 writer->appendBool("Debug support", fDebugSupport);
1132 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1133 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1134 writer->appendBool("Base instance support", fBaseInstanceSupport);
1135 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1136 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1137 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1138 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1139 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1140 writer->appendBool("BGRA to RGBA readback conversions are slow",
1141 fRGBAToBGRAReadbackConversionsAreSlow);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001142 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1143 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001144 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1145 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1146 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1147 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001148 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1149 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001150
Brian Osman71a18892017-08-10 10:23:25 -04001151 writer->beginArray("configs");
1152
bsalomon41e4384e2016-01-08 09:12:44 -08001153 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001154 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001155 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1156 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1157 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
1158 writer->appendHexU32("e_format",
1159 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage]);
1160 writer->appendHexU32(
1161 "e_format_teximage",
1162 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1163 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1164 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1165 writer->appendHexU32("i_for_renderbuffer",
1166 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1167 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001168 }
1169
Brian Osman71a18892017-08-10 10:23:25 -04001170 writer->endArray();
1171 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001172}
1173
bsalomon41e4384e2016-01-08 09:12:44 -08001174bool GrGLCaps::bgraIsInternalFormat() const {
1175 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1176}
1177
bsalomon76148af2016-01-12 11:13:47 -08001178bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1179 GrGLenum* internalFormat, GrGLenum* externalFormat,
1180 GrGLenum* externalType) const {
1181 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1182 externalFormat, externalType)) {
1183 return false;
1184 }
1185 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1186 return true;
1187}
1188
bsalomon76148af2016-01-12 11:13:47 -08001189bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1190 GrGLenum* externalFormat, GrGLenum* externalType) const {
1191 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1192 externalFormat, externalType)) {
1193 return false;
1194 }
1195 return true;
1196}
1197
1198bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001199 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1200 return true;
1201}
1202
1203bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1204 ExternalFormatUsage usage, GrGLenum* externalFormat,
1205 GrGLenum* externalType) const {
1206 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001207
1208 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1209 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1210
1211 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1212 // made to work in many cases using glPixelStore and what not but is not needed currently.
1213 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1214 return false;
1215 }
1216
1217 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1218 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1219
bsalomone9573312016-01-25 14:33:25 -08001220 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1221 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1222 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1223 // texture, not the red component.
1224 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001225 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001226 *externalFormat = GR_GL_ALPHA;
1227 }
1228 }
1229
bsalomon76148af2016-01-12 11:13:47 -08001230 return true;
1231}
1232
brianosman20471892016-12-02 06:43:32 -08001233void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1234 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001235 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001236 /*
1237 Comments on renderability of configs on various GL versions.
1238 OpenGL < 3.0:
1239 no built in support for render targets.
1240 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1241 format RGB, RGBA and NV float formats we don't use.
1242 This is the following:
1243 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1244 RGB10_A2, RGBA12,RGBA16
1245 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1246 since they aren't required by later standards and the driver can simply return
1247 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1248 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1249 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1250 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1251 This adds a lot of additional renderable sized formats, including ALPHA8.
1252 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1253 16F, 32I, 32UI, and 32F variants).
1254 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1255
1256 For both the above extensions we limit ourselves to those that are also required by
1257 OpenGL 3.0.
1258
1259 OpenGL 3.0:
1260 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1261 but are not required to be supported as renderable textures/renderbuffer.
1262 Required renderable color formats:
1263 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1264 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1265 RGB10_A2.
1266 - R11F_G11F_B10F.
1267 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1268 and RG8UI.
1269 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1270 - ALPHA8
1271
1272 OpenGL 3.1, 3.2, 3.3
1273 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1274 OpengGL 3.3, 4.0, 4.1
1275 Adds RGB10_A2UI.
1276 OpengGL 4.2
1277 Adds
1278 - RGB5_A1, RGBA4
1279 - RGB565
1280 OpenGL 4.4
1281 Does away with the separate list and adds a column to the sized internal color format
1282 table. However, no new formats become required color renderable.
1283
1284 ES 2.0
1285 color renderable: RGBA4, RGB5_A1, RGB565
1286 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1287 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1288 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1289 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1290 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1291 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1292
1293 ES 3.0
1294 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1295 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1296 RGB5_A1.
1297 - RGB8 and RGB565.
1298 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1299 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1300 ES 3.1
1301 Adds RGB10_A2, RGB10_A2UI,
1302 ES 3.2
1303 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1304 */
Brian Salomon44804c02018-01-23 16:51:28 -05001305
1306 // Correctness workarounds.
1307 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001308 bool disableSRGBForX86PowerVR = false;
1309 bool disableSRGBWriteControlForAdreno4xx = false;
1310 bool disableR8TexStorageForANGLEGL = false;
1311 bool disableSRGBRenderWithMSAAForMacAMD = false;
1312
1313 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1314 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1315 // and GL_RG on FBO textures.
1316 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1317
1318 bool isX86PowerVR = false;
1319#if defined(SK_CPU_X86)
1320 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1321 isX86PowerVR = true;
1322 }
1323#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001324 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1325 // blacklist that device (and any others that might be sharing the same driver).
1326 disableSRGBForX86PowerVR = isX86PowerVR;
1327 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1328
1329 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1330 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1331 // check that we are not going to OpenGL.
1332 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1333
1334 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1335#if defined(SK_BUILD_FOR_MAC)
1336 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1337#endif
1338 }
1339
Brian Salomon71d9d842016-11-03 13:42:00 -04001340 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1341 ConfigInfo::kFBOColorAttachment_Flag;
1342 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001343 if (kNone_MSFBOType != fMSFBOType) {
1344 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1345 }
bsalomon41e4384e2016-01-08 09:12:44 -08001346 GrGLStandard standard = ctxInfo.standard();
1347 GrGLVersion version = ctxInfo.version();
1348
cblume790d5132016-02-29 11:13:29 -08001349 bool texStorageSupported = false;
1350 if (kGL_GrGLStandard == standard) {
1351 // The EXT version can apply to either GL or GLES.
1352 texStorageSupported = version >= GR_GL_VER(4,2) ||
1353 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1354 ctxInfo.hasExtension("GL_EXT_texture_storage");
1355 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001356 texStorageSupported = version >= GR_GL_VER(3,0) ||
1357 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001358 }
1359
cdalton74b8d322016-04-11 14:47:28 -07001360 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1361
Brian Salomone609e812018-01-17 14:00:47 -05001362 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001363
1364 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001365 if (kGL_GrGLStandard == standard) {
1366 textureRedSupport =
1367 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1368 } else {
1369 textureRedSupport =
1370 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1371 }
1372 }
1373
bsalomon30447372015-12-21 09:03:05 -08001374 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1375 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001376 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001377 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001378 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001379 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001380
1381 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1382 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001383 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1384 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001385 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001386 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001387 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1388 if (kGL_GrGLStandard == standard) {
1389 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1390 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001391 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001392 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1393 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1394 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1395 }
egdaniel4999df82016-01-07 17:06:04 -08001396 }
cblume790d5132016-02-29 11:13:29 -08001397 if (texStorageSupported) {
1398 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1399 }
cdalton74b8d322016-04-11 14:47:28 -07001400 if (texelBufferSupport) {
1401 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1402 }
bsalomoncdee0092016-01-08 13:20:12 -08001403 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001404
bsalomon76148af2016-01-12 11:13:47 -08001405 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1406 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001407 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001408 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001409
1410 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1411 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1412 // GL_EXT_texture_format_BGRA8888.
1413 bool supportsBGRATexStorage = false;
1414
bsalomon41e4384e2016-01-08 09:12:44 -08001415 if (kGL_GrGLStandard == standard) {
1416 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1417 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1418 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1419 // Since the internal format is RGBA8, it is also renderable.
1420 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1421 allRenderFlags;
1422 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001423 // Since we are using RGBA8 we can use tex storage.
1424 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001425 } else {
1426 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1427 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1428 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001429 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1430 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1431 // driver remembers the external format when the texture is created (with TexImage).
1432 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1433 // We could work around this, but it adds even more state tracking to code that is
1434 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1435 // This also side-steps some ambiguous interactions with the texture storage extension.
1436 if (version >= GR_GL_VER(3,0)) {
1437 // The APPLE extension doesn't make this renderable.
1438 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001439 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001440 }
1441 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1442 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001443 nonMSAARenderFlags;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001444
1445 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1446 supportsBGRATexStorage = true;
1447 }
bsalomon41e4384e2016-01-08 09:12:44 -08001448 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001449 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001450 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1451 ConfigInfo::kRenderableWithMSAA_Flag;
1452 }
1453 }
1454 }
Brian Osman48c99192017-06-02 08:45:06 -04001455
Greg Daniel0ff79b22018-02-15 12:33:33 -05001456 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001457 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001458 }
bsalomoncdee0092016-01-08 13:20:12 -08001459 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001460
brianosmana6359362016-03-21 06:55:37 -07001461 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001462 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001463 if (kGL_GrGLStandard == standard) {
1464 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001465 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001466 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1467 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1468 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001469 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001470 }
1471 }
1472 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001473 if (fSRGBSupport) {
1474 fSRGBWriteControl = true;
1475 }
bsalomon41e4384e2016-01-08 09:12:44 -08001476 } else {
brianosman20471892016-12-02 06:43:32 -08001477 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001478 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001479 fSRGBSupport = false;
1480 }
bsalomon41e4384e2016-01-08 09:12:44 -08001481 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1482 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001483 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001484 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001485 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001486 }
brianosman20471892016-12-02 06:43:32 -08001487 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1488 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1489 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001490 fSRGBSupport = false;
1491 }
brianosman20471892016-12-02 06:43:32 -08001492
1493 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1494 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1495 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1496 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1497 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1498 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1499 // affects Windows.
1500 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1501 fSRGBSupport = false;
1502 }
1503
Brian Osman48c99192017-06-02 08:45:06 -04001504 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1505 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1506 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1507
Brian Osman67999392017-05-31 16:19:34 -04001508 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001509 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001510 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1511 }
Brian Osman67999392017-05-31 16:19:34 -04001512
bsalomon30447372015-12-21 09:03:05 -08001513 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1514 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1515 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1516 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001517 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1518 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001519 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001520 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001521 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001522 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001523 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001524 }
Brian Osman48c99192017-06-02 08:45:06 -04001525 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1526 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001527 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1528 }
bsalomoncdee0092016-01-08 13:20:12 -08001529 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001530 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1531 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1532 // is in this format, for example).
1533 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1534 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1535 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1536 // external format is GL_BGRA.
1537 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1538 GR_GL_BGRA;
1539 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1540 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001541 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001542 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001543 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001544 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001545
brianosmana6359362016-03-21 06:55:37 -07001546 if (texStorageSupported) {
1547 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1548 }
1549 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1550
bsalomon30447372015-12-21 09:03:05 -08001551 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1552 if (this->ES2CompatibilitySupport()) {
1553 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1554 } else {
1555 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1556 }
bsalomon76148af2016-01-12 11:13:47 -08001557 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1558 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001559 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001560 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001561 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1562 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001563 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001564 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1565 }
1566 } else {
1567 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1568 }
cblume790d5132016-02-29 11:13:29 -08001569 // 565 is not a sized internal format on desktop GL. So on desktop with
1570 // 565 we always use an unsized internal format to let the system pick
1571 // the best sized format to convert the 565 data to. Since TexStorage
1572 // only allows sized internal formats we disallow it.
1573 //
1574 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1575 // update.
1576 if (texStorageSupported && kGL_GrGLStandard != standard) {
1577 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1578 }
bsalomoncdee0092016-01-08 13:20:12 -08001579 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001580
1581 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1582 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001583 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1584 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001585 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001586 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001587 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1588 if (kGL_GrGLStandard == standard) {
1589 if (version >= GR_GL_VER(4, 2)) {
1590 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1591 }
1592 } else {
1593 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1594 }
cblume790d5132016-02-29 11:13:29 -08001595 if (texStorageSupported) {
1596 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1597 }
bsalomoncdee0092016-01-08 13:20:12 -08001598 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001599
Greg Danielef59d872017-11-17 16:47:21 -05001600 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1601 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1602
1603 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1604 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1605 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1606 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1607 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001608 }
Greg Danielef59d872017-11-17 16:47:21 -05001609 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1610 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
1611 alphaInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_ALPHA;
1612 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1613 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1614 alphaInfo.fFlags |= allRenderFlags;
1615 }
1616
1617 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1618 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1619 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1620 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1621 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
1622 redInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
1623 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001624
Brian Osman48c99192017-06-02 08:45:06 -04001625 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1626 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001627 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001628 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1629 }
1630 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1631 }
1632
Brian Salomone609e812018-01-17 14:00:47 -05001633 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001634 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1635 if (texelBufferSupport) {
1636 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1637 }
1638
1639 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1640 } else {
1641 redInfo.fFlags = 0;
1642
1643 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001644 }
bsalomon41e4384e2016-01-08 09:12:44 -08001645
Greg Daniel7af060a2017-12-05 16:27:11 -05001646 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1647 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1648 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1649 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1650 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1651 grayLumInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_LUMINANCE;
1652 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1653 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1654 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1655 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001656 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001657
1658 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1659 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1660 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1661 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1662 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
1663 grayRedInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
1664 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1665 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1666
1667#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1668 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001669 if (this->textureRedSupport() ||
1670 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1671 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1672 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1673 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1674 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1675 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1676 }
1677#endif
Brian Osman48c99192017-06-02 08:45:06 -04001678 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001679 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001680 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1681 }
1682 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1683 }
1684
Brian Salomone609e812018-01-17 14:00:47 -05001685 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001686 if (texelBufferSupport) {
1687 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1688 }
1689 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1690 } else {
1691 grayRedInfo.fFlags = 0;
1692 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001693 }
1694
bsalomon41e4384e2016-01-08 09:12:44 -08001695 // Check for [half] floating point texture support
1696 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1697 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1698 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1699 bool hasFPTextures = false;
1700 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001701 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001702 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001703 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001704
1705 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001706 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001707 hasFPTextures = true;
1708 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001709 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001710 }
1711 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001712 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001713 hasFPTextures = true;
1714 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001715 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001716 } else {
1717 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1718 ctxInfo.hasExtension("GL_OES_texture_float")) {
1719 hasFPTextures = true;
1720 }
1721 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1722 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1723 hasHalfFPTextures = true;
1724 }
1725 }
1726 }
bsalomon30447372015-12-21 09:03:05 -08001727
csmartdalton6aa0e112017-02-08 16:14:11 -05001728 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1729 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1730 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1731 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1732 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
1733 fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
1734 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1735 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1736 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001737 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001738 // For now we only enable rendering to float on desktop, because on ES we'd have to
1739 // solve many precision issues and no clients actually want this yet.
1740 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1741 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1742 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1743 }
bsalomon41e4384e2016-01-08 09:12:44 -08001744 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001745 if (texStorageSupported) {
1746 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1747 }
1748 if (texelBufferSupport) {
1749 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1750 }
1751 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001752 }
bsalomon30447372015-12-21 09:03:05 -08001753
Greg Danielef59d872017-11-17 16:47:21 -05001754 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001755 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001756 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001757 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001758 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001759 }
Greg Danielef59d872017-11-17 16:47:21 -05001760 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1761 redHalf.fFormats.fExternalType = redHalfExternalType;
1762 redHalf.fFormatType = kFloat_FormatType;
1763 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1764 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
1765 redHalf.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
1766 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001767 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001768 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1769
csmartdalton6aa0e112017-02-08 16:14:11 -05001770 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001771 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001772 redHalf.fFlags |= fpRenderFlags;
1773 }
1774
1775 if (texStorageSupported && !isCommandBufferES2) {
1776 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1777 }
1778
1779 if (texelBufferSupport) {
1780 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001781 }
1782 }
Greg Danielef59d872017-11-17 16:47:21 -05001783 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001784
1785 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1786 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001787 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1788 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001789 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001790 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1791 } else {
1792 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1793 }
bsalomon7928ef62016-01-05 10:26:39 -08001794 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001795 if (hasHalfFPTextures) {
1796 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1797 // ES requires 3.2 or EXT_color_buffer_half_float.
1798 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1799 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1800 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1801 }
1802 }
cblume790d5132016-02-29 11:13:29 -08001803 if (texStorageSupported) {
1804 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1805 }
cdalton74b8d322016-04-11 14:47:28 -07001806 if (texelBufferSupport) {
1807 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1808 }
bsalomoncdee0092016-01-08 13:20:12 -08001809 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001810
bsalomon30447372015-12-21 09:03:05 -08001811 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1812
1813 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001814 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1815 ctxInfo.version() >= GR_GL_VER(3,0));
1816 // All ES versions (thus far) require sized internal formats for render buffers.
1817 // TODO: Always use sized internal format?
1818 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1819
bsalomon30447372015-12-21 09:03:05 -08001820 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001821 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1822 // param to glTex[Sub]Image.
1823 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1824 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1825 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1826 fConfigTable[i].fFormats.fSizedInternalFormat :
1827 fConfigTable[i].fFormats.fBaseInternalFormat;
1828 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001829 fConfigTable[i].fFormats.fSizedInternalFormat :
1830 fConfigTable[i].fFormats.fBaseInternalFormat;
1831 }
Brian Salomon44804c02018-01-23 16:51:28 -05001832 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1833 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1834 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1835 // in ES.
1836 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1837 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1838 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1839 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001840 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1841 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001842 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1843 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001844 }
1845
bsalomon30447372015-12-21 09:03:05 -08001846 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1847 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1848 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1849 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1850 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001851 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001852 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001853
1854 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1855 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1856 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1857 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001858 }
1859
1860 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1861 // as a base format.
1862 // GL_EXT_texture_format_BGRA8888:
1863 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1864 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1865 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001866 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001867 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1868 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1869 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001870 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001871 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1872 }
1873
bsalomoncdee0092016-01-08 13:20:12 -08001874 // If we don't have texture swizzle support then the shader generator must insert the
1875 // swizzle into shader code.
1876 if (!this->textureSwizzleSupport()) {
1877 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001878 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001879 }
1880 }
1881
bsalomon7f9b2e42016-01-12 13:29:26 -08001882 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1883 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1884 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001885 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001886 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1887 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1888 if (GrPixelConfigIsAlphaOnly(config) &&
1889 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001890 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001891 }
1892 }
1893 }
1894
Greg Daniel81e7bf82017-07-19 14:47:42 -04001895 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1896 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001897 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1898 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001899 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001900 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1901 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001902 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001903 int count;
1904 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1905 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1906 1, &count);
1907 if (count) {
1908 int* temp = new int[count];
1909 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1910 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001911 // GL has a concept of MSAA rasterization with a single sample but we do not.
1912 if (count && temp[count - 1] == 1) {
1913 --count;
1914 SkASSERT(!count || temp[count -1] > 1);
1915 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001916 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001917 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04001918 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05001919 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04001920 for (int j = 0; j < count; ++j) {
1921 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
1922 }
1923 delete[] temp;
1924 }
1925 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05001926 // Fake out the table using some semi-standard counts up to the max allowed sample
1927 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05001928 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05001929 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
1930 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
1931 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
1932 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
1933 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05001934 // Chrome has a mock GL implementation that returns 0.
1935 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05001936
Brian Salomonbdecacf2018-02-02 20:32:49 -05001937 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04001938 int count = SK_ARRAY_COUNT(kDefaultSamples);
1939 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05001940 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001941 break;
1942 }
1943 }
1944 if (count > 0) {
1945 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
1946 }
1947 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05001948 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
1949 fConfigTable[i].fColorSampleCounts.setCount(1);
1950 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04001951 }
1952 }
1953
bsalomon30447372015-12-21 09:03:05 -08001954#ifdef SK_DEBUG
1955 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001956 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001957 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04001958 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
1959 // renderable.
1960 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
1961 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08001962 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1963 fConfigTable[i].fFormats.fBaseInternalFormat);
1964 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001965 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001966 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1967 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1968 fConfigTable[i].fFormats.fExternalFormat[j]);
1969 }
1970 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001971 }
1972#endif
1973}
1974
Robert Phillipsbf25d432017-04-07 10:08:53 -04001975bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Eric Karl74480882017-04-03 14:49:05 -07001976 bool* rectsMustMatch, bool* disallowSubrect) const {
1977 // By default, we don't require rects to match.
1978 *rectsMustMatch = false;
1979
1980 // By default, we allow subrects.
1981 *disallowSubrect = false;
1982
Brian Salomon467921e2017-03-06 16:17:12 -05001983 // If the src is a texture, we can implement the blit as a draw assuming the config is
1984 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05001985 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Robert Phillipsbf25d432017-04-07 10:08:53 -04001986 desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05001987 desc->fFlags = kRenderTarget_GrSurfaceFlag;
1988 desc->fConfig = src->config();
1989 return true;
1990 }
1991
Robert Phillipsbf25d432017-04-07 10:08:53 -04001992 {
1993 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
1994 // wrapped. In that case the proxy would already be instantiated.
1995 const GrTexture* srcTexture = src->priv().peekTexture();
1996 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
1997 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
1998 // Not supported for FBO blit or CopyTexSubImage
1999 return false;
2000 }
Brian Salomon467921e2017-03-06 16:17:12 -05002001 }
2002
2003 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2004 // possible and we return false to fallback to creating a render target dst for render-to-
2005 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2006 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002007 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002008 bool rectsMustMatchForBlitFramebuffer = false;
2009 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002010 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002011 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2012 rectsMustMatchForBlitFramebuffer = true;
2013 disallowSubrectForBlitFramebuffer = true;
2014 // Mirroring causes rects to mismatch later, don't allow it.
2015 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002016 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2017 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002018 rectsMustMatchForBlitFramebuffer = true;
2019 // Mirroring causes rects to mismatch later, don't allow it.
2020 originForBlitFramebuffer = src->origin();
2021 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002022 originForBlitFramebuffer = src->origin();
2023 }
2024
2025 // Check for format issues with glCopyTexSubImage2D
2026 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2027 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2028 // then we set up for that, otherwise fail.
2029 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2030 desc->fOrigin = originForBlitFramebuffer;
2031 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002032 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2033 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002034 return true;
2035 }
2036 return false;
2037 }
2038
Robert Phillipsbf25d432017-04-07 10:08:53 -04002039 {
Brian Salomon63e79732017-05-15 21:23:13 -04002040 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2041 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002042 if (srcIsMSAARenderbuffer) {
2043 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2044 // blit or fail.
2045 if (this->canConfigBeFBOColorAttachment(src->config())) {
2046 desc->fOrigin = originForBlitFramebuffer;
2047 desc->fConfig = src->config();
2048 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2049 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2050 return true;
2051 }
2052 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002053 }
Brian Salomon467921e2017-03-06 16:17:12 -05002054 }
2055
2056 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2057 desc->fConfig = src->config();
2058 desc->fOrigin = src->origin();
2059 desc->fFlags = kNone_GrSurfaceFlags;
2060 return true;
2061}
2062
Brian Salomon01b476a2018-01-23 11:06:41 -05002063void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo, const GrContextOptions& contextOptions, GrShaderCaps* shaderCaps) {
2064 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2065 // Thus we are blacklisting this extension for now on Adreno4xx devices.
2066 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2067 fDiscardRenderTargetSupport = false;
2068 fInvalidateFBType = kNone_InvalidateFBType;
2069 }
2070
2071 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2072 // 340.96 and 367.57.
2073 if (kGL_GrGLStandard == ctxInfo.standard() &&
2074 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
2075 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57)) {
2076 fClearTextureSupport = false;
2077 }
2078
2079 // Calling glClearTexImage crashes on the NexusPlayer.
2080 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2081 fClearTextureSupport = false;
2082 }
2083
2084 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2085#ifdef SK_BUILD_FOR_MAC
2086 if (shaderCaps->fGeometryShaderSupport) {
2087 shaderCaps->fGSInvocationsSupport = false;
2088 }
2089#endif
2090
2091 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2092 // shaders. @127.0 is the earliest verified driver to not crash.
2093 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
2094 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127,0)) {
2095 shaderCaps->fGeometryShaderSupport = false;
2096 }
2097
2098#if defined(__has_feature)
2099#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2100 // See skbug.com/7058
2101 fMapBufferType = kNone_MapBufferType;
2102 fMapBufferFlags = kNone_MapFlags;
2103#endif
2104#endif
2105
2106 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2107 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2108 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2109 // unclear whether this really affects a wide range of devices.
2110 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
2111 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0)) {
2112 fMapBufferType = kNone_MapBufferType;
2113 fMapBufferFlags = kNone_MapFlags;
2114 }
2115
2116 // TODO: re-enable for ANGLE
2117 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2118 fTransferBufferType = kNone_TransferBufferType;
2119 }
2120
2121 // Using MIPs on this GPU seems to be a source of trouble.
2122 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2123 fMipMapSupport = false;
2124 }
2125
2126 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2127 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2128 // around a driver bug related to gl_FragCoord.
2129 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2130 fMaxClipAnalyticFPs = 0;
2131 }
2132
2133#ifndef SK_BUILD_FOR_IOS
2134 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2135 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2136 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2137 ctxInfo.driver() != kChromium_GrGLDriver)) {
2138 fUseDrawToClearColor = true;
2139 }
2140#endif
2141
2142 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2143 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2144 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2145 fUseDrawToClearColor = true;
2146 }
2147
2148#ifdef SK_BUILD_FOR_MAC
2149 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2150 // full screen clears
2151 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2152 // perform full screen clears.
2153 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2154 fUseDrawToClearColor = true;
2155 }
2156#endif
2157
2158 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2159 // bugs seems to involve clearing too much and not skipping the clear.
2160 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2161 // but only for D3D11 ANGLE.
2162 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2163 fUseDrawToClearColor = true;
2164 }
2165
2166 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2167 // This is known to be fixed sometime between driver 145.0 and 219.0
2168 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0)) {
2169 fUseDrawToClearStencilClip = true;
2170 }
2171 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2172 }
2173
2174 // This was reproduced on the following configurations:
2175 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2176 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2177 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2178 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2179 // and not produced on:
2180 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2181 // The particular lines that get dropped from test images varies across different devices.
2182 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2183 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0)) {
2184 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2185 }
2186
2187 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2188 // given 1 << 15 or more instances.
2189 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2190 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
2191 }
2192
2193 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
2194 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
2195 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2196 fUseDrawInsteadOfAllRenderTargetWrites = true;
2197 }
2198
2199 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2200 fSampleShadingSupport = false;
2201 }
2202
2203#ifdef SK_BUILD_FOR_MAC
2204 static constexpr bool isMAC = true;
2205#else
2206 static constexpr bool isMAC = false;
2207#endif
2208
2209 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2210 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2211 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2212 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2213 if (fMipMapLevelAndLodControlSupport &&
2214 (contextOptions.fDoManualMipmapping ||
2215 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2216 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2217 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2218 fDoManualMipmapping = true;
2219 }
2220
2221 // See http://crbug.com/710443
2222#ifdef SK_BUILD_FOR_MAC
2223 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2224 fClearToBoundaryValuesIsBroken = true;
2225 }
2226#endif
2227 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2228 fDrawArraysBaseVertexIsBroken = true;
2229 }
2230
2231 // The ccpr vertex-shader implementation does not work on this platform. Only allow CCPR with
2232 // GS.
2233
2234 if (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2235 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer()) {
2236 bool gsSupport = fShaderCaps->geometryShaderSupport();
2237#if GR_TEST_UTILS
2238 gsSupport &= !contextOptions.fSuppressGeometryShaders;
2239#endif
2240 fBlacklistCoverageCounting = !gsSupport;
2241 }
2242 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2243 // Galaxy S7.
2244 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2245 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2246 shaderCaps->fFBFetchSupport = false;
2247 }
2248
Brian Salomon01b476a2018-01-23 11:06:41 -05002249 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2250 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2251
2252 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2253 // function that may require a gradient calculation inside a conditional block may return
2254 // undefined results". This appears to be an issue with the 'any' call since even the simple
2255 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2256 // from our GrTextureDomain processor.
2257 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2258
2259 // Known issue on at least some Intel platforms:
2260 // http://code.google.com/p/skia/issues/detail?id=946
2261 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2262 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2263 }
2264
2265 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
2266 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2267 // so we must do the abs first in a separate expression.
2268 shaderCaps->fCanUseMinAndAbsTogether = false;
2269
2270 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2271 // must avoid this condition.
2272 shaderCaps->fCanUseFractForNegativeValues = false;
2273 }
2274
2275 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2276 // thus must us -1.0 * %s.x to work correctly
2277 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2278 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2279 }
2280
2281 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2282 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2283 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2284 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2285 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2286 }
2287
2288 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2289 // the original dst color when reading the outColor even after being written to. By using a
2290 // local outColor we can work around this bug.
2291 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2292 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2293 }
2294
2295 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2296 // color, and that uniform contains an opaque color, and the output of the shader is only based
2297 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2298 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2299 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2300 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2301 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2302 shaderCaps->fMustObfuscateUniformColor = true;
2303 }
2304#ifdef SK_BUILD_FOR_WIN
2305 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2306 //
2307 // Basically, if a shader has a construct like:
2308 //
2309 // float x = someCondition ? someValue : 0;
2310 // float2 result = (0 == x) ? float2(x, x)
2311 // : float2(2 * x / x, 0);
2312 //
2313 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2314 // we've explicitly guarded the division with a check against zero. This manifests in much
2315 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2316 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2317 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2318 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2319 }
2320#endif
2321
2322 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2323 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2324 // that the interpolation of vertex shader outputs is quite inaccurate.
2325 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2326 shaderCaps->fCanUseFragCoord = false;
2327 shaderCaps->fInterpolantsAreInaccurate = true;
2328 }
2329
2330 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2331 // for now until its own blacklists can be updated.
2332 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2333 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2334 kIntel_GrGLDriver == ctxInfo.driver() ||
2335 kChromium_GrGLDriver == ctxInfo.driver()) {
2336 fBlendEquationSupport = kBasic_BlendEquationSupport;
2337 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2338 }
2339
2340 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2341 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002342 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00) &&
2343 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002344 fBlendEquationSupport = kBasic_BlendEquationSupport;
2345 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2346 }
2347
2348 if (this->advancedBlendEquationSupport()) {
2349 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
2350 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
2351 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2352 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2353 (1 << kColorBurn_GrBlendEquation);
2354 }
2355 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2356 // Blacklist color-burn on ARM until the fix is released.
2357 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2358 }
2359 }
2360
2361 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2362 if (fMultisampleDisableSupport &&
2363 this->shaderCaps()->dualSourceBlendingSupport() &&
2364 this->shaderCaps()->pathRenderingSupport() &&
2365 fUsesMixedSamples &&
2366#if GR_TEST_UTILS
2367 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2368#endif
2369 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2370 kChromium_GrGLDriver == ctxInfo.driver())) {
2371 fDiscardRenderTargetSupport = false;
2372 fInvalidateFBType = kNone_InvalidateFBType;
2373 }
2374}
2375
csmartdaltone0d36292016-07-29 08:14:20 -07002376void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002377 if (options.fDisableDriverCorrectnessWorkarounds) {
2378 SkASSERT(!fDoManualMipmapping);
2379 SkASSERT(!fClearToBoundaryValuesIsBroken);
2380 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2381 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2382 SkASSERT(!fUseDrawToClearColor);
2383 SkASSERT(!fUseDrawToClearStencilClip);
2384 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2385 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2386 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
2387 }
Brian Salomon9bada542017-06-12 12:09:30 -04002388 if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
2389 fUseDrawInsteadOfAllRenderTargetWrites = true;
2390 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002391 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2392 fUseDrawToClearColor = false;
2393 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2394 fUseDrawToClearColor = true;
2395 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002396 if (options.fDoManualMipmapping) {
2397 fDoManualMipmapping = true;
2398 }
csmartdaltone0d36292016-07-29 08:14:20 -07002399}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002400
Greg Daniel2a303902018-02-20 10:25:54 -05002401bool GrGLCaps::onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
2402 const GrGLFramebufferInfo* fbInfo = backendRT.getGLFramebufferInfo();
2403 SkASSERT(fbInfo);
2404 // Mixed samples are not supported for FBO 0;
2405 return fbInfo->fFBOID != 0;
2406}
2407
2408bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
2409 const GrGLFramebufferInfo* fbInfo = backendRT.getGLFramebufferInfo();
2410 SkASSERT(fbInfo);
2411 // Window Rectangles are not supported for FBO 0;
2412 return fbInfo->fFBOID != 0;
2413}
2414
Brian Salomonbdecacf2018-02-02 20:32:49 -05002415int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2416 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002417 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002418 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002419 return 0;
2420 }
2421
Brian Salomonbdecacf2018-02-02 20:32:49 -05002422 if (1 == requestedCount) {
2423 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2424 }
2425
Greg Daniel81e7bf82017-07-19 14:47:42 -04002426 for (int i = 0; i < count; ++i) {
2427 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2428 return fConfigTable[config].fColorSampleCounts[i];
2429 }
2430 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002431 return 0;
2432}
2433
2434int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2435 const auto& table = fConfigTable[config].fColorSampleCounts;
2436 if (!table.count()) {
2437 return 0;
2438 }
2439 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002440}
2441
Greg Danielfaa095e2017-12-19 13:15:02 -05002442bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2443 GrGLStandard standard) {
2444 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002445
2446 switch (ct) {
2447 case kUnknown_SkColorType:
2448 return false;
2449 case kAlpha_8_SkColorType:
2450 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002451 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002452 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002453 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002454 }
2455 break;
2456 case kRGB_565_SkColorType:
2457 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002458 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002459 }
2460 break;
2461 case kARGB_4444_SkColorType:
2462 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002463 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002464 }
2465 break;
2466 case kRGBA_8888_SkColorType:
2467 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002468 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002469 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002470 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002471 }
2472 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002473 case kRGB_888x_SkColorType:
2474 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002475 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002476 if (GR_GL_RGBA8 == format) {
2477 if (kGL_GrGLStandard == standard) {
2478 *config = kBGRA_8888_GrPixelConfig;
2479 }
2480 } else if (GR_GL_BGRA8 == format) {
2481 if (kGLES_GrGLStandard == standard) {
2482 *config = kBGRA_8888_GrPixelConfig;
2483 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002484 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002485 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002486 }
2487 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002488 case kRGBA_1010102_SkColorType:
2489 return false;
2490 case kRGB_101010x_SkColorType:
2491 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002492 case kGray_8_SkColorType:
2493 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002494 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002495 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002496 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002497 }
2498 break;
2499 case kRGBA_F16_SkColorType:
2500 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002501 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002502 }
2503 break;
2504 }
2505
Greg Danielfaa095e2017-12-19 13:15:02 -05002506 return kUnknown_GrPixelConfig != *config;
2507}
2508
2509bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2510 GrPixelConfig* config) const {
2511 const GrGLTextureInfo* texInfo = tex.getGLTextureInfo();
2512 if (!texInfo) {
2513 return false;
2514 }
2515 return validate_sized_format(texInfo->fFormat, ct, config, fStandard);
2516}
2517
2518bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2519 GrPixelConfig* config) const {
2520 const GrGLFramebufferInfo* fbInfo = rt.getGLFramebufferInfo();
2521 if (!fbInfo) {
2522 return false;
2523 }
2524 return validate_sized_format(fbInfo->fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002525}
2526
Robert Phillipsfc711a22018-02-13 17:03:00 -05002527bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2528 GrPixelConfig* config) const {
2529 const GrGLenum* glFormat = format.getGLFormat();
2530 if (!glFormat) {
2531 return false;
2532 }
2533 return validate_sized_format(*glFormat, ct, config, fStandard);
2534}
2535
2536