blob: 4996859c51e822f5860ba98c0d8ac8099c1db8d7 [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;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000035 fTextureRedSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040036 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000037 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000038 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070039 fDirectStateAccessSupport = false;
40 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080041 fES2CompatibilitySupport = false;
cdalton06604b92016-02-05 10:09:51 -080042 fDrawIndirectSupport = false;
43 fMultiDrawIndirectSupport = false;
44 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000045 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070046 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080047 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080048 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070049 fRGBA8888PixelsOpsAreSlow = false;
50 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080051 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080052 fRGBAToBGRAReadbackConversionsAreSlow = false;
brianosman09563ce2016-06-02 08:59:34 -070053 fDoManualMipmapping = false;
brianosman851c2382016-12-07 10:03:25 -080054 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070055 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040056 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060057 fDrawArraysBaseVertexIsBroken = false;
Brian Salomon43f8bf02017-10-18 08:33:29 -040058 fUseDrawToClearColor = false;
Mike Klein31550db2017-06-06 23:29:53 +000059 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040060 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
61 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040062 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050063 fProgramBinarySupport = false;
piotaixre4b23142014-10-02 10:57:53 -070064
Brian Salomone5e7eb12016-10-14 16:18:33 -040065 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060066 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080067
Brian Salomon94efbf52016-11-29 13:43:05 -050068 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070069
cdalton4cd67132015-06-10 19:23:46 -070070 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000071}
72
cdalton4cd67132015-06-10 19:23:46 -070073void GrGLCaps::init(const GrContextOptions& contextOptions,
74 const GrGLContextInfo& ctxInfo,
75 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000076 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000077 GrGLVersion version = ctxInfo.version();
78
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000079 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000080 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
81 &fMaxFragmentUniformVectors);
82 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000083 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000084 GrGLint max;
85 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
86 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000087 if (version >= GR_GL_VER(3, 2)) {
88 GrGLint profileMask;
89 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
90 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
91 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000092 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000093 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000095 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000096 fUnpackRowLengthSupport = true;
97 fUnpackFlipYSupport = false;
98 fPackRowLengthSupport = true;
99 fPackFlipYSupport = false;
100 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000101 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
102 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000103 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000104 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
105 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000106 fPackFlipYSupport =
107 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
108 }
109
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000110 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000111 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
112
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000113 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700114 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
115 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
116 ctxInfo.hasExtension("GL_NV_texture_barrier");
117 } else {
118 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
119 }
120
cdaltoneb79eea2016-02-26 10:39:34 -0800121 if (kGL_GrGLStandard == standard) {
122 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
123 ctxInfo.hasExtension("GL_ARB_texture_multisample");
124 } else {
125 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
126 }
127
Brian Salomon0ee6f952017-01-19 15:52:24 -0500128 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
hendrikwa0d5ad72014-12-02 07:30:30 -0800129 // and GL_RG on FBO textures.
Brian Salomon0ee6f952017-01-19 15:52:24 -0500130 if (kOSMesa_GrGLRenderer != ctxInfo.renderer()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800131 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000132 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
133 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800134 } else {
135 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
136 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000137 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000138 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000139 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000140 ctxInfo.hasExtension("GL_ARB_imaging");
141
egdaniel9250d242015-05-18 13:04:26 -0700142 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
143 // Thus we are blacklisting this extension for now on Adreno4xx devices.
144 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
145 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
146 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
147 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000148 fDiscardRenderTargetSupport = true;
149 fInvalidateFBType = kInvalidate_InvalidateFBType;
150 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
151 fDiscardRenderTargetSupport = true;
152 fInvalidateFBType = kDiscard_InvalidateFBType;
153 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000154
Chris Dalton344e9032017-12-11 15:42:09 -0700155 if (kARM_GrGLVendor == ctxInfo.vendor() ||
156 kImagination_GrGLVendor == ctxInfo.vendor() ||
157 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
158 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000159 }
160
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000161 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000162 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800163 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
164 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000165 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000166 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
167 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000168 }
169
cdalton626e1ff2015-06-12 13:56:46 -0700170 if (kGL_GrGLStandard == standard) {
171 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
172 } else {
173 fDirectStateAccessSupport = false;
174 }
175
176 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
177 fDebugSupport = true;
178 } else {
179 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
180 }
181
jvanverth3f801cb2014-12-16 09:49:38 -0800182 if (kGL_GrGLStandard == standard) {
183 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
184 }
185 else {
186 fES2CompatibilitySupport = true;
187 }
188
cdalton0edea2c2015-05-21 08:27:44 -0700189 if (kGL_GrGLStandard == standard) {
190 fMultisampleDisableSupport = true;
191 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700192 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700193 }
194
kkinnunend94708e2015-07-30 22:47:04 -0700195 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600196 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
197 // instanced arrays, but we could make this more granular if we wanted
198 fInstanceAttribSupport =
199 version >= GR_GL_VER(3, 2) ||
200 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
201 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
202 } else {
203 fInstanceAttribSupport =
204 version >= GR_GL_VER(3, 0) ||
205 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
206 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
207 }
208
209 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700210 if (version >= GR_GL_VER(3, 0)) {
211 fBindFragDataLocationSupport = true;
212 }
213 } else {
214 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
215 fBindFragDataLocationSupport = true;
216 }
joshualittc1f56b52015-06-22 12:31:31 -0700217 }
218
joshualitt7bdd70a2015-10-01 06:28:11 -0700219 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
220
kkinnunene06ed252016-02-16 23:15:40 -0800221 if (kGL_GrGLStandard == standard) {
222 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
223 // We also require textureSize() support for rectangle 2D samplers which was added in
224 // GLSL 1.40.
225 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
226 fRectangleTextureSupport = true;
227 }
bsalomone179a912016-01-20 06:18:10 -0800228 }
kkinnunene06ed252016-02-16 23:15:40 -0800229 } else {
230 // Command buffer exposes this in GL ES context for Chromium reasons,
231 // but it should not be used. Also, at the time of writing command buffer
232 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800233 }
234
bsalomoncdee0092016-01-08 13:20:12 -0800235 if (kGL_GrGLStandard == standard) {
236 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
237 fTextureSwizzleSupport = true;
238 }
239 } else {
240 if (version >= GR_GL_VER(3,0)) {
241 fTextureSwizzleSupport = true;
242 }
243 }
244
cblume09bd2c02016-03-01 14:08:28 -0800245 if (kGL_GrGLStandard == standard) {
246 fMipMapLevelAndLodControlSupport = true;
247 } else if (kGLES_GrGLStandard == standard) {
248 if (version >= GR_GL_VER(3,0)) {
249 fMipMapLevelAndLodControlSupport = true;
250 }
251 }
252
bsalomon88c7b982015-07-31 11:20:16 -0700253#ifdef SK_BUILD_FOR_WIN
254 // We're assuming that on Windows Chromium we're using ANGLE.
255 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
256 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700257 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700258 fRGBA8888PixelsOpsAreSlow = isANGLE;
259 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
260 // check DX11 ANGLE.
261 fPartialFBOReadIsSlow = isANGLE;
262#endif
263
ericrkb4ecabd2016-03-11 15:18:20 -0800264 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
265 bool isMAC = false;
266#ifdef SK_BUILD_FOR_MAC
267 isMAC = true;
268#endif
269
270 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
271 // vis-versa.
272 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
273
Brian Salomond17b4a62017-05-23 16:53:47 -0400274 if (kGL_GrGLStandard == standard) {
275 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
276 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
277 // 340.96 and 367.57.
278 if (ctxInfo.driver() != kNVIDIA_GrGLDriver ||
279 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(367, 57)) {
280 fClearTextureSupport = true;
281 }
282 }
283 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
284 // Calling glClearTexImage crashes on the NexusPlayer.
285 if (kPowerVRRogue_GrGLRenderer != ctxInfo.renderer()) {
286 fClearTextureSupport = true;
287 }
288 }
289
cdalton4cd67132015-06-10 19:23:46 -0700290 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700291 * GrShaderCaps fields
292 **************************************************************************/
293
egdaniel0a482332015-10-26 08:59:10 -0700294 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700295 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500296 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700297
Brian Osman195c05b2017-08-30 15:14:04 -0400298 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
299#if GR_TEST_UTILS
300 if (contextOptions.fSuppressPathRendering) {
301 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700302 }
Brian Osman195c05b2017-08-30 15:14:04 -0400303#endif
egdaniel05ded892015-10-26 07:38:05 -0700304
305 // For now these two are equivalent but we could have dst read in shader via some other method.
306 // Before setting this, initGLSL() must have been called.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500307 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
egdaniel05ded892015-10-26 07:38:05 -0700308
309 // Enable supported shader-related caps
310 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500311 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700312 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
313 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600314
Brian Salomon1edc5b92016-11-29 13:43:46 -0500315 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600316
egdaniel05ded892015-10-26 07:38:05 -0700317 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500318 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700319 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600320 if (shaderCaps->fGeometryShaderSupport) {
321 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
322#ifndef SK_BUILD_FOR_MAC
323 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
324 shaderCaps->fGSInvocationsSupport = true;
325 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
326 shaderCaps->fGSInvocationsSupport = true;
327 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
328 }
329#endif
330 }
331
Brian Salomon1edc5b92016-11-29 13:43:46 -0500332 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800333 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500334 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500335 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700336
Brian Salomon1edc5b92016-11-29 13:43:46 -0500337 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700338 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800339
Chris Dalton8fd79552018-01-11 00:46:14 -0500340 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
341 shaderCaps->fGeometryShaderSupport = true;
342 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
343 shaderCaps->fGeometryShaderSupport = true;
344 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
345 }
Chris Dalton08faf042017-12-21 14:30:33 -0700346 if (shaderCaps->fGeometryShaderSupport && kQualcomm_GrGLDriver == ctxInfo.driver()) {
347 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry shaders.
348 // @127.0 is the earliest verified driver to not crash.
349 shaderCaps->fGeometryShaderSupport = ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(127,0);
350 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600351 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
csmartdalton1d2aed02017-02-15 21:43:20 -0700352
Brian Salomon1edc5b92016-11-29 13:43:46 -0500353 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800354 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700355 }
356
cdalton9c3f1432016-03-11 10:07:37 -0800357 // Protect ourselves against tracking huge amounts of texture state.
358 static const uint8_t kMaxSaneSamplers = 32;
359 GrGLint maxSamplers;
360 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500361 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
362 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800363 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500364 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800365 }
366 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500367 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800368 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500369 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800370
Brian Salomonbbf05752017-11-30 11:30:48 -0500371 // This is all *very* approximate.
372 switch (ctxInfo.vendor()) {
373 case kNVIDIA_GrGLVendor:
374 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
375 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
376 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
377 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500378 case kImagination_GrGLVendor:
379 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
380 // it is always a win to use multitexturing.
381 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
382 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
383 std::numeric_limits<size_t>::max();
384 }
385 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500386 case kATI_GrGLVendor:
387 // So far no AMD GPU shows a performance difference. A tie goes to disabling
388 // multitexturing for simplicity's sake.
389 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
390 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500391 default:
392 break;
393 }
394
csmartdalton485a1202016-07-13 10:16:32 -0700395 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
396 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
397 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
398 // limit this decision to specific GPU families rather than basing it on the vendor alone.
399 if (!GR_GL_MUST_USE_VBO &&
400 !fIsCoreProfile &&
401 (kARM_GrGLVendor == ctxInfo.vendor() ||
402 kImagination_GrGLVendor == ctxInfo.vendor() ||
403 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
404 fPreferClientSideDynamicBuffers = true;
405 }
406
Chris Daltone4679fa2017-09-29 13:58:26 -0600407 if (kARM_GrGLVendor == ctxInfo.vendor()) {
Chris Dalton06cd6662017-10-07 14:37:57 -0600408 // Mali GPUs have rendering issues with CCPR. Blacklisting until we look into workarounds.
Chris Daltone4679fa2017-09-29 13:58:26 -0600409 fBlacklistCoverageCounting = true;
410 }
411
Eric Karl5c779752017-05-08 12:02:07 -0700412 if (!contextOptions.fAvoidStencilBuffers) {
413 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
414 this->initFSAASupport(contextOptions, ctxInfo, gli);
415 this->initStencilSupport(ctxInfo);
416 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400417
418 // Setup blit framebuffer
419 if (kGL_GrGLStandard != ctxInfo.standard()) {
420 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
421 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
422 kNoMSAADst_BlitFramebufferFlag |
423 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
424 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
425 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
426 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
427 // limitations.
428 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
429 kResolveMustBeFull_BlitFrambufferFlag |
430 kNoMSAADst_BlitFramebufferFlag |
431 kNoFormatConversion_BlitFramebufferFlag |
432 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
433 }
434 } else {
435 if (fUsesMixedSamples ||
436 ctxInfo.version() >= GR_GL_VER(3,0) ||
437 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
438 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
439 fBlitFramebufferFlags = 0;
440 }
441 }
442
cdalton1dd05422015-06-12 09:01:18 -0700443 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000444
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000445 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000446 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
447 // extension includes glMapBuffer.
448 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
449 fMapBufferFlags |= kSubset_MapFlag;
450 fMapBufferType = kMapBufferRange_MapBufferType;
451 } else {
452 fMapBufferType = kMapBuffer_MapBufferType;
453 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000454 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000455 // Unextended GLES2 doesn't have any buffer mapping.
456 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800457 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800458 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
459 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800460 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
461 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
462 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000463 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
464 fMapBufferFlags = kCanMap_MapFlag;
465 fMapBufferType = kMapBuffer_MapBufferType;
466 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000467 }
468
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400469#if defined(__has_feature)
470#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
471 // See skbug.com/7058
472 fMapBufferType = kNone_MapBufferType;
473 fMapBufferFlags = kNone_MapFlags;
474#endif
475#endif
476
Brian Salomone03a7292017-06-08 11:00:50 -0400477 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
478 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
479 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
480 // unclear whether this really affects a wide range of devices.
481 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer && ctxInfo.driver() == kQualcomm_GrGLDriver &&
482 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0)) {
483 fMapBufferType = kNone_MapBufferType;
484 fMapBufferFlags = kNone_MapFlags;
485 }
486
jvanverthd7a2c1f2015-12-07 07:36:44 -0800487 if (kGL_GrGLStandard == standard) {
488 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
489 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700490 }
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400491 } else if (kANGLE_GrGLDriver != ctxInfo.driver()) { // TODO: re-enable for ANGLE
492 if (version >= GR_GL_VER(3, 0) ||
493 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
494 // GL_EXT_unpack_subimage needed to support subtexture rectangles
495 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800496 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400497// TODO: get transfer buffers working in Chrome
498// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
499// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800500 }
501 }
502
joshualitte5b74c62015-06-01 14:17:47 -0700503 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
504 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700505 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700506#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500507 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
508 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
509 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700510 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700511#else
cdalton397536c2016-03-25 12:15:03 -0700512 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700513#endif
joshualitte5b74c62015-06-01 14:17:47 -0700514 }
515
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000516 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000517 fNPOTTextureTileSupport = true;
518 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000519 } else {
520 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000521 // ES3 has no limitations.
522 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
523 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000524 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
525 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
526 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
527 // to alllow arbitrary wrap modes, however.
528 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000529 }
530
bsalomone72bd022015-10-26 07:33:03 -0700531 // Using MIPs on this GPU seems to be a source of trouble.
532 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
533 fMipMapSupport = false;
534 }
535
bsalomon@google.combcce8922013-03-25 15:38:39 +0000536 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
537 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
538 // Our render targets are always created with textures as the color
539 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000540 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000541
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000542 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
543
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000544 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700545 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000546
robertphillips1b8e1b52015-06-24 06:54:10 -0700547#if 0
548 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
549 kQualcomm_GrGLVendor != ctxInfo.vendor();
550#endif
551
csmartdalton9bc11872016-08-09 12:42:47 -0700552 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
553 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700554 }
555
Chris Dalton584a79a2017-11-15 13:14:01 -0700556 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
557 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
558 // around a driver bug related to gl_FragCoord.
559 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
560 fMaxClipAnalyticFPs = 0;
561 }
562
Brian Salomon35c886b2017-11-01 19:10:33 -0400563#ifndef SK_BUILD_FOR_IOS
bsalomon63b21962014-11-05 07:05:34 -0800564 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800565 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
Brian Salomon1b52df32017-03-24 18:49:09 -0400566 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
567 ctxInfo.driver() != kChromium_GrGLDriver)) {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400568 fUseDrawToClearColor = true;
bsalomon63b21962014-11-05 07:05:34 -0800569 }
Brian Salomon35c886b2017-11-01 19:10:33 -0400570#endif
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400571
Robert Phillipsdbfecd02017-10-18 15:44:08 -0400572 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
573 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
574 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
575 fUseDrawToClearColor = true;
576 }
577
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400578#ifdef SK_BUILD_FOR_MAC
579 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
580 // full screen clears
Robert Phillips7f9b2152017-10-11 16:57:05 -0400581 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
582 // perform full screen clears.
583 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400584 fUseDrawToClearColor = true;
Robert Phillipsa2fd62a2017-10-05 12:46:21 -0400585 }
586#endif
587
Brian Salomon266ef6d2017-09-22 11:27:42 -0400588 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
589 // bugs seems to involve clearing too much and not skipping the clear.
Ben Wagner63fd7602017-10-09 15:45:33 -0400590 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
Robert Phillips3a930532017-10-04 18:03:24 -0400591 // but only for D3D11 ANGLE.
592 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400593 fUseDrawToClearColor = true;
Brian Salomon266ef6d2017-09-22 11:27:42 -0400594 }
bsalomon63b21962014-11-05 07:05:34 -0800595
joshualitt83bc2292015-06-18 14:18:02 -0700596 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomonb52fa022017-06-07 09:42:52 -0400597 // This is known to be fixed sometime between driver 145.0 and 219.0
598 if (ctxInfo.driver() == kQualcomm_GrGLDriver &&
599 ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0)) {
600 fUseDrawToClearStencilClip = true;
601 }
Brian Salomon9bada542017-06-12 12:09:30 -0400602 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
joshualitt83bc2292015-06-18 14:18:02 -0700603 }
604
Brian Salomonaf971de2017-06-08 16:11:33 -0400605 // This was reproduced on the following configurations:
606 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
607 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
608 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400609 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
Brian Salomonaf971de2017-06-08 16:11:33 -0400610 // and not produced on:
611 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400612 // The particular lines that get dropped from test images varies across different devices.
Brian Salomonaf971de2017-06-08 16:11:33 -0400613 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() && kQualcomm_GrGLDriver == ctxInfo.driver() &&
614 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0)) {
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400615 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
Brian Salomonaf971de2017-06-08 16:11:33 -0400616 }
617
Chris Daltoncc604e52017-10-06 16:27:32 -0600618 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
619 // given 1 << 15 or more instances.
620 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
621 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
622 }
623
bsalomonbabafcc2016-02-16 11:36:47 -0800624 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
625 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon9bada542017-06-12 12:09:30 -0400626 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
bsalomonbabafcc2016-02-16 11:36:47 -0800627 fUseDrawInsteadOfAllRenderTargetWrites = true;
628 }
629
robertphillips63926682015-08-20 09:39:02 -0700630#ifdef SK_BUILD_FOR_WIN
631 // On ANGLE deferring flushes can lead to GPU starvation
632 fPreferVRAMUseOverFlushes = !isANGLE;
633#endif
634
bsalomon7dea7b72015-08-19 08:26:51 -0700635 if (kChromium_GrGLDriver == ctxInfo.driver()) {
636 fMustClearUploadedBufferData = true;
637 }
638
bsalomond08ea5f2015-02-20 06:58:13 -0800639 if (kGL_GrGLStandard == standard) {
640 // ARB allows mixed size FBO attachments, EXT does not.
641 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
642 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
643 fOversizedStencilSupport = true;
644 } else {
645 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
646 }
647 } else {
648 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
649 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
650 }
651
joshualitt58001552015-06-26 12:46:36 -0700652 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700653 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
654 ctxInfo.hasExtension("GL_ARB_draw_indirect");
655 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
656 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700657 (fDrawIndirectSupport &&
658 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700659 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700660 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800661 } else {
662 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700663 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
664 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
665 fBaseInstanceSupport = fDrawIndirectSupport &&
666 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700667 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800668 }
669
ethannicholas28ef4452016-03-25 09:26:03 -0700670 if (kGL_GrGLStandard == standard) {
Greg Daniela5cb7812017-06-16 09:45:32 -0400671 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
ethannicholas6536ae52016-05-02 12:16:49 -0700672 ctxInfo.vendor() != kIntel_GrGLVendor) {
ethannicholas28ef4452016-03-25 09:26:03 -0700673 fSampleShadingSupport = true;
674 }
675 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
676 fSampleShadingSupport = true;
677 }
678
jvanverth84741b32016-09-30 08:39:02 -0700679 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
680 if (kGL_GrGLStandard == standard) {
681 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
682 fFenceSyncSupport = true;
683 }
Brian Osman93a23462017-06-21 15:13:39 -0400684 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700685 fFenceSyncSupport = true;
686 }
687
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400688 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500689 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500690
brianosman131ff132016-06-07 14:22:44 -0700691 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
692 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
693 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
694 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
brianosman09563ce2016-06-02 08:59:34 -0700695 if (fMipMapLevelAndLodControlSupport &&
brianosman9a3fbf72016-06-09 13:11:08 -0700696 (contextOptions.fDoManualMipmapping ||
697 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
brianosman131ff132016-06-07 14:22:44 -0700698 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
699 (kATI_GrGLVendor == ctxInfo.vendor()))) {
brianosman09563ce2016-06-02 08:59:34 -0700700 fDoManualMipmapping = true;
701 }
702
brianosman20471892016-12-02 06:43:32 -0800703 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
brianosman851c2382016-12-07 10:03:25 -0800704 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
705 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800706
Brian Salomon028a9a52017-05-11 11:39:08 -0400707 // See http://crbug.com/710443
708#ifdef SK_BUILD_FOR_MAC
709 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
Eric Karlaeaf22b2017-05-18 15:08:09 -0700710 fClearToBoundaryValuesIsBroken = true;
Brian Salomon028a9a52017-05-11 11:39:08 -0400711 }
712#endif
Chris Dalton9926f4b2017-05-17 15:15:50 -0600713 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
714 fDrawArraysBaseVertexIsBroken = true;
715 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400716
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400717 if (kGL_GrGLStandard == standard) {
718 if (version >= GR_GL_VER(4, 1)) {
719 fProgramBinarySupport = true;
720 }
721 } else if (version >= GR_GL_VER(3, 0)) {
722 fProgramBinarySupport = true;
723 }
724
bsalomoncdee0092016-01-08 13:20:12 -0800725 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
726 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800727 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700728
729 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500730 shaderCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000731}
732
egdaniel472d44e2015-10-22 08:20:00 -0700733const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
734 bool isCoreProfile) {
735 switch (generation) {
736 case k110_GrGLSLGeneration:
737 if (kGLES_GrGLStandard == standard) {
738 // ES2s shader language is based on version 1.20 but is version
739 // 1.00 of the ES language.
740 return "#version 100\n";
741 } else {
742 SkASSERT(kGL_GrGLStandard == standard);
743 return "#version 110\n";
744 }
745 case k130_GrGLSLGeneration:
746 SkASSERT(kGL_GrGLStandard == standard);
747 return "#version 130\n";
748 case k140_GrGLSLGeneration:
749 SkASSERT(kGL_GrGLStandard == standard);
750 return "#version 140\n";
751 case k150_GrGLSLGeneration:
752 SkASSERT(kGL_GrGLStandard == standard);
753 if (isCoreProfile) {
754 return "#version 150\n";
755 } else {
756 return "#version 150 compatibility\n";
757 }
758 case k330_GrGLSLGeneration:
759 if (kGLES_GrGLStandard == standard) {
760 return "#version 300 es\n";
761 } else {
762 SkASSERT(kGL_GrGLStandard == standard);
763 if (isCoreProfile) {
764 return "#version 330\n";
765 } else {
766 return "#version 330 compatibility\n";
767 }
768 }
cdalton33ad7012016-02-22 07:55:44 -0800769 case k400_GrGLSLGeneration:
770 SkASSERT(kGL_GrGLStandard == standard);
771 if (isCoreProfile) {
772 return "#version 400\n";
773 } else {
774 return "#version 400 compatibility\n";
775 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500776 case k420_GrGLSLGeneration:
777 SkASSERT(kGL_GrGLStandard == standard);
778 if (isCoreProfile) {
779 return "#version 420\n";
780 }
781 else {
782 return "#version 420 compatibility\n";
783 }
egdaniel472d44e2015-10-22 08:20:00 -0700784 case k310es_GrGLSLGeneration:
785 SkASSERT(kGLES_GrGLStandard == standard);
786 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800787 case k320es_GrGLSLGeneration:
788 SkASSERT(kGLES_GrGLStandard == standard);
789 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700790 }
791 return "<no version>";
792}
793
Chris Dalton47c8ed32017-11-15 18:27:09 -0700794bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
795 if (kGLES_GrGLStandard != ctxInfo.standard() &&
796 ctxInfo.version() < GR_GL_VER(4,1) &&
797 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
798 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
799 return true;
800 }
801 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
802 // geometry shaders don't have lower precision than vertex and fragment.
803 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
804 GrGLint range[2];
805 GrGLint bits;
806 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
807 if (range[0] < 127 || range[1] < 127 || bits < 23) {
808 return false;
809 }
810 }
811 return true;
812}
813
814void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700815 GrGLStandard standard = ctxInfo.standard();
816 GrGLVersion version = ctxInfo.version();
817
818 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500819 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700820 **************************************************************************/
821
Brian Salomon1edc5b92016-11-29 13:43:46 -0500822 GrShaderCaps* shaderCaps = fShaderCaps.get();
823 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700824 if (kGLES_GrGLStandard == standard) {
825 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500826 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
827 shaderCaps->fFBFetchSupport = true;
828 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
829 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700830 }
831 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
832 // 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 -0500833 shaderCaps->fFBFetchNeedsCustomOutput = false;
834 shaderCaps->fFBFetchSupport = true;
835 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
836 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700837 }
838 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
839 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500840 shaderCaps->fFBFetchNeedsCustomOutput = false;
841 shaderCaps->fFBFetchSupport = true;
842 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
843 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700844 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500845 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700846 }
847
egdaniel7517e452016-09-20 13:00:26 -0700848 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
849 // Galaxy S7.
850 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
851 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500852 shaderCaps->fFBFetchSupport = false;
egdaniel7517e452016-09-20 13:00:26 -0700853 }
854
Brian Salomon1edc5b92016-11-29 13:43:46 -0500855 shaderCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
egdaniel472d44e2015-10-22 08:20:00 -0700856
cdaltonc08f1962016-02-12 12:14:06 -0800857 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500858 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800859 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500860 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800861 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
862 }
Brian Salomon41274562017-09-15 09:40:03 -0700863 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
864 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
865 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800866 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500867 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800868 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
869 } else {
870 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500871 shaderCaps->fNoPerspectiveInterpolationSupport = true;
872 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800873 "GL_NV_shader_noperspective_interpolation";
874 }
875 }
876
cdalton33ad7012016-02-22 07:55:44 -0800877 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500878 shaderCaps->fMultisampleInterpolationSupport =
cdalton4a98cdb2016-03-01 12:12:20 -0800879 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
880 } else {
881 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500882 shaderCaps->fMultisampleInterpolationSupport = true;
cdalton4a98cdb2016-03-01 12:12:20 -0800883 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500884 shaderCaps->fMultisampleInterpolationSupport = true;
885 shaderCaps->fMultisampleInterpolationExtensionString =
cdalton4a98cdb2016-03-01 12:12:20 -0800886 "GL_OES_shader_multisample_interpolation";
887 }
888 }
889
890 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500891 shaderCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
cdalton33ad7012016-02-22 07:55:44 -0800892 } else {
893 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500894 shaderCaps->fSampleVariablesSupport = true;
cdalton33ad7012016-02-22 07:55:44 -0800895 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500896 shaderCaps->fSampleVariablesSupport = true;
897 shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
cdalton33ad7012016-02-22 07:55:44 -0800898 }
899 }
900
Brian Salomon1edc5b92016-11-29 13:43:46 -0500901 if (shaderCaps->fSampleVariablesSupport &&
csmartdaltonf848c9c2016-06-15 12:42:13 -0700902 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
903 // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500904 shaderCaps->fSampleMaskOverrideCoverageSupport =
csmartdaltonf848c9c2016-06-15 12:42:13 -0700905 kNVIDIA_GrGLDriver != ctxInfo.driver() ||
906 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
cdalton33ad7012016-02-22 07:55:44 -0800907 }
908
egdaniel472d44e2015-10-22 08:20:00 -0700909 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
Brian Salomon1edc5b92016-11-29 13:43:46 -0500910 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700911
912 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
913 // function that may require a gradient calculation inside a conditional block may return
914 // undefined results". This appears to be an issue with the 'any' call since even the simple
915 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
916 // from our GrTextureDomain processor.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500917 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700918
Brian Salomon1edc5b92016-11-29 13:43:46 -0500919 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
920 shaderCaps->fGLSLGeneration,
921 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800922
Brian Salomon1edc5b92016-11-29 13:43:46 -0500923 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
924 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800925 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800926
927 // Frag Coords Convention support is not part of ES
928 // Known issue on at least some Intel platforms:
929 // http://code.google.com/p/skia/issues/detail?id=946
930 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
931 kGLES_GrGLStandard != standard &&
932 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
933 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500934 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800935 }
936
937 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500938 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800939 }
940
cdalton9c3f1432016-03-11 10:07:37 -0800941 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
942 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500943 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800944 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
945 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
946 // At least one driver has been found that has this extension without the "GL_" prefix.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500947 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800948 }
949 }
950
Brian Salomon1edc5b92016-11-29 13:43:46 -0500951 if (shaderCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800952 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500953 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
bsalomon7ea33f52015-11-22 14:51:00 -0800954 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500955 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800956 }
957 }
958
cdaltonc04ce672016-03-11 14:07:38 -0800959 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500960 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800961 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500962 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700963 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
964 }
965
Brian Salomon1edc5b92016-11-29 13:43:46 -0500966 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700967 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500968 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700969 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
970 } else {
971 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
972 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500973 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700974 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500975 shaderCaps->fTexelBufferSupport = true;
976 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700977 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500978 shaderCaps->fTexelBufferSupport = true;
979 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700980 }
cdaltonc04ce672016-03-11 14:07:38 -0800981 }
982 }
983
Chris Dalton1d616352017-05-31 12:51:23 -0600984 if (kGL_GrGLStandard == standard) {
985 shaderCaps->fVertexIDSupport = true;
986 } else {
987 // Desktop GLSL 3.30 == ES GLSL 3.00.
988 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
989 }
990
Chris Dalton47c8ed32017-11-15 18:27:09 -0700991 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
992 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
993
egdaniel8dcdedc2015-11-11 06:27:20 -0800994 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Florin Malita8a0044f2017-08-07 14:38:22 -0400995 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
996 // so we must do the abs first in a separate expression.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500997 shaderCaps->fCanUseMinAndAbsTogether = false;
Florin Malita8a0044f2017-08-07 14:38:22 -0400998
999 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
1000 // must avoid this condition.
1001 shaderCaps->fCanUseFractForNegativeValues = false;
egdaniel8dcdedc2015-11-11 06:27:20 -08001002 }
1003
bsalomon7ea33f52015-11-22 14:51:00 -08001004 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
egdaniel8dcdedc2015-11-11 06:27:20 -08001005 // thus must us -1.0 * %s.x to work correctly
1006 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001007 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
egdaniel8dcdedc2015-11-11 06:27:20 -08001008 }
egdaniel138c2632016-08-17 10:59:00 -07001009
Greg Daniel10ed2432017-12-01 16:19:43 -05001010 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
1011 // when floor and abs are called on the same line. Thus we must execute an Op between them to
1012 // make sure the compiler doesn't re-inline them even if we break the calls apart.
1013 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1014 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
1015 }
1016
egdaniel138c2632016-08-17 10:59:00 -07001017 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
1018 // the original dst color when reading the outColor even after being written to. By using a
1019 // local outColor we can work around this bug.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001020 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
1021 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
egdaniel138c2632016-08-17 10:59:00 -07001022 }
csmartdalton2e777ea2017-02-15 10:41:27 -07001023
Brian Osmanac1e4962017-05-25 11:34:38 -04001024 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
1025 // color, and that uniform contains an opaque color, and the output of the shader is only based
1026 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
1027 // that the shader always outputs opaque values. In that case, it appears to remove the shader
1028 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
1029 // insert an extra bit of math on the uniform that confuses the compiler just enough...
1030 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
1031 shaderCaps->fMustObfuscateUniformColor = true;
1032 }
Brian Osmandff5d432017-08-01 14:46:18 -04001033
1034#ifdef SK_BUILD_FOR_WIN
1035 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
1036 //
1037 // Basically, if a shader has a construct like:
1038 //
1039 // float x = someCondition ? someValue : 0;
1040 // float2 result = (0 == x) ? float2(x, x)
1041 // : float2(2 * x / x, 0);
1042 //
1043 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
1044 // we've explicitly guarded the division with a check against zero. This manifests in much
1045 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
1046 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
1047 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
1048 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
1049 }
1050#endif
egdaniel472d44e2015-10-22 08:20:00 -07001051}
1052
kkinnunencfe62e32015-07-01 02:58:50 -07001053bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -07001054 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
1055
1056 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -07001057 return false;
1058 }
kkinnunen6bb6d402015-07-14 10:59:23 -07001059
kkinnunencfe62e32015-07-01 02:58:50 -07001060 if (kGL_GrGLStandard == ctxInfo.standard()) {
1061 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
1062 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
1063 return false;
1064 }
1065 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -07001066 if (!hasChromiumPathRendering &&
1067 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -07001068 return false;
1069 }
1070 }
1071 // We only support v1.3+ of GL_NV_path_rendering which allows us to
1072 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
1073 // additions are detected by checking the existence of the function.
1074 // We also use *Then* functions that not all drivers might have. Check
1075 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -08001076 if (!gli->fFunctions.fStencilThenCoverFillPath ||
1077 !gli->fFunctions.fStencilThenCoverStrokePath ||
1078 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
1079 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
1080 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -07001081 return false;
1082 }
1083 return true;
1084}
bsalomon1aa20292016-01-22 08:16:09 -08001085
Brian Salomon71d9d842016-11-03 13:42:00 -04001086bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -08001087 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -08001088 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -08001089 std::function<bool ()> bindRenderTarget,
1090 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -04001091 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -08001092 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -04001093 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -08001094 return false;
1095 }
bsalomon7928ef62016-01-05 10:26:39 -08001096
Brian Salomonbf7b6202016-11-11 16:08:03 -05001097 if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
1098 return false;
1099 }
1100
bsalomon76148af2016-01-12 11:13:47 -08001101 GrGLenum readFormat;
1102 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -04001103 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -08001104 return false;
1105 }
1106
bsalomon1aa20292016-01-22 08:16:09 -08001107 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -08001108 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
1109 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
1110 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
1111 // 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 -05001112 // The manual does not seem to fully match the spec as the spec allows integer formats
1113 // when the bound color buffer is an integer buffer. It doesn't specify which integer
1114 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -05001115 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
1116 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
1117 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -08001118 return false;
1119 }
1120 // There is also a set of allowed types, but all the types we use are in the set:
1121 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
1122 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
1123 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
1124 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
1125 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
1126 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
1127 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -08001128 return true;
piotaixre4b23142014-10-02 10:57:53 -07001129 }
bsalomon7928ef62016-01-05 10:26:39 -08001130
bsalomon76148af2016-01-12 11:13:47 -08001131 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -05001132 switch (fConfigTable[surfaceConfig].fFormatType) {
1133 case kNormalizedFixedPoint_FormatType:
1134 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
1135 return true;
1136 }
1137 break;
1138 case kInteger_FormatType:
1139 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
1140 return true;
1141 }
1142 break;
1143 case kFloat_FormatType:
1144 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
1145 return true;
1146 }
1147 break;
bsalomon7928ef62016-01-05 10:26:39 -08001148 }
1149
Brian Salomon71d9d842016-11-03 13:42:00 -04001150 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -08001151 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -04001152 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -08001153 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -08001154 if (!bindRenderTarget()) {
1155 return false;
1156 }
1157 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
1158 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -08001159 rpFormat->fFormat = format;
1160 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -08001161 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -08001162 }
1163
Brian Salomon71d9d842016-11-03 13:42:00 -04001164 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
1165 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -07001166}
1167
Eric Karl5c779752017-05-08 12:02:07 -07001168void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
1169 const GrGLInterface* gli) {
1170 // We need dual source blending and the ability to disable multisample in order to support mixed
1171 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
1172 // renderer is available and enabled; no other path renderers support this feature.
1173 if (fMultisampleDisableSupport &&
1174 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -04001175 this->shaderCaps()->pathRenderingSupport()
1176#if GR_TEST_UTILS
1177 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
1178#endif
1179 ) {
Eric Karl5c779752017-05-08 12:02:07 -07001180 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -04001181 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -07001182 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
1183 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
1184 kChromium_GrGLDriver == ctxInfo.driver())) {
1185 fDiscardRenderTargetSupport = false;
1186 fInvalidateFBType = kNone_InvalidateFBType;
1187 }
1188 }
1189
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001190 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -04001191 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
1192 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
1193 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
1194 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
1195 fAlpha8IsRenderable = true;
1196 }
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001197 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
1198 // ES3 driver bugs on at least one device with a tiled GPU (N10).
1199 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1200 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1201 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1202 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -08001203 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001204 fMSFBOType = kMixedSamples_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001205 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1206 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001207 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -04001208 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001209 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001210 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001211 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1212 fMSFBOType = kES_Apple_MSFBOType;
1213 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001214 } else {
egdanieleed519e2016-01-15 11:36:18 -08001215 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001216 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -04001217 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1218 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001219
Brian Salomon00731b42016-10-14 11:30:51 -04001220 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001221 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
1222 // Core profile removes ALPHA8 support.
1223 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1224 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
1225 // present.
1226 fAlpha8IsRenderable = true;
1227 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001228 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1229 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001230 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001231 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001232 }
Eric Karl5c779752017-05-08 12:02:07 -07001233
Robert Phillips3b3307f2017-05-24 07:44:02 -04001234 // We disable MSAA across the board for Intel GPUs
1235 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1236 fMSFBOType = kNone_MSFBOType;
1237 }
1238
Eric Karl5c779752017-05-08 12:02:07 -07001239 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
1240 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
1241 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
1242 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
1243 }
1244 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1245 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1246 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
1247 // This is to guard against platforms that may not support as many samples for
1248 // glRasterSamples as they do for framebuffers.
1249 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
1250 }
1251 fMaxColorSampleCount = fMaxStencilSampleCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001252}
1253
cdalton1dd05422015-06-12 09:01:18 -07001254void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001255 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001256
1257 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
1258 // for now until its own blacklists can be updated.
1259 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
Greg Daniel0ea7d432016-10-27 16:55:52 -04001260 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
cdalton1dd05422015-06-12 09:01:18 -07001261 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -07001262 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -07001263 return;
1264 }
1265
Greg Daniel210883c2017-11-27 15:14:01 -05001266 bool layoutQualifierSupport = false;
1267 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
1268 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1269 layoutQualifierSupport = true;
1270 }
1271
cdalton1dd05422015-06-12 09:01:18 -07001272 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1273 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001274 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001275 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1276 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001277 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001278 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001279 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1280 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1281 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1282 return;
1283 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1284 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001285 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001286 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001287 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001288 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001289 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1290 // slow on a particular platform.
1291 } else {
1292 return; // No advanced blend support.
1293 }
1294
1295 SkASSERT(this->advancedBlendEquationSupport());
1296
csmartdalton3b88a032016-08-04 14:43:49 -07001297 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1298 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1299 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
cdalton1dd05422015-06-12 09:01:18 -07001300 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1301 (1 << kColorBurn_GrBlendEquation);
1302 }
joel.liang9764c402015-07-09 19:46:18 -07001303 if (kARM_GrGLVendor == ctxInfo.vendor()) {
1304 // Blacklist color-burn on ARM until the fix is released.
1305 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1306 }
cdalton1dd05422015-06-12 09:01:18 -07001307}
1308
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001309namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001310const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001311}
1312
Eric Karl5c779752017-05-08 12:02:07 -07001313void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001314
1315 // Build up list of legal stencil formats (though perhaps not supported on
1316 // the particular gpu/driver) from most preferred to least.
1317
1318 // these consts are in order of most preferred to least preferred
1319 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1320
1321 static const StencilFormat
1322 // internal Format stencil bits total bits packed?
1323 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1324 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1325 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1326 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001327 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001328 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1329
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001330 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001331 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001332 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001333 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1334 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1335
1336 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1337 // require FBO support we can expect these are legal formats and don't
1338 // check. These also all support the unsized GL_STENCIL_INDEX.
1339 fStencilFormats.push_back() = gS8;
1340 fStencilFormats.push_back() = gS16;
1341 if (supportsPackedDS) {
1342 fStencilFormats.push_back() = gD24S8;
1343 }
1344 fStencilFormats.push_back() = gS4;
1345 if (supportsPackedDS) {
1346 fStencilFormats.push_back() = gDS;
1347 }
1348 } else {
1349 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1350 // for other formats.
1351 // ES doesn't support using the unsized format.
1352
1353 fStencilFormats.push_back() = gS8;
1354 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001355 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1356 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001357 fStencilFormats.push_back() = gD24S8;
1358 }
1359 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1360 fStencilFormats.push_back() = gS4;
1361 }
1362 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001363}
1364
Brian Osman71a18892017-08-10 10:23:25 -04001365void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001366
Brian Osman71a18892017-08-10 10:23:25 -04001367 // We are called by the base class, which has already called beginObject(). We choose to nest
1368 // all of our caps information in a named sub-object.
1369 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001370
Brian Osman71a18892017-08-10 10:23:25 -04001371 writer->beginArray("Stencil Formats");
1372
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001373 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001374 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001375 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1376 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1377 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001378 }
1379
Brian Osman71a18892017-08-10 10:23:25 -04001380 writer->endArray();
1381
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001382 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001383 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001384 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001385 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001386 "IMG MS To Texture",
1387 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001388 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001389 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001390 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001391 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1392 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1393 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1394 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1395 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001396 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001397
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001398 static const char* kInvalidateFBTypeStr[] = {
1399 "None",
1400 "Discard",
1401 "Invalidate",
1402 };
1403 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1404 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1405 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1406 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001407
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001408 static const char* kMapBufferTypeStr[] = {
1409 "None",
1410 "MapBuffer",
1411 "MapBufferRange",
1412 "Chromium",
1413 };
1414 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1415 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1416 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1417 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1418 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1419
Brian Osman71a18892017-08-10 10:23:25 -04001420 writer->appendBool("Core Profile", fIsCoreProfile);
1421 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1422 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1423 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1424 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1425 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1426 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1427 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1428 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001429
Brian Osman71a18892017-08-10 10:23:25 -04001430 writer->appendBool("Texture Usage support", fTextureUsageSupport);
1431 writer->appendBool("GL_R support", fTextureRedSupport);
1432 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1433 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1434 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
1435 writer->appendBool("Direct state access support", fDirectStateAccessSupport);
1436 writer->appendBool("Debug support", fDebugSupport);
1437 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1438 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1439 writer->appendBool("Base instance support", fBaseInstanceSupport);
1440 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1441 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1442 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1443 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1444 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1445 writer->appendBool("BGRA to RGBA readback conversions are slow",
1446 fRGBAToBGRAReadbackConversionsAreSlow);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001447 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1448 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001449 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1450 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1451 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1452 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001453 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1454 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001455
Brian Osman71a18892017-08-10 10:23:25 -04001456 writer->beginArray("configs");
1457
bsalomon41e4384e2016-01-08 09:12:44 -08001458 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001459 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001460 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1461 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1462 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
1463 writer->appendHexU32("e_format",
1464 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage]);
1465 writer->appendHexU32(
1466 "e_format_teximage",
1467 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1468 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1469 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1470 writer->appendHexU32("i_for_renderbuffer",
1471 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1472 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001473 }
1474
Brian Osman71a18892017-08-10 10:23:25 -04001475 writer->endArray();
1476 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001477}
1478
bsalomon41e4384e2016-01-08 09:12:44 -08001479bool GrGLCaps::bgraIsInternalFormat() const {
1480 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1481}
1482
bsalomon76148af2016-01-12 11:13:47 -08001483bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1484 GrGLenum* internalFormat, GrGLenum* externalFormat,
1485 GrGLenum* externalType) const {
1486 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1487 externalFormat, externalType)) {
1488 return false;
1489 }
1490 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1491 return true;
1492}
1493
bsalomon76148af2016-01-12 11:13:47 -08001494bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1495 GrGLenum* externalFormat, GrGLenum* externalType) const {
1496 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1497 externalFormat, externalType)) {
1498 return false;
1499 }
1500 return true;
1501}
1502
1503bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001504 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1505 return true;
1506}
1507
1508bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1509 ExternalFormatUsage usage, GrGLenum* externalFormat,
1510 GrGLenum* externalType) const {
1511 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001512
1513 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1514 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1515
1516 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1517 // made to work in many cases using glPixelStore and what not but is not needed currently.
1518 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1519 return false;
1520 }
1521
1522 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1523 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1524
bsalomone9573312016-01-25 14:33:25 -08001525 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1526 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1527 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1528 // texture, not the red component.
1529 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1530 if (this->textureRedSupport()) {
1531 SkASSERT(GR_GL_RED == *externalFormat);
1532 *externalFormat = GR_GL_ALPHA;
1533 }
1534 }
1535
bsalomon76148af2016-01-12 11:13:47 -08001536 return true;
1537}
1538
brianosman20471892016-12-02 06:43:32 -08001539void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1540 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001541 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001542 /*
1543 Comments on renderability of configs on various GL versions.
1544 OpenGL < 3.0:
1545 no built in support for render targets.
1546 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1547 format RGB, RGBA and NV float formats we don't use.
1548 This is the following:
1549 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1550 RGB10_A2, RGBA12,RGBA16
1551 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1552 since they aren't required by later standards and the driver can simply return
1553 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1554 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1555 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1556 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1557 This adds a lot of additional renderable sized formats, including ALPHA8.
1558 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1559 16F, 32I, 32UI, and 32F variants).
1560 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1561
1562 For both the above extensions we limit ourselves to those that are also required by
1563 OpenGL 3.0.
1564
1565 OpenGL 3.0:
1566 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1567 but are not required to be supported as renderable textures/renderbuffer.
1568 Required renderable color formats:
1569 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1570 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1571 RGB10_A2.
1572 - R11F_G11F_B10F.
1573 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1574 and RG8UI.
1575 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1576 - ALPHA8
1577
1578 OpenGL 3.1, 3.2, 3.3
1579 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1580 OpengGL 3.3, 4.0, 4.1
1581 Adds RGB10_A2UI.
1582 OpengGL 4.2
1583 Adds
1584 - RGB5_A1, RGBA4
1585 - RGB565
1586 OpenGL 4.4
1587 Does away with the separate list and adds a column to the sized internal color format
1588 table. However, no new formats become required color renderable.
1589
1590 ES 2.0
1591 color renderable: RGBA4, RGB5_A1, RGB565
1592 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1593 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1594 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1595 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1596 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1597 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1598
1599 ES 3.0
1600 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1601 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1602 RGB5_A1.
1603 - RGB8 and RGB565.
1604 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1605 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1606 ES 3.1
1607 Adds RGB10_A2, RGB10_A2UI,
1608 ES 3.2
1609 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1610 */
Brian Salomon71d9d842016-11-03 13:42:00 -04001611 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1612 ConfigInfo::kFBOColorAttachment_Flag;
1613 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001614 if (kNone_MSFBOType != fMSFBOType) {
1615 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1616 }
bsalomon41e4384e2016-01-08 09:12:44 -08001617 GrGLStandard standard = ctxInfo.standard();
1618 GrGLVersion version = ctxInfo.version();
1619
cblume790d5132016-02-29 11:13:29 -08001620 bool texStorageSupported = false;
1621 if (kGL_GrGLStandard == standard) {
1622 // The EXT version can apply to either GL or GLES.
1623 texStorageSupported = version >= GR_GL_VER(4,2) ||
1624 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1625 ctxInfo.hasExtension("GL_EXT_texture_storage");
1626 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001627 texStorageSupported = version >= GR_GL_VER(3,0) ||
1628 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001629 }
1630
1631 // TODO: remove after command buffer supports full ES 3.0
1632 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1633 kChromium_GrGLDriver == ctxInfo.driver()) {
1634 texStorageSupported = false;
1635 }
1636
cdalton74b8d322016-04-11 14:47:28 -07001637 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1638
bsalomon30447372015-12-21 09:03:05 -08001639 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1640 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001641 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001642 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001643 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001644 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001645
1646 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1647 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001648 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1649 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001650 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001651 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001652 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1653 if (kGL_GrGLStandard == standard) {
1654 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1655 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001656 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001657 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1658 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1659 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1660 }
egdaniel4999df82016-01-07 17:06:04 -08001661 }
cblume790d5132016-02-29 11:13:29 -08001662 if (texStorageSupported) {
1663 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1664 }
cdalton74b8d322016-04-11 14:47:28 -07001665 if (texelBufferSupport) {
1666 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1667 }
bsalomoncdee0092016-01-08 13:20:12 -08001668 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001669
bsalomon76148af2016-01-12 11:13:47 -08001670 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1671 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001672 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001673 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001674 if (kGL_GrGLStandard == standard) {
1675 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1676 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1677 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1678 // Since the internal format is RGBA8, it is also renderable.
1679 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1680 allRenderFlags;
1681 }
1682 } else {
1683 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1684 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1685 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001686 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1687 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1688 // driver remembers the external format when the texture is created (with TexImage).
1689 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1690 // We could work around this, but it adds even more state tracking to code that is
1691 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1692 // This also side-steps some ambiguous interactions with the texture storage extension.
1693 if (version >= GR_GL_VER(3,0)) {
1694 // The APPLE extension doesn't make this renderable.
1695 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon41e4384e2016-01-08 09:12:44 -08001696 }
1697 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1698 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001699 nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001700 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001701 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001702 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1703 ConfigInfo::kRenderableWithMSAA_Flag;
1704 }
1705 }
1706 }
Brian Osman48c99192017-06-02 08:45:06 -04001707
1708 bool isX86PowerVR = false;
1709#if defined(SK_CPU_X86)
1710 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1711 isX86PowerVR = true;
1712 }
1713#endif
1714
1715 // Adreno 3xx, 4xx, 5xx, and NexusPlayer all fail if we try to use TexStorage with BGRA
1716 if (texStorageSupported &&
1717 kAdreno3xx_GrGLRenderer != ctxInfo.renderer() &&
1718 kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1719 kAdreno5xx_GrGLRenderer != ctxInfo.renderer() &&
1720 !isX86PowerVR) {
1721 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001722 }
bsalomoncdee0092016-01-08 13:20:12 -08001723 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001724
brianosmana6359362016-03-21 06:55:37 -07001725 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001726 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001727 if (kGL_GrGLStandard == standard) {
1728 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001729 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001730 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1731 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1732 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001733 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001734 }
1735 }
1736 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001737 if (fSRGBSupport) {
1738 fSRGBWriteControl = true;
1739 }
bsalomon41e4384e2016-01-08 09:12:44 -08001740 } else {
brianosman20471892016-12-02 06:43:32 -08001741 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Osman48c99192017-06-02 08:45:06 -04001742 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1743 // blacklist that device (and any others that might be sharing the same driver).
1744 if (isX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001745 fSRGBSupport = false;
1746 }
bsalomon41e4384e2016-01-08 09:12:44 -08001747 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1748 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001749 // See https://bug.skia.org/5329 for Adreno4xx issue.
1750 fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1751 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001752 }
brianosman20471892016-12-02 06:43:32 -08001753 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1754 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1755 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001756 fSRGBSupport = false;
1757 }
brianosman20471892016-12-02 06:43:32 -08001758
1759 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1760 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1761 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1762 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1763 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1764 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1765 // affects Windows.
1766 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1767 fSRGBSupport = false;
1768 }
1769
Brian Osman48c99192017-06-02 08:45:06 -04001770 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1771 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1772 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1773
Brian Osman67999392017-05-31 16:19:34 -04001774 uint32_t srgbRenderFlags = allRenderFlags;
1775 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers
1776#if defined(SK_BUILD_FOR_MAC)
1777 if (kATI_GrGLVendor == ctxInfo.vendor()) {
1778 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1779 }
1780#endif
1781
bsalomon30447372015-12-21 09:03:05 -08001782 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1783 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1784 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1785 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001786 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1787 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001788 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001789 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001790 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001791 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001792 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001793 }
Brian Osman48c99192017-06-02 08:45:06 -04001794 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1795 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001796 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1797 }
bsalomoncdee0092016-01-08 13:20:12 -08001798 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001799 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1800 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1801 // is in this format, for example).
1802 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1803 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1804 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1805 // external format is GL_BGRA.
1806 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1807 GR_GL_BGRA;
1808 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1809 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001810 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001811 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001812 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001813 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001814
brianosmana6359362016-03-21 06:55:37 -07001815 if (texStorageSupported) {
1816 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1817 }
1818 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1819
Brian Salomonbf7b6202016-11-11 16:08:03 -05001820 bool hasIntegerTextures;
1821 if (standard == kGL_GrGLStandard) {
1822 hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1823 ctxInfo.hasExtension("GL_EXT_texture_integer");
1824 } else {
1825 hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1826 }
1827 // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1828 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1829 hasIntegerTextures = false;
1830 }
1831 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1832 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1833 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1834 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1835 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1836 // We currently only support using integer textures as srcs, not for rendering (even though GL
1837 // allows it).
1838 if (hasIntegerTextures) {
1839 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1840 ConfigInfo::kFBOColorAttachment_Flag;
1841 if (texStorageSupported) {
1842 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1843 ConfigInfo::kCanUseTexStorage_Flag;
1844 }
1845 }
1846
bsalomon30447372015-12-21 09:03:05 -08001847 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1848 if (this->ES2CompatibilitySupport()) {
1849 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1850 } else {
1851 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1852 }
bsalomon76148af2016-01-12 11:13:47 -08001853 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1854 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001855 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001856 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001857 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1858 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001859 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001860 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1861 }
1862 } else {
1863 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1864 }
cblume790d5132016-02-29 11:13:29 -08001865 // 565 is not a sized internal format on desktop GL. So on desktop with
1866 // 565 we always use an unsized internal format to let the system pick
1867 // the best sized format to convert the 565 data to. Since TexStorage
1868 // only allows sized internal formats we disallow it.
1869 //
1870 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1871 // update.
1872 if (texStorageSupported && kGL_GrGLStandard != standard) {
1873 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1874 }
bsalomoncdee0092016-01-08 13:20:12 -08001875 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001876
1877 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1878 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001879 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1880 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001881 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001882 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001883 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1884 if (kGL_GrGLStandard == standard) {
1885 if (version >= GR_GL_VER(4, 2)) {
1886 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1887 }
1888 } else {
1889 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1890 }
cblume790d5132016-02-29 11:13:29 -08001891 if (texStorageSupported) {
1892 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1893 }
bsalomoncdee0092016-01-08 13:20:12 -08001894 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001895
Greg Danielef59d872017-11-17 16:47:21 -05001896 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1897 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1898
1899 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1900 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1901 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1902 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1903 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001904 }
Greg Danielef59d872017-11-17 16:47:21 -05001905 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1906 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
1907 alphaInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_ALPHA;
1908 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1909 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1910 alphaInfo.fFlags |= allRenderFlags;
1911 }
1912
1913 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1914 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1915 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1916 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1917 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
1918 redInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
1919 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001920
Brian Osman48c99192017-06-02 08:45:06 -04001921 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1922 if (texStorageSupported && !isCommandBufferES2) {
Greg Danielef59d872017-11-17 16:47:21 -05001923 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on Alpha8
1924 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1925 // check that we are not going to OpenGL.
1926 if (GrGLANGLEBackend::kOpenGL != ctxInfo.angleBackend()) {
1927 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1928 }
1929 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1930 }
1931
1932 if (this->textureRedSupport()) {
1933 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1934 if (texelBufferSupport) {
1935 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1936 }
1937
1938 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1939 } else {
1940 redInfo.fFlags = 0;
1941
1942 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001943 }
bsalomon41e4384e2016-01-08 09:12:44 -08001944
Greg Daniel7af060a2017-12-05 16:27:11 -05001945 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1946 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1947 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1948 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1949 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1950 grayLumInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_LUMINANCE;
1951 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1952 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1953 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1954 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001955 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001956
1957 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1958 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1959 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1960 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1961 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
1962 grayRedInfo.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
1963 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1964 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1965
1966#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1967 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001968 if (this->textureRedSupport() ||
1969 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1970 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1971 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1972 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1973 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1974 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1975 }
1976#endif
Brian Osman48c99192017-06-02 08:45:06 -04001977 if (texStorageSupported && !isCommandBufferES2) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001978 if (GrGLANGLEBackend::kOpenGL != ctxInfo.angleBackend()) {
1979 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1980 }
1981 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1982 }
1983
1984 if (this->textureRedSupport()) {
1985 if (texelBufferSupport) {
1986 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1987 }
1988 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1989 } else {
1990 grayRedInfo.fFlags = 0;
1991 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001992 }
1993
bsalomon41e4384e2016-01-08 09:12:44 -08001994 // Check for [half] floating point texture support
1995 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1996 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1997 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1998 bool hasFPTextures = false;
1999 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002000 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08002001 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04002002 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08002003
2004 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05002005 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08002006 hasFPTextures = true;
2007 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002008 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08002009 }
2010 } else {
Greg Danielef59d872017-11-17 16:47:21 -05002011 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08002012 hasFPTextures = true;
2013 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002014 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08002015 } else {
2016 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
2017 ctxInfo.hasExtension("GL_OES_texture_float")) {
2018 hasFPTextures = true;
2019 }
2020 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
2021 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
2022 hasHalfFPTextures = true;
2023 }
2024 }
2025 }
bsalomon30447372015-12-21 09:03:05 -08002026
csmartdalton6aa0e112017-02-08 16:14:11 -05002027 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
2028 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
2029 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
2030 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
2031 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
2032 fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
2033 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
2034 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
2035 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04002036 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05002037 // For now we only enable rendering to float on desktop, because on ES we'd have to
2038 // solve many precision issues and no clients actually want this yet.
2039 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
2040 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
2041 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
2042 }
bsalomon41e4384e2016-01-08 09:12:44 -08002043 }
csmartdalton6aa0e112017-02-08 16:14:11 -05002044 if (texStorageSupported) {
2045 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2046 }
2047 if (texelBufferSupport) {
2048 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
2049 }
2050 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08002051 }
bsalomon30447372015-12-21 09:03:05 -08002052
Greg Danielef59d872017-11-17 16:47:21 -05002053 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00002054 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05002055 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00002056 } else {
Greg Danielef59d872017-11-17 16:47:21 -05002057 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00002058 }
Greg Danielef59d872017-11-17 16:47:21 -05002059 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
2060 redHalf.fFormats.fExternalType = redHalfExternalType;
2061 redHalf.fFormatType = kFloat_FormatType;
2062 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
2063 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
2064 redHalf.fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED;
2065 redHalf.fSwizzle = GrSwizzle::RRRR();
2066 if (this->textureRedSupport() && hasHalfFPTextures) {
2067 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
2068
csmartdalton6aa0e112017-02-08 16:14:11 -05002069 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
2070 (this->textureRedSupport() &&
2071 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05002072 redHalf.fFlags |= fpRenderFlags;
2073 }
2074
2075 if (texStorageSupported && !isCommandBufferES2) {
2076 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2077 }
2078
2079 if (texelBufferSupport) {
2080 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05002081 }
2082 }
Greg Danielef59d872017-11-17 16:47:21 -05002083 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08002084
2085 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
2086 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08002087 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
2088 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04002089 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08002090 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
2091 } else {
2092 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
2093 }
bsalomon7928ef62016-01-05 10:26:39 -08002094 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08002095 if (hasHalfFPTextures) {
2096 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
2097 // ES requires 3.2 or EXT_color_buffer_half_float.
2098 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
2099 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
2100 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
2101 }
2102 }
cblume790d5132016-02-29 11:13:29 -08002103 if (texStorageSupported) {
2104 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2105 }
cdalton74b8d322016-04-11 14:47:28 -07002106 if (texelBufferSupport) {
2107 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
2108 }
bsalomoncdee0092016-01-08 13:20:12 -08002109 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08002110
bsalomon30447372015-12-21 09:03:05 -08002111 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
2112
2113 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08002114 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
2115 ctxInfo.version() >= GR_GL_VER(3,0));
2116 // All ES versions (thus far) require sized internal formats for render buffers.
2117 // TODO: Always use sized internal format?
2118 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
2119
bsalomon30447372015-12-21 09:03:05 -08002120 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08002121 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
2122 // param to glTex[Sub]Image.
2123 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
2124 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
2125 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
2126 fConfigTable[i].fFormats.fSizedInternalFormat :
2127 fConfigTable[i].fFormats.fBaseInternalFormat;
2128 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08002129 fConfigTable[i].fFormats.fSizedInternalFormat :
2130 fConfigTable[i].fFormats.fBaseInternalFormat;
2131 }
Greg Daniel8713b882017-10-26 15:15:47 -04002132 // Gallium llvmpipe renderer on ES 3.0 does not have R8 so we use Alpha for
2133 // kAlpha_8_GrPixelConfig. Alpha8 is not a valid signed internal format so we must use the base
2134 // internal format for that config when doing TexImage calls.
Greg Danielb07b06e2017-11-18 21:26:17 -05002135 if(kGalliumLLVM_GrGLRenderer == ctxInfo.renderer() && !this->textureRedSupport()) {
Greg Danielef59d872017-11-17 16:47:21 -05002136 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat ==
2137 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat);
Greg Daniel8713b882017-10-26 15:15:47 -04002138 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
2139 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05002140 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
2141 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04002142 }
2143
bsalomon30447372015-12-21 09:03:05 -08002144 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
2145 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
2146 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
2147 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
2148 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08002149 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08002150 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07002151
2152 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
2153 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
2154 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
2155 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08002156 }
2157
2158 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2159 // as a base format.
2160 // GL_EXT_texture_format_BGRA8888:
2161 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
2162 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
2163 // formats.
halcanary9d524f22016-03-29 09:03:52 -07002164 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08002165 // ES 2.0: the extension makes BGRA an external format but not an internal format.
2166 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
2167 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08002168 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08002169 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
2170 }
2171
bsalomoncdee0092016-01-08 13:20:12 -08002172 // If we don't have texture swizzle support then the shader generator must insert the
2173 // swizzle into shader code.
2174 if (!this->textureSwizzleSupport()) {
2175 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002176 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08002177 }
2178 }
2179
bsalomon7f9b2e42016-01-12 13:29:26 -08002180 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
2181 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
2182 // gets written to the single component.
2183 if (this->textureRedSupport()) {
2184 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2185 GrPixelConfig config = static_cast<GrPixelConfig>(i);
2186 if (GrPixelConfigIsAlphaOnly(config) &&
2187 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002188 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08002189 }
2190 }
2191 }
2192
Greg Daniel81e7bf82017-07-19 14:47:42 -04002193 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2194 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Greg Daniel6bd729d2017-07-31 09:38:23 -04002195 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04002196 (ctxInfo.version() >= GR_GL_VER(4,2) ||
2197 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04002198 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002199 int count;
2200 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
2201 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
2202 1, &count);
2203 if (count) {
2204 int* temp = new int[count];
2205 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
2206 temp);
2207 fConfigTable[i].fColorSampleCounts.setCount(count+1);
2208 // We initialize our supported values with 0 (no msaa) and reverse the order
2209 // returned by GL so that the array is ascending.
2210 fConfigTable[i].fColorSampleCounts[0] = 0;
2211 for (int j = 0; j < count; ++j) {
2212 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2213 }
2214 delete[] temp;
2215 }
2216 } else {
2217 static const int kDefaultSamples[] = {0,1,2,4,8};
2218 int count = SK_ARRAY_COUNT(kDefaultSamples);
2219 for (; count > 0; --count) {
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00002220 if (kDefaultSamples[count-1] <= fMaxColorSampleCount) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002221 break;
2222 }
2223 }
2224 if (count > 0) {
2225 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2226 }
2227 }
2228 }
2229 }
2230
bsalomon30447372015-12-21 09:03:05 -08002231#ifdef SK_DEBUG
2232 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002233 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002234 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002235 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2236 // renderable.
2237 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2238 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002239 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2240 fConfigTable[i].fFormats.fBaseInternalFormat);
2241 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002242 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002243 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2244 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2245 fConfigTable[i].fFormats.fExternalFormat[j]);
2246 }
2247 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002248 }
2249#endif
2250}
2251
Robert Phillipsbf25d432017-04-07 10:08:53 -04002252bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Eric Karl74480882017-04-03 14:49:05 -07002253 bool* rectsMustMatch, bool* disallowSubrect) const {
2254 // By default, we don't require rects to match.
2255 *rectsMustMatch = false;
2256
2257 // By default, we allow subrects.
2258 *disallowSubrect = false;
2259
Brian Salomon467921e2017-03-06 16:17:12 -05002260 // If the src is a texture, we can implement the blit as a draw assuming the config is
2261 // renderable.
Robert Phillipsbf25d432017-04-07 10:08:53 -04002262 if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
2263 desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002264 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2265 desc->fConfig = src->config();
2266 return true;
2267 }
2268
Robert Phillipsbf25d432017-04-07 10:08:53 -04002269 {
2270 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2271 // wrapped. In that case the proxy would already be instantiated.
2272 const GrTexture* srcTexture = src->priv().peekTexture();
2273 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2274 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2275 // Not supported for FBO blit or CopyTexSubImage
2276 return false;
2277 }
Brian Salomon467921e2017-03-06 16:17:12 -05002278 }
2279
2280 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2281 // possible and we return false to fallback to creating a render target dst for render-to-
2282 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2283 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002284 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002285 bool rectsMustMatchForBlitFramebuffer = false;
2286 bool disallowSubrectForBlitFramebuffer = false;
2287 if (src->numColorSamples() &&
2288 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2289 rectsMustMatchForBlitFramebuffer = true;
2290 disallowSubrectForBlitFramebuffer = true;
2291 // Mirroring causes rects to mismatch later, don't allow it.
2292 originForBlitFramebuffer = src->origin();
2293 } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() &
2294 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
2295 rectsMustMatchForBlitFramebuffer = true;
2296 // Mirroring causes rects to mismatch later, don't allow it.
2297 originForBlitFramebuffer = src->origin();
2298 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002299 originForBlitFramebuffer = src->origin();
2300 }
2301
2302 // Check for format issues with glCopyTexSubImage2D
2303 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2304 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2305 // then we set up for that, otherwise fail.
2306 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2307 desc->fOrigin = originForBlitFramebuffer;
2308 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002309 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2310 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002311 return true;
2312 }
2313 return false;
2314 }
2315
Robert Phillipsbf25d432017-04-07 10:08:53 -04002316 {
Brian Salomon63e79732017-05-15 21:23:13 -04002317 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2318 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002319 if (srcIsMSAARenderbuffer) {
2320 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2321 // blit or fail.
2322 if (this->canConfigBeFBOColorAttachment(src->config())) {
2323 desc->fOrigin = originForBlitFramebuffer;
2324 desc->fConfig = src->config();
2325 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2326 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2327 return true;
2328 }
2329 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002330 }
Brian Salomon467921e2017-03-06 16:17:12 -05002331 }
2332
2333 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2334 desc->fConfig = src->config();
2335 desc->fOrigin = src->origin();
2336 desc->fFlags = kNone_GrSurfaceFlags;
2337 return true;
2338}
2339
csmartdaltone0d36292016-07-29 08:14:20 -07002340void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon9bada542017-06-12 12:09:30 -04002341 if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
2342 fUseDrawInsteadOfAllRenderTargetWrites = true;
2343 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002344 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2345 fUseDrawToClearColor = false;
2346 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2347 fUseDrawToClearColor = true;
2348 }
csmartdaltone0d36292016-07-29 08:14:20 -07002349}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002350
2351int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
2352 int count = fConfigTable[config].fColorSampleCounts.count();
2353 if (!count || !this->isConfigRenderable(config, true)) {
2354 return 0;
2355 }
2356
2357 for (int i = 0; i < count; ++i) {
2358 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2359 return fConfigTable[config].fColorSampleCounts[i];
2360 }
2361 }
2362 return fConfigTable[config].fColorSampleCounts[count-1];
2363}
2364
Greg Danielfaa095e2017-12-19 13:15:02 -05002365bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2366 GrGLStandard standard) {
2367 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002368
2369 switch (ct) {
2370 case kUnknown_SkColorType:
2371 return false;
2372 case kAlpha_8_SkColorType:
2373 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002374 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002375 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002376 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002377 }
2378 break;
2379 case kRGB_565_SkColorType:
2380 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002381 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002382 }
2383 break;
2384 case kARGB_4444_SkColorType:
2385 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002386 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002387 }
2388 break;
2389 case kRGBA_8888_SkColorType:
2390 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002391 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002392 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002393 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002394 }
2395 break;
2396 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002397 if (GR_GL_RGBA8 == format) {
2398 if (kGL_GrGLStandard == standard) {
2399 *config = kBGRA_8888_GrPixelConfig;
2400 }
2401 } else if (GR_GL_BGRA8 == format) {
2402 if (kGLES_GrGLStandard == standard) {
2403 *config = kBGRA_8888_GrPixelConfig;
2404 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002405 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002406 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002407 }
2408 break;
2409 case kGray_8_SkColorType:
2410 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002411 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002412 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002413 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002414 }
2415 break;
2416 case kRGBA_F16_SkColorType:
2417 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002418 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002419 }
2420 break;
2421 }
2422
Greg Danielfaa095e2017-12-19 13:15:02 -05002423 return kUnknown_GrPixelConfig != *config;
2424}
2425
2426bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2427 GrPixelConfig* config) const {
2428 const GrGLTextureInfo* texInfo = tex.getGLTextureInfo();
2429 if (!texInfo) {
2430 return false;
2431 }
2432 return validate_sized_format(texInfo->fFormat, ct, config, fStandard);
2433}
2434
2435bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2436 GrPixelConfig* config) const {
2437 const GrGLFramebufferInfo* fbInfo = rt.getGLFramebufferInfo();
2438 if (!fbInfo) {
2439 return false;
2440 }
2441 return validate_sized_format(fbInfo->fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002442}
2443