blob: 22f248b70a7e44175dc969dbc7f7f0c69a2393e6 [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"
Greg Daniel26dbe3b2018-05-03 10:35:42 -040013#include "GrRenderTargetProxyPriv.h"
Brian Salomon94efbf52016-11-29 13:43:05 -050014#include "GrShaderCaps.h"
Robert Phillipsbf25d432017-04-07 10:08:53 -040015#include "GrSurfaceProxyPriv.h"
Greg Daniel26dbe3b2018-05-03 10:35:42 -040016#include "GrTextureProxyPriv.h"
Brian Osman71a18892017-08-10 10:23:25 -040017#include "SkJSONWriter.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000018#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000019#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000020
bsalomon682c2692015-05-22 14:01:46 -070021GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
22 const GrGLContextInfo& ctxInfo,
23 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080024 fStandard = ctxInfo.standard();
25
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000026 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000027 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000028 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000029 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080030 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000031 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000032 fUnpackRowLengthSupport = false;
33 fUnpackFlipYSupport = false;
34 fPackRowLengthSupport = false;
35 fPackFlipYSupport = false;
36 fTextureUsageSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040037 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000038 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000039 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070040 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;
Robert Phillipsf2ec0242018-03-01 16:51:25 -050053 fUseBufferDataNullHint = SkToBool(GR_GL_USE_BUFFER_DATA_NULL_HINT);
brianosman09563ce2016-06-02 08:59:34 -070054 fDoManualMipmapping = false;
brianosman851c2382016-12-07 10:03:25 -080055 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070056 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040057 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060058 fDrawArraysBaseVertexIsBroken = false;
Brian Salomon43f8bf02017-10-18 08:33:29 -040059 fUseDrawToClearColor = false;
Mike Klein31550db2017-06-06 23:29:53 +000060 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040061 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
62 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040063 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
Chris Daltonda40cd22018-04-16 13:19:58 -060064 fRequiresFlushBetweenNonAndInstancedDraws = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050065 fProgramBinarySupport = false;
piotaixre4b23142014-10-02 10:57:53 -070066
Brian Salomone5e7eb12016-10-14 16:18:33 -040067 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060068 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080069
Brian Salomon94efbf52016-11-29 13:43:05 -050070 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070071
cdalton4cd67132015-06-10 19:23:46 -070072 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000073}
74
cdalton4cd67132015-06-10 19:23:46 -070075void GrGLCaps::init(const GrContextOptions& contextOptions,
76 const GrGLContextInfo& ctxInfo,
77 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000078 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000079 GrGLVersion version = ctxInfo.version();
80
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000081 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000082 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
83 &fMaxFragmentUniformVectors);
84 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000085 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000086 GrGLint max;
87 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
88 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000089 if (version >= GR_GL_VER(3, 2)) {
90 GrGLint profileMask;
91 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
92 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
93 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000095 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000096
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000097 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000098 fUnpackRowLengthSupport = true;
99 fUnpackFlipYSupport = false;
100 fPackRowLengthSupport = true;
101 fPackFlipYSupport = false;
102 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000103 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
104 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000105 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000106 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
107 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000108 fPackFlipYSupport =
109 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
110 }
111
Adrienne Walkerc48f7762018-05-15 13:03:13 -0700112 if (fDriverBugWorkarounds.pack_parameters_workaround_with_pack_buffer) {
113 // In some cases drivers handle copying the last row incorrectly
114 // when using GL_PACK_ROW_LENGTH. Chromium handles this by iterating
115 // through every row and conditionally clobbering that value, but
116 // Skia already has a scratch buffer workaround when pack row length
117 // is not supported, so just use that.
118 fPackRowLengthSupport = false;
119 }
120
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000121 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000122 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
123
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000124 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700125 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
126 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
127 ctxInfo.hasExtension("GL_NV_texture_barrier");
128 } else {
129 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
130 }
131
Robert Phillips7f861922018-01-30 13:13:42 +0000132 if (kGL_GrGLStandard == standard) {
133 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
134 ctxInfo.hasExtension("GL_ARB_texture_multisample");
135 } else {
136 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
137 }
138
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000139 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000140 ctxInfo.hasExtension("GL_ARB_imaging");
141
Brian Salomon01b476a2018-01-23 11:06:41 -0500142 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700143 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
144 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000145 fDiscardRenderTargetSupport = true;
146 fInvalidateFBType = kInvalidate_InvalidateFBType;
147 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
148 fDiscardRenderTargetSupport = true;
149 fInvalidateFBType = kDiscard_InvalidateFBType;
150 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000151
Chris Dalton27059d32018-01-23 14:06:50 -0700152 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
153 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
154 if (kGLES_GrGLStandard == standard) {
155 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
156 // TODO: Evaluate on PowerVR.
157 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
158 if (kARM_GrGLVendor == ctxInfo.vendor()) {
159 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
160 }
161 }
162
Chris Dalton344e9032017-12-11 15:42:09 -0700163 if (kARM_GrGLVendor == ctxInfo.vendor() ||
164 kImagination_GrGLVendor == ctxInfo.vendor() ||
165 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
166 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000167 }
168
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000169 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000170 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800171 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
172 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000173 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000174 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
175 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000176 }
177
cdalton626e1ff2015-06-12 13:56:46 -0700178 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
179 fDebugSupport = true;
180 } else {
181 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
182 }
183
jvanverth3f801cb2014-12-16 09:49:38 -0800184 if (kGL_GrGLStandard == standard) {
185 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
186 }
187 else {
188 fES2CompatibilitySupport = true;
189 }
190
cdalton0edea2c2015-05-21 08:27:44 -0700191 if (kGL_GrGLStandard == standard) {
192 fMultisampleDisableSupport = true;
193 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700194 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700195 }
196
kkinnunend94708e2015-07-30 22:47:04 -0700197 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600198 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
199 // instanced arrays, but we could make this more granular if we wanted
200 fInstanceAttribSupport =
201 version >= GR_GL_VER(3, 2) ||
202 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
203 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
204 } else {
205 fInstanceAttribSupport =
206 version >= GR_GL_VER(3, 0) ||
207 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
208 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
209 }
210
211 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700212 if (version >= GR_GL_VER(3, 0)) {
213 fBindFragDataLocationSupport = true;
214 }
215 } else {
216 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
217 fBindFragDataLocationSupport = true;
218 }
joshualittc1f56b52015-06-22 12:31:31 -0700219 }
220
joshualitt7bdd70a2015-10-01 06:28:11 -0700221 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
222
kkinnunene06ed252016-02-16 23:15:40 -0800223 if (kGL_GrGLStandard == standard) {
Weiliang Chen00f88662018-05-30 15:07:46 -0400224 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle") ||
225 ctxInfo.hasExtension("GL_ANGLE_texture_rectangle")) {
kkinnunene06ed252016-02-16 23:15:40 -0800226 // We also require textureSize() support for rectangle 2D samplers which was added in
227 // GLSL 1.40.
228 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
229 fRectangleTextureSupport = true;
230 }
bsalomone179a912016-01-20 06:18:10 -0800231 }
kkinnunene06ed252016-02-16 23:15:40 -0800232 } else {
233 // Command buffer exposes this in GL ES context for Chromium reasons,
234 // but it should not be used. Also, at the time of writing command buffer
235 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800236 }
237
bsalomoncdee0092016-01-08 13:20:12 -0800238 if (kGL_GrGLStandard == standard) {
239 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
240 fTextureSwizzleSupport = true;
241 }
242 } else {
243 if (version >= GR_GL_VER(3,0)) {
244 fTextureSwizzleSupport = true;
245 }
246 }
247
cblume09bd2c02016-03-01 14:08:28 -0800248 if (kGL_GrGLStandard == standard) {
249 fMipMapLevelAndLodControlSupport = true;
250 } else if (kGLES_GrGLStandard == standard) {
251 if (version >= GR_GL_VER(3,0)) {
252 fMipMapLevelAndLodControlSupport = true;
253 }
254 }
255
bsalomon88c7b982015-07-31 11:20:16 -0700256#ifdef SK_BUILD_FOR_WIN
257 // We're assuming that on Windows Chromium we're using ANGLE.
258 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
259 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700260 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700261 fRGBA8888PixelsOpsAreSlow = isANGLE;
262 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
263 // check DX11 ANGLE.
264 fPartialFBOReadIsSlow = isANGLE;
265#endif
266
ericrkb4ecabd2016-03-11 15:18:20 -0800267 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
268 bool isMAC = false;
269#ifdef SK_BUILD_FOR_MAC
270 isMAC = true;
271#endif
272
273 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
274 // vis-versa.
275 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
276
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500277 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
278 fUseBufferDataNullHint = false;
279 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
280 fUseBufferDataNullHint = true;
281 }
282
Brian Salomond17b4a62017-05-23 16:53:47 -0400283 if (kGL_GrGLStandard == standard) {
284 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400285 fClearTextureSupport = true;
286 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500287 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
288 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400289 }
290
cdalton4cd67132015-06-10 19:23:46 -0700291 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700292 * GrShaderCaps fields
293 **************************************************************************/
294
egdaniel0a482332015-10-26 08:59:10 -0700295 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700296 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500297 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700298
Brian Osman195c05b2017-08-30 15:14:04 -0400299 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
300#if GR_TEST_UTILS
301 if (contextOptions.fSuppressPathRendering) {
302 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700303 }
Brian Osman195c05b2017-08-30 15:14:04 -0400304#endif
egdaniel05ded892015-10-26 07:38:05 -0700305
egdaniel05ded892015-10-26 07:38:05 -0700306 // Enable supported shader-related caps
307 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500308 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700309 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
310 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600311
Brian Salomon1edc5b92016-11-29 13:43:46 -0500312 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600313
egdaniel05ded892015-10-26 07:38:05 -0700314 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500315 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700316 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600317 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600318 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
319 shaderCaps->fGSInvocationsSupport = true;
320 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
321 shaderCaps->fGSInvocationsSupport = true;
322 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
323 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600324 }
325
Brian Salomon1edc5b92016-11-29 13:43:46 -0500326 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800327 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500328 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500329 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700330
Brian Salomon1edc5b92016-11-29 13:43:46 -0500331 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700332 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800333
Chris Daltonfaca00d2018-01-19 15:56:07 -0700334 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
335 // backup impl that only uses vertex shaders.
336 if (kARM_GrGLVendor != ctxInfo.vendor()) {
337 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
338 shaderCaps->fGeometryShaderSupport = true;
339 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
340 shaderCaps->fGeometryShaderSupport = true;
341 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
342 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700343 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500344 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700345
Brian Salomon1edc5b92016-11-29 13:43:46 -0500346 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800347 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700348 }
349
cdalton9c3f1432016-03-11 10:07:37 -0800350 // Protect ourselves against tracking huge amounts of texture state.
351 static const uint8_t kMaxSaneSamplers = 32;
352 GrGLint maxSamplers;
353 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500354 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
355 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800356 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500357 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800358 }
359 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500360 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800361 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500362 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800363
Brian Salomonbbf05752017-11-30 11:30:48 -0500364 // This is all *very* approximate.
365 switch (ctxInfo.vendor()) {
366 case kNVIDIA_GrGLVendor:
367 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
368 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
369 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
370 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500371 case kImagination_GrGLVendor:
372 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
373 // it is always a win to use multitexturing.
374 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
375 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
376 std::numeric_limits<size_t>::max();
377 }
378 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500379 case kATI_GrGLVendor:
380 // So far no AMD GPU shows a performance difference. A tie goes to disabling
381 // multitexturing for simplicity's sake.
382 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
383 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500384 default:
385 break;
386 }
387
csmartdalton485a1202016-07-13 10:16:32 -0700388 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
389 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
390 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
391 // limit this decision to specific GPU families rather than basing it on the vendor alone.
392 if (!GR_GL_MUST_USE_VBO &&
393 !fIsCoreProfile &&
394 (kARM_GrGLVendor == ctxInfo.vendor() ||
395 kImagination_GrGLVendor == ctxInfo.vendor() ||
396 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
397 fPreferClientSideDynamicBuffers = true;
398 }
399
Eric Karl5c779752017-05-08 12:02:07 -0700400 if (!contextOptions.fAvoidStencilBuffers) {
401 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
402 this->initFSAASupport(contextOptions, ctxInfo, gli);
403 this->initStencilSupport(ctxInfo);
404 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400405
406 // Setup blit framebuffer
407 if (kGL_GrGLStandard != ctxInfo.standard()) {
408 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
409 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
410 kNoMSAADst_BlitFramebufferFlag |
411 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
412 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
413 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
414 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
415 // limitations.
416 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
417 kResolveMustBeFull_BlitFrambufferFlag |
418 kNoMSAADst_BlitFramebufferFlag |
419 kNoFormatConversion_BlitFramebufferFlag |
420 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
421 }
422 } else {
423 if (fUsesMixedSamples ||
424 ctxInfo.version() >= GR_GL_VER(3,0) ||
425 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
426 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
427 fBlitFramebufferFlags = 0;
428 }
429 }
430
cdalton1dd05422015-06-12 09:01:18 -0700431 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000432
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000433 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000434 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
435 // extension includes glMapBuffer.
436 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
437 fMapBufferFlags |= kSubset_MapFlag;
438 fMapBufferType = kMapBufferRange_MapBufferType;
439 } else {
440 fMapBufferType = kMapBuffer_MapBufferType;
441 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000442 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000443 // Unextended GLES2 doesn't have any buffer mapping.
444 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800445 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800446 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
447 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800448 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
449 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
450 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000451 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
452 fMapBufferFlags = kCanMap_MapFlag;
453 fMapBufferType = kMapBuffer_MapBufferType;
454 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000455 }
456
jvanverthd7a2c1f2015-12-07 07:36:44 -0800457 if (kGL_GrGLStandard == standard) {
458 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
459 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700460 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500461 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400462 if (version >= GR_GL_VER(3, 0) ||
463 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
464 // GL_EXT_unpack_subimage needed to support subtexture rectangles
465 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800466 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400467// TODO: get transfer buffers working in Chrome
468// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
469// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800470 }
471 }
472
joshualitte5b74c62015-06-01 14:17:47 -0700473 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
474 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700475 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700476#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500477 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
478 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
479 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700480 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700481#else
cdalton397536c2016-03-25 12:15:03 -0700482 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700483#endif
joshualitte5b74c62015-06-01 14:17:47 -0700484 }
485
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000486 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000487 fNPOTTextureTileSupport = true;
488 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000489 } else {
490 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000491 // ES3 has no limitations.
492 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
493 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000494 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
495 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
496 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
497 // to alllow arbitrary wrap modes, however.
498 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000499 }
500
bsalomon@google.combcce8922013-03-25 15:38:39 +0000501 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
Adrienne Walker724afe82018-05-15 11:36:26 -0700502
503 if (fDriverBugWorkarounds.max_texture_size_limit_4096) {
504 fMaxTextureSize = SkTMin(fMaxTextureSize, 4096);
505 }
506
bsalomon@google.combcce8922013-03-25 15:38:39 +0000507 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
508 // Our render targets are always created with textures as the color
509 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000510 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700511 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
512
513 if (kARM_GrGLVendor == ctxInfo.vendor()) {
514 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
515 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
516 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000517
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000518 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
519
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000520 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700521 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000522
robertphillips1b8e1b52015-06-24 06:54:10 -0700523#if 0
524 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
525 kQualcomm_GrGLVendor != ctxInfo.vendor();
526#endif
527
csmartdalton9bc11872016-08-09 12:42:47 -0700528 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
529 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700530 }
531
robertphillips63926682015-08-20 09:39:02 -0700532#ifdef SK_BUILD_FOR_WIN
533 // On ANGLE deferring flushes can lead to GPU starvation
534 fPreferVRAMUseOverFlushes = !isANGLE;
535#endif
536
bsalomon7dea7b72015-08-19 08:26:51 -0700537 if (kChromium_GrGLDriver == ctxInfo.driver()) {
538 fMustClearUploadedBufferData = true;
539 }
540
bsalomond08ea5f2015-02-20 06:58:13 -0800541 if (kGL_GrGLStandard == standard) {
542 // ARB allows mixed size FBO attachments, EXT does not.
543 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
544 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
545 fOversizedStencilSupport = true;
546 } else {
547 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
548 }
549 } else {
550 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
551 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
552 }
553
joshualitt58001552015-06-26 12:46:36 -0700554 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700555 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
556 ctxInfo.hasExtension("GL_ARB_draw_indirect");
557 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
558 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700559 (fDrawIndirectSupport &&
560 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700561 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700562 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800563 } else {
564 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700565 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
566 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
567 fBaseInstanceSupport = fDrawIndirectSupport &&
568 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700569 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800570 }
571
ethannicholas28ef4452016-03-25 09:26:03 -0700572 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500573 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700574 fSampleShadingSupport = true;
575 }
576 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
577 fSampleShadingSupport = true;
578 }
579
jvanverth84741b32016-09-30 08:39:02 -0700580 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
581 if (kGL_GrGLStandard == standard) {
582 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
583 fFenceSyncSupport = true;
584 }
Brian Osman93a23462017-06-21 15:13:39 -0400585 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700586 fFenceSyncSupport = true;
587 }
588
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400589 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500590 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500591
brianosman20471892016-12-02 06:43:32 -0800592 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500593
brianosman851c2382016-12-07 10:03:25 -0800594 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
595 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800596
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400597 if (kGL_GrGLStandard == standard) {
598 if (version >= GR_GL_VER(4, 1)) {
599 fProgramBinarySupport = true;
600 }
601 } else if (version >= GR_GL_VER(3, 0)) {
602 fProgramBinarySupport = true;
603 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400604 if (fProgramBinarySupport) {
605 GrGLint count;
606 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
607 fProgramBinarySupport = count > 0;
608 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400609
bsalomoncdee0092016-01-08 13:20:12 -0800610 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
611 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800612 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700613
Brian Salomon01b476a2018-01-23 11:06:41 -0500614 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
615 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
616 }
617
cdalton4cd67132015-06-10 19:23:46 -0700618 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500619 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700620
Brian Salomon01b476a2018-01-23 11:06:41 -0500621 // For now these two are equivalent but we could have dst read in shader via some other method.
622 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000623}
624
egdaniel472d44e2015-10-22 08:20:00 -0700625const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
626 bool isCoreProfile) {
627 switch (generation) {
628 case k110_GrGLSLGeneration:
629 if (kGLES_GrGLStandard == standard) {
630 // ES2s shader language is based on version 1.20 but is version
631 // 1.00 of the ES language.
632 return "#version 100\n";
633 } else {
634 SkASSERT(kGL_GrGLStandard == standard);
635 return "#version 110\n";
636 }
637 case k130_GrGLSLGeneration:
638 SkASSERT(kGL_GrGLStandard == standard);
639 return "#version 130\n";
640 case k140_GrGLSLGeneration:
641 SkASSERT(kGL_GrGLStandard == standard);
642 return "#version 140\n";
643 case k150_GrGLSLGeneration:
644 SkASSERT(kGL_GrGLStandard == standard);
645 if (isCoreProfile) {
646 return "#version 150\n";
647 } else {
648 return "#version 150 compatibility\n";
649 }
650 case k330_GrGLSLGeneration:
651 if (kGLES_GrGLStandard == standard) {
652 return "#version 300 es\n";
653 } else {
654 SkASSERT(kGL_GrGLStandard == standard);
655 if (isCoreProfile) {
656 return "#version 330\n";
657 } else {
658 return "#version 330 compatibility\n";
659 }
660 }
cdalton33ad7012016-02-22 07:55:44 -0800661 case k400_GrGLSLGeneration:
662 SkASSERT(kGL_GrGLStandard == standard);
663 if (isCoreProfile) {
664 return "#version 400\n";
665 } else {
666 return "#version 400 compatibility\n";
667 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500668 case k420_GrGLSLGeneration:
669 SkASSERT(kGL_GrGLStandard == standard);
670 if (isCoreProfile) {
671 return "#version 420\n";
672 }
673 else {
674 return "#version 420 compatibility\n";
675 }
egdaniel472d44e2015-10-22 08:20:00 -0700676 case k310es_GrGLSLGeneration:
677 SkASSERT(kGLES_GrGLStandard == standard);
678 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800679 case k320es_GrGLSLGeneration:
680 SkASSERT(kGLES_GrGLStandard == standard);
681 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700682 }
683 return "<no version>";
684}
685
Chris Dalton47c8ed32017-11-15 18:27:09 -0700686bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
687 if (kGLES_GrGLStandard != ctxInfo.standard() &&
688 ctxInfo.version() < GR_GL_VER(4,1) &&
689 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
690 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
691 return true;
692 }
693 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
694 // geometry shaders don't have lower precision than vertex and fragment.
695 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
696 GrGLint range[2];
697 GrGLint bits;
698 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
699 if (range[0] < 127 || range[1] < 127 || bits < 23) {
700 return false;
701 }
702 }
703 return true;
704}
705
706void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700707 GrGLStandard standard = ctxInfo.standard();
708 GrGLVersion version = ctxInfo.version();
709
710 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500711 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700712 **************************************************************************/
713
Brian Salomon1edc5b92016-11-29 13:43:46 -0500714 GrShaderCaps* shaderCaps = fShaderCaps.get();
715 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700716 if (kGLES_GrGLStandard == standard) {
717 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500718 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
719 shaderCaps->fFBFetchSupport = true;
720 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
721 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700722 }
723 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
724 // 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 -0500725 shaderCaps->fFBFetchNeedsCustomOutput = false;
726 shaderCaps->fFBFetchSupport = true;
727 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
728 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700729 }
730 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
731 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500732 shaderCaps->fFBFetchNeedsCustomOutput = false;
733 shaderCaps->fFBFetchSupport = true;
734 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
735 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700736 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500737 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700738 }
739
cdaltonc08f1962016-02-12 12:14:06 -0800740 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500741 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800742 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500743 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800744 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
745 }
Brian Salomon41274562017-09-15 09:40:03 -0700746 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
747 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
748 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800749 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500750 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800751 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
752 } else {
Brian Osman71a69952018-05-07 17:07:35 -0400753 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation") &&
754 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration /* GLSL ES 3.0 */) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500755 shaderCaps->fNoPerspectiveInterpolationSupport = true;
756 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800757 "GL_NV_shader_noperspective_interpolation";
758 }
759 }
760
Brian Salomon1edc5b92016-11-29 13:43:46 -0500761 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
762 shaderCaps->fGLSLGeneration,
763 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800764
Brian Salomon1edc5b92016-11-29 13:43:46 -0500765 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
766 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800767 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800768
769 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500770 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800771 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
772 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500773 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800774 }
775
776 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500777 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800778 }
779
cdalton9c3f1432016-03-11 10:07:37 -0800780 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400781 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
782 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400783 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400784 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
785 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
786 // At least one driver has been found that has this extension without the "GL_" prefix.
787 shaderCaps->fExternalTextureSupport = true;
788 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800789 }
790 }
791
cdaltonc04ce672016-03-11 14:07:38 -0800792 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500793 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800794 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500795 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700796 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
797 }
798
Brian Salomon1edc5b92016-11-29 13:43:46 -0500799 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700800 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500801 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700802 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
803 } else {
804 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
805 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500806 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700807 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500808 shaderCaps->fTexelBufferSupport = true;
809 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700810 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500811 shaderCaps->fTexelBufferSupport = true;
812 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700813 }
cdaltonc04ce672016-03-11 14:07:38 -0800814 }
815 }
816
Chris Dalton1d616352017-05-31 12:51:23 -0600817 if (kGL_GrGLStandard == standard) {
818 shaderCaps->fVertexIDSupport = true;
819 } else {
820 // Desktop GLSL 3.30 == ES GLSL 3.00.
821 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
822 }
823
Chris Dalton7c7ff032018-03-28 20:09:58 -0600824 if (kGL_GrGLStandard == standard) {
825 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
826 } else {
827 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
828 }
829
Chris Dalton47c8ed32017-11-15 18:27:09 -0700830 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
831 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700832}
833
kkinnunencfe62e32015-07-01 02:58:50 -0700834bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700835 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
836
837 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700838 return false;
839 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700840
kkinnunencfe62e32015-07-01 02:58:50 -0700841 if (kGL_GrGLStandard == ctxInfo.standard()) {
842 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
843 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
844 return false;
845 }
846 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700847 if (!hasChromiumPathRendering &&
848 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700849 return false;
850 }
851 }
852 // We only support v1.3+ of GL_NV_path_rendering which allows us to
853 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
854 // additions are detected by checking the existence of the function.
855 // We also use *Then* functions that not all drivers might have. Check
856 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800857 if (!gli->fFunctions.fStencilThenCoverFillPath ||
858 !gli->fFunctions.fStencilThenCoverStrokePath ||
859 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
860 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
861 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700862 return false;
863 }
864 return true;
865}
bsalomon1aa20292016-01-22 08:16:09 -0800866
Brian Salomon71d9d842016-11-03 13:42:00 -0400867bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800868 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800869 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800870 std::function<bool ()> bindRenderTarget,
871 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400872 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800873 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400874 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800875 return false;
876 }
bsalomon7928ef62016-01-05 10:26:39 -0800877
bsalomon76148af2016-01-12 11:13:47 -0800878 GrGLenum readFormat;
879 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400880 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800881 return false;
882 }
883
bsalomon1aa20292016-01-22 08:16:09 -0800884 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800885 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
886 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
887 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
888 // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500889 // The manual does not seem to fully match the spec as the spec allows integer formats
890 // when the bound color buffer is an integer buffer. It doesn't specify which integer
891 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500892 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
893 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
894 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800895 return false;
896 }
897 // There is also a set of allowed types, but all the types we use are in the set:
898 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
899 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
900 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
901 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
902 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
903 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
904 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800905 return true;
piotaixre4b23142014-10-02 10:57:53 -0700906 }
bsalomon7928ef62016-01-05 10:26:39 -0800907
bsalomon76148af2016-01-12 11:13:47 -0800908 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500909 switch (fConfigTable[surfaceConfig].fFormatType) {
910 case kNormalizedFixedPoint_FormatType:
911 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
912 return true;
913 }
914 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500915 case kFloat_FormatType:
916 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
917 return true;
918 }
919 break;
bsalomon7928ef62016-01-05 10:26:39 -0800920 }
921
Brian Salomon71d9d842016-11-03 13:42:00 -0400922 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800923 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400924 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800925 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800926 if (!bindRenderTarget()) {
927 return false;
928 }
929 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
930 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800931 rpFormat->fFormat = format;
932 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800933 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800934 }
935
Brian Salomon71d9d842016-11-03 13:42:00 -0400936 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
937 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700938}
939
Eric Karl5c779752017-05-08 12:02:07 -0700940void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
941 const GrGLInterface* gli) {
942 // We need dual source blending and the ability to disable multisample in order to support mixed
943 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
944 // renderer is available and enabled; no other path renderers support this feature.
945 if (fMultisampleDisableSupport &&
946 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400947 this->shaderCaps()->pathRenderingSupport()
948#if GR_TEST_UTILS
949 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
950#endif
951 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700952 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400953 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700954 }
955
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000956 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400957 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
958 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
959 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
960 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
961 fAlpha8IsRenderable = true;
962 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500963 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
964 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
965 // mixed samples we can't use multisampled-render-to-texture.
966 if (fUsesMixedSamples) {
967 fMSFBOType = kMixedSamples_MSFBOType;
968 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000969 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
970 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
971 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400972 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
973 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400974 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400975 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400976 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400977 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000978 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
979 fMSFBOType = kES_Apple_MSFBOType;
980 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000981 } else {
egdanieleed519e2016-01-15 11:36:18 -0800982 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700983 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400984 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
985 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400986
Brian Salomon00731b42016-10-14 11:30:51 -0400987 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400988 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
989 // Core profile removes ALPHA8 support.
990 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
991 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
992 // present.
993 fAlpha8IsRenderable = true;
994 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000995 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
996 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400997 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000998 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000999 }
Eric Karl5c779752017-05-08 12:02:07 -07001000
Brian Salomon01b476a2018-01-23 11:06:41 -05001001 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -04001002 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1003 fMSFBOType = kNone_MSFBOType;
1004 }
1005
Eric Karl5c779752017-05-08 12:02:07 -07001006 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1007 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1008 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -07001009 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001010}
1011
cdalton1dd05422015-06-12 09:01:18 -07001012void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001013 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001014
Greg Daniel210883c2017-11-27 15:14:01 -05001015 bool layoutQualifierSupport = false;
1016 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
1017 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1018 layoutQualifierSupport = true;
1019 }
1020
cdalton1dd05422015-06-12 09:01:18 -07001021 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1022 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001023 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001024 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1025 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001026 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001027 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001028 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1029 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001030 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001031 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001032 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001033 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001034 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1035 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001036 }
cdalton1dd05422015-06-12 09:01:18 -07001037}
1038
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001039namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001040const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001041}
1042
Eric Karl5c779752017-05-08 12:02:07 -07001043void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001044
1045 // Build up list of legal stencil formats (though perhaps not supported on
1046 // the particular gpu/driver) from most preferred to least.
1047
1048 // these consts are in order of most preferred to least preferred
1049 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1050
1051 static const StencilFormat
1052 // internal Format stencil bits total bits packed?
1053 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1054 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1055 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1056 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001057 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001058 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1059
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001060 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001061 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001062 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001063 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1064 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1065
1066 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1067 // require FBO support we can expect these are legal formats and don't
1068 // check. These also all support the unsized GL_STENCIL_INDEX.
1069 fStencilFormats.push_back() = gS8;
1070 fStencilFormats.push_back() = gS16;
1071 if (supportsPackedDS) {
1072 fStencilFormats.push_back() = gD24S8;
1073 }
1074 fStencilFormats.push_back() = gS4;
1075 if (supportsPackedDS) {
1076 fStencilFormats.push_back() = gDS;
1077 }
1078 } else {
1079 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1080 // for other formats.
1081 // ES doesn't support using the unsized format.
1082
1083 fStencilFormats.push_back() = gS8;
1084 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001085 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1086 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001087 fStencilFormats.push_back() = gD24S8;
1088 }
1089 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1090 fStencilFormats.push_back() = gS4;
1091 }
1092 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001093}
1094
Brian Osman71a18892017-08-10 10:23:25 -04001095void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001096
Brian Osman71a18892017-08-10 10:23:25 -04001097 // We are called by the base class, which has already called beginObject(). We choose to nest
1098 // all of our caps information in a named sub-object.
1099 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001100
Brian Osman71a18892017-08-10 10:23:25 -04001101 writer->beginArray("Stencil Formats");
1102
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001103 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001104 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001105 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1106 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1107 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001108 }
1109
Brian Osman71a18892017-08-10 10:23:25 -04001110 writer->endArray();
1111
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001112 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001113 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001114 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001115 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001116 "IMG MS To Texture",
1117 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001118 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001119 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001120 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001121 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1122 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1123 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1124 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1125 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001126 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001127
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001128 static const char* kInvalidateFBTypeStr[] = {
1129 "None",
1130 "Discard",
1131 "Invalidate",
1132 };
1133 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1134 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1135 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1136 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001137
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001138 static const char* kMapBufferTypeStr[] = {
1139 "None",
1140 "MapBuffer",
1141 "MapBufferRange",
1142 "Chromium",
1143 };
1144 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1145 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1146 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1147 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1148 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1149
Brian Osman71a18892017-08-10 10:23:25 -04001150 writer->appendBool("Core Profile", fIsCoreProfile);
1151 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1152 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1153 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1154 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1155 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1156 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1157 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1158 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001159
Brian Osman71a18892017-08-10 10:23:25 -04001160 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001161 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1162 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1163 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001164 writer->appendBool("Debug support", fDebugSupport);
1165 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1166 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1167 writer->appendBool("Base instance support", fBaseInstanceSupport);
1168 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1169 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1170 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1171 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1172 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1173 writer->appendBool("BGRA to RGBA readback conversions are slow",
1174 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001175 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001176 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1177 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001178 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1179 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1180 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1181 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001182 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1183 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001184
Brian Osman71a18892017-08-10 10:23:25 -04001185 writer->beginArray("configs");
1186
bsalomon41e4384e2016-01-08 09:12:44 -08001187 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001188 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001189 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1190 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1191 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001192 writer->appendHexU32("e_format_read_pixels",
1193 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001194 writer->appendHexU32(
1195 "e_format_teximage",
1196 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1197 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1198 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1199 writer->appendHexU32("i_for_renderbuffer",
1200 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1201 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001202 }
1203
Brian Osman71a18892017-08-10 10:23:25 -04001204 writer->endArray();
1205 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001206}
1207
bsalomon41e4384e2016-01-08 09:12:44 -08001208bool GrGLCaps::bgraIsInternalFormat() const {
1209 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1210}
1211
bsalomon76148af2016-01-12 11:13:47 -08001212bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1213 GrGLenum* internalFormat, GrGLenum* externalFormat,
1214 GrGLenum* externalType) const {
1215 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1216 externalFormat, externalType)) {
1217 return false;
1218 }
1219 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1220 return true;
1221}
1222
bsalomon76148af2016-01-12 11:13:47 -08001223bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1224 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001225 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001226 externalFormat, externalType)) {
1227 return false;
1228 }
1229 return true;
1230}
1231
1232bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001233 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1234 return true;
1235}
1236
1237bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1238 ExternalFormatUsage usage, GrGLenum* externalFormat,
1239 GrGLenum* externalType) const {
1240 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001241
1242 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1243 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1244
1245 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001246 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1247 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001248 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1249 return false;
1250 }
1251
1252 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1253 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1254
bsalomone9573312016-01-25 14:33:25 -08001255 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1256 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1257 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1258 // texture, not the red component.
1259 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001260 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001261 *externalFormat = GR_GL_ALPHA;
1262 }
1263 }
1264
bsalomon76148af2016-01-12 11:13:47 -08001265 return true;
1266}
1267
brianosman20471892016-12-02 06:43:32 -08001268void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1269 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001270 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001271 /*
1272 Comments on renderability of configs on various GL versions.
1273 OpenGL < 3.0:
1274 no built in support for render targets.
1275 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1276 format RGB, RGBA and NV float formats we don't use.
1277 This is the following:
1278 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1279 RGB10_A2, RGBA12,RGBA16
1280 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1281 since they aren't required by later standards and the driver can simply return
1282 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1283 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1284 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1285 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1286 This adds a lot of additional renderable sized formats, including ALPHA8.
1287 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1288 16F, 32I, 32UI, and 32F variants).
1289 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1290
1291 For both the above extensions we limit ourselves to those that are also required by
1292 OpenGL 3.0.
1293
1294 OpenGL 3.0:
1295 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1296 but are not required to be supported as renderable textures/renderbuffer.
1297 Required renderable color formats:
1298 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1299 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1300 RGB10_A2.
1301 - R11F_G11F_B10F.
1302 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1303 and RG8UI.
1304 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1305 - ALPHA8
1306
1307 OpenGL 3.1, 3.2, 3.3
1308 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1309 OpengGL 3.3, 4.0, 4.1
1310 Adds RGB10_A2UI.
1311 OpengGL 4.2
1312 Adds
1313 - RGB5_A1, RGBA4
1314 - RGB565
1315 OpenGL 4.4
1316 Does away with the separate list and adds a column to the sized internal color format
1317 table. However, no new formats become required color renderable.
1318
1319 ES 2.0
1320 color renderable: RGBA4, RGB5_A1, RGB565
1321 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1322 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1323 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1324 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1325 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1326 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1327
1328 ES 3.0
1329 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1330 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1331 RGB5_A1.
1332 - RGB8 and RGB565.
1333 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1334 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1335 ES 3.1
1336 Adds RGB10_A2, RGB10_A2UI,
1337 ES 3.2
1338 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1339 */
Brian Salomon44804c02018-01-23 16:51:28 -05001340
1341 // Correctness workarounds.
1342 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001343 bool disableSRGBForX86PowerVR = false;
1344 bool disableSRGBWriteControlForAdreno4xx = false;
1345 bool disableR8TexStorageForANGLEGL = false;
1346 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001347 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001348
1349 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1350 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1351 // and GL_RG on FBO textures.
1352 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1353
1354 bool isX86PowerVR = false;
1355#if defined(SK_CPU_X86)
1356 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1357 isX86PowerVR = true;
1358 }
1359#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001360 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1361 // blacklist that device (and any others that might be sharing the same driver).
1362 disableSRGBForX86PowerVR = isX86PowerVR;
1363 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1364
1365 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1366 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1367 // check that we are not going to OpenGL.
1368 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1369
1370 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1371#if defined(SK_BUILD_FOR_MAC)
1372 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1373#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001374 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1375 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001376 }
1377
Brian Salomon71d9d842016-11-03 13:42:00 -04001378 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1379 ConfigInfo::kFBOColorAttachment_Flag;
1380 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001381 if (kNone_MSFBOType != fMSFBOType) {
1382 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1383 }
bsalomon41e4384e2016-01-08 09:12:44 -08001384 GrGLStandard standard = ctxInfo.standard();
1385 GrGLVersion version = ctxInfo.version();
1386
cblume790d5132016-02-29 11:13:29 -08001387 bool texStorageSupported = false;
1388 if (kGL_GrGLStandard == standard) {
1389 // The EXT version can apply to either GL or GLES.
1390 texStorageSupported = version >= GR_GL_VER(4,2) ||
1391 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1392 ctxInfo.hasExtension("GL_EXT_texture_storage");
1393 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001394 texStorageSupported = version >= GR_GL_VER(3,0) ||
1395 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001396 }
1397
cdalton74b8d322016-04-11 14:47:28 -07001398 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1399
Brian Salomone609e812018-01-17 14:00:47 -05001400 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001401
1402 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001403 if (kGL_GrGLStandard == standard) {
1404 textureRedSupport =
1405 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1406 } else {
1407 textureRedSupport =
1408 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1409 }
1410 }
1411
bsalomon30447372015-12-21 09:03:05 -08001412 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1413 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001414 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001415 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001416 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001417 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001418
1419 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1420 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001421 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001422 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001423 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001424 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001425 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1426 if (kGL_GrGLStandard == standard) {
1427 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1428 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001429 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001430 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1431 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1432 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1433 }
egdaniel4999df82016-01-07 17:06:04 -08001434 }
cblume790d5132016-02-29 11:13:29 -08001435 if (texStorageSupported) {
1436 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1437 }
cdalton74b8d322016-04-11 14:47:28 -07001438 if (texelBufferSupport) {
1439 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1440 }
bsalomoncdee0092016-01-08 13:20:12 -08001441 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001442
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001443 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1444 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1445 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1446 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1447 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1448 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1449 // supportedReadPixelsColorType never returns it.
1450 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1451 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1452 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1453 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1454 if (kGL_GrGLStandard == standard) {
1455 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1456 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1457 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1458 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1459 // becomes an issue.
1460 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1461 // but we don't support that just for simplicity's sake.
1462 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1463 } else {
1464 // 3.0 and the extension support this as a render buffer format.
1465 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1466 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1467 }
1468 }
1469 if (texStorageSupported) {
1470 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1471 }
1472 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1473 if (disableRGB8ForMali400) {
1474 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1475 }
1476
1477 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001478 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001479 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001480 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001481
1482 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1483 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1484 // GL_EXT_texture_format_BGRA8888.
1485 bool supportsBGRATexStorage = false;
1486
bsalomon41e4384e2016-01-08 09:12:44 -08001487 if (kGL_GrGLStandard == standard) {
1488 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1489 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1490 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1491 // Since the internal format is RGBA8, it is also renderable.
1492 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1493 allRenderFlags;
1494 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001495 // Since we are using RGBA8 we can use tex storage.
1496 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001497 } else {
1498 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1499 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001500 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1501 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1502 nonMSAARenderFlags;
1503
1504 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1505 supportsBGRATexStorage = true;
1506 }
1507 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1508 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1509 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1510 ConfigInfo::kRenderableWithMSAA_Flag;
1511 }
1512 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001513 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1514 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1515 // driver remembers the external format when the texture is created (with TexImage).
1516 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1517 // We could work around this, but it adds even more state tracking to code that is
1518 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1519 // This also side-steps some ambiguous interactions with the texture storage extension.
1520 if (version >= GR_GL_VER(3,0)) {
1521 // The APPLE extension doesn't make this renderable.
1522 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001523 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001524 }
bsalomon41e4384e2016-01-08 09:12:44 -08001525 }
1526 }
Brian Osman48c99192017-06-02 08:45:06 -04001527
Greg Daniel0ff79b22018-02-15 12:33:33 -05001528 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001529 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001530 }
bsalomoncdee0092016-01-08 13:20:12 -08001531 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001532
brianosmana6359362016-03-21 06:55:37 -07001533 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001534 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001535 if (kGL_GrGLStandard == standard) {
1536 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001537 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001538 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1539 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1540 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001541 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001542 }
1543 }
1544 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001545 if (fSRGBSupport) {
1546 fSRGBWriteControl = true;
1547 }
bsalomon41e4384e2016-01-08 09:12:44 -08001548 } else {
brianosman20471892016-12-02 06:43:32 -08001549 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001550 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001551 fSRGBSupport = false;
1552 }
bsalomon41e4384e2016-01-08 09:12:44 -08001553 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1554 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001555 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001556 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001557 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001558 }
brianosman20471892016-12-02 06:43:32 -08001559 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1560 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1561 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001562 fSRGBSupport = false;
1563 }
brianosman20471892016-12-02 06:43:32 -08001564
1565 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1566 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1567 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1568 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1569 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1570 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1571 // affects Windows.
1572 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1573 fSRGBSupport = false;
1574 }
1575
Brian Osman48c99192017-06-02 08:45:06 -04001576 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1577 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1578 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1579
Brian Osman67999392017-05-31 16:19:34 -04001580 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001581 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001582 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1583 }
Brian Osman67999392017-05-31 16:19:34 -04001584
bsalomon30447372015-12-21 09:03:05 -08001585 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1586 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1587 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1588 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001589 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001590 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001591 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001592 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001593 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001594 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001595 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001596 }
Brian Osman48c99192017-06-02 08:45:06 -04001597 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1598 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001599 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1600 }
bsalomoncdee0092016-01-08 13:20:12 -08001601 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001602 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1603 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1604 // is in this format, for example).
1605 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1606 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1607 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1608 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001609 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001610 GR_GL_BGRA;
1611 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1612 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001613 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001614 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001615 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001616 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001617
brianosmana6359362016-03-21 06:55:37 -07001618 if (texStorageSupported) {
1619 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1620 }
1621 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1622
bsalomon30447372015-12-21 09:03:05 -08001623 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1624 if (this->ES2CompatibilitySupport()) {
1625 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1626 } else {
1627 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1628 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001629 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001630 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001631 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001632 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001633 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1634 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001635 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001636 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1637 }
1638 } else {
1639 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1640 }
cblume790d5132016-02-29 11:13:29 -08001641 // 565 is not a sized internal format on desktop GL. So on desktop with
1642 // 565 we always use an unsized internal format to let the system pick
1643 // the best sized format to convert the 565 data to. Since TexStorage
1644 // only allows sized internal formats we disallow it.
1645 //
1646 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1647 // update.
1648 if (texStorageSupported && kGL_GrGLStandard != standard) {
1649 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1650 }
bsalomoncdee0092016-01-08 13:20:12 -08001651 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001652
1653 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1654 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001655 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001656 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001657 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001658 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001659 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1660 if (kGL_GrGLStandard == standard) {
1661 if (version >= GR_GL_VER(4, 2)) {
1662 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1663 }
1664 } else {
1665 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1666 }
cblume790d5132016-02-29 11:13:29 -08001667 if (texStorageSupported) {
1668 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1669 }
bsalomoncdee0092016-01-08 13:20:12 -08001670 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001671
Brian Osman10fc6fd2018-03-02 11:01:10 -05001672 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1673 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001674 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001675 GR_GL_RGBA;
1676 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1677 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1678 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1679 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1680 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1681 allRenderFlags;
1682 }
1683 if (texStorageSupported) {
1684 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1685 }
1686 if (texelBufferSupport) {
1687 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1688 }
1689 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1690
Greg Danielef59d872017-11-17 16:47:21 -05001691 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1692 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1693
1694 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1695 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1696 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1697 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1698 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001699 }
Greg Danielef59d872017-11-17 16:47:21 -05001700 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1701 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001702 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001703 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1704 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1705 alphaInfo.fFlags |= allRenderFlags;
1706 }
1707
1708 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1709 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1710 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1711 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1712 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001713 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001714 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001715
Brian Osman48c99192017-06-02 08:45:06 -04001716 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1717 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001718 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001719 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1720 }
1721 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1722 }
1723
Brian Salomone609e812018-01-17 14:00:47 -05001724 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001725 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1726 if (texelBufferSupport) {
1727 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1728 }
1729
1730 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1731 } else {
1732 redInfo.fFlags = 0;
1733
1734 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001735 }
bsalomon41e4384e2016-01-08 09:12:44 -08001736
Greg Daniel7af060a2017-12-05 16:27:11 -05001737 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1738 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1739 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1740 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1741 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001742 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001743 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1744 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1745 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1746 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001747 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001748
1749 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1750 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1751 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1752 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1753 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001754 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001755 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1756 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1757
1758#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1759 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001760 if (this->textureRedSupport() ||
1761 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1762 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1763 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1764 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1765 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1766 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1767 }
1768#endif
Brian Osman48c99192017-06-02 08:45:06 -04001769 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001770 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001771 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1772 }
1773 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1774 }
1775
Brian Salomone609e812018-01-17 14:00:47 -05001776 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001777 if (texelBufferSupport) {
1778 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1779 }
1780 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1781 } else {
1782 grayRedInfo.fFlags = 0;
1783 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001784 }
1785
bsalomon41e4384e2016-01-08 09:12:44 -08001786 // Check for [half] floating point texture support
1787 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1788 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1789 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1790 bool hasFPTextures = false;
1791 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001792 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001793 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001794 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001795
1796 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001797 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001798 hasFPTextures = true;
1799 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001800 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001801 }
1802 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001803 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001804 hasFPTextures = true;
1805 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001806 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001807 } else {
1808 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1809 ctxInfo.hasExtension("GL_OES_texture_float")) {
1810 hasFPTextures = true;
1811 }
1812 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1813 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1814 hasHalfFPTextures = true;
1815 }
1816 }
1817 }
bsalomon30447372015-12-21 09:03:05 -08001818
csmartdalton6aa0e112017-02-08 16:14:11 -05001819 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1820 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1821 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1822 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1823 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001824 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001825 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1826 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1827 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001828 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001829 // For now we only enable rendering to float on desktop, because on ES we'd have to
1830 // solve many precision issues and no clients actually want this yet.
1831 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1832 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1833 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1834 }
bsalomon41e4384e2016-01-08 09:12:44 -08001835 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001836 if (texStorageSupported) {
1837 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1838 }
1839 if (texelBufferSupport) {
1840 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1841 }
1842 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001843 }
bsalomon30447372015-12-21 09:03:05 -08001844
Greg Danielef59d872017-11-17 16:47:21 -05001845 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001846 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001847 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001848 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001849 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001850 }
Greg Danielef59d872017-11-17 16:47:21 -05001851 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1852 redHalf.fFormats.fExternalType = redHalfExternalType;
1853 redHalf.fFormatType = kFloat_FormatType;
1854 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1855 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001856 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001857 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001858 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001859 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1860
csmartdalton6aa0e112017-02-08 16:14:11 -05001861 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001862 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001863 redHalf.fFlags |= fpRenderFlags;
1864 }
1865
1866 if (texStorageSupported && !isCommandBufferES2) {
1867 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1868 }
1869
1870 if (texelBufferSupport) {
1871 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001872 }
1873 }
Greg Danielef59d872017-11-17 16:47:21 -05001874 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001875
1876 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1877 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001878 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001879 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001880 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001881 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1882 } else {
1883 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1884 }
bsalomon7928ef62016-01-05 10:26:39 -08001885 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001886 if (hasHalfFPTextures) {
1887 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1888 // ES requires 3.2 or EXT_color_buffer_half_float.
1889 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1890 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1891 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1892 }
1893 }
cblume790d5132016-02-29 11:13:29 -08001894 if (texStorageSupported) {
1895 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1896 }
cdalton74b8d322016-04-11 14:47:28 -07001897 if (texelBufferSupport) {
1898 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1899 }
bsalomoncdee0092016-01-08 13:20:12 -08001900 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001901
bsalomon30447372015-12-21 09:03:05 -08001902 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1903
1904 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001905 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1906 ctxInfo.version() >= GR_GL_VER(3,0));
1907 // All ES versions (thus far) require sized internal formats for render buffers.
1908 // TODO: Always use sized internal format?
1909 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1910
bsalomon30447372015-12-21 09:03:05 -08001911 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001912 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1913 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001914 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001915 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001916 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1917 fConfigTable[i].fFormats.fSizedInternalFormat :
1918 fConfigTable[i].fFormats.fBaseInternalFormat;
1919 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001920 fConfigTable[i].fFormats.fSizedInternalFormat :
1921 fConfigTable[i].fFormats.fBaseInternalFormat;
1922 }
Brian Salomon44804c02018-01-23 16:51:28 -05001923 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1924 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1925 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1926 // in ES.
1927 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1928 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1929 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1930 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001931 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1932 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001933 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1934 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001935 }
1936
bsalomon30447372015-12-21 09:03:05 -08001937 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1938 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1939 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1940 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1941 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001942 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001943 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001944
1945 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1946 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1947 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1948 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001949 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001950 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1951 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1952 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1953 // slot.
1954 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1955 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001956
1957 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1958 // as a base format.
1959 // GL_EXT_texture_format_BGRA8888:
1960 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1961 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1962 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001963 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001964 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1965 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1966 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001967 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001968 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1969 }
1970
bsalomoncdee0092016-01-08 13:20:12 -08001971 // If we don't have texture swizzle support then the shader generator must insert the
1972 // swizzle into shader code.
1973 if (!this->textureSwizzleSupport()) {
1974 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001975 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001976 }
1977 }
1978
bsalomon7f9b2e42016-01-12 13:29:26 -08001979 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1980 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1981 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001982 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001983 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1984 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1985 if (GrPixelConfigIsAlphaOnly(config) &&
1986 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001987 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001988 }
1989 }
1990 }
1991
Greg Daniel81e7bf82017-07-19 14:47:42 -04001992 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1993 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001994 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1995 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001996 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001997 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1998 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001999 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002000 int count;
2001 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
2002 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
2003 1, &count);
2004 if (count) {
2005 int* temp = new int[count];
2006 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
2007 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05002008 // GL has a concept of MSAA rasterization with a single sample but we do not.
2009 if (count && temp[count - 1] == 1) {
2010 --count;
2011 SkASSERT(!count || temp[count -1] > 1);
2012 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04002013 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05002014 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04002015 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002016 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002017 for (int j = 0; j < count; ++j) {
2018 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2019 }
2020 delete[] temp;
2021 }
2022 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002023 // Fake out the table using some semi-standard counts up to the max allowed sample
2024 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002025 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002026 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2027 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2028 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2029 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2030 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002031 // Chrome has a mock GL implementation that returns 0.
2032 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002033
Brian Salomonbdecacf2018-02-02 20:32:49 -05002034 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002035 int count = SK_ARRAY_COUNT(kDefaultSamples);
2036 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002037 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002038 break;
2039 }
2040 }
2041 if (count > 0) {
2042 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2043 }
2044 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002045 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2046 fConfigTable[i].fColorSampleCounts.setCount(1);
2047 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002048 }
2049 }
2050
bsalomon30447372015-12-21 09:03:05 -08002051#ifdef SK_DEBUG
2052 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002053 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002054 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002055 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2056 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002057 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2058 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2059 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2060 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002061 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2062 fConfigTable[i].fFormats.fBaseInternalFormat);
2063 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002064 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002065 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2066 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2067 fConfigTable[i].fFormats.fExternalFormat[j]);
2068 }
2069 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002070 }
2071#endif
2072}
2073
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002074bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
2075 bool dstIsTextureable, bool dstIsGLTexture2D,
2076 GrSurfaceOrigin dstOrigin,
2077 GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
2078 bool srcIsTextureable, bool srcIsGLTexture2D,
2079 GrSurfaceOrigin srcOrigin) const {
2080 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2081 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2082 // many drivers would allow it to work, but ANGLE does not.
2083 if (kGLES_GrGLStandard == fStandard && this->bgraIsInternalFormat() &&
2084 (kBGRA_8888_GrPixelConfig == dstConfig || kBGRA_8888_GrPixelConfig == srcConfig)) {
2085 return false;
2086 }
2087
2088 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
2089 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
2090 return false;
2091 }
2092
2093 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
2094 // texture.
2095 if (!dstIsTextureable) {
2096 return false;
2097 }
2098
2099 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
2100 // is required
2101 if (this->canConfigBeFBOColorAttachment(srcConfig) &&
2102 (!srcIsTextureable || srcIsGLTexture2D) &&
2103 dstIsGLTexture2D &&
2104 dstOrigin == srcOrigin) {
2105 return true;
2106 } else {
2107 return false;
2108 }
2109}
2110
2111bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
2112 bool dstIsTextureable, bool dstIsGLTexture2D,
2113 GrSurfaceOrigin dstOrigin,
2114 GrPixelConfig srcConfig, int srcSampleCnt,
2115 bool srcIsTextureable, bool srcIsGLTexture2D,
2116 GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
2117 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2118 auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
2119 if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
2120 !this->canConfigBeFBOColorAttachment(srcConfig)) {
2121 return false;
2122 }
2123
2124 if (dstIsTextureable && !dstIsGLTexture2D) {
2125 return false;
2126 }
2127 if (srcIsTextureable && !srcIsGLTexture2D) {
2128 return false;
2129 }
2130
2131 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
2132 return false;
2133 }
2134 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
2135 // We would mirror to compensate for origin changes. Note that copySurface is
2136 // specified such that the src and dst rects are the same.
2137 if (dstOrigin != srcOrigin) {
2138 return false;
2139 }
2140 }
2141
2142 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
2143 if (srcSampleCnt > 1) {
2144 if (1 == dstSampleCnt) {
2145 return false;
2146 }
2147 if (SkRect::Make(srcRect) != srcBounds) {
2148 return false;
2149 }
2150 }
2151 }
2152
2153 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
2154 if (dstSampleCnt > 1) {
2155 return false;
2156 }
2157 }
2158
2159 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
2160 if (dstConfig != srcConfig) {
2161 return false;
2162 }
2163 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2164 if (srcSampleCnt > 1 && dstConfig != srcConfig) {
2165 return false;
2166 }
2167 }
2168
2169 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2170 if (srcSampleCnt > 1) {
2171 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
2172 return false;
2173 }
2174 if (dstOrigin != srcOrigin) {
2175 return false;
2176 }
2177 }
2178 }
2179 return true;
2180}
2181
2182bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
2183 return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
2184}
2185
2186static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
2187 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
2188 if (!rt) {
2189 return false;
2190 }
2191 // A RT has a separate MSAA renderbuffer if:
2192 // 1) It's multisampled
2193 // 2) We're using an extension with separate MSAA renderbuffers
2194 // 3) It's not FBO 0, which is special and always auto-resolves
2195 return rt->numColorSamples() > 1 &&
2196 glCaps.usesMSAARenderBuffers() &&
2197 !rt->rtPriv().glRTFBOIDIs0();
2198}
2199
2200bool GrGLCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
2201 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2202 GrSurfaceOrigin dstOrigin = dst->origin();
2203 GrSurfaceOrigin srcOrigin = src->origin();
2204
2205 GrPixelConfig dstConfig = dst->config();
2206 GrPixelConfig srcConfig = src->config();
2207
2208 int dstSampleCnt = 0;
2209 int srcSampleCnt = 0;
2210 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
2211 dstSampleCnt = rtProxy->numColorSamples();
2212 }
2213 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
2214 srcSampleCnt = rtProxy->numColorSamples();
2215 }
2216 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
2217 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
2218
2219 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
2220 // swizzle.
2221 if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
2222 this->shaderCaps()->configOutputSwizzle(dst->config())) {
2223 return false;
2224 }
2225
2226 const GrTextureProxy* dstTex = dst->asTextureProxy();
2227 const GrTextureProxy* srcTex = src->asTextureProxy();
2228
2229 bool dstIsTex2D = dstTex ? dstTex->texPriv().isGLTexture2D() : false;
2230 bool srcIsTex2D = srcTex ? srcTex->texPriv().isGLTexture2D() : false;
2231
2232 // One of the possible requirements for copy as blit is that the srcRect must match the bounds
2233 // of the src surface. If we have a approx fit surface we can't know for sure what the src
2234 // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
2235 // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
2236 // know we will at least be able to do it as a draw.
2237#ifdef SK_DEBUG
2238 if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2239 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2240 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
2241 !src->priv().isExact()) {
2242 SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
2243 }
2244#endif
2245
2246 return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
2247 SkToBool(dstTex), dstIsTex2D, dstOrigin,
2248 srcConfig, has_msaa_render_buffer(src, *this),
2249 SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
2250 this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2251 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2252 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
2253 dstPoint) ||
2254 this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
2255}
2256
Robert Phillipsbf25d432017-04-07 10:08:53 -04002257bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002258 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2259 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002260 // By default, we don't require rects to match.
2261 *rectsMustMatch = false;
2262
2263 // By default, we allow subrects.
2264 *disallowSubrect = false;
2265
Brian Salomon467921e2017-03-06 16:17:12 -05002266 // If the src is a texture, we can implement the blit as a draw assuming the config is
2267 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002268 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002269 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002270 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2271 desc->fConfig = src->config();
2272 return true;
2273 }
2274
Robert Phillipsbf25d432017-04-07 10:08:53 -04002275 {
2276 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2277 // wrapped. In that case the proxy would already be instantiated.
2278 const GrTexture* srcTexture = src->priv().peekTexture();
2279 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2280 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2281 // Not supported for FBO blit or CopyTexSubImage
2282 return false;
2283 }
Brian Salomon467921e2017-03-06 16:17:12 -05002284 }
2285
2286 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2287 // possible and we return false to fallback to creating a render target dst for render-to-
2288 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2289 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002290 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002291 bool rectsMustMatchForBlitFramebuffer = false;
2292 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002293 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002294 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2295 rectsMustMatchForBlitFramebuffer = true;
2296 disallowSubrectForBlitFramebuffer = true;
2297 // Mirroring causes rects to mismatch later, don't allow it.
2298 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002299 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2300 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002301 rectsMustMatchForBlitFramebuffer = true;
2302 // Mirroring causes rects to mismatch later, don't allow it.
2303 originForBlitFramebuffer = src->origin();
2304 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002305 originForBlitFramebuffer = src->origin();
2306 }
2307
2308 // Check for format issues with glCopyTexSubImage2D
2309 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2310 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2311 // then we set up for that, otherwise fail.
2312 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002313 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002314 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002315 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2316 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002317 return true;
2318 }
2319 return false;
2320 }
2321
Robert Phillipsbf25d432017-04-07 10:08:53 -04002322 {
Brian Salomon63e79732017-05-15 21:23:13 -04002323 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2324 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002325 if (srcIsMSAARenderbuffer) {
2326 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2327 // blit or fail.
2328 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002329 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002330 desc->fConfig = src->config();
2331 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2332 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2333 return true;
2334 }
2335 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002336 }
Brian Salomon467921e2017-03-06 16:17:12 -05002337 }
2338
2339 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002340 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002341 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002342 desc->fFlags = kNone_GrSurfaceFlags;
2343 return true;
2344}
2345
Greg Daniel691f5e72018-02-28 14:21:34 -05002346void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2347 const GrContextOptions& contextOptions,
2348 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002349 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2350 // Thus we are blacklisting this extension for now on Adreno4xx devices.
Adrienne Walker0e383942018-05-15 11:33:47 -07002351 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2352 fDriverBugWorkarounds.disable_discard_framebuffer) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002353 fDiscardRenderTargetSupport = false;
2354 fInvalidateFBType = kNone_InvalidateFBType;
2355 }
2356
2357 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2358 // 340.96 and 367.57.
2359 if (kGL_GrGLStandard == ctxInfo.standard() &&
2360 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002361 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002362 fClearTextureSupport = false;
2363 }
2364
2365 // Calling glClearTexImage crashes on the NexusPlayer.
2366 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2367 fClearTextureSupport = false;
2368 }
2369
2370 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2371#ifdef SK_BUILD_FOR_MAC
2372 if (shaderCaps->fGeometryShaderSupport) {
2373 shaderCaps->fGSInvocationsSupport = false;
2374 }
2375#endif
2376
2377 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2378 // shaders. @127.0 is the earliest verified driver to not crash.
2379 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002380 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002381 shaderCaps->fGeometryShaderSupport = false;
2382 }
2383
2384#if defined(__has_feature)
2385#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2386 // See skbug.com/7058
2387 fMapBufferType = kNone_MapBufferType;
2388 fMapBufferFlags = kNone_MapFlags;
2389#endif
2390#endif
2391
2392 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2393 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2394 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2395 // unclear whether this really affects a wide range of devices.
2396 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002397 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002398 fMapBufferType = kNone_MapBufferType;
2399 fMapBufferFlags = kNone_MapFlags;
2400 }
2401
2402 // TODO: re-enable for ANGLE
2403 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2404 fTransferBufferType = kNone_TransferBufferType;
2405 }
2406
2407 // Using MIPs on this GPU seems to be a source of trouble.
2408 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2409 fMipMapSupport = false;
2410 }
2411
2412 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2413 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2414 // around a driver bug related to gl_FragCoord.
2415 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2416 fMaxClipAnalyticFPs = 0;
2417 }
2418
2419#ifndef SK_BUILD_FOR_IOS
2420 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2421 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2422 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2423 ctxInfo.driver() != kChromium_GrGLDriver)) {
2424 fUseDrawToClearColor = true;
2425 }
2426#endif
2427
2428 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2429 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2430 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2431 fUseDrawToClearColor = true;
2432 }
2433
2434#ifdef SK_BUILD_FOR_MAC
2435 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2436 // full screen clears
2437 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2438 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002439 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2440 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2441 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2442 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002443 fUseDrawToClearColor = true;
2444 }
2445#endif
2446
2447 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2448 // bugs seems to involve clearing too much and not skipping the clear.
2449 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2450 // but only for D3D11 ANGLE.
2451 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2452 fUseDrawToClearColor = true;
2453 }
2454
2455 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2456 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002457 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002458 fUseDrawToClearStencilClip = true;
2459 }
2460 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2461 }
2462
Adrienne Walker94f585e2018-05-15 11:47:07 -07002463 if (fDriverBugWorkarounds.gl_clear_broken) {
2464 fUseDrawToClearColor = true;
2465 fUseDrawToClearStencilClip = true;
2466 }
2467
Brian Salomon01b476a2018-01-23 11:06:41 -05002468 // This was reproduced on the following configurations:
2469 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2470 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2471 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2472 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2473 // and not produced on:
2474 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2475 // The particular lines that get dropped from test images varies across different devices.
2476 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002477 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002478 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2479 }
2480
Chris Dalton6f5e77a2018-04-23 21:14:42 -06002481 if (kIntelSkylake_GrGLRenderer == ctxInfo.renderer() ||
2482 (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2483 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer())) {
Chris Daltonda40cd22018-04-16 13:19:58 -06002484 fRequiresFlushBetweenNonAndInstancedDraws = true;
2485 }
2486
Brian Salomon01b476a2018-01-23 11:06:41 -05002487 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2488 // given 1 << 15 or more instances.
2489 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2490 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
Adrienne Walker001cae02018-05-15 11:38:44 -07002491 } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
2492 fMaxInstancesPerDrawArraysWithoutCrashing = 0x4000000;
Brian Salomon01b476a2018-01-23 11:06:41 -05002493 }
2494
2495 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002496 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002497 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2498 fUseDrawInsteadOfAllRenderTargetWrites = true;
2499 }
2500
2501 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2502 fSampleShadingSupport = false;
2503 }
2504
2505#ifdef SK_BUILD_FOR_MAC
2506 static constexpr bool isMAC = true;
2507#else
2508 static constexpr bool isMAC = false;
2509#endif
2510
2511 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2512 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2513 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2514 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2515 if (fMipMapLevelAndLodControlSupport &&
2516 (contextOptions.fDoManualMipmapping ||
2517 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2518 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2519 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2520 fDoManualMipmapping = true;
2521 }
2522
2523 // See http://crbug.com/710443
2524#ifdef SK_BUILD_FOR_MAC
2525 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2526 fClearToBoundaryValuesIsBroken = true;
2527 }
2528#endif
2529 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2530 fDrawArraysBaseVertexIsBroken = true;
2531 }
2532
Brian Salomon01b476a2018-01-23 11:06:41 -05002533 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2534 // Galaxy S7.
2535 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2536 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2537 shaderCaps->fFBFetchSupport = false;
2538 }
2539
Brian Salomon01b476a2018-01-23 11:06:41 -05002540 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2541 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2542
2543 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2544 // function that may require a gradient calculation inside a conditional block may return
2545 // undefined results". This appears to be an issue with the 'any' call since even the simple
2546 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2547 // from our GrTextureDomain processor.
2548 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2549
2550 // Known issue on at least some Intel platforms:
2551 // http://code.google.com/p/skia/issues/detail?id=946
2552 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2553 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2554 }
2555
Chris Dalton0090ef62018-03-28 17:35:00 -06002556 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002557 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2558 // so we must do the abs first in a separate expression.
2559 shaderCaps->fCanUseMinAndAbsTogether = false;
2560
2561 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2562 // must avoid this condition.
2563 shaderCaps->fCanUseFractForNegativeValues = false;
2564 }
2565
2566 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2567 // thus must us -1.0 * %s.x to work correctly
2568 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2569 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2570 }
2571
2572 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2573 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2574 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2575 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2576 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2577 }
2578
2579 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2580 // the original dst color when reading the outColor even after being written to. By using a
2581 // local outColor we can work around this bug.
2582 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2583 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2584 }
2585
2586 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2587 // color, and that uniform contains an opaque color, and the output of the shader is only based
2588 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2589 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2590 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2591 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2592 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2593 shaderCaps->fMustObfuscateUniformColor = true;
2594 }
2595#ifdef SK_BUILD_FOR_WIN
2596 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2597 //
2598 // Basically, if a shader has a construct like:
2599 //
2600 // float x = someCondition ? someValue : 0;
2601 // float2 result = (0 == x) ? float2(x, x)
2602 // : float2(2 * x / x, 0);
2603 //
2604 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2605 // we've explicitly guarded the division with a check against zero. This manifests in much
2606 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2607 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2608 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2609 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2610 }
2611#endif
2612
2613 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2614 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2615 // that the interpolation of vertex shader outputs is quite inaccurate.
2616 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2617 shaderCaps->fCanUseFragCoord = false;
2618 shaderCaps->fInterpolantsAreInaccurate = true;
2619 }
2620
Chris Dalton0090ef62018-03-28 17:35:00 -06002621 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2622 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2623 shaderCaps->fCanUseFragCoord = false;
2624 }
2625
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002626 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2627 // (Are they implemented with fp16?)
2628 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2629 shaderCaps->fIncompleteShortIntPrecision = true;
2630 }
2631
Brian Salomon01b476a2018-01-23 11:06:41 -05002632 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2633 // for now until its own blacklists can be updated.
2634 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2635 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2636 kIntel_GrGLDriver == ctxInfo.driver() ||
2637 kChromium_GrGLDriver == ctxInfo.driver()) {
2638 fBlendEquationSupport = kBasic_BlendEquationSupport;
2639 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2640 }
2641
2642 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2643 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002644 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002645 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002646 fBlendEquationSupport = kBasic_BlendEquationSupport;
2647 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2648 }
2649
Adrienne Walker68314842018-05-14 14:02:53 -07002650 if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
2651 fBlendEquationSupport = kBasic_BlendEquationSupport;
2652 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2653 }
2654
Brian Salomon01b476a2018-01-23 11:06:41 -05002655 if (this->advancedBlendEquationSupport()) {
2656 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002657 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002658 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2659 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2660 (1 << kColorBurn_GrBlendEquation);
2661 }
2662 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2663 // Blacklist color-burn on ARM until the fix is released.
2664 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2665 }
2666 }
2667
2668 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2669 if (fMultisampleDisableSupport &&
2670 this->shaderCaps()->dualSourceBlendingSupport() &&
2671 this->shaderCaps()->pathRenderingSupport() &&
2672 fUsesMixedSamples &&
2673#if GR_TEST_UTILS
2674 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2675#endif
2676 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2677 kChromium_GrGLDriver == ctxInfo.driver())) {
2678 fDiscardRenderTargetSupport = false;
2679 fInvalidateFBType = kNone_InvalidateFBType;
2680 }
Brian Osmanc585e202018-04-04 14:08:27 -04002681
Brian Osman061020e2018-04-17 14:22:15 -04002682 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2683 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2684 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2685 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002686 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2687 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002688 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002689 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002690 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2691 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002692 }
Brian Osman2fa53742018-05-03 15:05:12 -04002693
2694#ifdef SK_BUILD_FOR_IOS
2695 // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
2696 // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
2697 // is to just blacklist the feature.
2698 // https://github.com/flutter/flutter/issues/16718
2699 // https://bugreport.apple.com/web/?problemID=39948888
2700 fUnpackRowLengthSupport = false;
2701#endif
Brian Salomon01b476a2018-01-23 11:06:41 -05002702}
2703
csmartdaltone0d36292016-07-29 08:14:20 -07002704void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002705 if (options.fDisableDriverCorrectnessWorkarounds) {
2706 SkASSERT(!fDoManualMipmapping);
2707 SkASSERT(!fClearToBoundaryValuesIsBroken);
2708 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2709 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2710 SkASSERT(!fUseDrawToClearColor);
2711 SkASSERT(!fUseDrawToClearStencilClip);
2712 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2713 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2714 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Chris Daltonda40cd22018-04-16 13:19:58 -06002715 SkASSERT(!fRequiresFlushBetweenNonAndInstancedDraws);
Brian Salomon01b476a2018-01-23 11:06:41 -05002716 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002717 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2718 fUseDrawToClearColor = false;
2719 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2720 fUseDrawToClearColor = true;
2721 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002722 if (options.fDoManualMipmapping) {
2723 fDoManualMipmapping = true;
2724 }
csmartdaltone0d36292016-07-29 08:14:20 -07002725}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002726
Brian Salomon3d86a192018-02-27 16:46:11 -05002727bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2728 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2729 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2730 if (tex->hasBaseLevelBeenBoundToFBO()) {
2731 return false;
2732 }
2733 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002734 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002735 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2736 return false;
2737 }
2738 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2739 return false;
2740 }
2741 return SkToBool(surface->asTexture());
2742 }
2743 return true;
2744}
2745
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002746bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2747 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2748 // We don't support reading pixels directly from EXTERNAL textures as it would require
2749 // binding the texture to a FBO.
2750 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2751 return false;
2752 }
2753 }
2754 return true;
2755}
2756
2757GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2758 GrColorType dstColorType) const {
2759 // For now, we mostly report the read back format that is required by the ES spec without
2760 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2761 // this as makes sense to increase performance and correctness.
2762 switch (fConfigTable[config].fFormatType) {
2763 case kNormalizedFixedPoint_FormatType:
2764 return GrColorType::kRGBA_8888;
2765 case kFloat_FormatType:
2766 // We cheat a little here and allow F16 read back if the src and dst match.
2767 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2768 return GrColorType::kRGBA_F16;
2769 }
2770 if ((kAlpha_half_GrPixelConfig == config ||
2771 kAlpha_half_as_Red_GrPixelConfig == config) &&
2772 GrColorType::kAlpha_F16 == dstColorType) {
2773 return GrColorType::kAlpha_F16;
2774 }
2775 // And similar for full float RG.
2776 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2777 return GrColorType::kRG_F32;
2778 }
2779 return GrColorType::kRGBA_F32;
2780 }
2781 return GrColorType::kUnknown;
2782}
2783
Greg Daniel2a303902018-02-20 10:25:54 -05002784bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002785 GrGLFramebufferInfo fbInfo;
2786 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002787 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002788 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002789}
2790
Brian Salomonbdecacf2018-02-02 20:32:49 -05002791int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2792 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002793 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002794 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002795 return 0;
2796 }
2797
Brian Salomonbdecacf2018-02-02 20:32:49 -05002798 if (1 == requestedCount) {
2799 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2800 }
2801
Greg Daniel81e7bf82017-07-19 14:47:42 -04002802 for (int i = 0; i < count; ++i) {
2803 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
Adrienne Walkerd7c79782018-05-15 11:41:24 -07002804 int count = fConfigTable[config].fColorSampleCounts[i];
2805 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
2806 count = SkTMin(count, 4);
2807 }
2808 return count;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002809 }
2810 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002811 return 0;
2812}
2813
2814int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2815 const auto& table = fConfigTable[config].fColorSampleCounts;
2816 if (!table.count()) {
2817 return 0;
2818 }
Adrienne Walker3a69c742018-05-21 11:05:48 -07002819 int count = table[table.count() - 1];
2820 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
2821 count = SkTMin(count, 4);
2822 }
2823 return count;
Brian Salomond653cac2018-02-01 13:58:00 -05002824}
2825
Greg Danielfaa095e2017-12-19 13:15:02 -05002826bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2827 GrGLStandard standard) {
2828 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002829
2830 switch (ct) {
2831 case kUnknown_SkColorType:
2832 return false;
2833 case kAlpha_8_SkColorType:
2834 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002835 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002836 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002837 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002838 }
2839 break;
2840 case kRGB_565_SkColorType:
2841 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002842 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002843 }
2844 break;
2845 case kARGB_4444_SkColorType:
2846 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002847 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002848 }
2849 break;
2850 case kRGBA_8888_SkColorType:
2851 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002852 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002853 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002854 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002855 }
2856 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002857 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002858 if (GR_GL_RGB8 == format) {
2859 *config = kRGB_888_GrPixelConfig;
2860 }
2861 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002862 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002863 if (GR_GL_RGBA8 == format) {
2864 if (kGL_GrGLStandard == standard) {
2865 *config = kBGRA_8888_GrPixelConfig;
2866 }
2867 } else if (GR_GL_BGRA8 == format) {
2868 if (kGLES_GrGLStandard == standard) {
2869 *config = kBGRA_8888_GrPixelConfig;
2870 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002871 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002872 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002873 }
2874 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002875 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002876 if (GR_GL_RGB10_A2 == format) {
2877 *config = kRGBA_1010102_GrPixelConfig;
2878 }
2879 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002880 case kRGB_101010x_SkColorType:
2881 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002882 case kGray_8_SkColorType:
2883 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002884 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002885 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002886 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002887 }
2888 break;
2889 case kRGBA_F16_SkColorType:
2890 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002891 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002892 }
2893 break;
2894 }
2895
Greg Danielfaa095e2017-12-19 13:15:02 -05002896 return kUnknown_GrPixelConfig != *config;
2897}
2898
2899bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2900 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002901 GrGLTextureInfo texInfo;
2902 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002903 return false;
2904 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002905 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002906}
2907
2908bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2909 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002910 GrGLFramebufferInfo fbInfo;
2911 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002912 return false;
2913 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002914 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002915}
2916
Robert Phillipsfc711a22018-02-13 17:03:00 -05002917bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2918 GrPixelConfig* config) const {
2919 const GrGLenum* glFormat = format.getGLFormat();
2920 if (!glFormat) {
2921 return false;
2922 }
2923 return validate_sized_format(*glFormat, ct, config, fStandard);
2924}