blob: 727db6c648c7256c7fc8cab923f6545625c882b0 [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);
Adrienne Walker724afe82018-05-15 11:36:26 -0700492
493 if (fDriverBugWorkarounds.max_texture_size_limit_4096) {
494 fMaxTextureSize = SkTMin(fMaxTextureSize, 4096);
495 }
496
bsalomon@google.combcce8922013-03-25 15:38:39 +0000497 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
498 // Our render targets are always created with textures as the color
499 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000500 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700501 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
502
503 if (kARM_GrGLVendor == ctxInfo.vendor()) {
504 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
505 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
506 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000507
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000508 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
509
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000510 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700511 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000512
robertphillips1b8e1b52015-06-24 06:54:10 -0700513#if 0
514 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
515 kQualcomm_GrGLVendor != ctxInfo.vendor();
516#endif
517
csmartdalton9bc11872016-08-09 12:42:47 -0700518 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
519 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700520 }
521
robertphillips63926682015-08-20 09:39:02 -0700522#ifdef SK_BUILD_FOR_WIN
523 // On ANGLE deferring flushes can lead to GPU starvation
524 fPreferVRAMUseOverFlushes = !isANGLE;
525#endif
526
bsalomon7dea7b72015-08-19 08:26:51 -0700527 if (kChromium_GrGLDriver == ctxInfo.driver()) {
528 fMustClearUploadedBufferData = true;
529 }
530
bsalomond08ea5f2015-02-20 06:58:13 -0800531 if (kGL_GrGLStandard == standard) {
532 // ARB allows mixed size FBO attachments, EXT does not.
533 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
534 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
535 fOversizedStencilSupport = true;
536 } else {
537 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
538 }
539 } else {
540 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
541 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
542 }
543
joshualitt58001552015-06-26 12:46:36 -0700544 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700545 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
546 ctxInfo.hasExtension("GL_ARB_draw_indirect");
547 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
548 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700549 (fDrawIndirectSupport &&
550 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700551 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700552 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800553 } else {
554 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700555 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
556 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
557 fBaseInstanceSupport = fDrawIndirectSupport &&
558 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700559 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800560 }
561
ethannicholas28ef4452016-03-25 09:26:03 -0700562 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500563 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700564 fSampleShadingSupport = true;
565 }
566 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
567 fSampleShadingSupport = true;
568 }
569
jvanverth84741b32016-09-30 08:39:02 -0700570 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
571 if (kGL_GrGLStandard == standard) {
572 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
573 fFenceSyncSupport = true;
574 }
Brian Osman93a23462017-06-21 15:13:39 -0400575 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700576 fFenceSyncSupport = true;
577 }
578
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400579 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500580 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500581
brianosman20471892016-12-02 06:43:32 -0800582 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500583
brianosman851c2382016-12-07 10:03:25 -0800584 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
585 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800586
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400587 if (kGL_GrGLStandard == standard) {
588 if (version >= GR_GL_VER(4, 1)) {
589 fProgramBinarySupport = true;
590 }
591 } else if (version >= GR_GL_VER(3, 0)) {
592 fProgramBinarySupport = true;
593 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400594 if (fProgramBinarySupport) {
595 GrGLint count;
596 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
597 fProgramBinarySupport = count > 0;
598 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400599
bsalomoncdee0092016-01-08 13:20:12 -0800600 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
601 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800602 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700603
Brian Salomon01b476a2018-01-23 11:06:41 -0500604 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
605 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
606 }
607
cdalton4cd67132015-06-10 19:23:46 -0700608 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500609 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700610
Brian Salomon01b476a2018-01-23 11:06:41 -0500611 // For now these two are equivalent but we could have dst read in shader via some other method.
612 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000613}
614
egdaniel472d44e2015-10-22 08:20:00 -0700615const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
616 bool isCoreProfile) {
617 switch (generation) {
618 case k110_GrGLSLGeneration:
619 if (kGLES_GrGLStandard == standard) {
620 // ES2s shader language is based on version 1.20 but is version
621 // 1.00 of the ES language.
622 return "#version 100\n";
623 } else {
624 SkASSERT(kGL_GrGLStandard == standard);
625 return "#version 110\n";
626 }
627 case k130_GrGLSLGeneration:
628 SkASSERT(kGL_GrGLStandard == standard);
629 return "#version 130\n";
630 case k140_GrGLSLGeneration:
631 SkASSERT(kGL_GrGLStandard == standard);
632 return "#version 140\n";
633 case k150_GrGLSLGeneration:
634 SkASSERT(kGL_GrGLStandard == standard);
635 if (isCoreProfile) {
636 return "#version 150\n";
637 } else {
638 return "#version 150 compatibility\n";
639 }
640 case k330_GrGLSLGeneration:
641 if (kGLES_GrGLStandard == standard) {
642 return "#version 300 es\n";
643 } else {
644 SkASSERT(kGL_GrGLStandard == standard);
645 if (isCoreProfile) {
646 return "#version 330\n";
647 } else {
648 return "#version 330 compatibility\n";
649 }
650 }
cdalton33ad7012016-02-22 07:55:44 -0800651 case k400_GrGLSLGeneration:
652 SkASSERT(kGL_GrGLStandard == standard);
653 if (isCoreProfile) {
654 return "#version 400\n";
655 } else {
656 return "#version 400 compatibility\n";
657 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500658 case k420_GrGLSLGeneration:
659 SkASSERT(kGL_GrGLStandard == standard);
660 if (isCoreProfile) {
661 return "#version 420\n";
662 }
663 else {
664 return "#version 420 compatibility\n";
665 }
egdaniel472d44e2015-10-22 08:20:00 -0700666 case k310es_GrGLSLGeneration:
667 SkASSERT(kGLES_GrGLStandard == standard);
668 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800669 case k320es_GrGLSLGeneration:
670 SkASSERT(kGLES_GrGLStandard == standard);
671 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700672 }
673 return "<no version>";
674}
675
Chris Dalton47c8ed32017-11-15 18:27:09 -0700676bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
677 if (kGLES_GrGLStandard != ctxInfo.standard() &&
678 ctxInfo.version() < GR_GL_VER(4,1) &&
679 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
680 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
681 return true;
682 }
683 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
684 // geometry shaders don't have lower precision than vertex and fragment.
685 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
686 GrGLint range[2];
687 GrGLint bits;
688 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
689 if (range[0] < 127 || range[1] < 127 || bits < 23) {
690 return false;
691 }
692 }
693 return true;
694}
695
696void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700697 GrGLStandard standard = ctxInfo.standard();
698 GrGLVersion version = ctxInfo.version();
699
700 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500701 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700702 **************************************************************************/
703
Brian Salomon1edc5b92016-11-29 13:43:46 -0500704 GrShaderCaps* shaderCaps = fShaderCaps.get();
705 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700706 if (kGLES_GrGLStandard == standard) {
707 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500708 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
709 shaderCaps->fFBFetchSupport = true;
710 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
711 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700712 }
713 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
714 // 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 -0500715 shaderCaps->fFBFetchNeedsCustomOutput = false;
716 shaderCaps->fFBFetchSupport = true;
717 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
718 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700719 }
720 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
721 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500722 shaderCaps->fFBFetchNeedsCustomOutput = false;
723 shaderCaps->fFBFetchSupport = true;
724 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
725 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700726 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500727 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700728 }
729
cdaltonc08f1962016-02-12 12:14:06 -0800730 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500731 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800732 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500733 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800734 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
735 }
Brian Salomon41274562017-09-15 09:40:03 -0700736 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
737 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
738 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800739 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500740 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800741 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
742 } else {
Brian Osman71a69952018-05-07 17:07:35 -0400743 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation") &&
744 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration /* GLSL ES 3.0 */) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500745 shaderCaps->fNoPerspectiveInterpolationSupport = true;
746 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800747 "GL_NV_shader_noperspective_interpolation";
748 }
749 }
750
Brian Salomon1edc5b92016-11-29 13:43:46 -0500751 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
752 shaderCaps->fGLSLGeneration,
753 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800754
Brian Salomon1edc5b92016-11-29 13:43:46 -0500755 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
756 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800757 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800758
759 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500760 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800761 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
762 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500763 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800764 }
765
766 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500767 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800768 }
769
cdalton9c3f1432016-03-11 10:07:37 -0800770 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400771 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
772 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400773 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400774 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
775 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
776 // At least one driver has been found that has this extension without the "GL_" prefix.
777 shaderCaps->fExternalTextureSupport = true;
778 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800779 }
780 }
781
cdaltonc04ce672016-03-11 14:07:38 -0800782 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500783 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800784 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500785 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700786 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
787 }
788
Brian Salomon1edc5b92016-11-29 13:43:46 -0500789 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700790 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500791 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700792 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
793 } else {
794 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
795 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500796 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700797 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500798 shaderCaps->fTexelBufferSupport = true;
799 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700800 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500801 shaderCaps->fTexelBufferSupport = true;
802 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700803 }
cdaltonc04ce672016-03-11 14:07:38 -0800804 }
805 }
806
Chris Dalton1d616352017-05-31 12:51:23 -0600807 if (kGL_GrGLStandard == standard) {
808 shaderCaps->fVertexIDSupport = true;
809 } else {
810 // Desktop GLSL 3.30 == ES GLSL 3.00.
811 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
812 }
813
Chris Dalton7c7ff032018-03-28 20:09:58 -0600814 if (kGL_GrGLStandard == standard) {
815 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
816 } else {
817 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
818 }
819
Chris Dalton47c8ed32017-11-15 18:27:09 -0700820 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
821 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700822}
823
kkinnunencfe62e32015-07-01 02:58:50 -0700824bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700825 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
826
827 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700828 return false;
829 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700830
kkinnunencfe62e32015-07-01 02:58:50 -0700831 if (kGL_GrGLStandard == ctxInfo.standard()) {
832 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
833 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
834 return false;
835 }
836 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700837 if (!hasChromiumPathRendering &&
838 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700839 return false;
840 }
841 }
842 // We only support v1.3+ of GL_NV_path_rendering which allows us to
843 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
844 // additions are detected by checking the existence of the function.
845 // We also use *Then* functions that not all drivers might have. Check
846 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800847 if (!gli->fFunctions.fStencilThenCoverFillPath ||
848 !gli->fFunctions.fStencilThenCoverStrokePath ||
849 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
850 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
851 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700852 return false;
853 }
854 return true;
855}
bsalomon1aa20292016-01-22 08:16:09 -0800856
Brian Salomon71d9d842016-11-03 13:42:00 -0400857bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800858 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800859 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800860 std::function<bool ()> bindRenderTarget,
861 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400862 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800863 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400864 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800865 return false;
866 }
bsalomon7928ef62016-01-05 10:26:39 -0800867
bsalomon76148af2016-01-12 11:13:47 -0800868 GrGLenum readFormat;
869 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400870 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800871 return false;
872 }
873
bsalomon1aa20292016-01-22 08:16:09 -0800874 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800875 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
876 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
877 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
878 // 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 -0500879 // The manual does not seem to fully match the spec as the spec allows integer formats
880 // when the bound color buffer is an integer buffer. It doesn't specify which integer
881 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500882 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
883 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
884 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800885 return false;
886 }
887 // There is also a set of allowed types, but all the types we use are in the set:
888 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
889 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
890 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
891 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
892 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
893 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
894 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800895 return true;
piotaixre4b23142014-10-02 10:57:53 -0700896 }
bsalomon7928ef62016-01-05 10:26:39 -0800897
bsalomon76148af2016-01-12 11:13:47 -0800898 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500899 switch (fConfigTable[surfaceConfig].fFormatType) {
900 case kNormalizedFixedPoint_FormatType:
901 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
902 return true;
903 }
904 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500905 case kFloat_FormatType:
906 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
907 return true;
908 }
909 break;
bsalomon7928ef62016-01-05 10:26:39 -0800910 }
911
Brian Salomon71d9d842016-11-03 13:42:00 -0400912 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800913 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400914 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800915 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800916 if (!bindRenderTarget()) {
917 return false;
918 }
919 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
920 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800921 rpFormat->fFormat = format;
922 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800923 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800924 }
925
Brian Salomon71d9d842016-11-03 13:42:00 -0400926 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
927 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700928}
929
Eric Karl5c779752017-05-08 12:02:07 -0700930void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
931 const GrGLInterface* gli) {
932 // We need dual source blending and the ability to disable multisample in order to support mixed
933 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
934 // renderer is available and enabled; no other path renderers support this feature.
935 if (fMultisampleDisableSupport &&
936 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400937 this->shaderCaps()->pathRenderingSupport()
938#if GR_TEST_UTILS
939 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
940#endif
941 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700942 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400943 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700944 }
945
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000946 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400947 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
948 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
949 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
950 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
951 fAlpha8IsRenderable = true;
952 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500953 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
954 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
955 // mixed samples we can't use multisampled-render-to-texture.
956 if (fUsesMixedSamples) {
957 fMSFBOType = kMixedSamples_MSFBOType;
958 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000959 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
960 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
961 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400962 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
963 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400964 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400965 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400966 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400967 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000968 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
969 fMSFBOType = kES_Apple_MSFBOType;
970 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000971 } else {
egdanieleed519e2016-01-15 11:36:18 -0800972 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700973 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400974 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
975 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400976
Brian Salomon00731b42016-10-14 11:30:51 -0400977 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400978 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
979 // Core profile removes ALPHA8 support.
980 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
981 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
982 // present.
983 fAlpha8IsRenderable = true;
984 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000985 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
986 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400987 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000988 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000989 }
Eric Karl5c779752017-05-08 12:02:07 -0700990
Brian Salomon01b476a2018-01-23 11:06:41 -0500991 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400992 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
993 fMSFBOType = kNone_MSFBOType;
994 }
995
Eric Karl5c779752017-05-08 12:02:07 -0700996 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
997 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
998 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700999 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001000}
1001
cdalton1dd05422015-06-12 09:01:18 -07001002void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001003 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001004
Greg Daniel210883c2017-11-27 15:14:01 -05001005 bool layoutQualifierSupport = false;
1006 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
1007 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1008 layoutQualifierSupport = true;
1009 }
1010
cdalton1dd05422015-06-12 09:01:18 -07001011 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1012 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001013 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001014 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1015 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001016 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001017 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001018 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1019 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001020 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001021 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001022 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001023 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001024 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1025 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001026 }
cdalton1dd05422015-06-12 09:01:18 -07001027}
1028
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001029namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001030const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001031}
1032
Eric Karl5c779752017-05-08 12:02:07 -07001033void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001034
1035 // Build up list of legal stencil formats (though perhaps not supported on
1036 // the particular gpu/driver) from most preferred to least.
1037
1038 // these consts are in order of most preferred to least preferred
1039 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1040
1041 static const StencilFormat
1042 // internal Format stencil bits total bits packed?
1043 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1044 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1045 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1046 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001047 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001048 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1049
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001050 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001051 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001052 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001053 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1054 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1055
1056 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1057 // require FBO support we can expect these are legal formats and don't
1058 // check. These also all support the unsized GL_STENCIL_INDEX.
1059 fStencilFormats.push_back() = gS8;
1060 fStencilFormats.push_back() = gS16;
1061 if (supportsPackedDS) {
1062 fStencilFormats.push_back() = gD24S8;
1063 }
1064 fStencilFormats.push_back() = gS4;
1065 if (supportsPackedDS) {
1066 fStencilFormats.push_back() = gDS;
1067 }
1068 } else {
1069 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1070 // for other formats.
1071 // ES doesn't support using the unsized format.
1072
1073 fStencilFormats.push_back() = gS8;
1074 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001075 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1076 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001077 fStencilFormats.push_back() = gD24S8;
1078 }
1079 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1080 fStencilFormats.push_back() = gS4;
1081 }
1082 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001083}
1084
Brian Osman71a18892017-08-10 10:23:25 -04001085void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001086
Brian Osman71a18892017-08-10 10:23:25 -04001087 // We are called by the base class, which has already called beginObject(). We choose to nest
1088 // all of our caps information in a named sub-object.
1089 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001090
Brian Osman71a18892017-08-10 10:23:25 -04001091 writer->beginArray("Stencil Formats");
1092
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001093 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001094 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001095 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1096 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1097 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001098 }
1099
Brian Osman71a18892017-08-10 10:23:25 -04001100 writer->endArray();
1101
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001102 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001103 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001104 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001105 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001106 "IMG MS To Texture",
1107 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001108 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001109 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001110 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001111 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1112 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1113 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1114 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1115 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001116 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001117
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001118 static const char* kInvalidateFBTypeStr[] = {
1119 "None",
1120 "Discard",
1121 "Invalidate",
1122 };
1123 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1124 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1125 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1126 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001127
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001128 static const char* kMapBufferTypeStr[] = {
1129 "None",
1130 "MapBuffer",
1131 "MapBufferRange",
1132 "Chromium",
1133 };
1134 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1135 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1136 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1137 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1138 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1139
Brian Osman71a18892017-08-10 10:23:25 -04001140 writer->appendBool("Core Profile", fIsCoreProfile);
1141 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1142 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1143 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1144 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1145 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1146 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1147 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1148 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001149
Brian Osman71a18892017-08-10 10:23:25 -04001150 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001151 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1152 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1153 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001154 writer->appendBool("Debug support", fDebugSupport);
1155 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1156 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1157 writer->appendBool("Base instance support", fBaseInstanceSupport);
1158 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1159 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1160 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1161 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1162 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1163 writer->appendBool("BGRA to RGBA readback conversions are slow",
1164 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001165 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001166 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1167 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001168 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1169 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1170 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1171 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001172 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1173 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001174
Brian Osman71a18892017-08-10 10:23:25 -04001175 writer->beginArray("configs");
1176
bsalomon41e4384e2016-01-08 09:12:44 -08001177 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001178 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001179 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1180 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1181 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001182 writer->appendHexU32("e_format_read_pixels",
1183 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001184 writer->appendHexU32(
1185 "e_format_teximage",
1186 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1187 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1188 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1189 writer->appendHexU32("i_for_renderbuffer",
1190 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1191 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001192 }
1193
Brian Osman71a18892017-08-10 10:23:25 -04001194 writer->endArray();
1195 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001196}
1197
bsalomon41e4384e2016-01-08 09:12:44 -08001198bool GrGLCaps::bgraIsInternalFormat() const {
1199 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1200}
1201
bsalomon76148af2016-01-12 11:13:47 -08001202bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1203 GrGLenum* internalFormat, GrGLenum* externalFormat,
1204 GrGLenum* externalType) const {
1205 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1206 externalFormat, externalType)) {
1207 return false;
1208 }
1209 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1210 return true;
1211}
1212
bsalomon76148af2016-01-12 11:13:47 -08001213bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1214 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001215 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001216 externalFormat, externalType)) {
1217 return false;
1218 }
1219 return true;
1220}
1221
1222bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001223 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1224 return true;
1225}
1226
1227bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1228 ExternalFormatUsage usage, GrGLenum* externalFormat,
1229 GrGLenum* externalType) const {
1230 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001231
1232 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1233 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1234
1235 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001236 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1237 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001238 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1239 return false;
1240 }
1241
1242 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1243 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1244
bsalomone9573312016-01-25 14:33:25 -08001245 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1246 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1247 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1248 // texture, not the red component.
1249 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001250 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001251 *externalFormat = GR_GL_ALPHA;
1252 }
1253 }
1254
bsalomon76148af2016-01-12 11:13:47 -08001255 return true;
1256}
1257
brianosman20471892016-12-02 06:43:32 -08001258void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1259 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001260 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001261 /*
1262 Comments on renderability of configs on various GL versions.
1263 OpenGL < 3.0:
1264 no built in support for render targets.
1265 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1266 format RGB, RGBA and NV float formats we don't use.
1267 This is the following:
1268 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1269 RGB10_A2, RGBA12,RGBA16
1270 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1271 since they aren't required by later standards and the driver can simply return
1272 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1273 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1274 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1275 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1276 This adds a lot of additional renderable sized formats, including ALPHA8.
1277 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1278 16F, 32I, 32UI, and 32F variants).
1279 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1280
1281 For both the above extensions we limit ourselves to those that are also required by
1282 OpenGL 3.0.
1283
1284 OpenGL 3.0:
1285 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1286 but are not required to be supported as renderable textures/renderbuffer.
1287 Required renderable color formats:
1288 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1289 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1290 RGB10_A2.
1291 - R11F_G11F_B10F.
1292 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1293 and RG8UI.
1294 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1295 - ALPHA8
1296
1297 OpenGL 3.1, 3.2, 3.3
1298 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1299 OpengGL 3.3, 4.0, 4.1
1300 Adds RGB10_A2UI.
1301 OpengGL 4.2
1302 Adds
1303 - RGB5_A1, RGBA4
1304 - RGB565
1305 OpenGL 4.4
1306 Does away with the separate list and adds a column to the sized internal color format
1307 table. However, no new formats become required color renderable.
1308
1309 ES 2.0
1310 color renderable: RGBA4, RGB5_A1, RGB565
1311 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1312 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1313 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1314 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1315 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1316 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1317
1318 ES 3.0
1319 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1320 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1321 RGB5_A1.
1322 - RGB8 and RGB565.
1323 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1324 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1325 ES 3.1
1326 Adds RGB10_A2, RGB10_A2UI,
1327 ES 3.2
1328 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1329 */
Brian Salomon44804c02018-01-23 16:51:28 -05001330
1331 // Correctness workarounds.
1332 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001333 bool disableSRGBForX86PowerVR = false;
1334 bool disableSRGBWriteControlForAdreno4xx = false;
1335 bool disableR8TexStorageForANGLEGL = false;
1336 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001337 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001338
1339 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1340 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1341 // and GL_RG on FBO textures.
1342 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1343
1344 bool isX86PowerVR = false;
1345#if defined(SK_CPU_X86)
1346 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1347 isX86PowerVR = true;
1348 }
1349#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001350 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1351 // blacklist that device (and any others that might be sharing the same driver).
1352 disableSRGBForX86PowerVR = isX86PowerVR;
1353 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1354
1355 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1356 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1357 // check that we are not going to OpenGL.
1358 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1359
1360 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1361#if defined(SK_BUILD_FOR_MAC)
1362 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1363#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001364 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1365 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001366 }
1367
Brian Salomon71d9d842016-11-03 13:42:00 -04001368 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1369 ConfigInfo::kFBOColorAttachment_Flag;
1370 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001371 if (kNone_MSFBOType != fMSFBOType) {
1372 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1373 }
bsalomon41e4384e2016-01-08 09:12:44 -08001374 GrGLStandard standard = ctxInfo.standard();
1375 GrGLVersion version = ctxInfo.version();
1376
cblume790d5132016-02-29 11:13:29 -08001377 bool texStorageSupported = false;
1378 if (kGL_GrGLStandard == standard) {
1379 // The EXT version can apply to either GL or GLES.
1380 texStorageSupported = version >= GR_GL_VER(4,2) ||
1381 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1382 ctxInfo.hasExtension("GL_EXT_texture_storage");
1383 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001384 texStorageSupported = version >= GR_GL_VER(3,0) ||
1385 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001386 }
1387
cdalton74b8d322016-04-11 14:47:28 -07001388 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1389
Brian Salomone609e812018-01-17 14:00:47 -05001390 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001391
1392 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001393 if (kGL_GrGLStandard == standard) {
1394 textureRedSupport =
1395 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1396 } else {
1397 textureRedSupport =
1398 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1399 }
1400 }
1401
bsalomon30447372015-12-21 09:03:05 -08001402 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1403 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001404 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001405 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001406 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001407 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001408
1409 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1410 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001411 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001412 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001413 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001414 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001415 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1416 if (kGL_GrGLStandard == standard) {
1417 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1418 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001419 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001420 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1421 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1422 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1423 }
egdaniel4999df82016-01-07 17:06:04 -08001424 }
cblume790d5132016-02-29 11:13:29 -08001425 if (texStorageSupported) {
1426 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1427 }
cdalton74b8d322016-04-11 14:47:28 -07001428 if (texelBufferSupport) {
1429 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1430 }
bsalomoncdee0092016-01-08 13:20:12 -08001431 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001432
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001433 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1434 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1435 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1436 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1437 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1438 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1439 // supportedReadPixelsColorType never returns it.
1440 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1441 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1442 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1443 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1444 if (kGL_GrGLStandard == standard) {
1445 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1446 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1447 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1448 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1449 // becomes an issue.
1450 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1451 // but we don't support that just for simplicity's sake.
1452 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1453 } else {
1454 // 3.0 and the extension support this as a render buffer format.
1455 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1456 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1457 }
1458 }
1459 if (texStorageSupported) {
1460 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1461 }
1462 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1463 if (disableRGB8ForMali400) {
1464 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1465 }
1466
1467 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001468 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001469 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001470 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001471
1472 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1473 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1474 // GL_EXT_texture_format_BGRA8888.
1475 bool supportsBGRATexStorage = false;
1476
bsalomon41e4384e2016-01-08 09:12:44 -08001477 if (kGL_GrGLStandard == standard) {
1478 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1479 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1480 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1481 // Since the internal format is RGBA8, it is also renderable.
1482 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1483 allRenderFlags;
1484 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001485 // Since we are using RGBA8 we can use tex storage.
1486 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001487 } else {
1488 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1489 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001490 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1491 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1492 nonMSAARenderFlags;
1493
1494 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1495 supportsBGRATexStorage = true;
1496 }
1497 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1498 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1499 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1500 ConfigInfo::kRenderableWithMSAA_Flag;
1501 }
1502 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001503 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1504 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1505 // driver remembers the external format when the texture is created (with TexImage).
1506 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1507 // We could work around this, but it adds even more state tracking to code that is
1508 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1509 // This also side-steps some ambiguous interactions with the texture storage extension.
1510 if (version >= GR_GL_VER(3,0)) {
1511 // The APPLE extension doesn't make this renderable.
1512 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001513 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001514 }
bsalomon41e4384e2016-01-08 09:12:44 -08001515 }
1516 }
Brian Osman48c99192017-06-02 08:45:06 -04001517
Greg Daniel0ff79b22018-02-15 12:33:33 -05001518 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001519 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001520 }
bsalomoncdee0092016-01-08 13:20:12 -08001521 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001522
brianosmana6359362016-03-21 06:55:37 -07001523 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001524 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001525 if (kGL_GrGLStandard == standard) {
1526 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001527 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001528 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1529 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1530 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001531 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001532 }
1533 }
1534 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001535 if (fSRGBSupport) {
1536 fSRGBWriteControl = true;
1537 }
bsalomon41e4384e2016-01-08 09:12:44 -08001538 } else {
brianosman20471892016-12-02 06:43:32 -08001539 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001540 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001541 fSRGBSupport = false;
1542 }
bsalomon41e4384e2016-01-08 09:12:44 -08001543 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1544 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001545 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001546 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001547 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001548 }
brianosman20471892016-12-02 06:43:32 -08001549 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1550 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1551 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001552 fSRGBSupport = false;
1553 }
brianosman20471892016-12-02 06:43:32 -08001554
1555 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1556 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1557 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1558 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1559 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1560 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1561 // affects Windows.
1562 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1563 fSRGBSupport = false;
1564 }
1565
Brian Osman48c99192017-06-02 08:45:06 -04001566 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1567 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1568 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1569
Brian Osman67999392017-05-31 16:19:34 -04001570 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001571 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001572 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1573 }
Brian Osman67999392017-05-31 16:19:34 -04001574
bsalomon30447372015-12-21 09:03:05 -08001575 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1576 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1577 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1578 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001579 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001580 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001581 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001582 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001583 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001584 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001585 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001586 }
Brian Osman48c99192017-06-02 08:45:06 -04001587 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1588 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001589 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1590 }
bsalomoncdee0092016-01-08 13:20:12 -08001591 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001592 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1593 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1594 // is in this format, for example).
1595 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1596 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1597 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1598 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001599 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001600 GR_GL_BGRA;
1601 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1602 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001603 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001604 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001605 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001606 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001607
brianosmana6359362016-03-21 06:55:37 -07001608 if (texStorageSupported) {
1609 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1610 }
1611 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1612
bsalomon30447372015-12-21 09:03:05 -08001613 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1614 if (this->ES2CompatibilitySupport()) {
1615 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1616 } else {
1617 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1618 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001619 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001620 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001621 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001622 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001623 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1624 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001625 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001626 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1627 }
1628 } else {
1629 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1630 }
cblume790d5132016-02-29 11:13:29 -08001631 // 565 is not a sized internal format on desktop GL. So on desktop with
1632 // 565 we always use an unsized internal format to let the system pick
1633 // the best sized format to convert the 565 data to. Since TexStorage
1634 // only allows sized internal formats we disallow it.
1635 //
1636 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1637 // update.
1638 if (texStorageSupported && kGL_GrGLStandard != standard) {
1639 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1640 }
bsalomoncdee0092016-01-08 13:20:12 -08001641 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001642
1643 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1644 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001645 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001646 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001647 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001648 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001649 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1650 if (kGL_GrGLStandard == standard) {
1651 if (version >= GR_GL_VER(4, 2)) {
1652 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1653 }
1654 } else {
1655 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1656 }
cblume790d5132016-02-29 11:13:29 -08001657 if (texStorageSupported) {
1658 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1659 }
bsalomoncdee0092016-01-08 13:20:12 -08001660 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001661
Brian Osman10fc6fd2018-03-02 11:01:10 -05001662 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1663 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001664 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001665 GR_GL_RGBA;
1666 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1667 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1668 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1669 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1670 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1671 allRenderFlags;
1672 }
1673 if (texStorageSupported) {
1674 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1675 }
1676 if (texelBufferSupport) {
1677 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1678 }
1679 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1680
Greg Danielef59d872017-11-17 16:47:21 -05001681 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1682 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1683
1684 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1685 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1686 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1687 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1688 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001689 }
Greg Danielef59d872017-11-17 16:47:21 -05001690 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1691 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001692 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001693 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1694 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1695 alphaInfo.fFlags |= allRenderFlags;
1696 }
1697
1698 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1699 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1700 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1701 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1702 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001703 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001704 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001705
Brian Osman48c99192017-06-02 08:45:06 -04001706 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1707 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001708 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001709 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1710 }
1711 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1712 }
1713
Brian Salomone609e812018-01-17 14:00:47 -05001714 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001715 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1716 if (texelBufferSupport) {
1717 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1718 }
1719
1720 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1721 } else {
1722 redInfo.fFlags = 0;
1723
1724 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001725 }
bsalomon41e4384e2016-01-08 09:12:44 -08001726
Greg Daniel7af060a2017-12-05 16:27:11 -05001727 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1728 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1729 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1730 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1731 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001732 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001733 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1734 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1735 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1736 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001737 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001738
1739 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1740 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1741 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1742 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1743 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001744 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001745 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1746 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1747
1748#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1749 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001750 if (this->textureRedSupport() ||
1751 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1752 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1753 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1754 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1755 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1756 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1757 }
1758#endif
Brian Osman48c99192017-06-02 08:45:06 -04001759 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001760 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001761 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1762 }
1763 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1764 }
1765
Brian Salomone609e812018-01-17 14:00:47 -05001766 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001767 if (texelBufferSupport) {
1768 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1769 }
1770 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1771 } else {
1772 grayRedInfo.fFlags = 0;
1773 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001774 }
1775
bsalomon41e4384e2016-01-08 09:12:44 -08001776 // Check for [half] floating point texture support
1777 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1778 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1779 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1780 bool hasFPTextures = false;
1781 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001782 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001783 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001784 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001785
1786 if (kGL_GrGLStandard == standard) {
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 }
1792 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001793 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001794 hasFPTextures = true;
1795 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001796 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001797 } else {
1798 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1799 ctxInfo.hasExtension("GL_OES_texture_float")) {
1800 hasFPTextures = true;
1801 }
1802 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1803 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1804 hasHalfFPTextures = true;
1805 }
1806 }
1807 }
bsalomon30447372015-12-21 09:03:05 -08001808
csmartdalton6aa0e112017-02-08 16:14:11 -05001809 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1810 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1811 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1812 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1813 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001814 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001815 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1816 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1817 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001818 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001819 // For now we only enable rendering to float on desktop, because on ES we'd have to
1820 // solve many precision issues and no clients actually want this yet.
1821 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1822 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1823 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1824 }
bsalomon41e4384e2016-01-08 09:12:44 -08001825 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001826 if (texStorageSupported) {
1827 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1828 }
1829 if (texelBufferSupport) {
1830 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1831 }
1832 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001833 }
bsalomon30447372015-12-21 09:03:05 -08001834
Greg Danielef59d872017-11-17 16:47:21 -05001835 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001836 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001837 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001838 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001839 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001840 }
Greg Danielef59d872017-11-17 16:47:21 -05001841 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1842 redHalf.fFormats.fExternalType = redHalfExternalType;
1843 redHalf.fFormatType = kFloat_FormatType;
1844 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1845 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001846 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001847 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001848 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001849 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1850
csmartdalton6aa0e112017-02-08 16:14:11 -05001851 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001852 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001853 redHalf.fFlags |= fpRenderFlags;
1854 }
1855
1856 if (texStorageSupported && !isCommandBufferES2) {
1857 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1858 }
1859
1860 if (texelBufferSupport) {
1861 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001862 }
1863 }
Greg Danielef59d872017-11-17 16:47:21 -05001864 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001865
1866 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1867 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001868 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001869 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001870 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001871 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1872 } else {
1873 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1874 }
bsalomon7928ef62016-01-05 10:26:39 -08001875 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001876 if (hasHalfFPTextures) {
1877 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1878 // ES requires 3.2 or EXT_color_buffer_half_float.
1879 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1880 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1881 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1882 }
1883 }
cblume790d5132016-02-29 11:13:29 -08001884 if (texStorageSupported) {
1885 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1886 }
cdalton74b8d322016-04-11 14:47:28 -07001887 if (texelBufferSupport) {
1888 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1889 }
bsalomoncdee0092016-01-08 13:20:12 -08001890 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001891
bsalomon30447372015-12-21 09:03:05 -08001892 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1893
1894 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001895 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1896 ctxInfo.version() >= GR_GL_VER(3,0));
1897 // All ES versions (thus far) require sized internal formats for render buffers.
1898 // TODO: Always use sized internal format?
1899 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1900
bsalomon30447372015-12-21 09:03:05 -08001901 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001902 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1903 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001904 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001905 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001906 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1907 fConfigTable[i].fFormats.fSizedInternalFormat :
1908 fConfigTable[i].fFormats.fBaseInternalFormat;
1909 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001910 fConfigTable[i].fFormats.fSizedInternalFormat :
1911 fConfigTable[i].fFormats.fBaseInternalFormat;
1912 }
Brian Salomon44804c02018-01-23 16:51:28 -05001913 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1914 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1915 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1916 // in ES.
1917 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1918 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1919 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1920 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001921 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1922 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001923 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1924 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001925 }
1926
bsalomon30447372015-12-21 09:03:05 -08001927 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1928 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1929 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1930 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1931 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001932 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001933 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001934
1935 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1936 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1937 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1938 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001939 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001940 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1941 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1942 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1943 // slot.
1944 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1945 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001946
1947 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1948 // as a base format.
1949 // GL_EXT_texture_format_BGRA8888:
1950 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1951 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1952 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001953 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001954 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1955 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1956 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001957 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001958 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1959 }
1960
bsalomoncdee0092016-01-08 13:20:12 -08001961 // If we don't have texture swizzle support then the shader generator must insert the
1962 // swizzle into shader code.
1963 if (!this->textureSwizzleSupport()) {
1964 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001965 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001966 }
1967 }
1968
bsalomon7f9b2e42016-01-12 13:29:26 -08001969 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1970 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1971 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001972 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001973 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1974 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1975 if (GrPixelConfigIsAlphaOnly(config) &&
1976 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001977 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001978 }
1979 }
1980 }
1981
Greg Daniel81e7bf82017-07-19 14:47:42 -04001982 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1983 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001984 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1985 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001986 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001987 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1988 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001989 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001990 int count;
1991 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1992 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1993 1, &count);
1994 if (count) {
1995 int* temp = new int[count];
1996 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1997 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001998 // GL has a concept of MSAA rasterization with a single sample but we do not.
1999 if (count && temp[count - 1] == 1) {
2000 --count;
2001 SkASSERT(!count || temp[count -1] > 1);
2002 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04002003 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05002004 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04002005 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002006 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002007 for (int j = 0; j < count; ++j) {
2008 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2009 }
2010 delete[] temp;
2011 }
2012 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002013 // Fake out the table using some semi-standard counts up to the max allowed sample
2014 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002015 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002016 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2017 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2018 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2019 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2020 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002021 // Chrome has a mock GL implementation that returns 0.
2022 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002023
Brian Salomonbdecacf2018-02-02 20:32:49 -05002024 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002025 int count = SK_ARRAY_COUNT(kDefaultSamples);
2026 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002027 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002028 break;
2029 }
2030 }
2031 if (count > 0) {
2032 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2033 }
2034 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002035 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2036 fConfigTable[i].fColorSampleCounts.setCount(1);
2037 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002038 }
2039 }
2040
bsalomon30447372015-12-21 09:03:05 -08002041#ifdef SK_DEBUG
2042 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002043 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002044 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002045 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2046 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002047 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2048 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2049 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2050 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002051 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2052 fConfigTable[i].fFormats.fBaseInternalFormat);
2053 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002054 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002055 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2056 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2057 fConfigTable[i].fFormats.fExternalFormat[j]);
2058 }
2059 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002060 }
2061#endif
2062}
2063
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002064bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
2065 bool dstIsTextureable, bool dstIsGLTexture2D,
2066 GrSurfaceOrigin dstOrigin,
2067 GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
2068 bool srcIsTextureable, bool srcIsGLTexture2D,
2069 GrSurfaceOrigin srcOrigin) const {
2070 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2071 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2072 // many drivers would allow it to work, but ANGLE does not.
2073 if (kGLES_GrGLStandard == fStandard && this->bgraIsInternalFormat() &&
2074 (kBGRA_8888_GrPixelConfig == dstConfig || kBGRA_8888_GrPixelConfig == srcConfig)) {
2075 return false;
2076 }
2077
2078 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
2079 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
2080 return false;
2081 }
2082
2083 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
2084 // texture.
2085 if (!dstIsTextureable) {
2086 return false;
2087 }
2088
2089 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
2090 // is required
2091 if (this->canConfigBeFBOColorAttachment(srcConfig) &&
2092 (!srcIsTextureable || srcIsGLTexture2D) &&
2093 dstIsGLTexture2D &&
2094 dstOrigin == srcOrigin) {
2095 return true;
2096 } else {
2097 return false;
2098 }
2099}
2100
2101bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
2102 bool dstIsTextureable, bool dstIsGLTexture2D,
2103 GrSurfaceOrigin dstOrigin,
2104 GrPixelConfig srcConfig, int srcSampleCnt,
2105 bool srcIsTextureable, bool srcIsGLTexture2D,
2106 GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
2107 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2108 auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
2109 if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
2110 !this->canConfigBeFBOColorAttachment(srcConfig)) {
2111 return false;
2112 }
2113
2114 if (dstIsTextureable && !dstIsGLTexture2D) {
2115 return false;
2116 }
2117 if (srcIsTextureable && !srcIsGLTexture2D) {
2118 return false;
2119 }
2120
2121 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
2122 return false;
2123 }
2124 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
2125 // We would mirror to compensate for origin changes. Note that copySurface is
2126 // specified such that the src and dst rects are the same.
2127 if (dstOrigin != srcOrigin) {
2128 return false;
2129 }
2130 }
2131
2132 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
2133 if (srcSampleCnt > 1) {
2134 if (1 == dstSampleCnt) {
2135 return false;
2136 }
2137 if (SkRect::Make(srcRect) != srcBounds) {
2138 return false;
2139 }
2140 }
2141 }
2142
2143 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
2144 if (dstSampleCnt > 1) {
2145 return false;
2146 }
2147 }
2148
2149 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
2150 if (dstConfig != srcConfig) {
2151 return false;
2152 }
2153 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2154 if (srcSampleCnt > 1 && dstConfig != srcConfig) {
2155 return false;
2156 }
2157 }
2158
2159 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2160 if (srcSampleCnt > 1) {
2161 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
2162 return false;
2163 }
2164 if (dstOrigin != srcOrigin) {
2165 return false;
2166 }
2167 }
2168 }
2169 return true;
2170}
2171
2172bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
2173 return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
2174}
2175
2176static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
2177 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
2178 if (!rt) {
2179 return false;
2180 }
2181 // A RT has a separate MSAA renderbuffer if:
2182 // 1) It's multisampled
2183 // 2) We're using an extension with separate MSAA renderbuffers
2184 // 3) It's not FBO 0, which is special and always auto-resolves
2185 return rt->numColorSamples() > 1 &&
2186 glCaps.usesMSAARenderBuffers() &&
2187 !rt->rtPriv().glRTFBOIDIs0();
2188}
2189
2190bool GrGLCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
2191 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2192 GrSurfaceOrigin dstOrigin = dst->origin();
2193 GrSurfaceOrigin srcOrigin = src->origin();
2194
2195 GrPixelConfig dstConfig = dst->config();
2196 GrPixelConfig srcConfig = src->config();
2197
2198 int dstSampleCnt = 0;
2199 int srcSampleCnt = 0;
2200 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
2201 dstSampleCnt = rtProxy->numColorSamples();
2202 }
2203 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
2204 srcSampleCnt = rtProxy->numColorSamples();
2205 }
2206 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
2207 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
2208
2209 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
2210 // swizzle.
2211 if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
2212 this->shaderCaps()->configOutputSwizzle(dst->config())) {
2213 return false;
2214 }
2215
2216 const GrTextureProxy* dstTex = dst->asTextureProxy();
2217 const GrTextureProxy* srcTex = src->asTextureProxy();
2218
2219 bool dstIsTex2D = dstTex ? dstTex->texPriv().isGLTexture2D() : false;
2220 bool srcIsTex2D = srcTex ? srcTex->texPriv().isGLTexture2D() : false;
2221
2222 // One of the possible requirements for copy as blit is that the srcRect must match the bounds
2223 // of the src surface. If we have a approx fit surface we can't know for sure what the src
2224 // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
2225 // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
2226 // know we will at least be able to do it as a draw.
2227#ifdef SK_DEBUG
2228 if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2229 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2230 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
2231 !src->priv().isExact()) {
2232 SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
2233 }
2234#endif
2235
2236 return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
2237 SkToBool(dstTex), dstIsTex2D, dstOrigin,
2238 srcConfig, has_msaa_render_buffer(src, *this),
2239 SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
2240 this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2241 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2242 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
2243 dstPoint) ||
2244 this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
2245}
2246
Robert Phillipsbf25d432017-04-07 10:08:53 -04002247bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002248 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2249 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002250 // By default, we don't require rects to match.
2251 *rectsMustMatch = false;
2252
2253 // By default, we allow subrects.
2254 *disallowSubrect = false;
2255
Brian Salomon467921e2017-03-06 16:17:12 -05002256 // If the src is a texture, we can implement the blit as a draw assuming the config is
2257 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002258 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002259 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002260 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2261 desc->fConfig = src->config();
2262 return true;
2263 }
2264
Robert Phillipsbf25d432017-04-07 10:08:53 -04002265 {
2266 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2267 // wrapped. In that case the proxy would already be instantiated.
2268 const GrTexture* srcTexture = src->priv().peekTexture();
2269 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2270 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2271 // Not supported for FBO blit or CopyTexSubImage
2272 return false;
2273 }
Brian Salomon467921e2017-03-06 16:17:12 -05002274 }
2275
2276 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2277 // possible and we return false to fallback to creating a render target dst for render-to-
2278 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2279 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002280 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002281 bool rectsMustMatchForBlitFramebuffer = false;
2282 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002283 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002284 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2285 rectsMustMatchForBlitFramebuffer = true;
2286 disallowSubrectForBlitFramebuffer = true;
2287 // Mirroring causes rects to mismatch later, don't allow it.
2288 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002289 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2290 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002291 rectsMustMatchForBlitFramebuffer = true;
2292 // Mirroring causes rects to mismatch later, don't allow it.
2293 originForBlitFramebuffer = src->origin();
2294 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002295 originForBlitFramebuffer = src->origin();
2296 }
2297
2298 // Check for format issues with glCopyTexSubImage2D
2299 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2300 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2301 // then we set up for that, otherwise fail.
2302 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002303 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002304 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002305 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2306 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002307 return true;
2308 }
2309 return false;
2310 }
2311
Robert Phillipsbf25d432017-04-07 10:08:53 -04002312 {
Brian Salomon63e79732017-05-15 21:23:13 -04002313 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2314 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002315 if (srcIsMSAARenderbuffer) {
2316 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2317 // blit or fail.
2318 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002319 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002320 desc->fConfig = src->config();
2321 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2322 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2323 return true;
2324 }
2325 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002326 }
Brian Salomon467921e2017-03-06 16:17:12 -05002327 }
2328
2329 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002330 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002331 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002332 desc->fFlags = kNone_GrSurfaceFlags;
2333 return true;
2334}
2335
Greg Daniel691f5e72018-02-28 14:21:34 -05002336void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2337 const GrContextOptions& contextOptions,
2338 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002339 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2340 // Thus we are blacklisting this extension for now on Adreno4xx devices.
Adrienne Walker0e383942018-05-15 11:33:47 -07002341 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2342 fDriverBugWorkarounds.disable_discard_framebuffer) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002343 fDiscardRenderTargetSupport = false;
2344 fInvalidateFBType = kNone_InvalidateFBType;
2345 }
2346
2347 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2348 // 340.96 and 367.57.
2349 if (kGL_GrGLStandard == ctxInfo.standard() &&
2350 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002351 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002352 fClearTextureSupport = false;
2353 }
2354
2355 // Calling glClearTexImage crashes on the NexusPlayer.
2356 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2357 fClearTextureSupport = false;
2358 }
2359
2360 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2361#ifdef SK_BUILD_FOR_MAC
2362 if (shaderCaps->fGeometryShaderSupport) {
2363 shaderCaps->fGSInvocationsSupport = false;
2364 }
2365#endif
2366
2367 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2368 // shaders. @127.0 is the earliest verified driver to not crash.
2369 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002370 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002371 shaderCaps->fGeometryShaderSupport = false;
2372 }
2373
2374#if defined(__has_feature)
2375#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2376 // See skbug.com/7058
2377 fMapBufferType = kNone_MapBufferType;
2378 fMapBufferFlags = kNone_MapFlags;
2379#endif
2380#endif
2381
2382 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2383 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2384 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2385 // unclear whether this really affects a wide range of devices.
2386 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002387 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002388 fMapBufferType = kNone_MapBufferType;
2389 fMapBufferFlags = kNone_MapFlags;
2390 }
2391
2392 // TODO: re-enable for ANGLE
2393 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2394 fTransferBufferType = kNone_TransferBufferType;
2395 }
2396
2397 // Using MIPs on this GPU seems to be a source of trouble.
2398 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2399 fMipMapSupport = false;
2400 }
2401
2402 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2403 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2404 // around a driver bug related to gl_FragCoord.
2405 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2406 fMaxClipAnalyticFPs = 0;
2407 }
2408
2409#ifndef SK_BUILD_FOR_IOS
2410 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2411 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2412 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2413 ctxInfo.driver() != kChromium_GrGLDriver)) {
2414 fUseDrawToClearColor = true;
2415 }
2416#endif
2417
2418 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2419 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2420 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2421 fUseDrawToClearColor = true;
2422 }
2423
2424#ifdef SK_BUILD_FOR_MAC
2425 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2426 // full screen clears
2427 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2428 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002429 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2430 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2431 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2432 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002433 fUseDrawToClearColor = true;
2434 }
2435#endif
2436
2437 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2438 // bugs seems to involve clearing too much and not skipping the clear.
2439 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2440 // but only for D3D11 ANGLE.
2441 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2442 fUseDrawToClearColor = true;
2443 }
2444
2445 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2446 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002447 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002448 fUseDrawToClearStencilClip = true;
2449 }
2450 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2451 }
2452
2453 // This was reproduced on the following configurations:
2454 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2455 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2456 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2457 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2458 // and not produced on:
2459 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2460 // The particular lines that get dropped from test images varies across different devices.
2461 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002462 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002463 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2464 }
2465
Chris Dalton6f5e77a2018-04-23 21:14:42 -06002466 if (kIntelSkylake_GrGLRenderer == ctxInfo.renderer() ||
2467 (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2468 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer())) {
Chris Daltonda40cd22018-04-16 13:19:58 -06002469 fRequiresFlushBetweenNonAndInstancedDraws = true;
2470 }
2471
Brian Salomon01b476a2018-01-23 11:06:41 -05002472 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2473 // given 1 << 15 or more instances.
2474 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2475 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
Adrienne Walker001cae02018-05-15 11:38:44 -07002476 } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
2477 fMaxInstancesPerDrawArraysWithoutCrashing = 0x4000000;
Brian Salomon01b476a2018-01-23 11:06:41 -05002478 }
2479
2480 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002481 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002482 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2483 fUseDrawInsteadOfAllRenderTargetWrites = true;
2484 }
2485
2486 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2487 fSampleShadingSupport = false;
2488 }
2489
2490#ifdef SK_BUILD_FOR_MAC
2491 static constexpr bool isMAC = true;
2492#else
2493 static constexpr bool isMAC = false;
2494#endif
2495
2496 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2497 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2498 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2499 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2500 if (fMipMapLevelAndLodControlSupport &&
2501 (contextOptions.fDoManualMipmapping ||
2502 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2503 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2504 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2505 fDoManualMipmapping = true;
2506 }
2507
2508 // See http://crbug.com/710443
2509#ifdef SK_BUILD_FOR_MAC
2510 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2511 fClearToBoundaryValuesIsBroken = true;
2512 }
2513#endif
2514 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2515 fDrawArraysBaseVertexIsBroken = true;
2516 }
2517
Brian Salomon01b476a2018-01-23 11:06:41 -05002518 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2519 // Galaxy S7.
2520 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2521 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2522 shaderCaps->fFBFetchSupport = false;
2523 }
2524
Brian Salomon01b476a2018-01-23 11:06:41 -05002525 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2526 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2527
2528 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2529 // function that may require a gradient calculation inside a conditional block may return
2530 // undefined results". This appears to be an issue with the 'any' call since even the simple
2531 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2532 // from our GrTextureDomain processor.
2533 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2534
2535 // Known issue on at least some Intel platforms:
2536 // http://code.google.com/p/skia/issues/detail?id=946
2537 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2538 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2539 }
2540
Chris Dalton0090ef62018-03-28 17:35:00 -06002541 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002542 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2543 // so we must do the abs first in a separate expression.
2544 shaderCaps->fCanUseMinAndAbsTogether = false;
2545
2546 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2547 // must avoid this condition.
2548 shaderCaps->fCanUseFractForNegativeValues = false;
2549 }
2550
2551 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2552 // thus must us -1.0 * %s.x to work correctly
2553 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2554 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2555 }
2556
2557 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2558 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2559 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2560 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2561 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2562 }
2563
2564 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2565 // the original dst color when reading the outColor even after being written to. By using a
2566 // local outColor we can work around this bug.
2567 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2568 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2569 }
2570
2571 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2572 // color, and that uniform contains an opaque color, and the output of the shader is only based
2573 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2574 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2575 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2576 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2577 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2578 shaderCaps->fMustObfuscateUniformColor = true;
2579 }
2580#ifdef SK_BUILD_FOR_WIN
2581 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2582 //
2583 // Basically, if a shader has a construct like:
2584 //
2585 // float x = someCondition ? someValue : 0;
2586 // float2 result = (0 == x) ? float2(x, x)
2587 // : float2(2 * x / x, 0);
2588 //
2589 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2590 // we've explicitly guarded the division with a check against zero. This manifests in much
2591 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2592 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2593 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2594 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2595 }
2596#endif
2597
2598 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2599 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2600 // that the interpolation of vertex shader outputs is quite inaccurate.
2601 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2602 shaderCaps->fCanUseFragCoord = false;
2603 shaderCaps->fInterpolantsAreInaccurate = true;
2604 }
2605
Chris Dalton0090ef62018-03-28 17:35:00 -06002606 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2607 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2608 shaderCaps->fCanUseFragCoord = false;
2609 }
2610
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002611 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2612 // (Are they implemented with fp16?)
2613 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2614 shaderCaps->fIncompleteShortIntPrecision = true;
2615 }
2616
Brian Salomon01b476a2018-01-23 11:06:41 -05002617 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2618 // for now until its own blacklists can be updated.
2619 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2620 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2621 kIntel_GrGLDriver == ctxInfo.driver() ||
2622 kChromium_GrGLDriver == ctxInfo.driver()) {
2623 fBlendEquationSupport = kBasic_BlendEquationSupport;
2624 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2625 }
2626
2627 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2628 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002629 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002630 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002631 fBlendEquationSupport = kBasic_BlendEquationSupport;
2632 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2633 }
2634
Adrienne Walker68314842018-05-14 14:02:53 -07002635 if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
2636 fBlendEquationSupport = kBasic_BlendEquationSupport;
2637 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2638 }
2639
Brian Salomon01b476a2018-01-23 11:06:41 -05002640 if (this->advancedBlendEquationSupport()) {
2641 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002642 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002643 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2644 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2645 (1 << kColorBurn_GrBlendEquation);
2646 }
2647 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2648 // Blacklist color-burn on ARM until the fix is released.
2649 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2650 }
2651 }
2652
2653 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2654 if (fMultisampleDisableSupport &&
2655 this->shaderCaps()->dualSourceBlendingSupport() &&
2656 this->shaderCaps()->pathRenderingSupport() &&
2657 fUsesMixedSamples &&
2658#if GR_TEST_UTILS
2659 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2660#endif
2661 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2662 kChromium_GrGLDriver == ctxInfo.driver())) {
2663 fDiscardRenderTargetSupport = false;
2664 fInvalidateFBType = kNone_InvalidateFBType;
2665 }
Brian Osmanc585e202018-04-04 14:08:27 -04002666
Brian Osman061020e2018-04-17 14:22:15 -04002667 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2668 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2669 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2670 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002671 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2672 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002673 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002674 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002675 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2676 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002677 }
Brian Osman2fa53742018-05-03 15:05:12 -04002678
2679#ifdef SK_BUILD_FOR_IOS
2680 // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
2681 // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
2682 // is to just blacklist the feature.
2683 // https://github.com/flutter/flutter/issues/16718
2684 // https://bugreport.apple.com/web/?problemID=39948888
2685 fUnpackRowLengthSupport = false;
2686#endif
Brian Salomon01b476a2018-01-23 11:06:41 -05002687}
2688
csmartdaltone0d36292016-07-29 08:14:20 -07002689void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002690 if (options.fDisableDriverCorrectnessWorkarounds) {
2691 SkASSERT(!fDoManualMipmapping);
2692 SkASSERT(!fClearToBoundaryValuesIsBroken);
2693 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2694 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2695 SkASSERT(!fUseDrawToClearColor);
2696 SkASSERT(!fUseDrawToClearStencilClip);
2697 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2698 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2699 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Chris Daltonda40cd22018-04-16 13:19:58 -06002700 SkASSERT(!fRequiresFlushBetweenNonAndInstancedDraws);
Brian Salomon01b476a2018-01-23 11:06:41 -05002701 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002702 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2703 fUseDrawToClearColor = false;
2704 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2705 fUseDrawToClearColor = true;
2706 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002707 if (options.fDoManualMipmapping) {
2708 fDoManualMipmapping = true;
2709 }
csmartdaltone0d36292016-07-29 08:14:20 -07002710}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002711
Brian Salomon3d86a192018-02-27 16:46:11 -05002712bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2713 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2714 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2715 if (tex->hasBaseLevelBeenBoundToFBO()) {
2716 return false;
2717 }
2718 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002719 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002720 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2721 return false;
2722 }
2723 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2724 return false;
2725 }
2726 return SkToBool(surface->asTexture());
2727 }
2728 return true;
2729}
2730
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002731bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2732 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2733 // We don't support reading pixels directly from EXTERNAL textures as it would require
2734 // binding the texture to a FBO.
2735 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2736 return false;
2737 }
2738 }
2739 return true;
2740}
2741
2742GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2743 GrColorType dstColorType) const {
2744 // For now, we mostly report the read back format that is required by the ES spec without
2745 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2746 // this as makes sense to increase performance and correctness.
2747 switch (fConfigTable[config].fFormatType) {
2748 case kNormalizedFixedPoint_FormatType:
2749 return GrColorType::kRGBA_8888;
2750 case kFloat_FormatType:
2751 // We cheat a little here and allow F16 read back if the src and dst match.
2752 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2753 return GrColorType::kRGBA_F16;
2754 }
2755 if ((kAlpha_half_GrPixelConfig == config ||
2756 kAlpha_half_as_Red_GrPixelConfig == config) &&
2757 GrColorType::kAlpha_F16 == dstColorType) {
2758 return GrColorType::kAlpha_F16;
2759 }
2760 // And similar for full float RG.
2761 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2762 return GrColorType::kRG_F32;
2763 }
2764 return GrColorType::kRGBA_F32;
2765 }
2766 return GrColorType::kUnknown;
2767}
2768
Greg Daniel2a303902018-02-20 10:25:54 -05002769bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002770 GrGLFramebufferInfo fbInfo;
2771 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002772 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002773 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002774}
2775
Brian Salomonbdecacf2018-02-02 20:32:49 -05002776int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2777 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002778 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002779 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002780 return 0;
2781 }
2782
Brian Salomonbdecacf2018-02-02 20:32:49 -05002783 if (1 == requestedCount) {
2784 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2785 }
2786
Greg Daniel81e7bf82017-07-19 14:47:42 -04002787 for (int i = 0; i < count; ++i) {
2788 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2789 return fConfigTable[config].fColorSampleCounts[i];
2790 }
2791 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002792 return 0;
2793}
2794
2795int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2796 const auto& table = fConfigTable[config].fColorSampleCounts;
2797 if (!table.count()) {
2798 return 0;
2799 }
2800 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002801}
2802
Greg Danielfaa095e2017-12-19 13:15:02 -05002803bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2804 GrGLStandard standard) {
2805 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002806
2807 switch (ct) {
2808 case kUnknown_SkColorType:
2809 return false;
2810 case kAlpha_8_SkColorType:
2811 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002812 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002813 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002814 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002815 }
2816 break;
2817 case kRGB_565_SkColorType:
2818 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002819 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002820 }
2821 break;
2822 case kARGB_4444_SkColorType:
2823 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002824 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002825 }
2826 break;
2827 case kRGBA_8888_SkColorType:
2828 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002829 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002830 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002831 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002832 }
2833 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002834 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002835 if (GR_GL_RGB8 == format) {
2836 *config = kRGB_888_GrPixelConfig;
2837 }
2838 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002839 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002840 if (GR_GL_RGBA8 == format) {
2841 if (kGL_GrGLStandard == standard) {
2842 *config = kBGRA_8888_GrPixelConfig;
2843 }
2844 } else if (GR_GL_BGRA8 == format) {
2845 if (kGLES_GrGLStandard == standard) {
2846 *config = kBGRA_8888_GrPixelConfig;
2847 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002848 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002849 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002850 }
2851 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002852 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002853 if (GR_GL_RGB10_A2 == format) {
2854 *config = kRGBA_1010102_GrPixelConfig;
2855 }
2856 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002857 case kRGB_101010x_SkColorType:
2858 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002859 case kGray_8_SkColorType:
2860 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002861 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002862 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002863 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002864 }
2865 break;
2866 case kRGBA_F16_SkColorType:
2867 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002868 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002869 }
2870 break;
2871 }
2872
Greg Danielfaa095e2017-12-19 13:15:02 -05002873 return kUnknown_GrPixelConfig != *config;
2874}
2875
2876bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2877 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002878 GrGLTextureInfo texInfo;
2879 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002880 return false;
2881 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002882 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002883}
2884
2885bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2886 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002887 GrGLFramebufferInfo fbInfo;
2888 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002889 return false;
2890 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002891 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002892}
2893
Robert Phillipsfc711a22018-02-13 17:03:00 -05002894bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2895 GrPixelConfig* config) const {
2896 const GrGLenum* glFormat = format.getGLFormat();
2897 if (!glFormat) {
2898 return false;
2899 }
2900 return validate_sized_format(*glFormat, ct, config, fStandard);
2901}
2902
2903