blob: 95791f12bb11abe7067a13fba04b7ab176fa58e0 [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"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000015#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000016#include "SkTSort.h"
Brian Salomon467921e2017-03-06 16:17:12 -050017#include "instanced/GLInstancedRendering.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;
brianosman20471892016-12-02 06:43:32 -080054 fSRGBDecodeDisableSupport = false;
brianosman851c2382016-12-07 10:03:25 -080055 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070056 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040057 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060058 fDrawArraysBaseVertexIsBroken = false;
Mike Klein31550db2017-06-06 23:29:53 +000059 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040060 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
61 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040062 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
piotaixre4b23142014-10-02 10:57:53 -070063
Brian Salomone5e7eb12016-10-14 16:18:33 -040064 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
bsalomon083617b2016-02-12 12:10:14 -080065
Brian Salomon94efbf52016-11-29 13:43:05 -050066 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070067
cdalton4cd67132015-06-10 19:23:46 -070068 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000069}
70
cdalton4cd67132015-06-10 19:23:46 -070071void GrGLCaps::init(const GrContextOptions& contextOptions,
72 const GrGLContextInfo& ctxInfo,
73 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000074 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000075 GrGLVersion version = ctxInfo.version();
76
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000077 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000078 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
79 &fMaxFragmentUniformVectors);
80 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000081 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000082 GrGLint max;
83 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
84 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000085 if (version >= GR_GL_VER(3, 2)) {
86 GrGLint profileMask;
87 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
88 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
89 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000090 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000091 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000092
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000093 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094 fUnpackRowLengthSupport = true;
95 fUnpackFlipYSupport = false;
96 fPackRowLengthSupport = true;
97 fPackFlipYSupport = false;
98 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000099 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
100 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000101 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000102 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
103 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000104 fPackFlipYSupport =
105 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
106 }
107
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000108 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000109 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
110
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000111 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700112 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
113 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
114 ctxInfo.hasExtension("GL_NV_texture_barrier");
115 } else {
116 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
117 }
118
cdaltoneb79eea2016-02-26 10:39:34 -0800119 if (kGL_GrGLStandard == standard) {
120 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
121 ctxInfo.hasExtension("GL_ARB_texture_multisample");
122 } else {
123 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
124 }
125
Brian Salomon0ee6f952017-01-19 15:52:24 -0500126 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
hendrikwa0d5ad72014-12-02 07:30:30 -0800127 // and GL_RG on FBO textures.
Brian Salomon0ee6f952017-01-19 15:52:24 -0500128 if (kOSMesa_GrGLRenderer != ctxInfo.renderer()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800129 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000130 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
131 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800132 } else {
133 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
134 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000135 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000136 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000137 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000138 ctxInfo.hasExtension("GL_ARB_imaging");
139
egdaniel9250d242015-05-18 13:04:26 -0700140 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
141 // Thus we are blacklisting this extension for now on Adreno4xx devices.
142 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
143 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
144 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
145 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000146 fDiscardRenderTargetSupport = true;
147 fInvalidateFBType = kInvalidate_InvalidateFBType;
148 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
149 fDiscardRenderTargetSupport = true;
150 fInvalidateFBType = kDiscard_InvalidateFBType;
151 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000152
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000153 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
154 fFullClearIsFree = true;
155 }
156
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000157 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000158 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800159 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
160 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000161 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000162 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
163 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000164 }
165
cdalton626e1ff2015-06-12 13:56:46 -0700166 if (kGL_GrGLStandard == standard) {
167 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
168 } else {
169 fDirectStateAccessSupport = false;
170 }
171
172 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
173 fDebugSupport = true;
174 } else {
175 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
176 }
177
jvanverth3f801cb2014-12-16 09:49:38 -0800178 if (kGL_GrGLStandard == standard) {
179 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
180 }
181 else {
182 fES2CompatibilitySupport = true;
183 }
184
cdalton0edea2c2015-05-21 08:27:44 -0700185 if (kGL_GrGLStandard == standard) {
186 fMultisampleDisableSupport = true;
187 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700188 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700189 }
190
kkinnunend94708e2015-07-30 22:47:04 -0700191 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600192 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
193 // instanced arrays, but we could make this more granular if we wanted
194 fInstanceAttribSupport =
195 version >= GR_GL_VER(3, 2) ||
196 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
197 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
198 } else {
199 fInstanceAttribSupport =
200 version >= GR_GL_VER(3, 0) ||
201 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
202 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
203 }
204
205 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700206 if (version >= GR_GL_VER(3, 0)) {
207 fBindFragDataLocationSupport = true;
208 }
209 } else {
210 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
211 fBindFragDataLocationSupport = true;
212 }
joshualittc1f56b52015-06-22 12:31:31 -0700213 }
214
joshualitt7bdd70a2015-10-01 06:28:11 -0700215 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
216
kkinnunene06ed252016-02-16 23:15:40 -0800217 if (kGL_GrGLStandard == standard) {
218 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
219 // We also require textureSize() support for rectangle 2D samplers which was added in
220 // GLSL 1.40.
221 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
222 fRectangleTextureSupport = true;
223 }
bsalomone179a912016-01-20 06:18:10 -0800224 }
kkinnunene06ed252016-02-16 23:15:40 -0800225 } else {
226 // Command buffer exposes this in GL ES context for Chromium reasons,
227 // but it should not be used. Also, at the time of writing command buffer
228 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800229 }
230
bsalomoncdee0092016-01-08 13:20:12 -0800231 if (kGL_GrGLStandard == standard) {
232 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
233 fTextureSwizzleSupport = true;
234 }
235 } else {
236 if (version >= GR_GL_VER(3,0)) {
237 fTextureSwizzleSupport = true;
238 }
239 }
240
cblume09bd2c02016-03-01 14:08:28 -0800241 if (kGL_GrGLStandard == standard) {
242 fMipMapLevelAndLodControlSupport = true;
243 } else if (kGLES_GrGLStandard == standard) {
244 if (version >= GR_GL_VER(3,0)) {
245 fMipMapLevelAndLodControlSupport = true;
246 }
247 }
248
bsalomon88c7b982015-07-31 11:20:16 -0700249#ifdef SK_BUILD_FOR_WIN
250 // We're assuming that on Windows Chromium we're using ANGLE.
251 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
252 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700253 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700254 fRGBA8888PixelsOpsAreSlow = isANGLE;
255 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
256 // check DX11 ANGLE.
257 fPartialFBOReadIsSlow = isANGLE;
258#endif
259
ericrkb4ecabd2016-03-11 15:18:20 -0800260 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
261 bool isMAC = false;
262#ifdef SK_BUILD_FOR_MAC
263 isMAC = true;
264#endif
265
266 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
267 // vis-versa.
268 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
269
Brian Salomond17b4a62017-05-23 16:53:47 -0400270 if (kGL_GrGLStandard == standard) {
271 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
272 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
273 // 340.96 and 367.57.
274 if (ctxInfo.driver() != kNVIDIA_GrGLDriver ||
275 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(367, 57)) {
276 fClearTextureSupport = true;
277 }
278 }
279 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
280 // Calling glClearTexImage crashes on the NexusPlayer.
281 if (kPowerVRRogue_GrGLRenderer != ctxInfo.renderer()) {
282 fClearTextureSupport = true;
283 }
284 }
285
cdalton4cd67132015-06-10 19:23:46 -0700286 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700287 * GrShaderCaps fields
288 **************************************************************************/
289
egdaniel0a482332015-10-26 08:59:10 -0700290 // This must be called after fCoreProfile is set on the GrGLCaps
291 this->initGLSL(ctxInfo);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500292 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700293
csmartdalton008b9d82017-02-22 12:00:42 -0700294 if (!contextOptions.fSuppressPathRendering) {
295 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
296 }
egdaniel05ded892015-10-26 07:38:05 -0700297
298 // For now these two are equivalent but we could have dst read in shader via some other method.
299 // Before setting this, initGLSL() must have been called.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500300 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
egdaniel05ded892015-10-26 07:38:05 -0700301
302 // Enable supported shader-related caps
303 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500304 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700305 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
306 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Brian Salomon1edc5b92016-11-29 13:43:46 -0500307 shaderCaps->fShaderDerivativeSupport = true;
egdaniel05ded892015-10-26 07:38:05 -0700308 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500309 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700310 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500311 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800312 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700313 }
314 else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500315 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700316
Brian Salomon1edc5b92016-11-29 13:43:46 -0500317 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700318 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800319
csmartdalton1d2aed02017-02-15 21:43:20 -0700320 shaderCaps->fGeometryShaderSupport = ctxInfo.hasExtension("GL_EXT_geometry_shader");
321
Brian Salomon1edc5b92016-11-29 13:43:46 -0500322 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800323 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700324 }
325
cdalton9c3f1432016-03-11 10:07:37 -0800326 // Protect ourselves against tracking huge amounts of texture state.
327 static const uint8_t kMaxSaneSamplers = 32;
328 GrGLint maxSamplers;
329 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500330 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
331 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800332 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500333 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800334 }
335 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500336 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800337 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500338 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800339
Brian Salomonf26f7a02016-11-15 14:05:01 -0500340 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500341 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(4, 2);
342 if (!shaderCaps->fImageLoadStoreSupport &&
Brian Salomonf26f7a02016-11-15 14:05:01 -0500343 ctxInfo.hasExtension("GL_ARB_shader_image_load_store")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500344 shaderCaps->fImageLoadStoreSupport = true;
345 shaderCaps->fImageLoadStoreExtensionString = "GL_ARB_shader_image_load_store";
Brian Salomonf26f7a02016-11-15 14:05:01 -0500346 }
347 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500348 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500349 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500350 if (shaderCaps->fImageLoadStoreSupport) {
Brian Salomonf26f7a02016-11-15 14:05:01 -0500351 // Protect ourselves against tracking huge amounts of image state.
352 static constexpr int kMaxSaneImages = 4;
353 GrGLint maxUnits;
354 GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
Brian Salomonf9f45122016-11-29 11:59:17 -0500355 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500356 &shaderCaps->fMaxVertexImageStorages);
357 if (shaderCaps->fGeometryShaderSupport) {
Brian Salomonf9f45122016-11-29 11:59:17 -0500358 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500359 &shaderCaps->fMaxGeometryImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500360 }
361 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500362 &shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500363 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500364 &shaderCaps->fMaxCombinedImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500365 // We use one unit for every image uniform
Brian Salomon1edc5b92016-11-29 13:43:46 -0500366 shaderCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(shaderCaps->fMaxCombinedImageStorages,
367 maxUnits), kMaxSaneImages);
368 shaderCaps->fMaxVertexImageStorages = SkTMin(maxUnits,
369 shaderCaps->fMaxVertexImageStorages);
370 shaderCaps->fMaxGeometryImageStorages = SkTMin(maxUnits,
371 shaderCaps->fMaxGeometryImageStorages);
372 shaderCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
373 shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500374 }
375
csmartdalton485a1202016-07-13 10:16:32 -0700376 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
377 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
378 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
379 // limit this decision to specific GPU families rather than basing it on the vendor alone.
380 if (!GR_GL_MUST_USE_VBO &&
381 !fIsCoreProfile &&
382 (kARM_GrGLVendor == ctxInfo.vendor() ||
383 kImagination_GrGLVendor == ctxInfo.vendor() ||
384 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
385 fPreferClientSideDynamicBuffers = true;
386 }
387
Eric Karl5c779752017-05-08 12:02:07 -0700388 if (!contextOptions.fAvoidStencilBuffers) {
389 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
390 this->initFSAASupport(contextOptions, ctxInfo, gli);
391 this->initStencilSupport(ctxInfo);
392 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400393
394 // Setup blit framebuffer
395 if (kGL_GrGLStandard != ctxInfo.standard()) {
396 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
397 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
398 kNoMSAADst_BlitFramebufferFlag |
399 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
400 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
401 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
402 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
403 // limitations.
404 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
405 kResolveMustBeFull_BlitFrambufferFlag |
406 kNoMSAADst_BlitFramebufferFlag |
407 kNoFormatConversion_BlitFramebufferFlag |
408 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
409 }
410 } else {
411 if (fUsesMixedSamples ||
412 ctxInfo.version() >= GR_GL_VER(3,0) ||
413 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
414 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
415 fBlitFramebufferFlags = 0;
416 }
417 }
418
cdalton1dd05422015-06-12 09:01:18 -0700419 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000420
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000421 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000422 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
423 // extension includes glMapBuffer.
424 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
425 fMapBufferFlags |= kSubset_MapFlag;
426 fMapBufferType = kMapBufferRange_MapBufferType;
427 } else {
428 fMapBufferType = kMapBuffer_MapBufferType;
429 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000430 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000431 // Unextended GLES2 doesn't have any buffer mapping.
432 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800433 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800434 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
435 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800436 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
437 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
438 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000439 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
440 fMapBufferFlags = kCanMap_MapFlag;
441 fMapBufferType = kMapBuffer_MapBufferType;
442 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000443 }
444
Brian Salomone03a7292017-06-08 11:00:50 -0400445 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
446 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
447 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
448 // unclear whether this really affects a wide range of devices.
449 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer && ctxInfo.driver() == kQualcomm_GrGLDriver &&
450 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0)) {
451 fMapBufferType = kNone_MapBufferType;
452 fMapBufferFlags = kNone_MapFlags;
453 }
454
jvanverthd7a2c1f2015-12-07 07:36:44 -0800455 if (kGL_GrGLStandard == standard) {
456 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
457 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700458 }
jvanverthd7a2c1f2015-12-07 07:36:44 -0800459 } else {
460 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
461 fTransferBufferType = kPBO_TransferBufferType;
jvanverthc3d706f2016-04-20 10:33:27 -0700462 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
463 fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800464 }
465 }
466
joshualitte5b74c62015-06-01 14:17:47 -0700467 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
468 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700469 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700470#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500471 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
472 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
473 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700474 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700475#else
cdalton397536c2016-03-25 12:15:03 -0700476 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700477#endif
joshualitte5b74c62015-06-01 14:17:47 -0700478 }
479
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000480 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000481 fNPOTTextureTileSupport = true;
482 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000483 } else {
484 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000485 // ES3 has no limitations.
486 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
487 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000488 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
489 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
490 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
491 // to alllow arbitrary wrap modes, however.
492 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000493 }
494
bsalomone72bd022015-10-26 07:33:03 -0700495 // Using MIPs on this GPU seems to be a source of trouble.
496 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
497 fMipMapSupport = false;
498 }
499
bsalomon@google.combcce8922013-03-25 15:38:39 +0000500 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
501 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
502 // Our render targets are always created with textures as the color
503 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000504 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000505
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000506 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
507
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000508 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700509 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000510
robertphillips1b8e1b52015-06-24 06:54:10 -0700511#if 0
512 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
513 kQualcomm_GrGLVendor != ctxInfo.vendor();
514#endif
515
csmartdalton9bc11872016-08-09 12:42:47 -0700516 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
517 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700518 }
519
bsalomon63b21962014-11-05 07:05:34 -0800520 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800521 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
Brian Salomon1b52df32017-03-24 18:49:09 -0400522 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
523 ctxInfo.driver() != kChromium_GrGLDriver)) {
bsalomon63b21962014-11-05 07:05:34 -0800524 fUseDrawInsteadOfClear = true;
525 }
526
joshualitt83bc2292015-06-18 14:18:02 -0700527 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomonb52fa022017-06-07 09:42:52 -0400528 // This is known to be fixed sometime between driver 145.0 and 219.0
529 if (ctxInfo.driver() == kQualcomm_GrGLDriver &&
530 ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0)) {
531 fUseDrawToClearStencilClip = true;
532 }
Brian Salomon9bada542017-06-12 12:09:30 -0400533 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
joshualitt83bc2292015-06-18 14:18:02 -0700534 }
535
Brian Salomonaf971de2017-06-08 16:11:33 -0400536 // This was reproduced on the following configurations:
537 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
538 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
539 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400540 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
Brian Salomonaf971de2017-06-08 16:11:33 -0400541 // and not produced on:
542 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400543 // The particular lines that get dropped from test images varies across different devices.
Brian Salomonaf971de2017-06-08 16:11:33 -0400544 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() && kQualcomm_GrGLDriver == ctxInfo.driver() &&
545 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0)) {
Brian Salomon6d9c88b2017-06-12 10:24:42 -0400546 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
Brian Salomonaf971de2017-06-08 16:11:33 -0400547 }
548
bsalomonbabafcc2016-02-16 11:36:47 -0800549 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
550 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon9bada542017-06-12 12:09:30 -0400551 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
bsalomonbabafcc2016-02-16 11:36:47 -0800552 fUseDrawInsteadOfAllRenderTargetWrites = true;
553 }
554
robertphillips63926682015-08-20 09:39:02 -0700555#ifdef SK_BUILD_FOR_WIN
556 // On ANGLE deferring flushes can lead to GPU starvation
557 fPreferVRAMUseOverFlushes = !isANGLE;
558#endif
559
bsalomon7dea7b72015-08-19 08:26:51 -0700560 if (kChromium_GrGLDriver == ctxInfo.driver()) {
561 fMustClearUploadedBufferData = true;
562 }
563
bsalomond08ea5f2015-02-20 06:58:13 -0800564 if (kGL_GrGLStandard == standard) {
565 // ARB allows mixed size FBO attachments, EXT does not.
566 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
567 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
568 fOversizedStencilSupport = true;
569 } else {
570 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
571 }
572 } else {
573 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
574 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
575 }
576
joshualitt58001552015-06-26 12:46:36 -0700577 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700578 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
579 ctxInfo.hasExtension("GL_ARB_draw_indirect");
580 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
581 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700582 (fDrawIndirectSupport &&
583 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700584 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700585 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800586 } else {
587 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700588 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
589 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
590 fBaseInstanceSupport = fDrawIndirectSupport &&
591 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700592 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800593 }
594
Brian Salomon1edc5b92016-11-29 13:43:46 -0500595 this->initShaderPrecisionTable(ctxInfo, gli, shaderCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800596
597 if (contextOptions.fUseShaderSwizzling) {
598 fTextureSwizzleSupport = false;
599 }
600
ethannicholas28ef4452016-03-25 09:26:03 -0700601 if (kGL_GrGLStandard == standard) {
Greg Daniela5cb7812017-06-16 09:45:32 -0400602 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
ethannicholas6536ae52016-05-02 12:16:49 -0700603 ctxInfo.vendor() != kIntel_GrGLVendor) {
ethannicholas28ef4452016-03-25 09:26:03 -0700604 fSampleShadingSupport = true;
605 }
606 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
607 fSampleShadingSupport = true;
608 }
609
jvanverth84741b32016-09-30 08:39:02 -0700610 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
611 if (kGL_GrGLStandard == standard) {
612 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
613 fFenceSyncSupport = true;
614 }
615 } else if (version >= GR_GL_VER(3, 0)) {
616 fFenceSyncSupport = true;
617 }
Greg Daniela5cb7812017-06-16 09:45:32 -0400618#ifdef SK_BUILD_FOR_MAC
619 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
620 // See skia:6770
621 fFenceSyncSupport = false;
622 }
623#endif
jvanverth84741b32016-09-30 08:39:02 -0700624
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400625 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500626 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500627
brianosman131ff132016-06-07 14:22:44 -0700628 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
629 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
630 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
631 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
brianosman09563ce2016-06-02 08:59:34 -0700632 if (fMipMapLevelAndLodControlSupport &&
brianosman9a3fbf72016-06-09 13:11:08 -0700633 (contextOptions.fDoManualMipmapping ||
634 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
brianosman131ff132016-06-07 14:22:44 -0700635 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
636 (kATI_GrGLVendor == ctxInfo.vendor()))) {
brianosman09563ce2016-06-02 08:59:34 -0700637 fDoManualMipmapping = true;
638 }
639
brianosman20471892016-12-02 06:43:32 -0800640 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
brianosman851c2382016-12-07 10:03:25 -0800641 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
642 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800643
Brian Salomon028a9a52017-05-11 11:39:08 -0400644 // See http://crbug.com/710443
645#ifdef SK_BUILD_FOR_MAC
646 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
Eric Karlaeaf22b2017-05-18 15:08:09 -0700647 fClearToBoundaryValuesIsBroken = true;
Brian Salomon028a9a52017-05-11 11:39:08 -0400648 }
649#endif
Chris Dalton9926f4b2017-05-17 15:15:50 -0600650 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
651 fDrawArraysBaseVertexIsBroken = true;
652 }
Brian Salomon028a9a52017-05-11 11:39:08 -0400653
bsalomoncdee0092016-01-08 13:20:12 -0800654 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
655 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800656 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700657
658 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500659 shaderCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000660}
661
egdaniel472d44e2015-10-22 08:20:00 -0700662const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
663 bool isCoreProfile) {
664 switch (generation) {
665 case k110_GrGLSLGeneration:
666 if (kGLES_GrGLStandard == standard) {
667 // ES2s shader language is based on version 1.20 but is version
668 // 1.00 of the ES language.
669 return "#version 100\n";
670 } else {
671 SkASSERT(kGL_GrGLStandard == standard);
672 return "#version 110\n";
673 }
674 case k130_GrGLSLGeneration:
675 SkASSERT(kGL_GrGLStandard == standard);
676 return "#version 130\n";
677 case k140_GrGLSLGeneration:
678 SkASSERT(kGL_GrGLStandard == standard);
679 return "#version 140\n";
680 case k150_GrGLSLGeneration:
681 SkASSERT(kGL_GrGLStandard == standard);
682 if (isCoreProfile) {
683 return "#version 150\n";
684 } else {
685 return "#version 150 compatibility\n";
686 }
687 case k330_GrGLSLGeneration:
688 if (kGLES_GrGLStandard == standard) {
689 return "#version 300 es\n";
690 } else {
691 SkASSERT(kGL_GrGLStandard == standard);
692 if (isCoreProfile) {
693 return "#version 330\n";
694 } else {
695 return "#version 330 compatibility\n";
696 }
697 }
cdalton33ad7012016-02-22 07:55:44 -0800698 case k400_GrGLSLGeneration:
699 SkASSERT(kGL_GrGLStandard == standard);
700 if (isCoreProfile) {
701 return "#version 400\n";
702 } else {
703 return "#version 400 compatibility\n";
704 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500705 case k420_GrGLSLGeneration:
706 SkASSERT(kGL_GrGLStandard == standard);
707 if (isCoreProfile) {
708 return "#version 420\n";
709 }
710 else {
711 return "#version 420 compatibility\n";
712 }
egdaniel472d44e2015-10-22 08:20:00 -0700713 case k310es_GrGLSLGeneration:
714 SkASSERT(kGLES_GrGLStandard == standard);
715 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800716 case k320es_GrGLSLGeneration:
717 SkASSERT(kGLES_GrGLStandard == standard);
718 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700719 }
720 return "<no version>";
721}
722
egdaniel05ded892015-10-26 07:38:05 -0700723void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700724 GrGLStandard standard = ctxInfo.standard();
725 GrGLVersion version = ctxInfo.version();
726
727 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500728 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700729 **************************************************************************/
730
Brian Salomon1edc5b92016-11-29 13:43:46 -0500731 GrShaderCaps* shaderCaps = fShaderCaps.get();
732 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700733 if (kGLES_GrGLStandard == standard) {
734 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500735 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
736 shaderCaps->fFBFetchSupport = true;
737 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
738 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700739 }
740 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
741 // 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 -0500742 shaderCaps->fFBFetchNeedsCustomOutput = false;
743 shaderCaps->fFBFetchSupport = true;
744 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
745 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700746 }
747 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
748 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500749 shaderCaps->fFBFetchNeedsCustomOutput = false;
750 shaderCaps->fFBFetchSupport = true;
751 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
752 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700753 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500754 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700755 }
756
egdaniel7517e452016-09-20 13:00:26 -0700757 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
758 // Galaxy S7.
759 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
760 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500761 shaderCaps->fFBFetchSupport = false;
egdaniel7517e452016-09-20 13:00:26 -0700762 }
763
Brian Salomon1edc5b92016-11-29 13:43:46 -0500764 shaderCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
egdaniel472d44e2015-10-22 08:20:00 -0700765
cdaltonc08f1962016-02-12 12:14:06 -0800766 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500767 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800768 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500769 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800770 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
771 }
772
773 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500774 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800775 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
776 } else {
777 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500778 shaderCaps->fNoPerspectiveInterpolationSupport = true;
779 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800780 "GL_NV_shader_noperspective_interpolation";
781 }
782 }
783
cdalton33ad7012016-02-22 07:55:44 -0800784 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500785 shaderCaps->fMultisampleInterpolationSupport =
cdalton4a98cdb2016-03-01 12:12:20 -0800786 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
787 } else {
788 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500789 shaderCaps->fMultisampleInterpolationSupport = true;
cdalton4a98cdb2016-03-01 12:12:20 -0800790 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500791 shaderCaps->fMultisampleInterpolationSupport = true;
792 shaderCaps->fMultisampleInterpolationExtensionString =
cdalton4a98cdb2016-03-01 12:12:20 -0800793 "GL_OES_shader_multisample_interpolation";
794 }
795 }
796
797 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500798 shaderCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
cdalton33ad7012016-02-22 07:55:44 -0800799 } else {
800 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500801 shaderCaps->fSampleVariablesSupport = true;
cdalton33ad7012016-02-22 07:55:44 -0800802 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500803 shaderCaps->fSampleVariablesSupport = true;
804 shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
cdalton33ad7012016-02-22 07:55:44 -0800805 }
806 }
807
Brian Salomon1edc5b92016-11-29 13:43:46 -0500808 if (shaderCaps->fSampleVariablesSupport &&
csmartdaltonf848c9c2016-06-15 12:42:13 -0700809 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
810 // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500811 shaderCaps->fSampleMaskOverrideCoverageSupport =
csmartdaltonf848c9c2016-06-15 12:42:13 -0700812 kNVIDIA_GrGLDriver != ctxInfo.driver() ||
813 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
cdalton33ad7012016-02-22 07:55:44 -0800814 }
815
egdaniel472d44e2015-10-22 08:20:00 -0700816 // 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 -0500817 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700818
819 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
820 // function that may require a gradient calculation inside a conditional block may return
821 // undefined results". This appears to be an issue with the 'any' call since even the simple
822 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
823 // from our GrTextureDomain processor.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500824 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700825
Brian Salomon1edc5b92016-11-29 13:43:46 -0500826 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
827 shaderCaps->fGLSLGeneration,
828 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800829
Brian Salomon1edc5b92016-11-29 13:43:46 -0500830 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
831 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800832 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800833
834 // Frag Coords Convention support is not part of ES
835 // Known issue on at least some Intel platforms:
836 // http://code.google.com/p/skia/issues/detail?id=946
837 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
838 kGLES_GrGLStandard != standard &&
839 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
840 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500841 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800842 }
843
844 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500845 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800846 }
847
cdalton9c3f1432016-03-11 10:07:37 -0800848 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
849 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500850 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800851 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
852 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
853 // At least one driver has been found that has this extension without the "GL_" prefix.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500854 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800855 }
856 }
857
Brian Salomon1edc5b92016-11-29 13:43:46 -0500858 if (shaderCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800859 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500860 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
bsalomon7ea33f52015-11-22 14:51:00 -0800861 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500862 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800863 }
864 }
865
cdaltonc04ce672016-03-11 14:07:38 -0800866 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500867 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800868 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500869 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700870 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
871 }
872
Brian Salomon1edc5b92016-11-29 13:43:46 -0500873 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700874 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500875 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700876 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
877 } else {
878 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
879 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500880 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700881 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500882 shaderCaps->fTexelBufferSupport = true;
883 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700884 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500885 shaderCaps->fTexelBufferSupport = true;
886 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700887 }
cdaltonc04ce672016-03-11 14:07:38 -0800888 }
889 }
890
Chris Dalton1d616352017-05-31 12:51:23 -0600891 if (kGL_GrGLStandard == standard) {
892 shaderCaps->fVertexIDSupport = true;
893 } else {
894 // Desktop GLSL 3.30 == ES GLSL 3.00.
895 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
896 }
897
egdaniel8dcdedc2015-11-11 06:27:20 -0800898 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
899 // the abs first in a separate expression.
900 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500901 shaderCaps->fCanUseMinAndAbsTogether = false;
egdaniel8dcdedc2015-11-11 06:27:20 -0800902 }
903
bsalomon7ea33f52015-11-22 14:51:00 -0800904 // 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 -0800905 // thus must us -1.0 * %s.x to work correctly
906 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500907 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
egdaniel8dcdedc2015-11-11 06:27:20 -0800908 }
egdaniel138c2632016-08-17 10:59:00 -0700909
910 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
911 // the original dst color when reading the outColor even after being written to. By using a
912 // local outColor we can work around this bug.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500913 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
914 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
egdaniel138c2632016-08-17 10:59:00 -0700915 }
csmartdalton2e777ea2017-02-15 10:41:27 -0700916
917#ifdef SK_BUILD_FOR_MAC
918 // On at least some MacBooks, geometry shaders fall apart if we use more than one invocation. To
919 // work around this, we always use a single invocation and wrap the shader in a loop. The long-
920 // term plan for this WAR is for it to eventually be baked into SkSL.
921 shaderCaps->fMustImplementGSInvocationsWithLoop = true;
922#endif
Brian Osmanac1e4962017-05-25 11:34:38 -0400923
924 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
925 // color, and that uniform contains an opaque color, and the output of the shader is only based
926 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
927 // that the shader always outputs opaque values. In that case, it appears to remove the shader
928 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
929 // insert an extra bit of math on the uniform that confuses the compiler just enough...
930 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
931 shaderCaps->fMustObfuscateUniformColor = true;
932 }
egdaniel472d44e2015-10-22 08:20:00 -0700933}
934
kkinnunencfe62e32015-07-01 02:58:50 -0700935bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700936 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
937
938 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700939 return false;
940 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700941
kkinnunencfe62e32015-07-01 02:58:50 -0700942 if (kGL_GrGLStandard == ctxInfo.standard()) {
943 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
944 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
945 return false;
946 }
947 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700948 if (!hasChromiumPathRendering &&
949 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700950 return false;
951 }
952 }
953 // We only support v1.3+ of GL_NV_path_rendering which allows us to
954 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
955 // additions are detected by checking the existence of the function.
956 // We also use *Then* functions that not all drivers might have. Check
957 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800958 if (!gli->fFunctions.fStencilThenCoverFillPath ||
959 !gli->fFunctions.fStencilThenCoverStrokePath ||
960 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
961 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
962 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700963 return false;
964 }
965 return true;
966}
bsalomon1aa20292016-01-22 08:16:09 -0800967
Brian Salomon71d9d842016-11-03 13:42:00 -0400968bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800969 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800970 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800971 std::function<bool ()> bindRenderTarget,
972 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400973 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800974 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400975 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800976 return false;
977 }
bsalomon7928ef62016-01-05 10:26:39 -0800978
Brian Salomonbf7b6202016-11-11 16:08:03 -0500979 if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
980 return false;
981 }
982
bsalomon76148af2016-01-12 11:13:47 -0800983 GrGLenum readFormat;
984 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400985 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800986 return false;
987 }
988
bsalomon1aa20292016-01-22 08:16:09 -0800989 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800990 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
991 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
992 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
993 // 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 -0500994 // The manual does not seem to fully match the spec as the spec allows integer formats
995 // when the bound color buffer is an integer buffer. It doesn't specify which integer
996 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500997 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
998 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
999 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -08001000 return false;
1001 }
1002 // There is also a set of allowed types, but all the types we use are in the set:
1003 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
1004 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
1005 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
1006 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
1007 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
1008 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
1009 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -08001010 return true;
piotaixre4b23142014-10-02 10:57:53 -07001011 }
bsalomon7928ef62016-01-05 10:26:39 -08001012
bsalomon76148af2016-01-12 11:13:47 -08001013 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -05001014 switch (fConfigTable[surfaceConfig].fFormatType) {
1015 case kNormalizedFixedPoint_FormatType:
1016 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
1017 return true;
1018 }
1019 break;
1020 case kInteger_FormatType:
1021 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
1022 return true;
1023 }
1024 break;
1025 case kFloat_FormatType:
1026 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
1027 return true;
1028 }
1029 break;
bsalomon7928ef62016-01-05 10:26:39 -08001030 }
1031
Brian Salomon71d9d842016-11-03 13:42:00 -04001032 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -08001033 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -04001034 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -08001035 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -08001036 if (!bindRenderTarget()) {
1037 return false;
1038 }
1039 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
1040 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -08001041 rpFormat->fFormat = format;
1042 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -08001043 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -08001044 }
1045
Brian Salomon71d9d842016-11-03 13:42:00 -04001046 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
1047 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -07001048}
1049
Eric Karl5c779752017-05-08 12:02:07 -07001050void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
1051 const GrGLInterface* gli) {
1052 // We need dual source blending and the ability to disable multisample in order to support mixed
1053 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
1054 // renderer is available and enabled; no other path renderers support this feature.
1055 if (fMultisampleDisableSupport &&
1056 this->shaderCaps()->dualSourceBlendingSupport() &&
1057 this->shaderCaps()->pathRenderingSupport() &&
1058 (contextOptions.fGpuPathRenderers & GrContextOptions::GpuPathRenderers::kStencilAndCover)) {
1059 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -04001060 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -07001061 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
1062 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
1063 kChromium_GrGLDriver == ctxInfo.driver())) {
1064 fDiscardRenderTargetSupport = false;
1065 fInvalidateFBType = kNone_InvalidateFBType;
1066 }
1067 }
1068
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001069 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001070 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
1071 // ES3 driver bugs on at least one device with a tiled GPU (N10).
1072 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
1073 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
1074 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
1075 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -08001076 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001077 fMSFBOType = kMixedSamples_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001078 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1079 fMSFBOType = kStandard_MSFBOType;
1080 fAlpha8IsRenderable = true;
1081 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -04001082 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001083 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001084 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +00001085 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
1086 fMSFBOType = kES_Apple_MSFBOType;
1087 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001088 } else {
egdanieleed519e2016-01-15 11:36:18 -08001089 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001090 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -04001091 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1092 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001093
Brian Salomon00731b42016-10-14 11:30:51 -04001094 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -04001095 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
1096 // Core profile removes ALPHA8 support.
1097 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
1098 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
1099 // present.
1100 fAlpha8IsRenderable = true;
1101 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001102 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1103 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -04001104 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001105 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001106 }
Eric Karl5c779752017-05-08 12:02:07 -07001107
Robert Phillips3b3307f2017-05-24 07:44:02 -04001108 // We disable MSAA across the board for Intel GPUs
1109 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1110 fMSFBOType = kNone_MSFBOType;
1111 }
1112
Eric Karl5c779752017-05-08 12:02:07 -07001113 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
1114 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
1115 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
1116 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
1117 }
1118 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1119 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1120 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
1121 // This is to guard against platforms that may not support as many samples for
1122 // glRasterSamples as they do for framebuffers.
1123 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
1124 }
1125 fMaxColorSampleCount = fMaxStencilSampleCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001126}
1127
cdalton1dd05422015-06-12 09:01:18 -07001128void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001129 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001130
1131 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
1132 // for now until its own blacklists can be updated.
1133 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
Greg Daniel0ea7d432016-10-27 16:55:52 -04001134 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
cdalton1dd05422015-06-12 09:01:18 -07001135 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -07001136 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -07001137 return;
1138 }
1139
1140 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1141 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001142 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001143 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
1144 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001145 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001146 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1147 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1148 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1149 return;
1150 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1151 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001152 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001153 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
1154 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001155 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001156 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1157 // slow on a particular platform.
1158 } else {
1159 return; // No advanced blend support.
1160 }
1161
1162 SkASSERT(this->advancedBlendEquationSupport());
1163
csmartdalton3b88a032016-08-04 14:43:49 -07001164 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1165 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1166 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
cdalton1dd05422015-06-12 09:01:18 -07001167 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1168 (1 << kColorBurn_GrBlendEquation);
1169 }
joel.liang9764c402015-07-09 19:46:18 -07001170 if (kARM_GrGLVendor == ctxInfo.vendor()) {
1171 // Blacklist color-burn on ARM until the fix is released.
1172 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1173 }
cdalton1dd05422015-06-12 09:01:18 -07001174}
1175
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001176namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001177const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001178}
1179
Eric Karl5c779752017-05-08 12:02:07 -07001180void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001181
1182 // Build up list of legal stencil formats (though perhaps not supported on
1183 // the particular gpu/driver) from most preferred to least.
1184
1185 // these consts are in order of most preferred to least preferred
1186 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1187
1188 static const StencilFormat
1189 // internal Format stencil bits total bits packed?
1190 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1191 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1192 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1193 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001194 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001195 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1196
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001197 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001198 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001199 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001200 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1201 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1202
1203 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1204 // require FBO support we can expect these are legal formats and don't
1205 // check. These also all support the unsized GL_STENCIL_INDEX.
1206 fStencilFormats.push_back() = gS8;
1207 fStencilFormats.push_back() = gS16;
1208 if (supportsPackedDS) {
1209 fStencilFormats.push_back() = gD24S8;
1210 }
1211 fStencilFormats.push_back() = gS4;
1212 if (supportsPackedDS) {
1213 fStencilFormats.push_back() = gDS;
1214 }
1215 } else {
1216 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1217 // for other formats.
1218 // ES doesn't support using the unsized format.
1219
1220 fStencilFormats.push_back() = gS8;
1221 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001222 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1223 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001224 fStencilFormats.push_back() = gD24S8;
1225 }
1226 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1227 fStencilFormats.push_back() = gS4;
1228 }
1229 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001230}
1231
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001232SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001233
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001234 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +00001235
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001236 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001237 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001238 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001239 i,
1240 fStencilFormats[i].fStencilBits,
1241 fStencilFormats[i].fTotalBits);
1242 }
1243
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001244 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001245 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001246 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001247 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001248 "IMG MS To Texture",
1249 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001250 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001251 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001252 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001253 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1254 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1255 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1256 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1257 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001258 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001259
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001260 static const char* kInvalidateFBTypeStr[] = {
1261 "None",
1262 "Discard",
1263 "Invalidate",
1264 };
1265 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1266 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1267 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1268 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001269
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001270 static const char* kMapBufferTypeStr[] = {
1271 "None",
1272 "MapBuffer",
1273 "MapBufferRange",
1274 "Chromium",
1275 };
1276 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1277 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1278 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1279 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1280 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1281
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001282 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001283 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001284 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001285 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001286 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001287 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
1288 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
1289 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
1290 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +00001291
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001292 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001293 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
Robert Phillips5ab72762017-06-07 12:04:18 -04001294 r.appendf("Alpha8 is renderable: %s\n", (fAlpha8IsRenderable ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001295 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001296 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -07001297 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
1298 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdalton06604b92016-02-05 10:09:51 -08001299 r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
1300 r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
1301 r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -07001302 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
1303 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -07001304 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -08001305 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -08001306 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
halcanary9d524f22016-03-29 09:03:52 -07001307 r.appendf("BGRA to RGBA readback conversions are slow: %s\n",
ericrkb4ecabd2016-03-11 15:18:20 -08001308 (fRGBAToBGRAReadbackConversionsAreSlow ? "YES" : "NO"));
Brian Salomon9bada542017-06-12 12:09:30 -04001309 r.appendf("Intermediate texture for partial updates of unorm textures ever bound to FBOs: %s\n",
1310 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO ? "YES" : "NO");
1311 r.appendf("Intermediate texture for all updates of textures bound to FBOs: %s\n",
1312 fUseDrawInsteadOfAllRenderTargetWrites ? "YES" : "NO");
bsalomon41e4384e2016-01-08 09:12:44 -08001313
1314 r.append("Configs\n-------\n");
1315 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1316 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -08001317 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
1318 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -08001319 i,
1320 fConfigTable[i].fFlags,
1321 fConfigTable[i].fFormats.fBaseInternalFormat,
1322 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -08001323 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
1324 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -08001325 fConfigTable[i].fFormats.fExternalType,
1326 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -08001327 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -08001328 }
1329
jvanverthe9c0fc62015-04-29 11:18:05 -07001330 return r;
1331}
1332
jvanverthe9c0fc62015-04-29 11:18:05 -07001333static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1334 switch (p) {
1335 case kLow_GrSLPrecision:
1336 return GR_GL_LOW_FLOAT;
1337 case kMedium_GrSLPrecision:
1338 return GR_GL_MEDIUM_FLOAT;
1339 case kHigh_GrSLPrecision:
1340 return GR_GL_HIGH_FLOAT;
Brian Osman33aa2c72017-04-05 09:26:15 -04001341 default:
1342 SkFAIL("Unexpected precision type.");
1343 return -1;
jvanverthe9c0fc62015-04-29 11:18:05 -07001344 }
jvanverthe9c0fc62015-04-29 11:18:05 -07001345}
1346
1347static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1348 switch (type) {
1349 case kVertex_GrShaderType:
1350 return GR_GL_VERTEX_SHADER;
1351 case kGeometry_GrShaderType:
1352 return GR_GL_GEOMETRY_SHADER;
1353 case kFragment_GrShaderType:
1354 return GR_GL_FRAGMENT_SHADER;
1355 }
1356 SkFAIL("Unknown shader type.");
1357 return -1;
1358}
1359
jvanverthcba99b82015-06-24 06:59:57 -07001360void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
halcanary9d524f22016-03-29 09:03:52 -07001361 const GrGLInterface* intf,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001362 GrShaderCaps* shaderCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001363 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1364 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1365 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1366 if (kGeometry_GrShaderType != s) {
1367 GrShaderType shaderType = static_cast<GrShaderType>(s);
1368 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001369 GrShaderCaps::PrecisionInfo* first = nullptr;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001370 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001371 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1372 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1373 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1374 GrGLint range[2];
1375 GrGLint bits;
1376 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1377 if (bits) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001378 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1379 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1380 shaderCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001381 if (!first) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001382 first = &shaderCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001383 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001384 else if (!shaderCaps->fShaderPrecisionVaries) {
1385 shaderCaps->fShaderPrecisionVaries =
1386 (*first != shaderCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001387 }
1388 }
1389 }
1390 }
1391 }
1392 }
1393 else {
1394 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001395 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001396 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1397 if (kGeometry_GrShaderType != s) {
1398 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001399 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1400 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1401 shaderCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001402 }
1403 }
1404 }
1405 }
1406 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1407 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1408 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1409 // are recommended against.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001410 if (shaderCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001411 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001412 shaderCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1413 shaderCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001414 }
1415 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001416 shaderCaps->initSamplerPrecisionTable();
jvanverthe9c0fc62015-04-29 11:18:05 -07001417}
1418
bsalomon41e4384e2016-01-08 09:12:44 -08001419bool GrGLCaps::bgraIsInternalFormat() const {
1420 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1421}
1422
bsalomon76148af2016-01-12 11:13:47 -08001423bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1424 GrGLenum* internalFormat, GrGLenum* externalFormat,
1425 GrGLenum* externalType) const {
1426 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1427 externalFormat, externalType)) {
1428 return false;
1429 }
1430 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1431 return true;
1432}
1433
bsalomon76148af2016-01-12 11:13:47 -08001434bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1435 GrGLenum* externalFormat, GrGLenum* externalType) const {
1436 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1437 externalFormat, externalType)) {
1438 return false;
1439 }
1440 return true;
1441}
1442
1443bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001444 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1445 return true;
1446}
1447
1448bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1449 ExternalFormatUsage usage, GrGLenum* externalFormat,
1450 GrGLenum* externalType) const {
1451 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001452
1453 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1454 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1455
1456 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1457 // made to work in many cases using glPixelStore and what not but is not needed currently.
1458 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1459 return false;
1460 }
1461
1462 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1463 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1464
bsalomone9573312016-01-25 14:33:25 -08001465 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1466 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1467 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1468 // texture, not the red component.
1469 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1470 if (this->textureRedSupport()) {
1471 SkASSERT(GR_GL_RED == *externalFormat);
1472 *externalFormat = GR_GL_ALPHA;
1473 }
1474 }
1475
bsalomon76148af2016-01-12 11:13:47 -08001476 return true;
1477}
1478
brianosman20471892016-12-02 06:43:32 -08001479void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1480 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001481 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001482 /*
1483 Comments on renderability of configs on various GL versions.
1484 OpenGL < 3.0:
1485 no built in support for render targets.
1486 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1487 format RGB, RGBA and NV float formats we don't use.
1488 This is the following:
1489 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1490 RGB10_A2, RGBA12,RGBA16
1491 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1492 since they aren't required by later standards and the driver can simply return
1493 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1494 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1495 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1496 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1497 This adds a lot of additional renderable sized formats, including ALPHA8.
1498 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1499 16F, 32I, 32UI, and 32F variants).
1500 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1501
1502 For both the above extensions we limit ourselves to those that are also required by
1503 OpenGL 3.0.
1504
1505 OpenGL 3.0:
1506 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1507 but are not required to be supported as renderable textures/renderbuffer.
1508 Required renderable color formats:
1509 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1510 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1511 RGB10_A2.
1512 - R11F_G11F_B10F.
1513 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1514 and RG8UI.
1515 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1516 - ALPHA8
1517
1518 OpenGL 3.1, 3.2, 3.3
1519 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1520 OpengGL 3.3, 4.0, 4.1
1521 Adds RGB10_A2UI.
1522 OpengGL 4.2
1523 Adds
1524 - RGB5_A1, RGBA4
1525 - RGB565
1526 OpenGL 4.4
1527 Does away with the separate list and adds a column to the sized internal color format
1528 table. However, no new formats become required color renderable.
1529
1530 ES 2.0
1531 color renderable: RGBA4, RGB5_A1, RGB565
1532 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1533 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1534 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1535 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1536 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1537 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1538
1539 ES 3.0
1540 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1541 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1542 RGB5_A1.
1543 - RGB8 and RGB565.
1544 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1545 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1546 ES 3.1
1547 Adds RGB10_A2, RGB10_A2UI,
1548 ES 3.2
1549 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1550 */
Brian Salomon71d9d842016-11-03 13:42:00 -04001551 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1552 ConfigInfo::kFBOColorAttachment_Flag;
1553 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001554 if (kNone_MSFBOType != fMSFBOType) {
1555 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1556 }
bsalomon41e4384e2016-01-08 09:12:44 -08001557 GrGLStandard standard = ctxInfo.standard();
1558 GrGLVersion version = ctxInfo.version();
1559
cblume790d5132016-02-29 11:13:29 -08001560 bool texStorageSupported = false;
1561 if (kGL_GrGLStandard == standard) {
1562 // The EXT version can apply to either GL or GLES.
1563 texStorageSupported = version >= GR_GL_VER(4,2) ||
1564 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1565 ctxInfo.hasExtension("GL_EXT_texture_storage");
1566 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001567 texStorageSupported = version >= GR_GL_VER(3,0) ||
1568 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001569 }
1570
1571 // TODO: remove after command buffer supports full ES 3.0
1572 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1573 kChromium_GrGLDriver == ctxInfo.driver()) {
1574 texStorageSupported = false;
1575 }
1576
cdalton74b8d322016-04-11 14:47:28 -07001577 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1578
bsalomon30447372015-12-21 09:03:05 -08001579 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1580 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001581 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001582 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001583 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001584 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001585
1586 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1587 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001588 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1589 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001590 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001591 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001592 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1593 if (kGL_GrGLStandard == standard) {
1594 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1595 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001596 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001597 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1598 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1599 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1600 }
egdaniel4999df82016-01-07 17:06:04 -08001601 }
cblume790d5132016-02-29 11:13:29 -08001602 if (texStorageSupported) {
1603 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1604 }
cdalton74b8d322016-04-11 14:47:28 -07001605 if (texelBufferSupport) {
1606 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1607 }
bsalomoncdee0092016-01-08 13:20:12 -08001608 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001609
bsalomon76148af2016-01-12 11:13:47 -08001610 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1611 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001612 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001613 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001614 if (kGL_GrGLStandard == standard) {
1615 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1616 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1617 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1618 // Since the internal format is RGBA8, it is also renderable.
1619 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1620 allRenderFlags;
1621 }
1622 } else {
1623 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1624 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1625 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001626 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1627 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1628 // driver remembers the external format when the texture is created (with TexImage).
1629 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1630 // We could work around this, but it adds even more state tracking to code that is
1631 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1632 // This also side-steps some ambiguous interactions with the texture storage extension.
1633 if (version >= GR_GL_VER(3,0)) {
1634 // The APPLE extension doesn't make this renderable.
1635 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon41e4384e2016-01-08 09:12:44 -08001636 }
1637 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1638 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001639 nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001640 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001641 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001642 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1643 ConfigInfo::kRenderableWithMSAA_Flag;
1644 }
1645 }
1646 }
Brian Osman48c99192017-06-02 08:45:06 -04001647
1648 bool isX86PowerVR = false;
1649#if defined(SK_CPU_X86)
1650 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1651 isX86PowerVR = true;
1652 }
1653#endif
1654
1655 // Adreno 3xx, 4xx, 5xx, and NexusPlayer all fail if we try to use TexStorage with BGRA
1656 if (texStorageSupported &&
1657 kAdreno3xx_GrGLRenderer != ctxInfo.renderer() &&
1658 kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1659 kAdreno5xx_GrGLRenderer != ctxInfo.renderer() &&
1660 !isX86PowerVR) {
1661 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001662 }
bsalomoncdee0092016-01-08 13:20:12 -08001663 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001664
brianosmana6359362016-03-21 06:55:37 -07001665 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001666 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001667 if (kGL_GrGLStandard == standard) {
1668 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001669 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001670 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1671 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1672 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001673 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001674 }
1675 }
1676 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001677 if (fSRGBSupport) {
1678 fSRGBWriteControl = true;
1679 }
bsalomon41e4384e2016-01-08 09:12:44 -08001680 } else {
brianosman20471892016-12-02 06:43:32 -08001681 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Osman48c99192017-06-02 08:45:06 -04001682 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1683 // blacklist that device (and any others that might be sharing the same driver).
1684 if (isX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001685 fSRGBSupport = false;
1686 }
bsalomon41e4384e2016-01-08 09:12:44 -08001687 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1688 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001689 // See https://bug.skia.org/5329 for Adreno4xx issue.
1690 fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1691 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001692 }
brianosman20471892016-12-02 06:43:32 -08001693 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1694 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1695 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001696 fSRGBSupport = false;
1697 }
brianosman20471892016-12-02 06:43:32 -08001698
1699 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1700 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1701 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1702 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1703 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1704 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1705 // affects Windows.
1706 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1707 fSRGBSupport = false;
1708 }
1709
Brian Osman48c99192017-06-02 08:45:06 -04001710 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1711 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1712 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1713
Brian Osman67999392017-05-31 16:19:34 -04001714 uint32_t srgbRenderFlags = allRenderFlags;
1715 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers
1716#if defined(SK_BUILD_FOR_MAC)
1717 if (kATI_GrGLVendor == ctxInfo.vendor()) {
1718 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1719 }
1720#endif
1721
bsalomon30447372015-12-21 09:03:05 -08001722 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1723 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1724 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1725 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001726 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1727 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001728 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001729 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001730 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001731 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001732 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001733 }
Brian Osman48c99192017-06-02 08:45:06 -04001734 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1735 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001736 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1737 }
bsalomoncdee0092016-01-08 13:20:12 -08001738 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001739 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1740 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1741 // is in this format, for example).
1742 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1743 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1744 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1745 // external format is GL_BGRA.
1746 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1747 GR_GL_BGRA;
1748 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1749 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001750 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001751 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001752 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001753 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001754
brianosmana6359362016-03-21 06:55:37 -07001755 if (texStorageSupported) {
1756 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1757 }
1758 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1759
Brian Salomonbf7b6202016-11-11 16:08:03 -05001760 bool hasIntegerTextures;
1761 if (standard == kGL_GrGLStandard) {
1762 hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1763 ctxInfo.hasExtension("GL_EXT_texture_integer");
1764 } else {
1765 hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1766 }
1767 // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1768 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1769 hasIntegerTextures = false;
1770 }
1771 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1772 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1773 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1774 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1775 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1776 // We currently only support using integer textures as srcs, not for rendering (even though GL
1777 // allows it).
1778 if (hasIntegerTextures) {
1779 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1780 ConfigInfo::kFBOColorAttachment_Flag;
1781 if (texStorageSupported) {
1782 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1783 ConfigInfo::kCanUseTexStorage_Flag;
1784 }
1785 }
1786
bsalomon30447372015-12-21 09:03:05 -08001787 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1788 if (this->ES2CompatibilitySupport()) {
1789 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1790 } else {
1791 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1792 }
bsalomon76148af2016-01-12 11:13:47 -08001793 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1794 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001795 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001796 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001797 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1798 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001799 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001800 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1801 }
1802 } else {
1803 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1804 }
cblume790d5132016-02-29 11:13:29 -08001805 // 565 is not a sized internal format on desktop GL. So on desktop with
1806 // 565 we always use an unsized internal format to let the system pick
1807 // the best sized format to convert the 565 data to. Since TexStorage
1808 // only allows sized internal formats we disallow it.
1809 //
1810 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1811 // update.
1812 if (texStorageSupported && kGL_GrGLStandard != standard) {
1813 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1814 }
bsalomoncdee0092016-01-08 13:20:12 -08001815 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001816
1817 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1818 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001819 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1820 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001821 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001822 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001823 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1824 if (kGL_GrGLStandard == standard) {
1825 if (version >= GR_GL_VER(4, 2)) {
1826 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1827 }
1828 } else {
1829 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1830 }
cblume790d5132016-02-29 11:13:29 -08001831 if (texStorageSupported) {
1832 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1833 }
bsalomoncdee0092016-01-08 13:20:12 -08001834 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001835
Brian Osmanf4faccd2017-01-10 16:53:58 -05001836 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1837 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1838 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001839 if (this->textureRedSupport()) {
1840 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1841 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001842 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1843 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001844 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001845 if (texelBufferSupport) {
1846 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1847 }
Robert Phillips5ab72762017-06-07 12:04:18 -04001848 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
bsalomon30447372015-12-21 09:03:05 -08001849 } else {
1850 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1851 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001852 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1853 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001854 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
Robert Phillips5ab72762017-06-07 12:04:18 -04001855 if (fAlpha8IsRenderable) {
1856 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1857 }
bsalomon30447372015-12-21 09:03:05 -08001858 }
Robert Phillips5ab72762017-06-07 12:04:18 -04001859
Brian Osman48c99192017-06-02 08:45:06 -04001860 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1861 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001862 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1863 }
bsalomon41e4384e2016-01-08 09:12:44 -08001864
Brian Osmanf4faccd2017-01-10 16:53:58 -05001865 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1866 fConfigTable[kGray_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1867 fConfigTable[kGray_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001868 if (this->textureRedSupport()) {
1869 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1870 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1871 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1872 GR_GL_RED;
1873 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRA();
1874 if (texelBufferSupport) {
1875 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1876 }
1877 } else {
1878 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1879 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1880 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1881 GR_GL_LUMINANCE;
1882 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1883 }
Brian Osman986563b2017-01-10 14:20:02 -05001884#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster
1885 if (this->textureRedSupport() ||
1886 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1887 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1888 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1889 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1890 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1891 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1892 }
1893#endif
Brian Osman48c99192017-06-02 08:45:06 -04001894 if (texStorageSupported && !isCommandBufferES2) {
Brian Osman986563b2017-01-10 14:20:02 -05001895 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1896 }
1897
bsalomon41e4384e2016-01-08 09:12:44 -08001898 // Check for [half] floating point texture support
1899 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1900 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1901 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1902 bool hasFPTextures = false;
1903 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001904 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001905 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001906 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001907
1908 if (kGL_GrGLStandard == standard) {
1909 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1910 hasFPTextures = true;
1911 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001912 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001913 }
1914 } else {
1915 if (version >= GR_GL_VER(3, 1)) {
1916 hasFPTextures = true;
1917 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001918 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001919 } else {
1920 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1921 ctxInfo.hasExtension("GL_OES_texture_float")) {
1922 hasFPTextures = true;
1923 }
1924 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1925 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1926 hasHalfFPTextures = true;
1927 }
1928 }
1929 }
bsalomon30447372015-12-21 09:03:05 -08001930
csmartdalton6aa0e112017-02-08 16:14:11 -05001931 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1932 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1933 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1934 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1935 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
1936 fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
1937 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1938 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1939 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001940 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001941 // For now we only enable rendering to float on desktop, because on ES we'd have to
1942 // solve many precision issues and no clients actually want this yet.
1943 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1944 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1945 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1946 }
bsalomon41e4384e2016-01-08 09:12:44 -08001947 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001948 if (texStorageSupported) {
1949 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1950 }
1951 if (texelBufferSupport) {
1952 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1953 }
1954 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001955 }
bsalomon30447372015-12-21 09:03:05 -08001956
1957 if (this->textureRedSupport()) {
1958 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1959 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001960 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1961 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001962 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001963 if (texelBufferSupport) {
1964 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |=
1965 ConfigInfo::kCanUseWithTexelBuffer_Flag;
1966 }
bsalomon30447372015-12-21 09:03:05 -08001967 } else {
1968 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1969 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001970 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1971 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001972 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001973 }
Brian Osman3a887252016-11-17 13:27:31 -05001974 // ANGLE always returns GL_HALF_FLOAT_OES for GL_IMPLEMENTATION_COLOR_READ_TYPE, even though
1975 // ES3 would typically return GL_HALF_FLOAT. The correct fix is for us to respect the value
1976 // returned when we query, but that turns into a bigger refactor, so just work around it.
1977 if (kGL_GrGLStandard == ctxInfo.standard() ||
1978 (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
bsalomon30447372015-12-21 09:03:05 -08001979 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1980 } else {
1981 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1982 }
bsalomon7928ef62016-01-05 10:26:39 -08001983 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
cblume790d5132016-02-29 11:13:29 -08001984 if (texStorageSupported) {
1985 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1986 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001987 if (hasHalfFPTextures) {
1988 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1989 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1990 // GL_RED internal format.
1991 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
1992 (this->textureRedSupport() &&
1993 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1994 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1995 }
1996 }
bsalomon30447372015-12-21 09:03:05 -08001997
1998 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1999 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08002000 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
2001 GR_GL_RGBA;
Brian Osman3a887252016-11-17 13:27:31 -05002002 // See comment above, re: ANGLE and ES3.
2003 if (kGL_GrGLStandard == ctxInfo.standard() ||
2004 (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
bsalomon30447372015-12-21 09:03:05 -08002005 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
2006 } else {
2007 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
2008 }
bsalomon7928ef62016-01-05 10:26:39 -08002009 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08002010 if (hasHalfFPTextures) {
2011 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
2012 // ES requires 3.2 or EXT_color_buffer_half_float.
2013 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
2014 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
2015 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
2016 }
2017 }
cblume790d5132016-02-29 11:13:29 -08002018 if (texStorageSupported) {
2019 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
2020 }
cdalton74b8d322016-04-11 14:47:28 -07002021 if (texelBufferSupport) {
2022 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
2023 }
bsalomoncdee0092016-01-08 13:20:12 -08002024 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08002025
bsalomon30447372015-12-21 09:03:05 -08002026 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
2027
2028 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08002029 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
2030 ctxInfo.version() >= GR_GL_VER(3,0));
2031 // All ES versions (thus far) require sized internal formats for render buffers.
2032 // TODO: Always use sized internal format?
2033 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
2034
bsalomon30447372015-12-21 09:03:05 -08002035 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08002036 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
2037 // param to glTex[Sub]Image.
2038 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
2039 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
2040 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
2041 fConfigTable[i].fFormats.fSizedInternalFormat :
2042 fConfigTable[i].fFormats.fBaseInternalFormat;
2043 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08002044 fConfigTable[i].fFormats.fSizedInternalFormat :
2045 fConfigTable[i].fFormats.fBaseInternalFormat;
2046 }
2047 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
2048 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
2049 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
2050 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
2051 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08002052 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08002053 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07002054
2055 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
2056 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
2057 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
2058 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08002059 }
2060
2061 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
2062 // as a base format.
2063 // GL_EXT_texture_format_BGRA8888:
2064 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
2065 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
2066 // formats.
halcanary9d524f22016-03-29 09:03:52 -07002067 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08002068 // ES 2.0: the extension makes BGRA an external format but not an internal format.
2069 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
2070 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08002071 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08002072 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
2073 }
2074
bsalomoncdee0092016-01-08 13:20:12 -08002075 // If we don't have texture swizzle support then the shader generator must insert the
2076 // swizzle into shader code.
2077 if (!this->textureSwizzleSupport()) {
2078 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002079 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08002080 }
2081 }
2082
bsalomon7f9b2e42016-01-12 13:29:26 -08002083 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
2084 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
2085 // gets written to the single component.
2086 if (this->textureRedSupport()) {
2087 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2088 GrPixelConfig config = static_cast<GrPixelConfig>(i);
2089 if (GrPixelConfigIsAlphaOnly(config) &&
2090 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002091 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08002092 }
2093 }
2094 }
2095
Brian Salomonf9f45122016-11-29 11:59:17 -05002096 // We currently only support images on rgba textures formats. We could add additional formats
2097 // if desired. The shader builder would have to be updated to add swizzles where appropriate
2098 // (e.g. where we use GL_RED textures to implement alpha configs).
2099 if (this->shaderCaps()->imageLoadStoreSupport()) {
2100 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
2101 ConfigInfo::kCanUseAsImageStorage_Flag;
2102 // In OpenGL ES a texture may only be used with BindImageTexture if it has been made
2103 // immutable via TexStorage. We create non-integer textures as mutable textures using
2104 // TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
2105 // storage support for non-integer textures.
2106 if (kGL_GrGLStandard == ctxInfo.standard()) {
2107 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2108 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
2109 ConfigInfo::kCanUseAsImageStorage_Flag;
2110 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2111 }
2112 }
2113
bsalomon30447372015-12-21 09:03:05 -08002114#ifdef SK_DEBUG
2115 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002116 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002117 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002118 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2119 // renderable.
2120 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2121 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002122 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2123 fConfigTable[i].fFormats.fBaseInternalFormat);
2124 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002125 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002126 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2127 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2128 fConfigTable[i].fFormats.fExternalFormat[j]);
2129 }
2130 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002131 }
2132#endif
2133}
2134
Robert Phillipsbf25d432017-04-07 10:08:53 -04002135bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Eric Karl74480882017-04-03 14:49:05 -07002136 bool* rectsMustMatch, bool* disallowSubrect) const {
2137 // By default, we don't require rects to match.
2138 *rectsMustMatch = false;
2139
2140 // By default, we allow subrects.
2141 *disallowSubrect = false;
2142
Brian Salomon467921e2017-03-06 16:17:12 -05002143 // If the src is a texture, we can implement the blit as a draw assuming the config is
2144 // renderable.
Robert Phillipsbf25d432017-04-07 10:08:53 -04002145 if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
2146 desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002147 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2148 desc->fConfig = src->config();
2149 return true;
2150 }
2151
Robert Phillipsbf25d432017-04-07 10:08:53 -04002152 {
2153 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2154 // wrapped. In that case the proxy would already be instantiated.
2155 const GrTexture* srcTexture = src->priv().peekTexture();
2156 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2157 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2158 // Not supported for FBO blit or CopyTexSubImage
2159 return false;
2160 }
Brian Salomon467921e2017-03-06 16:17:12 -05002161 }
2162
2163 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2164 // possible and we return false to fallback to creating a render target dst for render-to-
2165 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2166 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002167 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002168 bool rectsMustMatchForBlitFramebuffer = false;
2169 bool disallowSubrectForBlitFramebuffer = false;
2170 if (src->numColorSamples() &&
2171 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2172 rectsMustMatchForBlitFramebuffer = true;
2173 disallowSubrectForBlitFramebuffer = true;
2174 // Mirroring causes rects to mismatch later, don't allow it.
2175 originForBlitFramebuffer = src->origin();
2176 } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() &
2177 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
2178 rectsMustMatchForBlitFramebuffer = true;
2179 // Mirroring causes rects to mismatch later, don't allow it.
2180 originForBlitFramebuffer = src->origin();
2181 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002182 originForBlitFramebuffer = src->origin();
2183 }
2184
2185 // Check for format issues with glCopyTexSubImage2D
2186 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2187 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2188 // then we set up for that, otherwise fail.
2189 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2190 desc->fOrigin = originForBlitFramebuffer;
2191 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002192 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2193 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002194 return true;
2195 }
2196 return false;
2197 }
2198
Robert Phillipsbf25d432017-04-07 10:08:53 -04002199 {
Brian Salomon63e79732017-05-15 21:23:13 -04002200 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2201 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002202 if (srcIsMSAARenderbuffer) {
2203 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2204 // blit or fail.
2205 if (this->canConfigBeFBOColorAttachment(src->config())) {
2206 desc->fOrigin = originForBlitFramebuffer;
2207 desc->fConfig = src->config();
2208 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2209 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2210 return true;
2211 }
2212 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002213 }
Brian Salomon467921e2017-03-06 16:17:12 -05002214 }
2215
2216 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2217 desc->fConfig = src->config();
2218 desc->fOrigin = src->origin();
2219 desc->fFlags = kNone_GrSurfaceFlags;
2220 return true;
2221}
2222
csmartdaltone0d36292016-07-29 08:14:20 -07002223void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
2224 if (options.fEnableInstancedRendering) {
2225 fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
2226#ifndef SK_BUILD_FOR_MAC
2227 // OS X doesn't seem to write correctly to floating point textures when using
2228 // glDraw*Indirect, regardless of the underlying GPU.
2229 fAvoidInstancedDrawsToFPTargets = true;
2230#endif
2231 }
Brian Salomon9bada542017-06-12 12:09:30 -04002232 if (options.fUseDrawInsteadOfPartialRenderTargetWrite) {
2233 fUseDrawInsteadOfAllRenderTargetWrites = true;
2234 }
csmartdaltone0d36292016-07-29 08:14:20 -07002235}