blob: 39520189d79db87953752479f7586265d3a6c831 [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) {
224 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
225 // We also require textureSize() support for rectangle 2D samplers which was added in
226 // GLSL 1.40.
227 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
228 fRectangleTextureSupport = true;
229 }
bsalomone179a912016-01-20 06:18:10 -0800230 }
kkinnunene06ed252016-02-16 23:15:40 -0800231 } else {
232 // Command buffer exposes this in GL ES context for Chromium reasons,
233 // but it should not be used. Also, at the time of writing command buffer
234 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800235 }
236
bsalomoncdee0092016-01-08 13:20:12 -0800237 if (kGL_GrGLStandard == standard) {
238 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
239 fTextureSwizzleSupport = true;
240 }
241 } else {
242 if (version >= GR_GL_VER(3,0)) {
243 fTextureSwizzleSupport = true;
244 }
245 }
246
cblume09bd2c02016-03-01 14:08:28 -0800247 if (kGL_GrGLStandard == standard) {
248 fMipMapLevelAndLodControlSupport = true;
249 } else if (kGLES_GrGLStandard == standard) {
250 if (version >= GR_GL_VER(3,0)) {
251 fMipMapLevelAndLodControlSupport = true;
252 }
253 }
254
bsalomon88c7b982015-07-31 11:20:16 -0700255#ifdef SK_BUILD_FOR_WIN
256 // We're assuming that on Windows Chromium we're using ANGLE.
257 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
258 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700259 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700260 fRGBA8888PixelsOpsAreSlow = isANGLE;
261 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
262 // check DX11 ANGLE.
263 fPartialFBOReadIsSlow = isANGLE;
264#endif
265
ericrkb4ecabd2016-03-11 15:18:20 -0800266 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
267 bool isMAC = false;
268#ifdef SK_BUILD_FOR_MAC
269 isMAC = true;
270#endif
271
272 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
273 // vis-versa.
274 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
275
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500276 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
277 fUseBufferDataNullHint = false;
278 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
279 fUseBufferDataNullHint = true;
280 }
281
Brian Salomond17b4a62017-05-23 16:53:47 -0400282 if (kGL_GrGLStandard == standard) {
283 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400284 fClearTextureSupport = true;
285 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500286 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
287 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400288 }
289
cdalton4cd67132015-06-10 19:23:46 -0700290 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700291 * GrShaderCaps fields
292 **************************************************************************/
293
egdaniel0a482332015-10-26 08:59:10 -0700294 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700295 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500296 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700297
Brian Osman195c05b2017-08-30 15:14:04 -0400298 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
299#if GR_TEST_UTILS
300 if (contextOptions.fSuppressPathRendering) {
301 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700302 }
Brian Osman195c05b2017-08-30 15:14:04 -0400303#endif
egdaniel05ded892015-10-26 07:38:05 -0700304
egdaniel05ded892015-10-26 07:38:05 -0700305 // Enable supported shader-related caps
306 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500307 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700308 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
309 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600310
Brian Salomon1edc5b92016-11-29 13:43:46 -0500311 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600312
egdaniel05ded892015-10-26 07:38:05 -0700313 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500314 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700315 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600316 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600317 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
318 shaderCaps->fGSInvocationsSupport = true;
319 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
320 shaderCaps->fGSInvocationsSupport = true;
321 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
322 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600323 }
324
Brian Salomon1edc5b92016-11-29 13:43:46 -0500325 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800326 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500327 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500328 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700329
Brian Salomon1edc5b92016-11-29 13:43:46 -0500330 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700331 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800332
Chris Daltonfaca00d2018-01-19 15:56:07 -0700333 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
334 // backup impl that only uses vertex shaders.
335 if (kARM_GrGLVendor != ctxInfo.vendor()) {
336 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
337 shaderCaps->fGeometryShaderSupport = true;
338 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
339 shaderCaps->fGeometryShaderSupport = true;
340 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
341 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700342 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500343 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700344
Brian Salomon1edc5b92016-11-29 13:43:46 -0500345 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800346 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700347 }
348
cdalton9c3f1432016-03-11 10:07:37 -0800349 // Protect ourselves against tracking huge amounts of texture state.
350 static const uint8_t kMaxSaneSamplers = 32;
351 GrGLint maxSamplers;
352 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500353 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
354 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800355 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500356 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800357 }
358 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500359 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800360 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500361 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800362
Brian Salomonbbf05752017-11-30 11:30:48 -0500363 // This is all *very* approximate.
364 switch (ctxInfo.vendor()) {
365 case kNVIDIA_GrGLVendor:
366 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
367 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
368 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
369 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500370 case kImagination_GrGLVendor:
371 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
372 // it is always a win to use multitexturing.
373 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
374 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
375 std::numeric_limits<size_t>::max();
376 }
377 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500378 case kATI_GrGLVendor:
379 // So far no AMD GPU shows a performance difference. A tie goes to disabling
380 // multitexturing for simplicity's sake.
381 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
382 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500383 default:
384 break;
385 }
386
csmartdalton485a1202016-07-13 10:16:32 -0700387 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
388 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
389 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
390 // limit this decision to specific GPU families rather than basing it on the vendor alone.
391 if (!GR_GL_MUST_USE_VBO &&
392 !fIsCoreProfile &&
393 (kARM_GrGLVendor == ctxInfo.vendor() ||
394 kImagination_GrGLVendor == ctxInfo.vendor() ||
395 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
396 fPreferClientSideDynamicBuffers = true;
397 }
398
Eric Karl5c779752017-05-08 12:02:07 -0700399 if (!contextOptions.fAvoidStencilBuffers) {
400 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
401 this->initFSAASupport(contextOptions, ctxInfo, gli);
402 this->initStencilSupport(ctxInfo);
403 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400404
405 // Setup blit framebuffer
406 if (kGL_GrGLStandard != ctxInfo.standard()) {
407 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
408 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
409 kNoMSAADst_BlitFramebufferFlag |
410 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
411 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
412 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
413 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
414 // limitations.
415 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
416 kResolveMustBeFull_BlitFrambufferFlag |
417 kNoMSAADst_BlitFramebufferFlag |
418 kNoFormatConversion_BlitFramebufferFlag |
419 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
420 }
421 } else {
422 if (fUsesMixedSamples ||
423 ctxInfo.version() >= GR_GL_VER(3,0) ||
424 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
425 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
426 fBlitFramebufferFlags = 0;
427 }
428 }
429
cdalton1dd05422015-06-12 09:01:18 -0700430 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000431
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000432 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000433 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
434 // extension includes glMapBuffer.
435 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
436 fMapBufferFlags |= kSubset_MapFlag;
437 fMapBufferType = kMapBufferRange_MapBufferType;
438 } else {
439 fMapBufferType = kMapBuffer_MapBufferType;
440 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000441 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000442 // Unextended GLES2 doesn't have any buffer mapping.
443 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800444 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800445 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
446 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800447 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
448 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
449 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000450 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
451 fMapBufferFlags = kCanMap_MapFlag;
452 fMapBufferType = kMapBuffer_MapBufferType;
453 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000454 }
455
jvanverthd7a2c1f2015-12-07 07:36:44 -0800456 if (kGL_GrGLStandard == standard) {
457 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
458 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700459 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500460 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400461 if (version >= GR_GL_VER(3, 0) ||
462 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
463 // GL_EXT_unpack_subimage needed to support subtexture rectangles
464 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800465 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400466// TODO: get transfer buffers working in Chrome
467// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
468// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800469 }
470 }
471
joshualitte5b74c62015-06-01 14:17:47 -0700472 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
473 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700474 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700475#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500476 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
477 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
478 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700479 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700480#else
cdalton397536c2016-03-25 12:15:03 -0700481 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700482#endif
joshualitte5b74c62015-06-01 14:17:47 -0700483 }
484
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000485 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000486 fNPOTTextureTileSupport = true;
487 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000488 } else {
489 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000490 // ES3 has no limitations.
491 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
492 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000493 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
494 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
495 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
496 // to alllow arbitrary wrap modes, however.
497 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000498 }
499
bsalomon@google.combcce8922013-03-25 15:38:39 +0000500 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
Adrienne Walker724afe82018-05-15 11:36:26 -0700501
502 if (fDriverBugWorkarounds.max_texture_size_limit_4096) {
503 fMaxTextureSize = SkTMin(fMaxTextureSize, 4096);
504 }
505
bsalomon@google.combcce8922013-03-25 15:38:39 +0000506 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
507 // Our render targets are always created with textures as the color
508 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000509 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700510 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
511
512 if (kARM_GrGLVendor == ctxInfo.vendor()) {
513 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
514 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
515 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000516
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000517 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
518
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000519 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700520 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000521
robertphillips1b8e1b52015-06-24 06:54:10 -0700522#if 0
523 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
524 kQualcomm_GrGLVendor != ctxInfo.vendor();
525#endif
526
csmartdalton9bc11872016-08-09 12:42:47 -0700527 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
528 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700529 }
530
robertphillips63926682015-08-20 09:39:02 -0700531#ifdef SK_BUILD_FOR_WIN
532 // On ANGLE deferring flushes can lead to GPU starvation
533 fPreferVRAMUseOverFlushes = !isANGLE;
534#endif
535
bsalomon7dea7b72015-08-19 08:26:51 -0700536 if (kChromium_GrGLDriver == ctxInfo.driver()) {
537 fMustClearUploadedBufferData = true;
538 }
539
bsalomond08ea5f2015-02-20 06:58:13 -0800540 if (kGL_GrGLStandard == standard) {
541 // ARB allows mixed size FBO attachments, EXT does not.
542 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
543 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
544 fOversizedStencilSupport = true;
545 } else {
546 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
547 }
548 } else {
549 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
550 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
551 }
552
joshualitt58001552015-06-26 12:46:36 -0700553 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700554 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
555 ctxInfo.hasExtension("GL_ARB_draw_indirect");
556 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
557 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700558 (fDrawIndirectSupport &&
559 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700560 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700561 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800562 } else {
563 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700564 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
565 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
566 fBaseInstanceSupport = fDrawIndirectSupport &&
567 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700568 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800569 }
570
ethannicholas28ef4452016-03-25 09:26:03 -0700571 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500572 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700573 fSampleShadingSupport = true;
574 }
575 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
576 fSampleShadingSupport = true;
577 }
578
jvanverth84741b32016-09-30 08:39:02 -0700579 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
580 if (kGL_GrGLStandard == standard) {
581 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
582 fFenceSyncSupport = true;
583 }
Brian Osman93a23462017-06-21 15:13:39 -0400584 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700585 fFenceSyncSupport = true;
586 }
587
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400588 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500589 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500590
brianosman20471892016-12-02 06:43:32 -0800591 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500592
brianosman851c2382016-12-07 10:03:25 -0800593 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
594 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800595
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400596 if (kGL_GrGLStandard == standard) {
597 if (version >= GR_GL_VER(4, 1)) {
598 fProgramBinarySupport = true;
599 }
600 } else if (version >= GR_GL_VER(3, 0)) {
601 fProgramBinarySupport = true;
602 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400603 if (fProgramBinarySupport) {
604 GrGLint count;
605 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
606 fProgramBinarySupport = count > 0;
607 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400608
bsalomoncdee0092016-01-08 13:20:12 -0800609 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
610 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800611 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700612
Brian Salomon01b476a2018-01-23 11:06:41 -0500613 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
614 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
615 }
616
cdalton4cd67132015-06-10 19:23:46 -0700617 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500618 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700619
Brian Salomon01b476a2018-01-23 11:06:41 -0500620 // For now these two are equivalent but we could have dst read in shader via some other method.
621 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000622}
623
egdaniel472d44e2015-10-22 08:20:00 -0700624const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
625 bool isCoreProfile) {
626 switch (generation) {
627 case k110_GrGLSLGeneration:
628 if (kGLES_GrGLStandard == standard) {
629 // ES2s shader language is based on version 1.20 but is version
630 // 1.00 of the ES language.
631 return "#version 100\n";
632 } else {
633 SkASSERT(kGL_GrGLStandard == standard);
634 return "#version 110\n";
635 }
636 case k130_GrGLSLGeneration:
637 SkASSERT(kGL_GrGLStandard == standard);
638 return "#version 130\n";
639 case k140_GrGLSLGeneration:
640 SkASSERT(kGL_GrGLStandard == standard);
641 return "#version 140\n";
642 case k150_GrGLSLGeneration:
643 SkASSERT(kGL_GrGLStandard == standard);
644 if (isCoreProfile) {
645 return "#version 150\n";
646 } else {
647 return "#version 150 compatibility\n";
648 }
649 case k330_GrGLSLGeneration:
650 if (kGLES_GrGLStandard == standard) {
651 return "#version 300 es\n";
652 } else {
653 SkASSERT(kGL_GrGLStandard == standard);
654 if (isCoreProfile) {
655 return "#version 330\n";
656 } else {
657 return "#version 330 compatibility\n";
658 }
659 }
cdalton33ad7012016-02-22 07:55:44 -0800660 case k400_GrGLSLGeneration:
661 SkASSERT(kGL_GrGLStandard == standard);
662 if (isCoreProfile) {
663 return "#version 400\n";
664 } else {
665 return "#version 400 compatibility\n";
666 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500667 case k420_GrGLSLGeneration:
668 SkASSERT(kGL_GrGLStandard == standard);
669 if (isCoreProfile) {
670 return "#version 420\n";
671 }
672 else {
673 return "#version 420 compatibility\n";
674 }
egdaniel472d44e2015-10-22 08:20:00 -0700675 case k310es_GrGLSLGeneration:
676 SkASSERT(kGLES_GrGLStandard == standard);
677 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800678 case k320es_GrGLSLGeneration:
679 SkASSERT(kGLES_GrGLStandard == standard);
680 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700681 }
682 return "<no version>";
683}
684
Chris Dalton47c8ed32017-11-15 18:27:09 -0700685bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
686 if (kGLES_GrGLStandard != ctxInfo.standard() &&
687 ctxInfo.version() < GR_GL_VER(4,1) &&
688 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
689 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
690 return true;
691 }
692 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
693 // geometry shaders don't have lower precision than vertex and fragment.
694 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
695 GrGLint range[2];
696 GrGLint bits;
697 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
698 if (range[0] < 127 || range[1] < 127 || bits < 23) {
699 return false;
700 }
701 }
702 return true;
703}
704
705void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700706 GrGLStandard standard = ctxInfo.standard();
707 GrGLVersion version = ctxInfo.version();
708
709 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500710 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700711 **************************************************************************/
712
Brian Salomon1edc5b92016-11-29 13:43:46 -0500713 GrShaderCaps* shaderCaps = fShaderCaps.get();
714 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700715 if (kGLES_GrGLStandard == standard) {
716 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500717 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
718 shaderCaps->fFBFetchSupport = true;
719 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
720 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700721 }
722 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
723 // 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 -0500724 shaderCaps->fFBFetchNeedsCustomOutput = false;
725 shaderCaps->fFBFetchSupport = true;
726 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
727 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700728 }
729 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
730 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500731 shaderCaps->fFBFetchNeedsCustomOutput = false;
732 shaderCaps->fFBFetchSupport = true;
733 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
734 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700735 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500736 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700737 }
738
cdaltonc08f1962016-02-12 12:14:06 -0800739 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500740 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800741 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500742 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800743 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
744 }
Brian Salomon41274562017-09-15 09:40:03 -0700745 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
746 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
747 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800748 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500749 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800750 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
751 } else {
Brian Osman71a69952018-05-07 17:07:35 -0400752 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation") &&
753 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration /* GLSL ES 3.0 */) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500754 shaderCaps->fNoPerspectiveInterpolationSupport = true;
755 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800756 "GL_NV_shader_noperspective_interpolation";
757 }
758 }
759
Brian Salomon1edc5b92016-11-29 13:43:46 -0500760 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
761 shaderCaps->fGLSLGeneration,
762 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800763
Brian Salomon1edc5b92016-11-29 13:43:46 -0500764 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
765 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800766 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800767
768 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500769 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800770 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
771 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500772 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800773 }
774
775 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500776 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800777 }
778
cdalton9c3f1432016-03-11 10:07:37 -0800779 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400780 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
781 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400782 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400783 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
784 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
785 // At least one driver has been found that has this extension without the "GL_" prefix.
786 shaderCaps->fExternalTextureSupport = true;
787 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800788 }
789 }
790
cdaltonc04ce672016-03-11 14:07:38 -0800791 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500792 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800793 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500794 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700795 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
796 }
797
Brian Salomon1edc5b92016-11-29 13:43:46 -0500798 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700799 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500800 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700801 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
802 } else {
803 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
804 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500805 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700806 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500807 shaderCaps->fTexelBufferSupport = true;
808 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700809 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500810 shaderCaps->fTexelBufferSupport = true;
811 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700812 }
cdaltonc04ce672016-03-11 14:07:38 -0800813 }
814 }
815
Chris Dalton1d616352017-05-31 12:51:23 -0600816 if (kGL_GrGLStandard == standard) {
817 shaderCaps->fVertexIDSupport = true;
818 } else {
819 // Desktop GLSL 3.30 == ES GLSL 3.00.
820 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
821 }
822
Chris Dalton7c7ff032018-03-28 20:09:58 -0600823 if (kGL_GrGLStandard == standard) {
824 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
825 } else {
826 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
827 }
828
Chris Dalton47c8ed32017-11-15 18:27:09 -0700829 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
830 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700831}
832
kkinnunencfe62e32015-07-01 02:58:50 -0700833bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700834 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
835
836 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700837 return false;
838 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700839
kkinnunencfe62e32015-07-01 02:58:50 -0700840 if (kGL_GrGLStandard == ctxInfo.standard()) {
841 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
842 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
843 return false;
844 }
845 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700846 if (!hasChromiumPathRendering &&
847 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700848 return false;
849 }
850 }
851 // We only support v1.3+ of GL_NV_path_rendering which allows us to
852 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
853 // additions are detected by checking the existence of the function.
854 // We also use *Then* functions that not all drivers might have. Check
855 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800856 if (!gli->fFunctions.fStencilThenCoverFillPath ||
857 !gli->fFunctions.fStencilThenCoverStrokePath ||
858 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
859 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
860 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700861 return false;
862 }
863 return true;
864}
bsalomon1aa20292016-01-22 08:16:09 -0800865
Brian Salomon71d9d842016-11-03 13:42:00 -0400866bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800867 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800868 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800869 std::function<bool ()> bindRenderTarget,
870 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400871 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800872 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400873 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800874 return false;
875 }
bsalomon7928ef62016-01-05 10:26:39 -0800876
bsalomon76148af2016-01-12 11:13:47 -0800877 GrGLenum readFormat;
878 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400879 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800880 return false;
881 }
882
bsalomon1aa20292016-01-22 08:16:09 -0800883 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800884 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
885 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
886 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
887 // 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 -0500888 // The manual does not seem to fully match the spec as the spec allows integer formats
889 // when the bound color buffer is an integer buffer. It doesn't specify which integer
890 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500891 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
892 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
893 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800894 return false;
895 }
896 // There is also a set of allowed types, but all the types we use are in the set:
897 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
898 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
899 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
900 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
901 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
902 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
903 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800904 return true;
piotaixre4b23142014-10-02 10:57:53 -0700905 }
bsalomon7928ef62016-01-05 10:26:39 -0800906
bsalomon76148af2016-01-12 11:13:47 -0800907 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500908 switch (fConfigTable[surfaceConfig].fFormatType) {
909 case kNormalizedFixedPoint_FormatType:
910 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
911 return true;
912 }
913 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500914 case kFloat_FormatType:
915 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
916 return true;
917 }
918 break;
bsalomon7928ef62016-01-05 10:26:39 -0800919 }
920
Brian Salomon71d9d842016-11-03 13:42:00 -0400921 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800922 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400923 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800924 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800925 if (!bindRenderTarget()) {
926 return false;
927 }
928 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
929 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800930 rpFormat->fFormat = format;
931 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800932 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800933 }
934
Brian Salomon71d9d842016-11-03 13:42:00 -0400935 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
936 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700937}
938
Eric Karl5c779752017-05-08 12:02:07 -0700939void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
940 const GrGLInterface* gli) {
941 // We need dual source blending and the ability to disable multisample in order to support mixed
942 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
943 // renderer is available and enabled; no other path renderers support this feature.
944 if (fMultisampleDisableSupport &&
945 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400946 this->shaderCaps()->pathRenderingSupport()
947#if GR_TEST_UTILS
948 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
949#endif
950 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700951 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400952 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700953 }
954
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000955 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400956 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
957 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
958 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
959 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
960 fAlpha8IsRenderable = true;
961 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500962 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
963 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
964 // mixed samples we can't use multisampled-render-to-texture.
965 if (fUsesMixedSamples) {
966 fMSFBOType = kMixedSamples_MSFBOType;
967 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000968 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
969 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
970 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400971 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
972 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400973 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400974 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400975 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400976 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000977 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
978 fMSFBOType = kES_Apple_MSFBOType;
979 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000980 } else {
egdanieleed519e2016-01-15 11:36:18 -0800981 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700982 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400983 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
984 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400985
Brian Salomon00731b42016-10-14 11:30:51 -0400986 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400987 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
988 // Core profile removes ALPHA8 support.
989 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
990 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
991 // present.
992 fAlpha8IsRenderable = true;
993 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000994 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
995 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400996 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000997 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000998 }
Eric Karl5c779752017-05-08 12:02:07 -0700999
Brian Salomon01b476a2018-01-23 11:06:41 -05001000 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -04001001 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
1002 fMSFBOType = kNone_MSFBOType;
1003 }
1004
Eric Karl5c779752017-05-08 12:02:07 -07001005 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1006 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1007 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -07001008 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001009}
1010
cdalton1dd05422015-06-12 09:01:18 -07001011void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001012 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001013
Greg Daniel210883c2017-11-27 15:14:01 -05001014 bool layoutQualifierSupport = false;
1015 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
1016 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1017 layoutQualifierSupport = true;
1018 }
1019
cdalton1dd05422015-06-12 09:01:18 -07001020 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1021 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001022 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001023 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1024 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001025 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001026 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001027 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1028 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001029 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001030 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001031 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001032 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001033 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1034 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001035 }
cdalton1dd05422015-06-12 09:01:18 -07001036}
1037
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001038namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001039const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001040}
1041
Eric Karl5c779752017-05-08 12:02:07 -07001042void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001043
1044 // Build up list of legal stencil formats (though perhaps not supported on
1045 // the particular gpu/driver) from most preferred to least.
1046
1047 // these consts are in order of most preferred to least preferred
1048 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1049
1050 static const StencilFormat
1051 // internal Format stencil bits total bits packed?
1052 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1053 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1054 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1055 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001056 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001057 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1058
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001059 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001060 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001061 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001062 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1063 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1064
1065 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1066 // require FBO support we can expect these are legal formats and don't
1067 // check. These also all support the unsized GL_STENCIL_INDEX.
1068 fStencilFormats.push_back() = gS8;
1069 fStencilFormats.push_back() = gS16;
1070 if (supportsPackedDS) {
1071 fStencilFormats.push_back() = gD24S8;
1072 }
1073 fStencilFormats.push_back() = gS4;
1074 if (supportsPackedDS) {
1075 fStencilFormats.push_back() = gDS;
1076 }
1077 } else {
1078 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1079 // for other formats.
1080 // ES doesn't support using the unsized format.
1081
1082 fStencilFormats.push_back() = gS8;
1083 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001084 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1085 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001086 fStencilFormats.push_back() = gD24S8;
1087 }
1088 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1089 fStencilFormats.push_back() = gS4;
1090 }
1091 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001092}
1093
Brian Osman71a18892017-08-10 10:23:25 -04001094void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001095
Brian Osman71a18892017-08-10 10:23:25 -04001096 // We are called by the base class, which has already called beginObject(). We choose to nest
1097 // all of our caps information in a named sub-object.
1098 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001099
Brian Osman71a18892017-08-10 10:23:25 -04001100 writer->beginArray("Stencil Formats");
1101
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001102 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001103 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001104 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1105 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1106 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001107 }
1108
Brian Osman71a18892017-08-10 10:23:25 -04001109 writer->endArray();
1110
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001111 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001112 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001113 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001114 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001115 "IMG MS To Texture",
1116 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001117 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001118 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001119 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001120 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1121 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1122 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1123 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1124 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001125 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001126
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001127 static const char* kInvalidateFBTypeStr[] = {
1128 "None",
1129 "Discard",
1130 "Invalidate",
1131 };
1132 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1133 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1134 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1135 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001136
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001137 static const char* kMapBufferTypeStr[] = {
1138 "None",
1139 "MapBuffer",
1140 "MapBufferRange",
1141 "Chromium",
1142 };
1143 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1144 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1145 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1146 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1147 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1148
Brian Osman71a18892017-08-10 10:23:25 -04001149 writer->appendBool("Core Profile", fIsCoreProfile);
1150 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1151 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1152 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1153 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1154 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1155 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1156 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1157 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001158
Brian Osman71a18892017-08-10 10:23:25 -04001159 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001160 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1161 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1162 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001163 writer->appendBool("Debug support", fDebugSupport);
1164 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1165 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1166 writer->appendBool("Base instance support", fBaseInstanceSupport);
1167 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1168 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1169 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1170 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1171 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1172 writer->appendBool("BGRA to RGBA readback conversions are slow",
1173 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001174 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001175 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1176 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001177 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1178 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1179 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1180 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001181 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1182 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001183
Brian Osman71a18892017-08-10 10:23:25 -04001184 writer->beginArray("configs");
1185
bsalomon41e4384e2016-01-08 09:12:44 -08001186 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001187 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001188 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1189 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1190 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001191 writer->appendHexU32("e_format_read_pixels",
1192 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001193 writer->appendHexU32(
1194 "e_format_teximage",
1195 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1196 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1197 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1198 writer->appendHexU32("i_for_renderbuffer",
1199 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1200 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001201 }
1202
Brian Osman71a18892017-08-10 10:23:25 -04001203 writer->endArray();
1204 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001205}
1206
bsalomon41e4384e2016-01-08 09:12:44 -08001207bool GrGLCaps::bgraIsInternalFormat() const {
1208 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1209}
1210
bsalomon76148af2016-01-12 11:13:47 -08001211bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1212 GrGLenum* internalFormat, GrGLenum* externalFormat,
1213 GrGLenum* externalType) const {
1214 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1215 externalFormat, externalType)) {
1216 return false;
1217 }
1218 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1219 return true;
1220}
1221
bsalomon76148af2016-01-12 11:13:47 -08001222bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1223 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001224 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001225 externalFormat, externalType)) {
1226 return false;
1227 }
1228 return true;
1229}
1230
1231bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001232 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1233 return true;
1234}
1235
1236bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1237 ExternalFormatUsage usage, GrGLenum* externalFormat,
1238 GrGLenum* externalType) const {
1239 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001240
1241 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1242 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1243
1244 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001245 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1246 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001247 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1248 return false;
1249 }
1250
1251 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1252 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1253
bsalomone9573312016-01-25 14:33:25 -08001254 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1255 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1256 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1257 // texture, not the red component.
1258 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001259 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001260 *externalFormat = GR_GL_ALPHA;
1261 }
1262 }
1263
bsalomon76148af2016-01-12 11:13:47 -08001264 return true;
1265}
1266
brianosman20471892016-12-02 06:43:32 -08001267void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1268 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001269 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001270 /*
1271 Comments on renderability of configs on various GL versions.
1272 OpenGL < 3.0:
1273 no built in support for render targets.
1274 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1275 format RGB, RGBA and NV float formats we don't use.
1276 This is the following:
1277 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1278 RGB10_A2, RGBA12,RGBA16
1279 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1280 since they aren't required by later standards and the driver can simply return
1281 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1282 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1283 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1284 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1285 This adds a lot of additional renderable sized formats, including ALPHA8.
1286 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1287 16F, 32I, 32UI, and 32F variants).
1288 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1289
1290 For both the above extensions we limit ourselves to those that are also required by
1291 OpenGL 3.0.
1292
1293 OpenGL 3.0:
1294 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1295 but are not required to be supported as renderable textures/renderbuffer.
1296 Required renderable color formats:
1297 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1298 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1299 RGB10_A2.
1300 - R11F_G11F_B10F.
1301 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1302 and RG8UI.
1303 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1304 - ALPHA8
1305
1306 OpenGL 3.1, 3.2, 3.3
1307 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1308 OpengGL 3.3, 4.0, 4.1
1309 Adds RGB10_A2UI.
1310 OpengGL 4.2
1311 Adds
1312 - RGB5_A1, RGBA4
1313 - RGB565
1314 OpenGL 4.4
1315 Does away with the separate list and adds a column to the sized internal color format
1316 table. However, no new formats become required color renderable.
1317
1318 ES 2.0
1319 color renderable: RGBA4, RGB5_A1, RGB565
1320 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1321 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1322 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1323 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1324 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1325 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1326
1327 ES 3.0
1328 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1329 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1330 RGB5_A1.
1331 - RGB8 and RGB565.
1332 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1333 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1334 ES 3.1
1335 Adds RGB10_A2, RGB10_A2UI,
1336 ES 3.2
1337 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1338 */
Brian Salomon44804c02018-01-23 16:51:28 -05001339
1340 // Correctness workarounds.
1341 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001342 bool disableSRGBForX86PowerVR = false;
1343 bool disableSRGBWriteControlForAdreno4xx = false;
1344 bool disableR8TexStorageForANGLEGL = false;
1345 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001346 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001347
1348 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1349 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1350 // and GL_RG on FBO textures.
1351 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1352
1353 bool isX86PowerVR = false;
1354#if defined(SK_CPU_X86)
1355 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1356 isX86PowerVR = true;
1357 }
1358#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001359 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1360 // blacklist that device (and any others that might be sharing the same driver).
1361 disableSRGBForX86PowerVR = isX86PowerVR;
1362 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1363
1364 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1365 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1366 // check that we are not going to OpenGL.
1367 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1368
1369 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1370#if defined(SK_BUILD_FOR_MAC)
1371 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1372#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001373 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1374 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001375 }
1376
Brian Salomon71d9d842016-11-03 13:42:00 -04001377 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1378 ConfigInfo::kFBOColorAttachment_Flag;
1379 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001380 if (kNone_MSFBOType != fMSFBOType) {
1381 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1382 }
bsalomon41e4384e2016-01-08 09:12:44 -08001383 GrGLStandard standard = ctxInfo.standard();
1384 GrGLVersion version = ctxInfo.version();
1385
cblume790d5132016-02-29 11:13:29 -08001386 bool texStorageSupported = false;
1387 if (kGL_GrGLStandard == standard) {
1388 // The EXT version can apply to either GL or GLES.
1389 texStorageSupported = version >= GR_GL_VER(4,2) ||
1390 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1391 ctxInfo.hasExtension("GL_EXT_texture_storage");
1392 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001393 texStorageSupported = version >= GR_GL_VER(3,0) ||
1394 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001395 }
1396
cdalton74b8d322016-04-11 14:47:28 -07001397 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1398
Brian Salomone609e812018-01-17 14:00:47 -05001399 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001400
1401 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001402 if (kGL_GrGLStandard == standard) {
1403 textureRedSupport =
1404 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1405 } else {
1406 textureRedSupport =
1407 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1408 }
1409 }
1410
bsalomon30447372015-12-21 09:03:05 -08001411 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1412 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001413 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001414 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001415 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001416 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001417
1418 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1419 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001420 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001421 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001422 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001423 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001424 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1425 if (kGL_GrGLStandard == standard) {
1426 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1427 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001428 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001429 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1430 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1431 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1432 }
egdaniel4999df82016-01-07 17:06:04 -08001433 }
cblume790d5132016-02-29 11:13:29 -08001434 if (texStorageSupported) {
1435 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1436 }
cdalton74b8d322016-04-11 14:47:28 -07001437 if (texelBufferSupport) {
1438 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1439 }
bsalomoncdee0092016-01-08 13:20:12 -08001440 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001441
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001442 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1443 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1444 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1445 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1446 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1447 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1448 // supportedReadPixelsColorType never returns it.
1449 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1450 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1451 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1452 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1453 if (kGL_GrGLStandard == standard) {
1454 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1455 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1456 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1457 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1458 // becomes an issue.
1459 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1460 // but we don't support that just for simplicity's sake.
1461 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1462 } else {
1463 // 3.0 and the extension support this as a render buffer format.
1464 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1465 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1466 }
1467 }
1468 if (texStorageSupported) {
1469 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1470 }
1471 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1472 if (disableRGB8ForMali400) {
1473 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1474 }
1475
1476 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001477 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001478 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001479 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001480
1481 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1482 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1483 // GL_EXT_texture_format_BGRA8888.
1484 bool supportsBGRATexStorage = false;
1485
bsalomon41e4384e2016-01-08 09:12:44 -08001486 if (kGL_GrGLStandard == standard) {
1487 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1488 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1489 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1490 // Since the internal format is RGBA8, it is also renderable.
1491 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1492 allRenderFlags;
1493 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001494 // Since we are using RGBA8 we can use tex storage.
1495 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001496 } else {
1497 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1498 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001499 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1500 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1501 nonMSAARenderFlags;
1502
1503 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1504 supportsBGRATexStorage = true;
1505 }
1506 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1507 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1508 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1509 ConfigInfo::kRenderableWithMSAA_Flag;
1510 }
1511 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001512 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1513 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1514 // driver remembers the external format when the texture is created (with TexImage).
1515 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1516 // We could work around this, but it adds even more state tracking to code that is
1517 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1518 // This also side-steps some ambiguous interactions with the texture storage extension.
1519 if (version >= GR_GL_VER(3,0)) {
1520 // The APPLE extension doesn't make this renderable.
1521 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001522 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001523 }
bsalomon41e4384e2016-01-08 09:12:44 -08001524 }
1525 }
Brian Osman48c99192017-06-02 08:45:06 -04001526
Greg Daniel0ff79b22018-02-15 12:33:33 -05001527 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001528 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001529 }
bsalomoncdee0092016-01-08 13:20:12 -08001530 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001531
brianosmana6359362016-03-21 06:55:37 -07001532 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001533 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001534 if (kGL_GrGLStandard == standard) {
1535 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001536 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001537 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1538 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1539 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001540 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001541 }
1542 }
1543 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001544 if (fSRGBSupport) {
1545 fSRGBWriteControl = true;
1546 }
bsalomon41e4384e2016-01-08 09:12:44 -08001547 } else {
brianosman20471892016-12-02 06:43:32 -08001548 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001549 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001550 fSRGBSupport = false;
1551 }
bsalomon41e4384e2016-01-08 09:12:44 -08001552 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1553 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001554 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001555 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001556 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001557 }
brianosman20471892016-12-02 06:43:32 -08001558 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1559 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1560 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001561 fSRGBSupport = false;
1562 }
brianosman20471892016-12-02 06:43:32 -08001563
1564 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1565 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1566 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1567 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1568 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1569 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1570 // affects Windows.
1571 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1572 fSRGBSupport = false;
1573 }
1574
Brian Osman48c99192017-06-02 08:45:06 -04001575 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1576 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1577 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1578
Brian Osman67999392017-05-31 16:19:34 -04001579 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001580 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001581 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1582 }
Brian Osman67999392017-05-31 16:19:34 -04001583
bsalomon30447372015-12-21 09:03:05 -08001584 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1585 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1586 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1587 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001588 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001589 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001590 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001591 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001592 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001593 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001594 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001595 }
Brian Osman48c99192017-06-02 08:45:06 -04001596 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1597 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001598 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1599 }
bsalomoncdee0092016-01-08 13:20:12 -08001600 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001601 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1602 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1603 // is in this format, for example).
1604 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1605 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1606 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1607 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001608 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001609 GR_GL_BGRA;
1610 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1611 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001612 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001613 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001614 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001615 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001616
brianosmana6359362016-03-21 06:55:37 -07001617 if (texStorageSupported) {
1618 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1619 }
1620 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1621
bsalomon30447372015-12-21 09:03:05 -08001622 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1623 if (this->ES2CompatibilitySupport()) {
1624 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1625 } else {
1626 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1627 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001628 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001629 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001630 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001631 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001632 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1633 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001634 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001635 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1636 }
1637 } else {
1638 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1639 }
cblume790d5132016-02-29 11:13:29 -08001640 // 565 is not a sized internal format on desktop GL. So on desktop with
1641 // 565 we always use an unsized internal format to let the system pick
1642 // the best sized format to convert the 565 data to. Since TexStorage
1643 // only allows sized internal formats we disallow it.
1644 //
1645 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1646 // update.
1647 if (texStorageSupported && kGL_GrGLStandard != standard) {
1648 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1649 }
bsalomoncdee0092016-01-08 13:20:12 -08001650 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001651
1652 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1653 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001654 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001655 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001656 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001657 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001658 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1659 if (kGL_GrGLStandard == standard) {
1660 if (version >= GR_GL_VER(4, 2)) {
1661 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1662 }
1663 } else {
1664 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1665 }
cblume790d5132016-02-29 11:13:29 -08001666 if (texStorageSupported) {
1667 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1668 }
bsalomoncdee0092016-01-08 13:20:12 -08001669 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001670
Brian Osman10fc6fd2018-03-02 11:01:10 -05001671 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1672 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001673 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001674 GR_GL_RGBA;
1675 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1676 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1677 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1678 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1679 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1680 allRenderFlags;
1681 }
1682 if (texStorageSupported) {
1683 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1684 }
1685 if (texelBufferSupport) {
1686 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1687 }
1688 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1689
Greg Danielef59d872017-11-17 16:47:21 -05001690 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1691 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1692
1693 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1694 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1695 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1696 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1697 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001698 }
Greg Danielef59d872017-11-17 16:47:21 -05001699 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1700 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001701 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001702 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1703 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1704 alphaInfo.fFlags |= allRenderFlags;
1705 }
1706
1707 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1708 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1709 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1710 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1711 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001712 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001713 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001714
Brian Osman48c99192017-06-02 08:45:06 -04001715 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1716 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001717 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001718 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1719 }
1720 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1721 }
1722
Brian Salomone609e812018-01-17 14:00:47 -05001723 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001724 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1725 if (texelBufferSupport) {
1726 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1727 }
1728
1729 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1730 } else {
1731 redInfo.fFlags = 0;
1732
1733 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001734 }
bsalomon41e4384e2016-01-08 09:12:44 -08001735
Greg Daniel7af060a2017-12-05 16:27:11 -05001736 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1737 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1738 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1739 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1740 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001741 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001742 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1743 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1744 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1745 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001746 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001747
1748 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1749 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1750 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1751 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1752 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001753 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001754 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1755 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1756
1757#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1758 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001759 if (this->textureRedSupport() ||
1760 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1761 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1762 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1763 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1764 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1765 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1766 }
1767#endif
Brian Osman48c99192017-06-02 08:45:06 -04001768 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001769 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001770 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1771 }
1772 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1773 }
1774
Brian Salomone609e812018-01-17 14:00:47 -05001775 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001776 if (texelBufferSupport) {
1777 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1778 }
1779 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1780 } else {
1781 grayRedInfo.fFlags = 0;
1782 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001783 }
1784
bsalomon41e4384e2016-01-08 09:12:44 -08001785 // Check for [half] floating point texture support
1786 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1787 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1788 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1789 bool hasFPTextures = false;
1790 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001791 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001792 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001793 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001794
1795 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001796 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001797 hasFPTextures = true;
1798 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001799 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001800 }
1801 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001802 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001803 hasFPTextures = true;
1804 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001805 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001806 } else {
1807 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1808 ctxInfo.hasExtension("GL_OES_texture_float")) {
1809 hasFPTextures = true;
1810 }
1811 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1812 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1813 hasHalfFPTextures = true;
1814 }
1815 }
1816 }
bsalomon30447372015-12-21 09:03:05 -08001817
csmartdalton6aa0e112017-02-08 16:14:11 -05001818 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1819 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1820 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1821 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1822 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001823 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001824 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1825 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1826 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001827 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001828 // For now we only enable rendering to float on desktop, because on ES we'd have to
1829 // solve many precision issues and no clients actually want this yet.
1830 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1831 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1832 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1833 }
bsalomon41e4384e2016-01-08 09:12:44 -08001834 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001835 if (texStorageSupported) {
1836 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1837 }
1838 if (texelBufferSupport) {
1839 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1840 }
1841 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001842 }
bsalomon30447372015-12-21 09:03:05 -08001843
Greg Danielef59d872017-11-17 16:47:21 -05001844 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001845 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001846 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001847 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001848 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001849 }
Greg Danielef59d872017-11-17 16:47:21 -05001850 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1851 redHalf.fFormats.fExternalType = redHalfExternalType;
1852 redHalf.fFormatType = kFloat_FormatType;
1853 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1854 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001855 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001856 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001857 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001858 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1859
csmartdalton6aa0e112017-02-08 16:14:11 -05001860 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001861 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001862 redHalf.fFlags |= fpRenderFlags;
1863 }
1864
1865 if (texStorageSupported && !isCommandBufferES2) {
1866 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1867 }
1868
1869 if (texelBufferSupport) {
1870 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001871 }
1872 }
Greg Danielef59d872017-11-17 16:47:21 -05001873 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001874
1875 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1876 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001877 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001878 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001879 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001880 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1881 } else {
1882 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1883 }
bsalomon7928ef62016-01-05 10:26:39 -08001884 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001885 if (hasHalfFPTextures) {
1886 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1887 // ES requires 3.2 or EXT_color_buffer_half_float.
1888 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1889 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1890 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1891 }
1892 }
cblume790d5132016-02-29 11:13:29 -08001893 if (texStorageSupported) {
1894 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1895 }
cdalton74b8d322016-04-11 14:47:28 -07001896 if (texelBufferSupport) {
1897 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1898 }
bsalomoncdee0092016-01-08 13:20:12 -08001899 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001900
bsalomon30447372015-12-21 09:03:05 -08001901 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1902
1903 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001904 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1905 ctxInfo.version() >= GR_GL_VER(3,0));
1906 // All ES versions (thus far) require sized internal formats for render buffers.
1907 // TODO: Always use sized internal format?
1908 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1909
bsalomon30447372015-12-21 09:03:05 -08001910 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001911 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1912 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001913 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001914 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001915 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1916 fConfigTable[i].fFormats.fSizedInternalFormat :
1917 fConfigTable[i].fFormats.fBaseInternalFormat;
1918 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001919 fConfigTable[i].fFormats.fSizedInternalFormat :
1920 fConfigTable[i].fFormats.fBaseInternalFormat;
1921 }
Brian Salomon44804c02018-01-23 16:51:28 -05001922 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1923 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1924 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1925 // in ES.
1926 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1927 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1928 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1929 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001930 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1931 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001932 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1933 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001934 }
1935
bsalomon30447372015-12-21 09:03:05 -08001936 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1937 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1938 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1939 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1940 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001941 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001942 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001943
1944 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1945 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1946 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1947 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001948 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001949 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1950 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1951 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1952 // slot.
1953 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1954 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001955
1956 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1957 // as a base format.
1958 // GL_EXT_texture_format_BGRA8888:
1959 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1960 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1961 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001962 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001963 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1964 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1965 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001966 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001967 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1968 }
1969
bsalomoncdee0092016-01-08 13:20:12 -08001970 // If we don't have texture swizzle support then the shader generator must insert the
1971 // swizzle into shader code.
1972 if (!this->textureSwizzleSupport()) {
1973 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001974 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001975 }
1976 }
1977
bsalomon7f9b2e42016-01-12 13:29:26 -08001978 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1979 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1980 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001981 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001982 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1983 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1984 if (GrPixelConfigIsAlphaOnly(config) &&
1985 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001986 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001987 }
1988 }
1989 }
1990
Greg Daniel81e7bf82017-07-19 14:47:42 -04001991 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1992 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001993 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1994 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001995 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001996 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1997 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001998 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001999 int count;
2000 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
2001 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
2002 1, &count);
2003 if (count) {
2004 int* temp = new int[count];
2005 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
2006 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05002007 // GL has a concept of MSAA rasterization with a single sample but we do not.
2008 if (count && temp[count - 1] == 1) {
2009 --count;
2010 SkASSERT(!count || temp[count -1] > 1);
2011 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04002012 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05002013 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04002014 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002015 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002016 for (int j = 0; j < count; ++j) {
2017 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2018 }
2019 delete[] temp;
2020 }
2021 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002022 // Fake out the table using some semi-standard counts up to the max allowed sample
2023 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002024 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002025 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2026 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2027 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2028 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2029 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002030 // Chrome has a mock GL implementation that returns 0.
2031 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002032
Brian Salomonbdecacf2018-02-02 20:32:49 -05002033 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002034 int count = SK_ARRAY_COUNT(kDefaultSamples);
2035 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002036 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002037 break;
2038 }
2039 }
2040 if (count > 0) {
2041 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2042 }
2043 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002044 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2045 fConfigTable[i].fColorSampleCounts.setCount(1);
2046 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002047 }
2048 }
2049
bsalomon30447372015-12-21 09:03:05 -08002050#ifdef SK_DEBUG
2051 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002052 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002053 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002054 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2055 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002056 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2057 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2058 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2059 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002060 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2061 fConfigTable[i].fFormats.fBaseInternalFormat);
2062 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002063 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002064 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2065 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2066 fConfigTable[i].fFormats.fExternalFormat[j]);
2067 }
2068 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002069 }
2070#endif
2071}
2072
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002073bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
2074 bool dstIsTextureable, bool dstIsGLTexture2D,
2075 GrSurfaceOrigin dstOrigin,
2076 GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
2077 bool srcIsTextureable, bool srcIsGLTexture2D,
2078 GrSurfaceOrigin srcOrigin) const {
2079 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2080 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2081 // many drivers would allow it to work, but ANGLE does not.
2082 if (kGLES_GrGLStandard == fStandard && this->bgraIsInternalFormat() &&
2083 (kBGRA_8888_GrPixelConfig == dstConfig || kBGRA_8888_GrPixelConfig == srcConfig)) {
2084 return false;
2085 }
2086
2087 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
2088 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
2089 return false;
2090 }
2091
2092 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
2093 // texture.
2094 if (!dstIsTextureable) {
2095 return false;
2096 }
2097
2098 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
2099 // is required
2100 if (this->canConfigBeFBOColorAttachment(srcConfig) &&
2101 (!srcIsTextureable || srcIsGLTexture2D) &&
2102 dstIsGLTexture2D &&
2103 dstOrigin == srcOrigin) {
2104 return true;
2105 } else {
2106 return false;
2107 }
2108}
2109
2110bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
2111 bool dstIsTextureable, bool dstIsGLTexture2D,
2112 GrSurfaceOrigin dstOrigin,
2113 GrPixelConfig srcConfig, int srcSampleCnt,
2114 bool srcIsTextureable, bool srcIsGLTexture2D,
2115 GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
2116 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2117 auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
2118 if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
2119 !this->canConfigBeFBOColorAttachment(srcConfig)) {
2120 return false;
2121 }
2122
2123 if (dstIsTextureable && !dstIsGLTexture2D) {
2124 return false;
2125 }
2126 if (srcIsTextureable && !srcIsGLTexture2D) {
2127 return false;
2128 }
2129
2130 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
2131 return false;
2132 }
2133 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
2134 // We would mirror to compensate for origin changes. Note that copySurface is
2135 // specified such that the src and dst rects are the same.
2136 if (dstOrigin != srcOrigin) {
2137 return false;
2138 }
2139 }
2140
2141 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
2142 if (srcSampleCnt > 1) {
2143 if (1 == dstSampleCnt) {
2144 return false;
2145 }
2146 if (SkRect::Make(srcRect) != srcBounds) {
2147 return false;
2148 }
2149 }
2150 }
2151
2152 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
2153 if (dstSampleCnt > 1) {
2154 return false;
2155 }
2156 }
2157
2158 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
2159 if (dstConfig != srcConfig) {
2160 return false;
2161 }
2162 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2163 if (srcSampleCnt > 1 && dstConfig != srcConfig) {
2164 return false;
2165 }
2166 }
2167
2168 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2169 if (srcSampleCnt > 1) {
2170 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
2171 return false;
2172 }
2173 if (dstOrigin != srcOrigin) {
2174 return false;
2175 }
2176 }
2177 }
2178 return true;
2179}
2180
2181bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
2182 return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
2183}
2184
2185static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
2186 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
2187 if (!rt) {
2188 return false;
2189 }
2190 // A RT has a separate MSAA renderbuffer if:
2191 // 1) It's multisampled
2192 // 2) We're using an extension with separate MSAA renderbuffers
2193 // 3) It's not FBO 0, which is special and always auto-resolves
2194 return rt->numColorSamples() > 1 &&
2195 glCaps.usesMSAARenderBuffers() &&
2196 !rt->rtPriv().glRTFBOIDIs0();
2197}
2198
2199bool GrGLCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
2200 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2201 GrSurfaceOrigin dstOrigin = dst->origin();
2202 GrSurfaceOrigin srcOrigin = src->origin();
2203
2204 GrPixelConfig dstConfig = dst->config();
2205 GrPixelConfig srcConfig = src->config();
2206
2207 int dstSampleCnt = 0;
2208 int srcSampleCnt = 0;
2209 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
2210 dstSampleCnt = rtProxy->numColorSamples();
2211 }
2212 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
2213 srcSampleCnt = rtProxy->numColorSamples();
2214 }
2215 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
2216 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
2217
2218 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
2219 // swizzle.
2220 if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
2221 this->shaderCaps()->configOutputSwizzle(dst->config())) {
2222 return false;
2223 }
2224
2225 const GrTextureProxy* dstTex = dst->asTextureProxy();
2226 const GrTextureProxy* srcTex = src->asTextureProxy();
2227
2228 bool dstIsTex2D = dstTex ? dstTex->texPriv().isGLTexture2D() : false;
2229 bool srcIsTex2D = srcTex ? srcTex->texPriv().isGLTexture2D() : false;
2230
2231 // One of the possible requirements for copy as blit is that the srcRect must match the bounds
2232 // of the src surface. If we have a approx fit surface we can't know for sure what the src
2233 // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
2234 // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
2235 // know we will at least be able to do it as a draw.
2236#ifdef SK_DEBUG
2237 if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2238 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2239 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
2240 !src->priv().isExact()) {
2241 SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
2242 }
2243#endif
2244
2245 return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
2246 SkToBool(dstTex), dstIsTex2D, dstOrigin,
2247 srcConfig, has_msaa_render_buffer(src, *this),
2248 SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
2249 this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2250 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2251 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
2252 dstPoint) ||
2253 this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
2254}
2255
Robert Phillipsbf25d432017-04-07 10:08:53 -04002256bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002257 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2258 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002259 // By default, we don't require rects to match.
2260 *rectsMustMatch = false;
2261
2262 // By default, we allow subrects.
2263 *disallowSubrect = false;
2264
Brian Salomon467921e2017-03-06 16:17:12 -05002265 // If the src is a texture, we can implement the blit as a draw assuming the config is
2266 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002267 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002268 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002269 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2270 desc->fConfig = src->config();
2271 return true;
2272 }
2273
Robert Phillipsbf25d432017-04-07 10:08:53 -04002274 {
2275 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2276 // wrapped. In that case the proxy would already be instantiated.
2277 const GrTexture* srcTexture = src->priv().peekTexture();
2278 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2279 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2280 // Not supported for FBO blit or CopyTexSubImage
2281 return false;
2282 }
Brian Salomon467921e2017-03-06 16:17:12 -05002283 }
2284
2285 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2286 // possible and we return false to fallback to creating a render target dst for render-to-
2287 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2288 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002289 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002290 bool rectsMustMatchForBlitFramebuffer = false;
2291 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002292 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002293 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2294 rectsMustMatchForBlitFramebuffer = true;
2295 disallowSubrectForBlitFramebuffer = true;
2296 // Mirroring causes rects to mismatch later, don't allow it.
2297 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002298 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2299 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002300 rectsMustMatchForBlitFramebuffer = true;
2301 // Mirroring causes rects to mismatch later, don't allow it.
2302 originForBlitFramebuffer = src->origin();
2303 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002304 originForBlitFramebuffer = src->origin();
2305 }
2306
2307 // Check for format issues with glCopyTexSubImage2D
2308 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2309 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2310 // then we set up for that, otherwise fail.
2311 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002312 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002313 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002314 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2315 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002316 return true;
2317 }
2318 return false;
2319 }
2320
Robert Phillipsbf25d432017-04-07 10:08:53 -04002321 {
Brian Salomon63e79732017-05-15 21:23:13 -04002322 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2323 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002324 if (srcIsMSAARenderbuffer) {
2325 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2326 // blit or fail.
2327 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002328 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002329 desc->fConfig = src->config();
2330 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2331 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2332 return true;
2333 }
2334 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002335 }
Brian Salomon467921e2017-03-06 16:17:12 -05002336 }
2337
2338 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002339 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002340 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002341 desc->fFlags = kNone_GrSurfaceFlags;
2342 return true;
2343}
2344
Greg Daniel691f5e72018-02-28 14:21:34 -05002345void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2346 const GrContextOptions& contextOptions,
2347 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002348 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2349 // Thus we are blacklisting this extension for now on Adreno4xx devices.
Adrienne Walker0e383942018-05-15 11:33:47 -07002350 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2351 fDriverBugWorkarounds.disable_discard_framebuffer) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002352 fDiscardRenderTargetSupport = false;
2353 fInvalidateFBType = kNone_InvalidateFBType;
2354 }
2355
2356 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2357 // 340.96 and 367.57.
2358 if (kGL_GrGLStandard == ctxInfo.standard() &&
2359 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002360 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002361 fClearTextureSupport = false;
2362 }
2363
2364 // Calling glClearTexImage crashes on the NexusPlayer.
2365 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2366 fClearTextureSupport = false;
2367 }
2368
2369 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2370#ifdef SK_BUILD_FOR_MAC
2371 if (shaderCaps->fGeometryShaderSupport) {
2372 shaderCaps->fGSInvocationsSupport = false;
2373 }
2374#endif
2375
2376 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2377 // shaders. @127.0 is the earliest verified driver to not crash.
2378 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002379 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002380 shaderCaps->fGeometryShaderSupport = false;
2381 }
2382
2383#if defined(__has_feature)
2384#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2385 // See skbug.com/7058
2386 fMapBufferType = kNone_MapBufferType;
2387 fMapBufferFlags = kNone_MapFlags;
2388#endif
2389#endif
2390
2391 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2392 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2393 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2394 // unclear whether this really affects a wide range of devices.
2395 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002396 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002397 fMapBufferType = kNone_MapBufferType;
2398 fMapBufferFlags = kNone_MapFlags;
2399 }
2400
2401 // TODO: re-enable for ANGLE
2402 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2403 fTransferBufferType = kNone_TransferBufferType;
2404 }
2405
2406 // Using MIPs on this GPU seems to be a source of trouble.
2407 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2408 fMipMapSupport = false;
2409 }
2410
2411 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2412 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2413 // around a driver bug related to gl_FragCoord.
2414 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2415 fMaxClipAnalyticFPs = 0;
2416 }
2417
2418#ifndef SK_BUILD_FOR_IOS
2419 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2420 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2421 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2422 ctxInfo.driver() != kChromium_GrGLDriver)) {
2423 fUseDrawToClearColor = true;
2424 }
2425#endif
2426
2427 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2428 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2429 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2430 fUseDrawToClearColor = true;
2431 }
2432
2433#ifdef SK_BUILD_FOR_MAC
2434 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2435 // full screen clears
2436 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2437 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002438 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2439 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2440 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2441 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002442 fUseDrawToClearColor = true;
2443 }
2444#endif
2445
2446 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2447 // bugs seems to involve clearing too much and not skipping the clear.
2448 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2449 // but only for D3D11 ANGLE.
2450 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2451 fUseDrawToClearColor = true;
2452 }
2453
2454 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2455 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002456 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002457 fUseDrawToClearStencilClip = true;
2458 }
2459 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2460 }
2461
Adrienne Walker94f585e2018-05-15 11:47:07 -07002462 if (fDriverBugWorkarounds.gl_clear_broken) {
2463 fUseDrawToClearColor = true;
2464 fUseDrawToClearStencilClip = true;
2465 }
2466
Brian Salomon01b476a2018-01-23 11:06:41 -05002467 // This was reproduced on the following configurations:
2468 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2469 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2470 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2471 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2472 // and not produced on:
2473 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2474 // The particular lines that get dropped from test images varies across different devices.
2475 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002476 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002477 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2478 }
2479
Chris Dalton6f5e77a2018-04-23 21:14:42 -06002480 if (kIntelSkylake_GrGLRenderer == ctxInfo.renderer() ||
2481 (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2482 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer())) {
Chris Daltonda40cd22018-04-16 13:19:58 -06002483 fRequiresFlushBetweenNonAndInstancedDraws = true;
2484 }
2485
Brian Salomon01b476a2018-01-23 11:06:41 -05002486 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2487 // given 1 << 15 or more instances.
2488 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2489 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
Adrienne Walker001cae02018-05-15 11:38:44 -07002490 } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
2491 fMaxInstancesPerDrawArraysWithoutCrashing = 0x4000000;
Brian Salomon01b476a2018-01-23 11:06:41 -05002492 }
2493
2494 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002495 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002496 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2497 fUseDrawInsteadOfAllRenderTargetWrites = true;
2498 }
2499
2500 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2501 fSampleShadingSupport = false;
2502 }
2503
2504#ifdef SK_BUILD_FOR_MAC
2505 static constexpr bool isMAC = true;
2506#else
2507 static constexpr bool isMAC = false;
2508#endif
2509
2510 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2511 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2512 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2513 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2514 if (fMipMapLevelAndLodControlSupport &&
2515 (contextOptions.fDoManualMipmapping ||
2516 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2517 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2518 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2519 fDoManualMipmapping = true;
2520 }
2521
2522 // See http://crbug.com/710443
2523#ifdef SK_BUILD_FOR_MAC
2524 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2525 fClearToBoundaryValuesIsBroken = true;
2526 }
2527#endif
2528 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2529 fDrawArraysBaseVertexIsBroken = true;
2530 }
2531
Brian Salomon01b476a2018-01-23 11:06:41 -05002532 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2533 // Galaxy S7.
2534 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2535 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2536 shaderCaps->fFBFetchSupport = false;
2537 }
2538
Brian Salomon01b476a2018-01-23 11:06:41 -05002539 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2540 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2541
2542 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2543 // function that may require a gradient calculation inside a conditional block may return
2544 // undefined results". This appears to be an issue with the 'any' call since even the simple
2545 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2546 // from our GrTextureDomain processor.
2547 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2548
2549 // Known issue on at least some Intel platforms:
2550 // http://code.google.com/p/skia/issues/detail?id=946
2551 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2552 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2553 }
2554
Chris Dalton0090ef62018-03-28 17:35:00 -06002555 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002556 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2557 // so we must do the abs first in a separate expression.
2558 shaderCaps->fCanUseMinAndAbsTogether = false;
2559
2560 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2561 // must avoid this condition.
2562 shaderCaps->fCanUseFractForNegativeValues = false;
2563 }
2564
2565 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2566 // thus must us -1.0 * %s.x to work correctly
2567 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2568 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2569 }
2570
2571 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2572 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2573 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2574 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2575 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2576 }
2577
2578 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2579 // the original dst color when reading the outColor even after being written to. By using a
2580 // local outColor we can work around this bug.
2581 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2582 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2583 }
2584
2585 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2586 // color, and that uniform contains an opaque color, and the output of the shader is only based
2587 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2588 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2589 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2590 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2591 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2592 shaderCaps->fMustObfuscateUniformColor = true;
2593 }
2594#ifdef SK_BUILD_FOR_WIN
2595 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2596 //
2597 // Basically, if a shader has a construct like:
2598 //
2599 // float x = someCondition ? someValue : 0;
2600 // float2 result = (0 == x) ? float2(x, x)
2601 // : float2(2 * x / x, 0);
2602 //
2603 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2604 // we've explicitly guarded the division with a check against zero. This manifests in much
2605 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2606 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2607 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2608 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2609 }
2610#endif
2611
2612 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2613 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2614 // that the interpolation of vertex shader outputs is quite inaccurate.
2615 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2616 shaderCaps->fCanUseFragCoord = false;
2617 shaderCaps->fInterpolantsAreInaccurate = true;
2618 }
2619
Chris Dalton0090ef62018-03-28 17:35:00 -06002620 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2621 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2622 shaderCaps->fCanUseFragCoord = false;
2623 }
2624
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002625 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2626 // (Are they implemented with fp16?)
2627 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2628 shaderCaps->fIncompleteShortIntPrecision = true;
2629 }
2630
Brian Salomon01b476a2018-01-23 11:06:41 -05002631 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2632 // for now until its own blacklists can be updated.
2633 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2634 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2635 kIntel_GrGLDriver == ctxInfo.driver() ||
2636 kChromium_GrGLDriver == ctxInfo.driver()) {
2637 fBlendEquationSupport = kBasic_BlendEquationSupport;
2638 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2639 }
2640
2641 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2642 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002643 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002644 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002645 fBlendEquationSupport = kBasic_BlendEquationSupport;
2646 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2647 }
2648
Adrienne Walker68314842018-05-14 14:02:53 -07002649 if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
2650 fBlendEquationSupport = kBasic_BlendEquationSupport;
2651 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2652 }
2653
Brian Salomon01b476a2018-01-23 11:06:41 -05002654 if (this->advancedBlendEquationSupport()) {
2655 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002656 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002657 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2658 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2659 (1 << kColorBurn_GrBlendEquation);
2660 }
2661 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2662 // Blacklist color-burn on ARM until the fix is released.
2663 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2664 }
2665 }
2666
2667 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2668 if (fMultisampleDisableSupport &&
2669 this->shaderCaps()->dualSourceBlendingSupport() &&
2670 this->shaderCaps()->pathRenderingSupport() &&
2671 fUsesMixedSamples &&
2672#if GR_TEST_UTILS
2673 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2674#endif
2675 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2676 kChromium_GrGLDriver == ctxInfo.driver())) {
2677 fDiscardRenderTargetSupport = false;
2678 fInvalidateFBType = kNone_InvalidateFBType;
2679 }
Brian Osmanc585e202018-04-04 14:08:27 -04002680
Brian Osman061020e2018-04-17 14:22:15 -04002681 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2682 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2683 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2684 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002685 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2686 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002687 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002688 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002689 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2690 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002691 }
Brian Osman2fa53742018-05-03 15:05:12 -04002692
2693#ifdef SK_BUILD_FOR_IOS
2694 // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
2695 // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
2696 // is to just blacklist the feature.
2697 // https://github.com/flutter/flutter/issues/16718
2698 // https://bugreport.apple.com/web/?problemID=39948888
2699 fUnpackRowLengthSupport = false;
2700#endif
Brian Salomon01b476a2018-01-23 11:06:41 -05002701}
2702
csmartdaltone0d36292016-07-29 08:14:20 -07002703void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002704 if (options.fDisableDriverCorrectnessWorkarounds) {
2705 SkASSERT(!fDoManualMipmapping);
2706 SkASSERT(!fClearToBoundaryValuesIsBroken);
2707 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2708 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2709 SkASSERT(!fUseDrawToClearColor);
2710 SkASSERT(!fUseDrawToClearStencilClip);
2711 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2712 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2713 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Chris Daltonda40cd22018-04-16 13:19:58 -06002714 SkASSERT(!fRequiresFlushBetweenNonAndInstancedDraws);
Brian Salomon01b476a2018-01-23 11:06:41 -05002715 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002716 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2717 fUseDrawToClearColor = false;
2718 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2719 fUseDrawToClearColor = true;
2720 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002721 if (options.fDoManualMipmapping) {
2722 fDoManualMipmapping = true;
2723 }
csmartdaltone0d36292016-07-29 08:14:20 -07002724}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002725
Brian Salomon3d86a192018-02-27 16:46:11 -05002726bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2727 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2728 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2729 if (tex->hasBaseLevelBeenBoundToFBO()) {
2730 return false;
2731 }
2732 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002733 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002734 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2735 return false;
2736 }
2737 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2738 return false;
2739 }
2740 return SkToBool(surface->asTexture());
2741 }
2742 return true;
2743}
2744
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002745bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2746 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2747 // We don't support reading pixels directly from EXTERNAL textures as it would require
2748 // binding the texture to a FBO.
2749 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2750 return false;
2751 }
2752 }
2753 return true;
2754}
2755
2756GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2757 GrColorType dstColorType) const {
2758 // For now, we mostly report the read back format that is required by the ES spec without
2759 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2760 // this as makes sense to increase performance and correctness.
2761 switch (fConfigTable[config].fFormatType) {
2762 case kNormalizedFixedPoint_FormatType:
2763 return GrColorType::kRGBA_8888;
2764 case kFloat_FormatType:
2765 // We cheat a little here and allow F16 read back if the src and dst match.
2766 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2767 return GrColorType::kRGBA_F16;
2768 }
2769 if ((kAlpha_half_GrPixelConfig == config ||
2770 kAlpha_half_as_Red_GrPixelConfig == config) &&
2771 GrColorType::kAlpha_F16 == dstColorType) {
2772 return GrColorType::kAlpha_F16;
2773 }
2774 // And similar for full float RG.
2775 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2776 return GrColorType::kRG_F32;
2777 }
2778 return GrColorType::kRGBA_F32;
2779 }
2780 return GrColorType::kUnknown;
2781}
2782
Greg Daniel2a303902018-02-20 10:25:54 -05002783bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002784 GrGLFramebufferInfo fbInfo;
2785 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002786 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002787 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002788}
2789
Brian Salomonbdecacf2018-02-02 20:32:49 -05002790int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2791 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002792 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002793 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002794 return 0;
2795 }
2796
Brian Salomonbdecacf2018-02-02 20:32:49 -05002797 if (1 == requestedCount) {
2798 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2799 }
2800
Greg Daniel81e7bf82017-07-19 14:47:42 -04002801 for (int i = 0; i < count; ++i) {
2802 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
Adrienne Walkerd7c79782018-05-15 11:41:24 -07002803 int count = fConfigTable[config].fColorSampleCounts[i];
2804 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
2805 count = SkTMin(count, 4);
2806 }
2807 return count;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002808 }
2809 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002810 return 0;
2811}
2812
2813int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2814 const auto& table = fConfigTable[config].fColorSampleCounts;
2815 if (!table.count()) {
2816 return 0;
2817 }
2818 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002819}
2820
Greg Danielfaa095e2017-12-19 13:15:02 -05002821bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2822 GrGLStandard standard) {
2823 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002824
2825 switch (ct) {
2826 case kUnknown_SkColorType:
2827 return false;
2828 case kAlpha_8_SkColorType:
2829 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002830 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002831 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002832 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002833 }
2834 break;
2835 case kRGB_565_SkColorType:
2836 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002837 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002838 }
2839 break;
2840 case kARGB_4444_SkColorType:
2841 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002842 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002843 }
2844 break;
2845 case kRGBA_8888_SkColorType:
2846 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002847 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002848 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002849 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002850 }
2851 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002852 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002853 if (GR_GL_RGB8 == format) {
2854 *config = kRGB_888_GrPixelConfig;
2855 }
2856 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002857 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002858 if (GR_GL_RGBA8 == format) {
2859 if (kGL_GrGLStandard == standard) {
2860 *config = kBGRA_8888_GrPixelConfig;
2861 }
2862 } else if (GR_GL_BGRA8 == format) {
2863 if (kGLES_GrGLStandard == standard) {
2864 *config = kBGRA_8888_GrPixelConfig;
2865 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002866 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002867 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002868 }
2869 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002870 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002871 if (GR_GL_RGB10_A2 == format) {
2872 *config = kRGBA_1010102_GrPixelConfig;
2873 }
2874 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002875 case kRGB_101010x_SkColorType:
2876 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002877 case kGray_8_SkColorType:
2878 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002879 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002880 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002881 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002882 }
2883 break;
2884 case kRGBA_F16_SkColorType:
2885 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002886 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002887 }
2888 break;
2889 }
2890
Greg Danielfaa095e2017-12-19 13:15:02 -05002891 return kUnknown_GrPixelConfig != *config;
2892}
2893
2894bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2895 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002896 GrGLTextureInfo texInfo;
2897 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002898 return false;
2899 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002900 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002901}
2902
2903bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2904 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002905 GrGLFramebufferInfo fbInfo;
2906 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002907 return false;
2908 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002909 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002910}
2911
Robert Phillipsfc711a22018-02-13 17:03:00 -05002912bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2913 GrPixelConfig* config) const {
2914 const GrGLenum* glFormat = format.getGLFormat();
2915 if (!glFormat) {
2916 return false;
2917 }
2918 return validate_sized_format(*glFormat, ct, config, fStandard);
2919}
2920
2921