blob: 3ae321dd9e5510cd1105629ef712742623ba2887 [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
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000112 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000113 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
114
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000115 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700116 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
117 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
118 ctxInfo.hasExtension("GL_NV_texture_barrier");
119 } else {
120 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
121 }
122
Robert Phillips7f861922018-01-30 13:13:42 +0000123 if (kGL_GrGLStandard == standard) {
124 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
125 ctxInfo.hasExtension("GL_ARB_texture_multisample");
126 } else {
127 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
128 }
129
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000130 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000131 ctxInfo.hasExtension("GL_ARB_imaging");
132
Brian Salomon01b476a2018-01-23 11:06:41 -0500133 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700134 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
135 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000136 fDiscardRenderTargetSupport = true;
137 fInvalidateFBType = kInvalidate_InvalidateFBType;
138 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
139 fDiscardRenderTargetSupport = true;
140 fInvalidateFBType = kDiscard_InvalidateFBType;
141 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000142
Chris Dalton27059d32018-01-23 14:06:50 -0700143 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
144 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
145 if (kGLES_GrGLStandard == standard) {
146 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
147 // TODO: Evaluate on PowerVR.
148 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
149 if (kARM_GrGLVendor == ctxInfo.vendor()) {
150 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
151 }
152 }
153
Chris Dalton344e9032017-12-11 15:42:09 -0700154 if (kARM_GrGLVendor == ctxInfo.vendor() ||
155 kImagination_GrGLVendor == ctxInfo.vendor() ||
156 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
157 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000158 }
159
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000160 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000161 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800162 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
163 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000164 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000165 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
166 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000167 }
168
cdalton626e1ff2015-06-12 13:56:46 -0700169 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
170 fDebugSupport = true;
171 } else {
172 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
173 }
174
jvanverth3f801cb2014-12-16 09:49:38 -0800175 if (kGL_GrGLStandard == standard) {
176 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
177 }
178 else {
179 fES2CompatibilitySupport = true;
180 }
181
cdalton0edea2c2015-05-21 08:27:44 -0700182 if (kGL_GrGLStandard == standard) {
183 fMultisampleDisableSupport = true;
184 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700185 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700186 }
187
kkinnunend94708e2015-07-30 22:47:04 -0700188 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600189 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
190 // instanced arrays, but we could make this more granular if we wanted
191 fInstanceAttribSupport =
192 version >= GR_GL_VER(3, 2) ||
193 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
194 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
195 } else {
196 fInstanceAttribSupport =
197 version >= GR_GL_VER(3, 0) ||
198 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
199 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
200 }
201
202 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700203 if (version >= GR_GL_VER(3, 0)) {
204 fBindFragDataLocationSupport = true;
205 }
206 } else {
207 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
208 fBindFragDataLocationSupport = true;
209 }
joshualittc1f56b52015-06-22 12:31:31 -0700210 }
211
joshualitt7bdd70a2015-10-01 06:28:11 -0700212 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
213
kkinnunene06ed252016-02-16 23:15:40 -0800214 if (kGL_GrGLStandard == standard) {
215 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
216 // We also require textureSize() support for rectangle 2D samplers which was added in
217 // GLSL 1.40.
218 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
219 fRectangleTextureSupport = true;
220 }
bsalomone179a912016-01-20 06:18:10 -0800221 }
kkinnunene06ed252016-02-16 23:15:40 -0800222 } else {
223 // Command buffer exposes this in GL ES context for Chromium reasons,
224 // but it should not be used. Also, at the time of writing command buffer
225 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800226 }
227
bsalomoncdee0092016-01-08 13:20:12 -0800228 if (kGL_GrGLStandard == standard) {
229 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
230 fTextureSwizzleSupport = true;
231 }
232 } else {
233 if (version >= GR_GL_VER(3,0)) {
234 fTextureSwizzleSupport = true;
235 }
236 }
237
cblume09bd2c02016-03-01 14:08:28 -0800238 if (kGL_GrGLStandard == standard) {
239 fMipMapLevelAndLodControlSupport = true;
240 } else if (kGLES_GrGLStandard == standard) {
241 if (version >= GR_GL_VER(3,0)) {
242 fMipMapLevelAndLodControlSupport = true;
243 }
244 }
245
bsalomon88c7b982015-07-31 11:20:16 -0700246#ifdef SK_BUILD_FOR_WIN
247 // We're assuming that on Windows Chromium we're using ANGLE.
248 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
249 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700250 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700251 fRGBA8888PixelsOpsAreSlow = isANGLE;
252 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
253 // check DX11 ANGLE.
254 fPartialFBOReadIsSlow = isANGLE;
255#endif
256
ericrkb4ecabd2016-03-11 15:18:20 -0800257 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
258 bool isMAC = false;
259#ifdef SK_BUILD_FOR_MAC
260 isMAC = true;
261#endif
262
263 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
264 // vis-versa.
265 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
266
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500267 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
268 fUseBufferDataNullHint = false;
269 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
270 fUseBufferDataNullHint = true;
271 }
272
Brian Salomond17b4a62017-05-23 16:53:47 -0400273 if (kGL_GrGLStandard == standard) {
274 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400275 fClearTextureSupport = true;
276 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500277 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
278 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400279 }
280
cdalton4cd67132015-06-10 19:23:46 -0700281 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700282 * GrShaderCaps fields
283 **************************************************************************/
284
egdaniel0a482332015-10-26 08:59:10 -0700285 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700286 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500287 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700288
Brian Osman195c05b2017-08-30 15:14:04 -0400289 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
290#if GR_TEST_UTILS
291 if (contextOptions.fSuppressPathRendering) {
292 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700293 }
Brian Osman195c05b2017-08-30 15:14:04 -0400294#endif
egdaniel05ded892015-10-26 07:38:05 -0700295
egdaniel05ded892015-10-26 07:38:05 -0700296 // Enable supported shader-related caps
297 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500298 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700299 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
300 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600301
Brian Salomon1edc5b92016-11-29 13:43:46 -0500302 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600303
egdaniel05ded892015-10-26 07:38:05 -0700304 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500305 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700306 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600307 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600308 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
309 shaderCaps->fGSInvocationsSupport = true;
310 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
311 shaderCaps->fGSInvocationsSupport = true;
312 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
313 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600314 }
315
Brian Salomon1edc5b92016-11-29 13:43:46 -0500316 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800317 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500318 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500319 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700320
Brian Salomon1edc5b92016-11-29 13:43:46 -0500321 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700322 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800323
Chris Daltonfaca00d2018-01-19 15:56:07 -0700324 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
325 // backup impl that only uses vertex shaders.
326 if (kARM_GrGLVendor != ctxInfo.vendor()) {
327 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
328 shaderCaps->fGeometryShaderSupport = true;
329 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
330 shaderCaps->fGeometryShaderSupport = true;
331 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
332 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700333 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500334 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700335
Brian Salomon1edc5b92016-11-29 13:43:46 -0500336 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800337 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700338 }
339
cdalton9c3f1432016-03-11 10:07:37 -0800340 // Protect ourselves against tracking huge amounts of texture state.
341 static const uint8_t kMaxSaneSamplers = 32;
342 GrGLint maxSamplers;
343 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500344 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
345 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800346 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500347 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800348 }
349 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500350 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800351 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500352 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800353
Brian Salomonbbf05752017-11-30 11:30:48 -0500354 // This is all *very* approximate.
355 switch (ctxInfo.vendor()) {
356 case kNVIDIA_GrGLVendor:
357 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
358 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
359 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
360 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500361 case kImagination_GrGLVendor:
362 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
363 // it is always a win to use multitexturing.
364 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
365 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
366 std::numeric_limits<size_t>::max();
367 }
368 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500369 case kATI_GrGLVendor:
370 // So far no AMD GPU shows a performance difference. A tie goes to disabling
371 // multitexturing for simplicity's sake.
372 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
373 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500374 default:
375 break;
376 }
377
csmartdalton485a1202016-07-13 10:16:32 -0700378 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
379 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
380 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
381 // limit this decision to specific GPU families rather than basing it on the vendor alone.
382 if (!GR_GL_MUST_USE_VBO &&
383 !fIsCoreProfile &&
384 (kARM_GrGLVendor == ctxInfo.vendor() ||
385 kImagination_GrGLVendor == ctxInfo.vendor() ||
386 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
387 fPreferClientSideDynamicBuffers = true;
388 }
389
Eric Karl5c779752017-05-08 12:02:07 -0700390 if (!contextOptions.fAvoidStencilBuffers) {
391 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
392 this->initFSAASupport(contextOptions, ctxInfo, gli);
393 this->initStencilSupport(ctxInfo);
394 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400395
396 // Setup blit framebuffer
397 if (kGL_GrGLStandard != ctxInfo.standard()) {
398 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
399 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
400 kNoMSAADst_BlitFramebufferFlag |
401 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
402 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
403 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
404 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
405 // limitations.
406 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
407 kResolveMustBeFull_BlitFrambufferFlag |
408 kNoMSAADst_BlitFramebufferFlag |
409 kNoFormatConversion_BlitFramebufferFlag |
410 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
411 }
412 } else {
413 if (fUsesMixedSamples ||
414 ctxInfo.version() >= GR_GL_VER(3,0) ||
415 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
416 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
417 fBlitFramebufferFlags = 0;
418 }
419 }
420
cdalton1dd05422015-06-12 09:01:18 -0700421 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000422
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000423 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000424 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
425 // extension includes glMapBuffer.
426 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
427 fMapBufferFlags |= kSubset_MapFlag;
428 fMapBufferType = kMapBufferRange_MapBufferType;
429 } else {
430 fMapBufferType = kMapBuffer_MapBufferType;
431 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000432 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000433 // Unextended GLES2 doesn't have any buffer mapping.
434 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800435 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800436 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
437 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800438 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
439 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
440 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000441 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
442 fMapBufferFlags = kCanMap_MapFlag;
443 fMapBufferType = kMapBuffer_MapBufferType;
444 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000445 }
446
jvanverthd7a2c1f2015-12-07 07:36:44 -0800447 if (kGL_GrGLStandard == standard) {
448 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
449 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700450 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500451 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400452 if (version >= GR_GL_VER(3, 0) ||
453 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
454 // GL_EXT_unpack_subimage needed to support subtexture rectangles
455 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800456 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400457// TODO: get transfer buffers working in Chrome
458// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
459// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800460 }
461 }
462
joshualitte5b74c62015-06-01 14:17:47 -0700463 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
464 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700465 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700466#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500467 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
468 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
469 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700470 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700471#else
cdalton397536c2016-03-25 12:15:03 -0700472 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700473#endif
joshualitte5b74c62015-06-01 14:17:47 -0700474 }
475
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000476 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000477 fNPOTTextureTileSupport = true;
478 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000479 } else {
480 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000481 // ES3 has no limitations.
482 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
483 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000484 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
485 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
486 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
487 // to alllow arbitrary wrap modes, however.
488 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000489 }
490
bsalomon@google.combcce8922013-03-25 15:38:39 +0000491 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
492 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
493 // Our render targets are always created with textures as the color
494 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000495 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700496 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
497
498 if (kARM_GrGLVendor == ctxInfo.vendor()) {
499 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
500 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
501 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000502
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000503 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
504
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000505 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700506 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000507
robertphillips1b8e1b52015-06-24 06:54:10 -0700508#if 0
509 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
510 kQualcomm_GrGLVendor != ctxInfo.vendor();
511#endif
512
csmartdalton9bc11872016-08-09 12:42:47 -0700513 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
514 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700515 }
516
robertphillips63926682015-08-20 09:39:02 -0700517#ifdef SK_BUILD_FOR_WIN
518 // On ANGLE deferring flushes can lead to GPU starvation
519 fPreferVRAMUseOverFlushes = !isANGLE;
520#endif
521
bsalomon7dea7b72015-08-19 08:26:51 -0700522 if (kChromium_GrGLDriver == ctxInfo.driver()) {
523 fMustClearUploadedBufferData = true;
524 }
525
bsalomond08ea5f2015-02-20 06:58:13 -0800526 if (kGL_GrGLStandard == standard) {
527 // ARB allows mixed size FBO attachments, EXT does not.
528 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
529 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
530 fOversizedStencilSupport = true;
531 } else {
532 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
533 }
534 } else {
535 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
536 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
537 }
538
joshualitt58001552015-06-26 12:46:36 -0700539 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700540 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
541 ctxInfo.hasExtension("GL_ARB_draw_indirect");
542 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
543 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700544 (fDrawIndirectSupport &&
545 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700546 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700547 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800548 } else {
549 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700550 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
551 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
552 fBaseInstanceSupport = fDrawIndirectSupport &&
553 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700554 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800555 }
556
ethannicholas28ef4452016-03-25 09:26:03 -0700557 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500558 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700559 fSampleShadingSupport = true;
560 }
561 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
562 fSampleShadingSupport = true;
563 }
564
jvanverth84741b32016-09-30 08:39:02 -0700565 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
566 if (kGL_GrGLStandard == standard) {
567 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
568 fFenceSyncSupport = true;
569 }
Brian Osman93a23462017-06-21 15:13:39 -0400570 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700571 fFenceSyncSupport = true;
572 }
573
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400574 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500575 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500576
brianosman20471892016-12-02 06:43:32 -0800577 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500578
brianosman851c2382016-12-07 10:03:25 -0800579 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
580 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800581
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400582 if (kGL_GrGLStandard == standard) {
583 if (version >= GR_GL_VER(4, 1)) {
584 fProgramBinarySupport = true;
585 }
586 } else if (version >= GR_GL_VER(3, 0)) {
587 fProgramBinarySupport = true;
588 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400589 if (fProgramBinarySupport) {
590 GrGLint count;
591 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
592 fProgramBinarySupport = count > 0;
593 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400594
bsalomoncdee0092016-01-08 13:20:12 -0800595 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
596 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800597 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700598
Brian Salomon01b476a2018-01-23 11:06:41 -0500599 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
600 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
601 }
602
cdalton4cd67132015-06-10 19:23:46 -0700603 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500604 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700605
Brian Salomon01b476a2018-01-23 11:06:41 -0500606 // For now these two are equivalent but we could have dst read in shader via some other method.
607 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000608}
609
egdaniel472d44e2015-10-22 08:20:00 -0700610const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
611 bool isCoreProfile) {
612 switch (generation) {
613 case k110_GrGLSLGeneration:
614 if (kGLES_GrGLStandard == standard) {
615 // ES2s shader language is based on version 1.20 but is version
616 // 1.00 of the ES language.
617 return "#version 100\n";
618 } else {
619 SkASSERT(kGL_GrGLStandard == standard);
620 return "#version 110\n";
621 }
622 case k130_GrGLSLGeneration:
623 SkASSERT(kGL_GrGLStandard == standard);
624 return "#version 130\n";
625 case k140_GrGLSLGeneration:
626 SkASSERT(kGL_GrGLStandard == standard);
627 return "#version 140\n";
628 case k150_GrGLSLGeneration:
629 SkASSERT(kGL_GrGLStandard == standard);
630 if (isCoreProfile) {
631 return "#version 150\n";
632 } else {
633 return "#version 150 compatibility\n";
634 }
635 case k330_GrGLSLGeneration:
636 if (kGLES_GrGLStandard == standard) {
637 return "#version 300 es\n";
638 } else {
639 SkASSERT(kGL_GrGLStandard == standard);
640 if (isCoreProfile) {
641 return "#version 330\n";
642 } else {
643 return "#version 330 compatibility\n";
644 }
645 }
cdalton33ad7012016-02-22 07:55:44 -0800646 case k400_GrGLSLGeneration:
647 SkASSERT(kGL_GrGLStandard == standard);
648 if (isCoreProfile) {
649 return "#version 400\n";
650 } else {
651 return "#version 400 compatibility\n";
652 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500653 case k420_GrGLSLGeneration:
654 SkASSERT(kGL_GrGLStandard == standard);
655 if (isCoreProfile) {
656 return "#version 420\n";
657 }
658 else {
659 return "#version 420 compatibility\n";
660 }
egdaniel472d44e2015-10-22 08:20:00 -0700661 case k310es_GrGLSLGeneration:
662 SkASSERT(kGLES_GrGLStandard == standard);
663 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800664 case k320es_GrGLSLGeneration:
665 SkASSERT(kGLES_GrGLStandard == standard);
666 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700667 }
668 return "<no version>";
669}
670
Chris Dalton47c8ed32017-11-15 18:27:09 -0700671bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
672 if (kGLES_GrGLStandard != ctxInfo.standard() &&
673 ctxInfo.version() < GR_GL_VER(4,1) &&
674 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
675 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
676 return true;
677 }
678 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
679 // geometry shaders don't have lower precision than vertex and fragment.
680 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
681 GrGLint range[2];
682 GrGLint bits;
683 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
684 if (range[0] < 127 || range[1] < 127 || bits < 23) {
685 return false;
686 }
687 }
688 return true;
689}
690
691void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700692 GrGLStandard standard = ctxInfo.standard();
693 GrGLVersion version = ctxInfo.version();
694
695 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500696 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700697 **************************************************************************/
698
Brian Salomon1edc5b92016-11-29 13:43:46 -0500699 GrShaderCaps* shaderCaps = fShaderCaps.get();
700 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700701 if (kGLES_GrGLStandard == standard) {
702 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500703 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
704 shaderCaps->fFBFetchSupport = true;
705 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
706 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700707 }
708 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
709 // 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 -0500710 shaderCaps->fFBFetchNeedsCustomOutput = false;
711 shaderCaps->fFBFetchSupport = true;
712 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
713 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700714 }
715 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
716 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500717 shaderCaps->fFBFetchNeedsCustomOutput = false;
718 shaderCaps->fFBFetchSupport = true;
719 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
720 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700721 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500722 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700723 }
724
cdaltonc08f1962016-02-12 12:14:06 -0800725 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500726 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800727 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500728 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800729 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
730 }
Brian Salomon41274562017-09-15 09:40:03 -0700731 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
732 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
733 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800734 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500735 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800736 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
737 } else {
738 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500739 shaderCaps->fNoPerspectiveInterpolationSupport = true;
740 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800741 "GL_NV_shader_noperspective_interpolation";
742 }
743 }
744
Brian Salomon1edc5b92016-11-29 13:43:46 -0500745 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
746 shaderCaps->fGLSLGeneration,
747 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800748
Brian Salomon1edc5b92016-11-29 13:43:46 -0500749 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
750 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800751 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800752
753 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500754 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800755 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
756 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500757 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800758 }
759
760 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500761 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800762 }
763
cdalton9c3f1432016-03-11 10:07:37 -0800764 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400765 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
766 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400767 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400768 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
769 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
770 // At least one driver has been found that has this extension without the "GL_" prefix.
771 shaderCaps->fExternalTextureSupport = true;
772 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800773 }
774 }
775
cdaltonc04ce672016-03-11 14:07:38 -0800776 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500777 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800778 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500779 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700780 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
781 }
782
Brian Salomon1edc5b92016-11-29 13:43:46 -0500783 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700784 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500785 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700786 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
787 } else {
788 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
789 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500790 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700791 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500792 shaderCaps->fTexelBufferSupport = true;
793 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700794 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500795 shaderCaps->fTexelBufferSupport = true;
796 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700797 }
cdaltonc04ce672016-03-11 14:07:38 -0800798 }
799 }
800
Chris Dalton1d616352017-05-31 12:51:23 -0600801 if (kGL_GrGLStandard == standard) {
802 shaderCaps->fVertexIDSupport = true;
803 } else {
804 // Desktop GLSL 3.30 == ES GLSL 3.00.
805 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
806 }
807
Chris Dalton7c7ff032018-03-28 20:09:58 -0600808 if (kGL_GrGLStandard == standard) {
809 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
810 } else {
811 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
812 }
813
Chris Dalton47c8ed32017-11-15 18:27:09 -0700814 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
815 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700816}
817
kkinnunencfe62e32015-07-01 02:58:50 -0700818bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700819 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
820
821 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700822 return false;
823 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700824
kkinnunencfe62e32015-07-01 02:58:50 -0700825 if (kGL_GrGLStandard == ctxInfo.standard()) {
826 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
827 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
828 return false;
829 }
830 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700831 if (!hasChromiumPathRendering &&
832 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700833 return false;
834 }
835 }
836 // We only support v1.3+ of GL_NV_path_rendering which allows us to
837 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
838 // additions are detected by checking the existence of the function.
839 // We also use *Then* functions that not all drivers might have. Check
840 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800841 if (!gli->fFunctions.fStencilThenCoverFillPath ||
842 !gli->fFunctions.fStencilThenCoverStrokePath ||
843 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
844 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
845 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700846 return false;
847 }
848 return true;
849}
bsalomon1aa20292016-01-22 08:16:09 -0800850
Brian Salomon71d9d842016-11-03 13:42:00 -0400851bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800852 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800853 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800854 std::function<bool ()> bindRenderTarget,
855 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400856 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800857 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400858 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800859 return false;
860 }
bsalomon7928ef62016-01-05 10:26:39 -0800861
bsalomon76148af2016-01-12 11:13:47 -0800862 GrGLenum readFormat;
863 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400864 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800865 return false;
866 }
867
bsalomon1aa20292016-01-22 08:16:09 -0800868 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800869 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
870 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
871 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
872 // 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 -0500873 // The manual does not seem to fully match the spec as the spec allows integer formats
874 // when the bound color buffer is an integer buffer. It doesn't specify which integer
875 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500876 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
877 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
878 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800879 return false;
880 }
881 // There is also a set of allowed types, but all the types we use are in the set:
882 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
883 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
884 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
885 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
886 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
887 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
888 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800889 return true;
piotaixre4b23142014-10-02 10:57:53 -0700890 }
bsalomon7928ef62016-01-05 10:26:39 -0800891
bsalomon76148af2016-01-12 11:13:47 -0800892 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500893 switch (fConfigTable[surfaceConfig].fFormatType) {
894 case kNormalizedFixedPoint_FormatType:
895 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
896 return true;
897 }
898 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500899 case kFloat_FormatType:
900 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
901 return true;
902 }
903 break;
bsalomon7928ef62016-01-05 10:26:39 -0800904 }
905
Brian Salomon71d9d842016-11-03 13:42:00 -0400906 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800907 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400908 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800909 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800910 if (!bindRenderTarget()) {
911 return false;
912 }
913 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
914 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800915 rpFormat->fFormat = format;
916 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800917 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800918 }
919
Brian Salomon71d9d842016-11-03 13:42:00 -0400920 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
921 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700922}
923
Eric Karl5c779752017-05-08 12:02:07 -0700924void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
925 const GrGLInterface* gli) {
926 // We need dual source blending and the ability to disable multisample in order to support mixed
927 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
928 // renderer is available and enabled; no other path renderers support this feature.
929 if (fMultisampleDisableSupport &&
930 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400931 this->shaderCaps()->pathRenderingSupport()
932#if GR_TEST_UTILS
933 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
934#endif
935 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700936 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400937 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700938 }
939
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000940 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400941 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
942 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
943 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
944 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
945 fAlpha8IsRenderable = true;
946 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500947 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
948 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
949 // mixed samples we can't use multisampled-render-to-texture.
950 if (fUsesMixedSamples) {
951 fMSFBOType = kMixedSamples_MSFBOType;
952 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000953 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
954 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
955 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400956 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
957 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400958 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400959 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400960 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400961 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000962 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
963 fMSFBOType = kES_Apple_MSFBOType;
964 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000965 } else {
egdanieleed519e2016-01-15 11:36:18 -0800966 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700967 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400968 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
969 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400970
Brian Salomon00731b42016-10-14 11:30:51 -0400971 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400972 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
973 // Core profile removes ALPHA8 support.
974 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
975 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
976 // present.
977 fAlpha8IsRenderable = true;
978 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000979 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
980 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400981 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000982 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000983 }
Eric Karl5c779752017-05-08 12:02:07 -0700984
Brian Salomon01b476a2018-01-23 11:06:41 -0500985 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400986 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
987 fMSFBOType = kNone_MSFBOType;
988 }
989
Eric Karl5c779752017-05-08 12:02:07 -0700990 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
991 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
992 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700993 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000994}
995
cdalton1dd05422015-06-12 09:01:18 -0700996void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500997 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -0700998
Greg Daniel210883c2017-11-27 15:14:01 -0500999 bool layoutQualifierSupport = false;
1000 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
1001 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1002 layoutQualifierSupport = true;
1003 }
1004
cdalton1dd05422015-06-12 09:01:18 -07001005 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1006 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001007 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001008 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1009 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001010 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001011 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001012 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1013 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001014 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001015 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001016 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001017 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001018 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1019 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001020 }
cdalton1dd05422015-06-12 09:01:18 -07001021}
1022
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001023namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001024const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001025}
1026
Eric Karl5c779752017-05-08 12:02:07 -07001027void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001028
1029 // Build up list of legal stencil formats (though perhaps not supported on
1030 // the particular gpu/driver) from most preferred to least.
1031
1032 // these consts are in order of most preferred to least preferred
1033 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1034
1035 static const StencilFormat
1036 // internal Format stencil bits total bits packed?
1037 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1038 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1039 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1040 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001041 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001042 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1043
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001044 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001045 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001046 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001047 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1048 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1049
1050 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1051 // require FBO support we can expect these are legal formats and don't
1052 // check. These also all support the unsized GL_STENCIL_INDEX.
1053 fStencilFormats.push_back() = gS8;
1054 fStencilFormats.push_back() = gS16;
1055 if (supportsPackedDS) {
1056 fStencilFormats.push_back() = gD24S8;
1057 }
1058 fStencilFormats.push_back() = gS4;
1059 if (supportsPackedDS) {
1060 fStencilFormats.push_back() = gDS;
1061 }
1062 } else {
1063 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1064 // for other formats.
1065 // ES doesn't support using the unsized format.
1066
1067 fStencilFormats.push_back() = gS8;
1068 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001069 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1070 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001071 fStencilFormats.push_back() = gD24S8;
1072 }
1073 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1074 fStencilFormats.push_back() = gS4;
1075 }
1076 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001077}
1078
Brian Osman71a18892017-08-10 10:23:25 -04001079void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001080
Brian Osman71a18892017-08-10 10:23:25 -04001081 // We are called by the base class, which has already called beginObject(). We choose to nest
1082 // all of our caps information in a named sub-object.
1083 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001084
Brian Osman71a18892017-08-10 10:23:25 -04001085 writer->beginArray("Stencil Formats");
1086
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001087 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001088 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001089 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1090 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1091 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001092 }
1093
Brian Osman71a18892017-08-10 10:23:25 -04001094 writer->endArray();
1095
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001096 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001097 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001098 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001099 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001100 "IMG MS To Texture",
1101 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001102 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001103 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001104 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001105 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1106 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1107 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1108 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1109 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001110 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001111
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001112 static const char* kInvalidateFBTypeStr[] = {
1113 "None",
1114 "Discard",
1115 "Invalidate",
1116 };
1117 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1118 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1119 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1120 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001121
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001122 static const char* kMapBufferTypeStr[] = {
1123 "None",
1124 "MapBuffer",
1125 "MapBufferRange",
1126 "Chromium",
1127 };
1128 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1129 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1130 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1131 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1132 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1133
Brian Osman71a18892017-08-10 10:23:25 -04001134 writer->appendBool("Core Profile", fIsCoreProfile);
1135 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1136 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1137 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1138 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1139 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1140 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1141 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1142 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001143
Brian Osman71a18892017-08-10 10:23:25 -04001144 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001145 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1146 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1147 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001148 writer->appendBool("Debug support", fDebugSupport);
1149 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1150 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1151 writer->appendBool("Base instance support", fBaseInstanceSupport);
1152 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1153 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1154 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1155 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1156 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1157 writer->appendBool("BGRA to RGBA readback conversions are slow",
1158 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001159 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001160 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1161 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001162 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1163 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1164 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1165 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001166 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1167 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001168
Brian Osman71a18892017-08-10 10:23:25 -04001169 writer->beginArray("configs");
1170
bsalomon41e4384e2016-01-08 09:12:44 -08001171 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001172 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001173 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1174 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1175 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001176 writer->appendHexU32("e_format_read_pixels",
1177 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001178 writer->appendHexU32(
1179 "e_format_teximage",
1180 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1181 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1182 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1183 writer->appendHexU32("i_for_renderbuffer",
1184 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1185 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001186 }
1187
Brian Osman71a18892017-08-10 10:23:25 -04001188 writer->endArray();
1189 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001190}
1191
bsalomon41e4384e2016-01-08 09:12:44 -08001192bool GrGLCaps::bgraIsInternalFormat() const {
1193 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1194}
1195
bsalomon76148af2016-01-12 11:13:47 -08001196bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1197 GrGLenum* internalFormat, GrGLenum* externalFormat,
1198 GrGLenum* externalType) const {
1199 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1200 externalFormat, externalType)) {
1201 return false;
1202 }
1203 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1204 return true;
1205}
1206
bsalomon76148af2016-01-12 11:13:47 -08001207bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1208 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001209 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001210 externalFormat, externalType)) {
1211 return false;
1212 }
1213 return true;
1214}
1215
1216bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001217 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1218 return true;
1219}
1220
1221bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1222 ExternalFormatUsage usage, GrGLenum* externalFormat,
1223 GrGLenum* externalType) const {
1224 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001225
1226 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1227 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1228
1229 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001230 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1231 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001232 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1233 return false;
1234 }
1235
1236 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1237 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1238
bsalomone9573312016-01-25 14:33:25 -08001239 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1240 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1241 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1242 // texture, not the red component.
1243 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001244 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001245 *externalFormat = GR_GL_ALPHA;
1246 }
1247 }
1248
bsalomon76148af2016-01-12 11:13:47 -08001249 return true;
1250}
1251
brianosman20471892016-12-02 06:43:32 -08001252void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1253 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001254 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001255 /*
1256 Comments on renderability of configs on various GL versions.
1257 OpenGL < 3.0:
1258 no built in support for render targets.
1259 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1260 format RGB, RGBA and NV float formats we don't use.
1261 This is the following:
1262 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1263 RGB10_A2, RGBA12,RGBA16
1264 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1265 since they aren't required by later standards and the driver can simply return
1266 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1267 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1268 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1269 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1270 This adds a lot of additional renderable sized formats, including ALPHA8.
1271 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1272 16F, 32I, 32UI, and 32F variants).
1273 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1274
1275 For both the above extensions we limit ourselves to those that are also required by
1276 OpenGL 3.0.
1277
1278 OpenGL 3.0:
1279 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1280 but are not required to be supported as renderable textures/renderbuffer.
1281 Required renderable color formats:
1282 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1283 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1284 RGB10_A2.
1285 - R11F_G11F_B10F.
1286 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1287 and RG8UI.
1288 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1289 - ALPHA8
1290
1291 OpenGL 3.1, 3.2, 3.3
1292 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1293 OpengGL 3.3, 4.0, 4.1
1294 Adds RGB10_A2UI.
1295 OpengGL 4.2
1296 Adds
1297 - RGB5_A1, RGBA4
1298 - RGB565
1299 OpenGL 4.4
1300 Does away with the separate list and adds a column to the sized internal color format
1301 table. However, no new formats become required color renderable.
1302
1303 ES 2.0
1304 color renderable: RGBA4, RGB5_A1, RGB565
1305 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1306 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1307 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1308 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1309 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1310 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1311
1312 ES 3.0
1313 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1314 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1315 RGB5_A1.
1316 - RGB8 and RGB565.
1317 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1318 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1319 ES 3.1
1320 Adds RGB10_A2, RGB10_A2UI,
1321 ES 3.2
1322 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1323 */
Brian Salomon44804c02018-01-23 16:51:28 -05001324
1325 // Correctness workarounds.
1326 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001327 bool disableSRGBForX86PowerVR = false;
1328 bool disableSRGBWriteControlForAdreno4xx = false;
1329 bool disableR8TexStorageForANGLEGL = false;
1330 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001331 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001332
1333 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1334 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1335 // and GL_RG on FBO textures.
1336 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1337
1338 bool isX86PowerVR = false;
1339#if defined(SK_CPU_X86)
1340 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1341 isX86PowerVR = true;
1342 }
1343#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001344 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1345 // blacklist that device (and any others that might be sharing the same driver).
1346 disableSRGBForX86PowerVR = isX86PowerVR;
1347 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1348
1349 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1350 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1351 // check that we are not going to OpenGL.
1352 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1353
1354 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1355#if defined(SK_BUILD_FOR_MAC)
1356 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1357#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001358 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1359 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001360 }
1361
Brian Salomon71d9d842016-11-03 13:42:00 -04001362 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1363 ConfigInfo::kFBOColorAttachment_Flag;
1364 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001365 if (kNone_MSFBOType != fMSFBOType) {
1366 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1367 }
bsalomon41e4384e2016-01-08 09:12:44 -08001368 GrGLStandard standard = ctxInfo.standard();
1369 GrGLVersion version = ctxInfo.version();
1370
cblume790d5132016-02-29 11:13:29 -08001371 bool texStorageSupported = false;
1372 if (kGL_GrGLStandard == standard) {
1373 // The EXT version can apply to either GL or GLES.
1374 texStorageSupported = version >= GR_GL_VER(4,2) ||
1375 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1376 ctxInfo.hasExtension("GL_EXT_texture_storage");
1377 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001378 texStorageSupported = version >= GR_GL_VER(3,0) ||
1379 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001380 }
1381
cdalton74b8d322016-04-11 14:47:28 -07001382 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1383
Brian Salomone609e812018-01-17 14:00:47 -05001384 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001385
1386 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001387 if (kGL_GrGLStandard == standard) {
1388 textureRedSupport =
1389 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1390 } else {
1391 textureRedSupport =
1392 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1393 }
1394 }
1395
bsalomon30447372015-12-21 09:03:05 -08001396 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1397 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001398 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001399 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001400 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001401 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001402
1403 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1404 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001405 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001406 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001407 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001408 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001409 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1410 if (kGL_GrGLStandard == standard) {
1411 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1412 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001413 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001414 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1415 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1416 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1417 }
egdaniel4999df82016-01-07 17:06:04 -08001418 }
cblume790d5132016-02-29 11:13:29 -08001419 if (texStorageSupported) {
1420 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1421 }
cdalton74b8d322016-04-11 14:47:28 -07001422 if (texelBufferSupport) {
1423 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1424 }
bsalomoncdee0092016-01-08 13:20:12 -08001425 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001426
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001427 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1428 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1429 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1430 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1431 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1432 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1433 // supportedReadPixelsColorType never returns it.
1434 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1435 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1436 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1437 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1438 if (kGL_GrGLStandard == standard) {
1439 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1440 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1441 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1442 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1443 // becomes an issue.
1444 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1445 // but we don't support that just for simplicity's sake.
1446 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1447 } else {
1448 // 3.0 and the extension support this as a render buffer format.
1449 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1450 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1451 }
1452 }
1453 if (texStorageSupported) {
1454 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1455 }
1456 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1457 if (disableRGB8ForMali400) {
1458 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1459 }
1460
1461 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001462 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001463 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001464 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001465
1466 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1467 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1468 // GL_EXT_texture_format_BGRA8888.
1469 bool supportsBGRATexStorage = false;
1470
bsalomon41e4384e2016-01-08 09:12:44 -08001471 if (kGL_GrGLStandard == standard) {
1472 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1473 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1474 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1475 // Since the internal format is RGBA8, it is also renderable.
1476 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1477 allRenderFlags;
1478 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001479 // Since we are using RGBA8 we can use tex storage.
1480 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001481 } else {
1482 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1483 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001484 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1485 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1486 nonMSAARenderFlags;
1487
1488 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1489 supportsBGRATexStorage = true;
1490 }
1491 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1492 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1493 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1494 ConfigInfo::kRenderableWithMSAA_Flag;
1495 }
1496 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001497 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1498 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1499 // driver remembers the external format when the texture is created (with TexImage).
1500 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1501 // We could work around this, but it adds even more state tracking to code that is
1502 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1503 // This also side-steps some ambiguous interactions with the texture storage extension.
1504 if (version >= GR_GL_VER(3,0)) {
1505 // The APPLE extension doesn't make this renderable.
1506 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001507 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001508 }
bsalomon41e4384e2016-01-08 09:12:44 -08001509 }
1510 }
Brian Osman48c99192017-06-02 08:45:06 -04001511
Greg Daniel0ff79b22018-02-15 12:33:33 -05001512 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001513 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001514 }
bsalomoncdee0092016-01-08 13:20:12 -08001515 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001516
brianosmana6359362016-03-21 06:55:37 -07001517 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001518 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001519 if (kGL_GrGLStandard == standard) {
1520 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001521 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001522 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1523 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1524 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001525 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001526 }
1527 }
1528 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001529 if (fSRGBSupport) {
1530 fSRGBWriteControl = true;
1531 }
bsalomon41e4384e2016-01-08 09:12:44 -08001532 } else {
brianosman20471892016-12-02 06:43:32 -08001533 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001534 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001535 fSRGBSupport = false;
1536 }
bsalomon41e4384e2016-01-08 09:12:44 -08001537 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1538 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001539 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001540 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001541 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001542 }
brianosman20471892016-12-02 06:43:32 -08001543 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1544 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1545 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001546 fSRGBSupport = false;
1547 }
brianosman20471892016-12-02 06:43:32 -08001548
1549 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1550 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1551 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1552 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1553 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1554 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1555 // affects Windows.
1556 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1557 fSRGBSupport = false;
1558 }
1559
Brian Osman48c99192017-06-02 08:45:06 -04001560 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1561 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1562 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1563
Brian Osman67999392017-05-31 16:19:34 -04001564 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001565 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001566 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1567 }
Brian Osman67999392017-05-31 16:19:34 -04001568
bsalomon30447372015-12-21 09:03:05 -08001569 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1570 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1571 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1572 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001573 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001574 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001575 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001576 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001577 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001578 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001579 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001580 }
Brian Osman48c99192017-06-02 08:45:06 -04001581 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1582 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001583 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1584 }
bsalomoncdee0092016-01-08 13:20:12 -08001585 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001586 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1587 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1588 // is in this format, for example).
1589 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1590 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1591 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1592 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001593 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001594 GR_GL_BGRA;
1595 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1596 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001597 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001598 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001599 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001600 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001601
brianosmana6359362016-03-21 06:55:37 -07001602 if (texStorageSupported) {
1603 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1604 }
1605 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1606
bsalomon30447372015-12-21 09:03:05 -08001607 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1608 if (this->ES2CompatibilitySupport()) {
1609 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1610 } else {
1611 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1612 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001613 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001614 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001615 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001616 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001617 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1618 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001619 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001620 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1621 }
1622 } else {
1623 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1624 }
cblume790d5132016-02-29 11:13:29 -08001625 // 565 is not a sized internal format on desktop GL. So on desktop with
1626 // 565 we always use an unsized internal format to let the system pick
1627 // the best sized format to convert the 565 data to. Since TexStorage
1628 // only allows sized internal formats we disallow it.
1629 //
1630 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1631 // update.
1632 if (texStorageSupported && kGL_GrGLStandard != standard) {
1633 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1634 }
bsalomoncdee0092016-01-08 13:20:12 -08001635 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001636
1637 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1638 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001639 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001640 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001641 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001642 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001643 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1644 if (kGL_GrGLStandard == standard) {
1645 if (version >= GR_GL_VER(4, 2)) {
1646 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1647 }
1648 } else {
1649 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1650 }
cblume790d5132016-02-29 11:13:29 -08001651 if (texStorageSupported) {
1652 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1653 }
bsalomoncdee0092016-01-08 13:20:12 -08001654 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001655
Brian Osman10fc6fd2018-03-02 11:01:10 -05001656 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1657 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001658 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001659 GR_GL_RGBA;
1660 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1661 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1662 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1663 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1664 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1665 allRenderFlags;
1666 }
1667 if (texStorageSupported) {
1668 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1669 }
1670 if (texelBufferSupport) {
1671 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1672 }
1673 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1674
Greg Danielef59d872017-11-17 16:47:21 -05001675 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1676 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1677
1678 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1679 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1680 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1681 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1682 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001683 }
Greg Danielef59d872017-11-17 16:47:21 -05001684 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1685 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001686 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001687 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1688 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1689 alphaInfo.fFlags |= allRenderFlags;
1690 }
1691
1692 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1693 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1694 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1695 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1696 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001697 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001698 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001699
Brian Osman48c99192017-06-02 08:45:06 -04001700 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1701 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001702 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001703 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1704 }
1705 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1706 }
1707
Brian Salomone609e812018-01-17 14:00:47 -05001708 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001709 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1710 if (texelBufferSupport) {
1711 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1712 }
1713
1714 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1715 } else {
1716 redInfo.fFlags = 0;
1717
1718 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001719 }
bsalomon41e4384e2016-01-08 09:12:44 -08001720
Greg Daniel7af060a2017-12-05 16:27:11 -05001721 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1722 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1723 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1724 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1725 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001726 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001727 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1728 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1729 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1730 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001731 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001732
1733 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1734 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1735 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1736 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1737 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001738 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001739 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1740 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1741
1742#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1743 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001744 if (this->textureRedSupport() ||
1745 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1746 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1747 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1748 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1749 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1750 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1751 }
1752#endif
Brian Osman48c99192017-06-02 08:45:06 -04001753 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001754 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001755 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1756 }
1757 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1758 }
1759
Brian Salomone609e812018-01-17 14:00:47 -05001760 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001761 if (texelBufferSupport) {
1762 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1763 }
1764 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1765 } else {
1766 grayRedInfo.fFlags = 0;
1767 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001768 }
1769
bsalomon41e4384e2016-01-08 09:12:44 -08001770 // Check for [half] floating point texture support
1771 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1772 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1773 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1774 bool hasFPTextures = false;
1775 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001776 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001777 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001778 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001779
1780 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001781 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001782 hasFPTextures = true;
1783 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001784 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001785 }
1786 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001787 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001788 hasFPTextures = true;
1789 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001790 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001791 } else {
1792 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1793 ctxInfo.hasExtension("GL_OES_texture_float")) {
1794 hasFPTextures = true;
1795 }
1796 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1797 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1798 hasHalfFPTextures = true;
1799 }
1800 }
1801 }
bsalomon30447372015-12-21 09:03:05 -08001802
csmartdalton6aa0e112017-02-08 16:14:11 -05001803 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1804 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1805 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1806 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1807 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001808 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001809 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1810 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1811 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001812 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001813 // For now we only enable rendering to float on desktop, because on ES we'd have to
1814 // solve many precision issues and no clients actually want this yet.
1815 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1816 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1817 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1818 }
bsalomon41e4384e2016-01-08 09:12:44 -08001819 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001820 if (texStorageSupported) {
1821 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1822 }
1823 if (texelBufferSupport) {
1824 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1825 }
1826 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001827 }
bsalomon30447372015-12-21 09:03:05 -08001828
Greg Danielef59d872017-11-17 16:47:21 -05001829 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001830 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001831 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001832 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001833 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001834 }
Greg Danielef59d872017-11-17 16:47:21 -05001835 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1836 redHalf.fFormats.fExternalType = redHalfExternalType;
1837 redHalf.fFormatType = kFloat_FormatType;
1838 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1839 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001840 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001841 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001842 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001843 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1844
csmartdalton6aa0e112017-02-08 16:14:11 -05001845 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001846 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001847 redHalf.fFlags |= fpRenderFlags;
1848 }
1849
1850 if (texStorageSupported && !isCommandBufferES2) {
1851 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1852 }
1853
1854 if (texelBufferSupport) {
1855 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001856 }
1857 }
Greg Danielef59d872017-11-17 16:47:21 -05001858 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001859
1860 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1861 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001862 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001863 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001864 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001865 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1866 } else {
1867 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1868 }
bsalomon7928ef62016-01-05 10:26:39 -08001869 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001870 if (hasHalfFPTextures) {
1871 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1872 // ES requires 3.2 or EXT_color_buffer_half_float.
1873 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1874 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1875 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1876 }
1877 }
cblume790d5132016-02-29 11:13:29 -08001878 if (texStorageSupported) {
1879 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1880 }
cdalton74b8d322016-04-11 14:47:28 -07001881 if (texelBufferSupport) {
1882 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1883 }
bsalomoncdee0092016-01-08 13:20:12 -08001884 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001885
bsalomon30447372015-12-21 09:03:05 -08001886 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1887
1888 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001889 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1890 ctxInfo.version() >= GR_GL_VER(3,0));
1891 // All ES versions (thus far) require sized internal formats for render buffers.
1892 // TODO: Always use sized internal format?
1893 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1894
bsalomon30447372015-12-21 09:03:05 -08001895 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001896 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1897 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001898 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001899 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001900 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1901 fConfigTable[i].fFormats.fSizedInternalFormat :
1902 fConfigTable[i].fFormats.fBaseInternalFormat;
1903 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001904 fConfigTable[i].fFormats.fSizedInternalFormat :
1905 fConfigTable[i].fFormats.fBaseInternalFormat;
1906 }
Brian Salomon44804c02018-01-23 16:51:28 -05001907 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1908 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1909 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1910 // in ES.
1911 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1912 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1913 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1914 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001915 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1916 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001917 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1918 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001919 }
1920
bsalomon30447372015-12-21 09:03:05 -08001921 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1922 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1923 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1924 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1925 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001926 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001927 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001928
1929 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1930 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1931 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1932 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001933 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001934 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1935 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1936 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1937 // slot.
1938 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1939 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001940
1941 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1942 // as a base format.
1943 // GL_EXT_texture_format_BGRA8888:
1944 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1945 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1946 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001947 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001948 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1949 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1950 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001951 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001952 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1953 }
1954
bsalomoncdee0092016-01-08 13:20:12 -08001955 // If we don't have texture swizzle support then the shader generator must insert the
1956 // swizzle into shader code.
1957 if (!this->textureSwizzleSupport()) {
1958 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001959 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001960 }
1961 }
1962
bsalomon7f9b2e42016-01-12 13:29:26 -08001963 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1964 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1965 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001966 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001967 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1968 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1969 if (GrPixelConfigIsAlphaOnly(config) &&
1970 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001971 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001972 }
1973 }
1974 }
1975
Greg Daniel81e7bf82017-07-19 14:47:42 -04001976 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1977 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001978 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1979 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001980 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001981 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1982 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001983 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001984 int count;
1985 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1986 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1987 1, &count);
1988 if (count) {
1989 int* temp = new int[count];
1990 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1991 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001992 // GL has a concept of MSAA rasterization with a single sample but we do not.
1993 if (count && temp[count - 1] == 1) {
1994 --count;
1995 SkASSERT(!count || temp[count -1] > 1);
1996 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001997 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001998 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04001999 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002000 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002001 for (int j = 0; j < count; ++j) {
2002 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2003 }
2004 delete[] temp;
2005 }
2006 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002007 // Fake out the table using some semi-standard counts up to the max allowed sample
2008 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002009 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002010 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2011 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2012 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2013 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2014 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002015 // Chrome has a mock GL implementation that returns 0.
2016 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002017
Brian Salomonbdecacf2018-02-02 20:32:49 -05002018 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002019 int count = SK_ARRAY_COUNT(kDefaultSamples);
2020 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002021 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002022 break;
2023 }
2024 }
2025 if (count > 0) {
2026 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2027 }
2028 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002029 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2030 fConfigTable[i].fColorSampleCounts.setCount(1);
2031 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002032 }
2033 }
2034
bsalomon30447372015-12-21 09:03:05 -08002035#ifdef SK_DEBUG
2036 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002037 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002038 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002039 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2040 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002041 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2042 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2043 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2044 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002045 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2046 fConfigTable[i].fFormats.fBaseInternalFormat);
2047 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002048 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002049 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2050 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2051 fConfigTable[i].fFormats.fExternalFormat[j]);
2052 }
2053 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002054 }
2055#endif
2056}
2057
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002058bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
2059 bool dstIsTextureable, bool dstIsGLTexture2D,
2060 GrSurfaceOrigin dstOrigin,
2061 GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
2062 bool srcIsTextureable, bool srcIsGLTexture2D,
2063 GrSurfaceOrigin srcOrigin) const {
2064 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2065 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2066 // many drivers would allow it to work, but ANGLE does not.
2067 if (kGLES_GrGLStandard == fStandard && this->bgraIsInternalFormat() &&
2068 (kBGRA_8888_GrPixelConfig == dstConfig || kBGRA_8888_GrPixelConfig == srcConfig)) {
2069 return false;
2070 }
2071
2072 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
2073 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
2074 return false;
2075 }
2076
2077 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
2078 // texture.
2079 if (!dstIsTextureable) {
2080 return false;
2081 }
2082
2083 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
2084 // is required
2085 if (this->canConfigBeFBOColorAttachment(srcConfig) &&
2086 (!srcIsTextureable || srcIsGLTexture2D) &&
2087 dstIsGLTexture2D &&
2088 dstOrigin == srcOrigin) {
2089 return true;
2090 } else {
2091 return false;
2092 }
2093}
2094
2095bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
2096 bool dstIsTextureable, bool dstIsGLTexture2D,
2097 GrSurfaceOrigin dstOrigin,
2098 GrPixelConfig srcConfig, int srcSampleCnt,
2099 bool srcIsTextureable, bool srcIsGLTexture2D,
2100 GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
2101 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2102 auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
2103 if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
2104 !this->canConfigBeFBOColorAttachment(srcConfig)) {
2105 return false;
2106 }
2107
2108 if (dstIsTextureable && !dstIsGLTexture2D) {
2109 return false;
2110 }
2111 if (srcIsTextureable && !srcIsGLTexture2D) {
2112 return false;
2113 }
2114
2115 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
2116 return false;
2117 }
2118 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
2119 // We would mirror to compensate for origin changes. Note that copySurface is
2120 // specified such that the src and dst rects are the same.
2121 if (dstOrigin != srcOrigin) {
2122 return false;
2123 }
2124 }
2125
2126 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
2127 if (srcSampleCnt > 1) {
2128 if (1 == dstSampleCnt) {
2129 return false;
2130 }
2131 if (SkRect::Make(srcRect) != srcBounds) {
2132 return false;
2133 }
2134 }
2135 }
2136
2137 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
2138 if (dstSampleCnt > 1) {
2139 return false;
2140 }
2141 }
2142
2143 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
2144 if (dstConfig != srcConfig) {
2145 return false;
2146 }
2147 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2148 if (srcSampleCnt > 1 && dstConfig != srcConfig) {
2149 return false;
2150 }
2151 }
2152
2153 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2154 if (srcSampleCnt > 1) {
2155 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
2156 return false;
2157 }
2158 if (dstOrigin != srcOrigin) {
2159 return false;
2160 }
2161 }
2162 }
2163 return true;
2164}
2165
2166bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
2167 return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
2168}
2169
2170static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
2171 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
2172 if (!rt) {
2173 return false;
2174 }
2175 // A RT has a separate MSAA renderbuffer if:
2176 // 1) It's multisampled
2177 // 2) We're using an extension with separate MSAA renderbuffers
2178 // 3) It's not FBO 0, which is special and always auto-resolves
2179 return rt->numColorSamples() > 1 &&
2180 glCaps.usesMSAARenderBuffers() &&
2181 !rt->rtPriv().glRTFBOIDIs0();
2182}
2183
2184bool GrGLCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
2185 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2186 GrSurfaceOrigin dstOrigin = dst->origin();
2187 GrSurfaceOrigin srcOrigin = src->origin();
2188
2189 GrPixelConfig dstConfig = dst->config();
2190 GrPixelConfig srcConfig = src->config();
2191
2192 int dstSampleCnt = 0;
2193 int srcSampleCnt = 0;
2194 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
2195 dstSampleCnt = rtProxy->numColorSamples();
2196 }
2197 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
2198 srcSampleCnt = rtProxy->numColorSamples();
2199 }
2200 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
2201 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
2202
2203 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
2204 // swizzle.
2205 if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
2206 this->shaderCaps()->configOutputSwizzle(dst->config())) {
2207 return false;
2208 }
2209
2210 const GrTextureProxy* dstTex = dst->asTextureProxy();
2211 const GrTextureProxy* srcTex = src->asTextureProxy();
2212
2213 bool dstIsTex2D = dstTex ? dstTex->texPriv().isGLTexture2D() : false;
2214 bool srcIsTex2D = srcTex ? srcTex->texPriv().isGLTexture2D() : false;
2215
2216 // One of the possible requirements for copy as blit is that the srcRect must match the bounds
2217 // of the src surface. If we have a approx fit surface we can't know for sure what the src
2218 // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
2219 // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
2220 // know we will at least be able to do it as a draw.
2221#ifdef SK_DEBUG
2222 if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2223 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2224 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
2225 !src->priv().isExact()) {
2226 SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
2227 }
2228#endif
2229
2230 return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
2231 SkToBool(dstTex), dstIsTex2D, dstOrigin,
2232 srcConfig, has_msaa_render_buffer(src, *this),
2233 SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
2234 this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2235 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2236 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
2237 dstPoint) ||
2238 this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
2239}
2240
Robert Phillipsbf25d432017-04-07 10:08:53 -04002241bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002242 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2243 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002244 // By default, we don't require rects to match.
2245 *rectsMustMatch = false;
2246
2247 // By default, we allow subrects.
2248 *disallowSubrect = false;
2249
Brian Salomon467921e2017-03-06 16:17:12 -05002250 // If the src is a texture, we can implement the blit as a draw assuming the config is
2251 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002252 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002253 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002254 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2255 desc->fConfig = src->config();
2256 return true;
2257 }
2258
Robert Phillipsbf25d432017-04-07 10:08:53 -04002259 {
2260 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2261 // wrapped. In that case the proxy would already be instantiated.
2262 const GrTexture* srcTexture = src->priv().peekTexture();
2263 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2264 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2265 // Not supported for FBO blit or CopyTexSubImage
2266 return false;
2267 }
Brian Salomon467921e2017-03-06 16:17:12 -05002268 }
2269
2270 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2271 // possible and we return false to fallback to creating a render target dst for render-to-
2272 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2273 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002274 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002275 bool rectsMustMatchForBlitFramebuffer = false;
2276 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002277 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002278 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2279 rectsMustMatchForBlitFramebuffer = true;
2280 disallowSubrectForBlitFramebuffer = true;
2281 // Mirroring causes rects to mismatch later, don't allow it.
2282 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002283 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2284 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002285 rectsMustMatchForBlitFramebuffer = true;
2286 // Mirroring causes rects to mismatch later, don't allow it.
2287 originForBlitFramebuffer = src->origin();
2288 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002289 originForBlitFramebuffer = src->origin();
2290 }
2291
2292 // Check for format issues with glCopyTexSubImage2D
2293 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2294 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2295 // then we set up for that, otherwise fail.
2296 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002297 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002298 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002299 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2300 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002301 return true;
2302 }
2303 return false;
2304 }
2305
Robert Phillipsbf25d432017-04-07 10:08:53 -04002306 {
Brian Salomon63e79732017-05-15 21:23:13 -04002307 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2308 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002309 if (srcIsMSAARenderbuffer) {
2310 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2311 // blit or fail.
2312 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002313 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002314 desc->fConfig = src->config();
2315 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2316 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2317 return true;
2318 }
2319 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002320 }
Brian Salomon467921e2017-03-06 16:17:12 -05002321 }
2322
2323 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002324 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002325 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002326 desc->fFlags = kNone_GrSurfaceFlags;
2327 return true;
2328}
2329
Greg Daniel691f5e72018-02-28 14:21:34 -05002330void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2331 const GrContextOptions& contextOptions,
2332 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002333 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2334 // Thus we are blacklisting this extension for now on Adreno4xx devices.
2335 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2336 fDiscardRenderTargetSupport = false;
2337 fInvalidateFBType = kNone_InvalidateFBType;
2338 }
2339
2340 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2341 // 340.96 and 367.57.
2342 if (kGL_GrGLStandard == ctxInfo.standard() &&
2343 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002344 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002345 fClearTextureSupport = false;
2346 }
2347
2348 // Calling glClearTexImage crashes on the NexusPlayer.
2349 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2350 fClearTextureSupport = false;
2351 }
2352
2353 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2354#ifdef SK_BUILD_FOR_MAC
2355 if (shaderCaps->fGeometryShaderSupport) {
2356 shaderCaps->fGSInvocationsSupport = false;
2357 }
2358#endif
2359
2360 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2361 // shaders. @127.0 is the earliest verified driver to not crash.
2362 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002363 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002364 shaderCaps->fGeometryShaderSupport = false;
2365 }
2366
2367#if defined(__has_feature)
2368#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2369 // See skbug.com/7058
2370 fMapBufferType = kNone_MapBufferType;
2371 fMapBufferFlags = kNone_MapFlags;
2372#endif
2373#endif
2374
2375 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2376 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2377 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2378 // unclear whether this really affects a wide range of devices.
2379 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002380 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002381 fMapBufferType = kNone_MapBufferType;
2382 fMapBufferFlags = kNone_MapFlags;
2383 }
2384
2385 // TODO: re-enable for ANGLE
2386 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2387 fTransferBufferType = kNone_TransferBufferType;
2388 }
2389
2390 // Using MIPs on this GPU seems to be a source of trouble.
2391 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2392 fMipMapSupport = false;
2393 }
2394
2395 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2396 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2397 // around a driver bug related to gl_FragCoord.
2398 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2399 fMaxClipAnalyticFPs = 0;
2400 }
2401
2402#ifndef SK_BUILD_FOR_IOS
2403 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2404 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2405 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2406 ctxInfo.driver() != kChromium_GrGLDriver)) {
2407 fUseDrawToClearColor = true;
2408 }
2409#endif
2410
2411 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2412 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2413 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2414 fUseDrawToClearColor = true;
2415 }
2416
2417#ifdef SK_BUILD_FOR_MAC
2418 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2419 // full screen clears
2420 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2421 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002422 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2423 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2424 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2425 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002426 fUseDrawToClearColor = true;
2427 }
2428#endif
2429
2430 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2431 // bugs seems to involve clearing too much and not skipping the clear.
2432 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2433 // but only for D3D11 ANGLE.
2434 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2435 fUseDrawToClearColor = true;
2436 }
2437
2438 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2439 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002440 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002441 fUseDrawToClearStencilClip = true;
2442 }
2443 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2444 }
2445
2446 // This was reproduced on the following configurations:
2447 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2448 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2449 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2450 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2451 // and not produced on:
2452 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2453 // The particular lines that get dropped from test images varies across different devices.
2454 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002455 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002456 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2457 }
2458
Chris Dalton6f5e77a2018-04-23 21:14:42 -06002459 if (kIntelSkylake_GrGLRenderer == ctxInfo.renderer() ||
2460 (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2461 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer())) {
Chris Daltonda40cd22018-04-16 13:19:58 -06002462 fRequiresFlushBetweenNonAndInstancedDraws = true;
2463 }
2464
Brian Salomon01b476a2018-01-23 11:06:41 -05002465 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2466 // given 1 << 15 or more instances.
2467 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2468 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
2469 }
2470
2471 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002472 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002473 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2474 fUseDrawInsteadOfAllRenderTargetWrites = true;
2475 }
2476
2477 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2478 fSampleShadingSupport = false;
2479 }
2480
2481#ifdef SK_BUILD_FOR_MAC
2482 static constexpr bool isMAC = true;
2483#else
2484 static constexpr bool isMAC = false;
2485#endif
2486
2487 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2488 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2489 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2490 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2491 if (fMipMapLevelAndLodControlSupport &&
2492 (contextOptions.fDoManualMipmapping ||
2493 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2494 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2495 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2496 fDoManualMipmapping = true;
2497 }
2498
2499 // See http://crbug.com/710443
2500#ifdef SK_BUILD_FOR_MAC
2501 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2502 fClearToBoundaryValuesIsBroken = true;
2503 }
2504#endif
2505 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2506 fDrawArraysBaseVertexIsBroken = true;
2507 }
2508
Brian Salomon01b476a2018-01-23 11:06:41 -05002509 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2510 // Galaxy S7.
2511 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2512 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2513 shaderCaps->fFBFetchSupport = false;
2514 }
2515
Brian Salomon01b476a2018-01-23 11:06:41 -05002516 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2517 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2518
2519 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2520 // function that may require a gradient calculation inside a conditional block may return
2521 // undefined results". This appears to be an issue with the 'any' call since even the simple
2522 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2523 // from our GrTextureDomain processor.
2524 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2525
2526 // Known issue on at least some Intel platforms:
2527 // http://code.google.com/p/skia/issues/detail?id=946
2528 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2529 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2530 }
2531
Chris Dalton0090ef62018-03-28 17:35:00 -06002532 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002533 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2534 // so we must do the abs first in a separate expression.
2535 shaderCaps->fCanUseMinAndAbsTogether = false;
2536
2537 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2538 // must avoid this condition.
2539 shaderCaps->fCanUseFractForNegativeValues = false;
2540 }
2541
2542 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2543 // thus must us -1.0 * %s.x to work correctly
2544 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2545 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2546 }
2547
2548 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2549 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2550 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2551 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2552 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2553 }
2554
2555 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2556 // the original dst color when reading the outColor even after being written to. By using a
2557 // local outColor we can work around this bug.
2558 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2559 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2560 }
2561
2562 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2563 // color, and that uniform contains an opaque color, and the output of the shader is only based
2564 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2565 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2566 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2567 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2568 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2569 shaderCaps->fMustObfuscateUniformColor = true;
2570 }
2571#ifdef SK_BUILD_FOR_WIN
2572 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2573 //
2574 // Basically, if a shader has a construct like:
2575 //
2576 // float x = someCondition ? someValue : 0;
2577 // float2 result = (0 == x) ? float2(x, x)
2578 // : float2(2 * x / x, 0);
2579 //
2580 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2581 // we've explicitly guarded the division with a check against zero. This manifests in much
2582 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2583 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2584 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2585 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2586 }
2587#endif
2588
2589 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2590 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2591 // that the interpolation of vertex shader outputs is quite inaccurate.
2592 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2593 shaderCaps->fCanUseFragCoord = false;
2594 shaderCaps->fInterpolantsAreInaccurate = true;
2595 }
2596
Chris Dalton0090ef62018-03-28 17:35:00 -06002597 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2598 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2599 shaderCaps->fCanUseFragCoord = false;
2600 }
2601
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002602 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2603 // (Are they implemented with fp16?)
2604 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2605 shaderCaps->fIncompleteShortIntPrecision = true;
2606 }
2607
Brian Salomon01b476a2018-01-23 11:06:41 -05002608 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2609 // for now until its own blacklists can be updated.
2610 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2611 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2612 kIntel_GrGLDriver == ctxInfo.driver() ||
2613 kChromium_GrGLDriver == ctxInfo.driver()) {
2614 fBlendEquationSupport = kBasic_BlendEquationSupport;
2615 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2616 }
2617
2618 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2619 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002620 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002621 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002622 fBlendEquationSupport = kBasic_BlendEquationSupport;
2623 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2624 }
2625
2626 if (this->advancedBlendEquationSupport()) {
2627 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002628 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002629 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2630 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2631 (1 << kColorBurn_GrBlendEquation);
2632 }
2633 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2634 // Blacklist color-burn on ARM until the fix is released.
2635 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2636 }
2637 }
2638
2639 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2640 if (fMultisampleDisableSupport &&
2641 this->shaderCaps()->dualSourceBlendingSupport() &&
2642 this->shaderCaps()->pathRenderingSupport() &&
2643 fUsesMixedSamples &&
2644#if GR_TEST_UTILS
2645 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2646#endif
2647 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2648 kChromium_GrGLDriver == ctxInfo.driver())) {
2649 fDiscardRenderTargetSupport = false;
2650 fInvalidateFBType = kNone_InvalidateFBType;
2651 }
Brian Osmanc585e202018-04-04 14:08:27 -04002652
Brian Osman061020e2018-04-17 14:22:15 -04002653 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2654 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2655 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2656 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002657 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2658 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002659 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002660 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002661 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2662 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002663 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002664}
2665
csmartdaltone0d36292016-07-29 08:14:20 -07002666void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002667 if (options.fDisableDriverCorrectnessWorkarounds) {
2668 SkASSERT(!fDoManualMipmapping);
2669 SkASSERT(!fClearToBoundaryValuesIsBroken);
2670 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2671 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2672 SkASSERT(!fUseDrawToClearColor);
2673 SkASSERT(!fUseDrawToClearStencilClip);
2674 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2675 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2676 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Chris Daltonda40cd22018-04-16 13:19:58 -06002677 SkASSERT(!fRequiresFlushBetweenNonAndInstancedDraws);
Brian Salomon01b476a2018-01-23 11:06:41 -05002678 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002679 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2680 fUseDrawToClearColor = false;
2681 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2682 fUseDrawToClearColor = true;
2683 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002684 if (options.fDoManualMipmapping) {
2685 fDoManualMipmapping = true;
2686 }
csmartdaltone0d36292016-07-29 08:14:20 -07002687}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002688
Brian Salomon3d86a192018-02-27 16:46:11 -05002689bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2690 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2691 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2692 if (tex->hasBaseLevelBeenBoundToFBO()) {
2693 return false;
2694 }
2695 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002696 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002697 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2698 return false;
2699 }
2700 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2701 return false;
2702 }
2703 return SkToBool(surface->asTexture());
2704 }
2705 return true;
2706}
2707
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002708bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2709 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2710 // We don't support reading pixels directly from EXTERNAL textures as it would require
2711 // binding the texture to a FBO.
2712 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2713 return false;
2714 }
2715 }
2716 return true;
2717}
2718
2719GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2720 GrColorType dstColorType) const {
2721 // For now, we mostly report the read back format that is required by the ES spec without
2722 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2723 // this as makes sense to increase performance and correctness.
2724 switch (fConfigTable[config].fFormatType) {
2725 case kNormalizedFixedPoint_FormatType:
2726 return GrColorType::kRGBA_8888;
2727 case kFloat_FormatType:
2728 // We cheat a little here and allow F16 read back if the src and dst match.
2729 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2730 return GrColorType::kRGBA_F16;
2731 }
2732 if ((kAlpha_half_GrPixelConfig == config ||
2733 kAlpha_half_as_Red_GrPixelConfig == config) &&
2734 GrColorType::kAlpha_F16 == dstColorType) {
2735 return GrColorType::kAlpha_F16;
2736 }
2737 // And similar for full float RG.
2738 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2739 return GrColorType::kRG_F32;
2740 }
2741 return GrColorType::kRGBA_F32;
2742 }
2743 return GrColorType::kUnknown;
2744}
2745
Greg Daniel2a303902018-02-20 10:25:54 -05002746bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002747 GrGLFramebufferInfo fbInfo;
2748 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002749 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002750 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002751}
2752
Brian Salomonbdecacf2018-02-02 20:32:49 -05002753int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2754 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002755 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002756 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002757 return 0;
2758 }
2759
Brian Salomonbdecacf2018-02-02 20:32:49 -05002760 if (1 == requestedCount) {
2761 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2762 }
2763
Greg Daniel81e7bf82017-07-19 14:47:42 -04002764 for (int i = 0; i < count; ++i) {
2765 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2766 return fConfigTable[config].fColorSampleCounts[i];
2767 }
2768 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002769 return 0;
2770}
2771
2772int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2773 const auto& table = fConfigTable[config].fColorSampleCounts;
2774 if (!table.count()) {
2775 return 0;
2776 }
2777 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002778}
2779
Greg Danielfaa095e2017-12-19 13:15:02 -05002780bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2781 GrGLStandard standard) {
2782 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002783
2784 switch (ct) {
2785 case kUnknown_SkColorType:
2786 return false;
2787 case kAlpha_8_SkColorType:
2788 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002789 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002790 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002791 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002792 }
2793 break;
2794 case kRGB_565_SkColorType:
2795 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002796 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002797 }
2798 break;
2799 case kARGB_4444_SkColorType:
2800 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002801 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002802 }
2803 break;
2804 case kRGBA_8888_SkColorType:
2805 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002806 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002807 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002808 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002809 }
2810 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002811 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002812 if (GR_GL_RGB8 == format) {
2813 *config = kRGB_888_GrPixelConfig;
2814 }
2815 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002816 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002817 if (GR_GL_RGBA8 == format) {
2818 if (kGL_GrGLStandard == standard) {
2819 *config = kBGRA_8888_GrPixelConfig;
2820 }
2821 } else if (GR_GL_BGRA8 == format) {
2822 if (kGLES_GrGLStandard == standard) {
2823 *config = kBGRA_8888_GrPixelConfig;
2824 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002825 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002826 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002827 }
2828 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002829 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002830 if (GR_GL_RGB10_A2 == format) {
2831 *config = kRGBA_1010102_GrPixelConfig;
2832 }
2833 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002834 case kRGB_101010x_SkColorType:
2835 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002836 case kGray_8_SkColorType:
2837 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002838 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002839 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002840 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002841 }
2842 break;
2843 case kRGBA_F16_SkColorType:
2844 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002845 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002846 }
2847 break;
2848 }
2849
Greg Danielfaa095e2017-12-19 13:15:02 -05002850 return kUnknown_GrPixelConfig != *config;
2851}
2852
2853bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2854 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002855 GrGLTextureInfo texInfo;
2856 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002857 return false;
2858 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002859 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002860}
2861
2862bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2863 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002864 GrGLFramebufferInfo fbInfo;
2865 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002866 return false;
2867 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002868 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002869}
2870
Robert Phillipsfc711a22018-02-13 17:03:00 -05002871bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2872 GrPixelConfig* config) const {
2873 const GrGLenum* glFormat = format.getGLFormat();
2874 if (!glFormat) {
2875 return false;
2876 }
2877 return validate_sized_format(*glFormat, ct, config, fStandard);
2878}
2879
2880