blob: c4e9f5a582d7ecaeb78a3600678a978701359d4b [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"
Greg Daniel4065d452018-11-16 15:43:41 -050018#include "SkGr.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000019#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000020#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000021
bsalomon682c2692015-05-22 14:01:46 -070022GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
23 const GrGLContextInfo& ctxInfo,
24 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080025 fStandard = ctxInfo.standard();
26
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000027 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000028 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000029 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000030 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080031 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000032 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000033 fUnpackRowLengthSupport = false;
34 fUnpackFlipYSupport = false;
35 fPackRowLengthSupport = false;
36 fPackFlipYSupport = false;
37 fTextureUsageSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040038 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000039 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000040 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070041 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080042 fES2CompatibilitySupport = false;
cdalton06604b92016-02-05 10:09:51 -080043 fDrawIndirectSupport = false;
44 fMultiDrawIndirectSupport = false;
45 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000046 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070047 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080048 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080049 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070050 fRGBA8888PixelsOpsAreSlow = false;
51 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080052 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080053 fRGBAToBGRAReadbackConversionsAreSlow = false;
Robert Phillipsf2ec0242018-03-01 16:51:25 -050054 fUseBufferDataNullHint = SkToBool(GR_GL_USE_BUFFER_DATA_NULL_HINT);
brianosman09563ce2016-06-02 08:59:34 -070055 fDoManualMipmapping = 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;
Brian Osman1348ed02018-09-12 09:08:39 -040064 fDetachStencilFromMSAABuffersBeforeReadPixels = false;
Brian Salomonf3841932018-11-29 09:13:37 -050065 fDontSetBaseOrMaxLevelForExternalTextures = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050066 fProgramBinarySupport = false;
Brian Salomona2a94a42018-10-16 10:54:10 -040067 fSamplerObjectSupport = false;
piotaixre4b23142014-10-02 10:57:53 -070068
Brian Salomone5e7eb12016-10-14 16:18:33 -040069 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Dalton1b4ad762018-10-04 11:58:09 -060070 fMaxInstancesPerDrawWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080071
Brian Salomon94efbf52016-11-29 13:43:05 -050072 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070073
cdalton4cd67132015-06-10 19:23:46 -070074 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000075}
76
cdalton4cd67132015-06-10 19:23:46 -070077void GrGLCaps::init(const GrContextOptions& contextOptions,
78 const GrGLContextInfo& ctxInfo,
79 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000080 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000081 GrGLVersion version = ctxInfo.version();
82
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000083 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000084 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
85 &fMaxFragmentUniformVectors);
86 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000087 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000088 GrGLint max;
89 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
90 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000091 if (version >= GR_GL_VER(3, 2)) {
92 GrGLint profileMask;
93 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
94 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
95 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000096 }
Adrienne Walker87785d52018-08-09 12:01:43 -070097 if (fDriverBugWorkarounds.max_fragment_uniform_vectors_32) {
98 fMaxFragmentUniformVectors = SkMin32(fMaxFragmentUniformVectors, 32);
99 }
bsalomon@google.com60da4172012-06-01 19:25:00 +0000100 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000101
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000102 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000103 fUnpackRowLengthSupport = true;
104 fUnpackFlipYSupport = false;
105 fPackRowLengthSupport = true;
106 fPackFlipYSupport = false;
107 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000108 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
109 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000110 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000111 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
112 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000113 fPackFlipYSupport =
114 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
115 }
116
Adrienne Walkerc48f7762018-05-15 13:03:13 -0700117 if (fDriverBugWorkarounds.pack_parameters_workaround_with_pack_buffer) {
118 // In some cases drivers handle copying the last row incorrectly
119 // when using GL_PACK_ROW_LENGTH. Chromium handles this by iterating
120 // through every row and conditionally clobbering that value, but
121 // Skia already has a scratch buffer workaround when pack row length
122 // is not supported, so just use that.
123 fPackRowLengthSupport = false;
124 }
125
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000126 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000127 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
128
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000129 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700130 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
131 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
132 ctxInfo.hasExtension("GL_NV_texture_barrier");
133 } else {
134 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
135 }
136
Robert Phillips7f861922018-01-30 13:13:42 +0000137 if (kGL_GrGLStandard == standard) {
138 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
139 ctxInfo.hasExtension("GL_ARB_texture_multisample");
140 } else {
141 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
142 }
143
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000144 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000145 ctxInfo.hasExtension("GL_ARB_imaging");
146
Brian Salomon01b476a2018-01-23 11:06:41 -0500147 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700148 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
149 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000150 fDiscardRenderTargetSupport = true;
151 fInvalidateFBType = kInvalidate_InvalidateFBType;
152 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
153 fDiscardRenderTargetSupport = true;
154 fInvalidateFBType = kDiscard_InvalidateFBType;
155 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000156
Chris Dalton27059d32018-01-23 14:06:50 -0700157 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
158 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
159 if (kGLES_GrGLStandard == standard) {
160 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
Chris Dalton27059d32018-01-23 14:06:50 -0700161 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
162 if (kARM_GrGLVendor == ctxInfo.vendor()) {
163 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
164 }
165 }
166
Chris Dalton344e9032017-12-11 15:42:09 -0700167 if (kARM_GrGLVendor == ctxInfo.vendor() ||
168 kImagination_GrGLVendor == ctxInfo.vendor() ||
169 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
170 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000171 }
172
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000173 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000174 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800175 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
176 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000177 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000178 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
179 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000180 }
181
cdalton626e1ff2015-06-12 13:56:46 -0700182 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
183 fDebugSupport = true;
184 } else {
185 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
186 }
187
jvanverth3f801cb2014-12-16 09:49:38 -0800188 if (kGL_GrGLStandard == standard) {
189 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
190 }
191 else {
192 fES2CompatibilitySupport = true;
193 }
194
cdalton0edea2c2015-05-21 08:27:44 -0700195 if (kGL_GrGLStandard == standard) {
196 fMultisampleDisableSupport = true;
197 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700198 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700199 }
200
kkinnunend94708e2015-07-30 22:47:04 -0700201 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600202 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
203 // instanced arrays, but we could make this more granular if we wanted
204 fInstanceAttribSupport =
205 version >= GR_GL_VER(3, 2) ||
206 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
207 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
208 } else {
209 fInstanceAttribSupport =
210 version >= GR_GL_VER(3, 0) ||
211 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
212 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
213 }
214
215 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700216 if (version >= GR_GL_VER(3, 0)) {
217 fBindFragDataLocationSupport = true;
218 }
219 } else {
220 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
221 fBindFragDataLocationSupport = true;
222 }
joshualittc1f56b52015-06-22 12:31:31 -0700223 }
224
joshualitt7bdd70a2015-10-01 06:28:11 -0700225 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
226
kkinnunene06ed252016-02-16 23:15:40 -0800227 if (kGL_GrGLStandard == standard) {
Weiliang Chen1e04b362018-07-12 17:13:35 -0400228 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle") ||
229 ctxInfo.hasExtension("GL_ANGLE_texture_rectangle")) {
Brian Salomon246bc3d2018-12-06 15:33:02 -0500230 fRectangleTextureSupport = true;
bsalomone179a912016-01-20 06:18:10 -0800231 }
kkinnunene06ed252016-02-16 23:15:40 -0800232 } else {
233 // Command buffer exposes this in GL ES context for Chromium reasons,
234 // but it should not be used. Also, at the time of writing command buffer
235 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800236 }
237
bsalomoncdee0092016-01-08 13:20:12 -0800238 if (kGL_GrGLStandard == standard) {
239 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
240 fTextureSwizzleSupport = true;
241 }
242 } else {
243 if (version >= GR_GL_VER(3,0)) {
244 fTextureSwizzleSupport = true;
245 }
246 }
247
cblume09bd2c02016-03-01 14:08:28 -0800248 if (kGL_GrGLStandard == standard) {
249 fMipMapLevelAndLodControlSupport = true;
250 } else if (kGLES_GrGLStandard == standard) {
251 if (version >= GR_GL_VER(3,0)) {
252 fMipMapLevelAndLodControlSupport = true;
253 }
254 }
255
bsalomon88c7b982015-07-31 11:20:16 -0700256#ifdef SK_BUILD_FOR_WIN
257 // We're assuming that on Windows Chromium we're using ANGLE.
258 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
259 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700260 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700261 fRGBA8888PixelsOpsAreSlow = isANGLE;
262 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
263 // check DX11 ANGLE.
264 fPartialFBOReadIsSlow = isANGLE;
265#endif
266
ericrkb4ecabd2016-03-11 15:18:20 -0800267 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
268 bool isMAC = false;
269#ifdef SK_BUILD_FOR_MAC
270 isMAC = true;
271#endif
272
273 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
274 // vis-versa.
275 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
276
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500277 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
278 fUseBufferDataNullHint = false;
279 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
280 fUseBufferDataNullHint = true;
281 }
282
Brian Salomond17b4a62017-05-23 16:53:47 -0400283 if (kGL_GrGLStandard == standard) {
284 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400285 fClearTextureSupport = true;
286 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500287 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
288 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400289 }
290
Greg Danielb2acf0a2018-09-12 09:17:11 -0400291#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
292 fSupportsAHardwareBufferImages = true;
293#endif
294
cdalton4cd67132015-06-10 19:23:46 -0700295 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700296 * GrShaderCaps fields
297 **************************************************************************/
298
egdaniel0a482332015-10-26 08:59:10 -0700299 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700300 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500301 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700302
Brian Osman195c05b2017-08-30 15:14:04 -0400303 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
304#if GR_TEST_UTILS
305 if (contextOptions.fSuppressPathRendering) {
306 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700307 }
Brian Osman195c05b2017-08-30 15:14:04 -0400308#endif
egdaniel05ded892015-10-26 07:38:05 -0700309
egdaniel05ded892015-10-26 07:38:05 -0700310 // Enable supported shader-related caps
311 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500312 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700313 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
Brian Salomon23c55b62018-06-19 16:28:41 -0400314 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600315
Brian Salomon1edc5b92016-11-29 13:43:46 -0500316 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600317
egdaniel05ded892015-10-26 07:38:05 -0700318 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500319 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700320 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600321 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600322 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
323 shaderCaps->fGSInvocationsSupport = true;
324 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
325 shaderCaps->fGSInvocationsSupport = true;
326 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
327 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600328 }
329
Brian Salomon1edc5b92016-11-29 13:43:46 -0500330 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800331 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500332 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500333 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700334
Brian Salomon1edc5b92016-11-29 13:43:46 -0500335 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700336 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800337
Chris Dalton1214be92018-06-28 19:06:27 -0600338 // Mali and early Adreno both have support for geometry shaders, but they appear to be
339 // implemented in software. In practice with ccpr, they are slower than the backup impl that
340 // only uses vertex shaders.
341 if (kARM_GrGLVendor != ctxInfo.vendor() &&
342 kAdreno3xx_GrGLRenderer != ctxInfo.renderer() &&
343 kAdreno4xx_other_GrGLRenderer != ctxInfo.renderer()) {
344
Chris Daltonfaca00d2018-01-19 15:56:07 -0700345 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
346 shaderCaps->fGeometryShaderSupport = true;
347 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
348 shaderCaps->fGeometryShaderSupport = true;
349 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
350 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700351 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500352 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700353
Brian Salomon1edc5b92016-11-29 13:43:46 -0500354 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800355 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700356 }
357
cdalton9c3f1432016-03-11 10:07:37 -0800358 // Protect ourselves against tracking huge amounts of texture state.
359 static const uint8_t kMaxSaneSamplers = 32;
360 GrGLint maxSamplers;
cdalton9c3f1432016-03-11 10:07:37 -0800361 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500362 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800363
csmartdalton485a1202016-07-13 10:16:32 -0700364 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
365 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
366 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
367 // limit this decision to specific GPU families rather than basing it on the vendor alone.
368 if (!GR_GL_MUST_USE_VBO &&
369 !fIsCoreProfile &&
370 (kARM_GrGLVendor == ctxInfo.vendor() ||
371 kImagination_GrGLVendor == ctxInfo.vendor() ||
372 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
373 fPreferClientSideDynamicBuffers = true;
374 }
375
Eric Karl5c779752017-05-08 12:02:07 -0700376 if (!contextOptions.fAvoidStencilBuffers) {
377 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
378 this->initFSAASupport(contextOptions, ctxInfo, gli);
379 this->initStencilSupport(ctxInfo);
380 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400381
382 // Setup blit framebuffer
383 if (kGL_GrGLStandard != ctxInfo.standard()) {
384 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
385 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
386 kNoMSAADst_BlitFramebufferFlag |
387 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
388 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
389 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
390 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
391 // limitations.
392 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
393 kResolveMustBeFull_BlitFrambufferFlag |
394 kNoMSAADst_BlitFramebufferFlag |
395 kNoFormatConversion_BlitFramebufferFlag |
396 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
397 }
398 } else {
399 if (fUsesMixedSamples ||
400 ctxInfo.version() >= GR_GL_VER(3,0) ||
401 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
402 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
403 fBlitFramebufferFlags = 0;
404 }
405 }
406
cdalton1dd05422015-06-12 09:01:18 -0700407 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000408
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000409 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000410 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
411 // extension includes glMapBuffer.
412 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
413 fMapBufferFlags |= kSubset_MapFlag;
414 fMapBufferType = kMapBufferRange_MapBufferType;
415 } else {
416 fMapBufferType = kMapBuffer_MapBufferType;
417 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000418 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000419 // Unextended GLES2 doesn't have any buffer mapping.
420 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800421 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800422 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
423 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800424 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
425 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
426 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000427 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
428 fMapBufferFlags = kCanMap_MapFlag;
429 fMapBufferType = kMapBuffer_MapBufferType;
430 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000431 }
432
jvanverthd7a2c1f2015-12-07 07:36:44 -0800433 if (kGL_GrGLStandard == standard) {
434 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
435 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700436 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500437 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400438 if (version >= GR_GL_VER(3, 0) ||
439 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
440 // GL_EXT_unpack_subimage needed to support subtexture rectangles
441 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800442 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400443// TODO: get transfer buffers working in Chrome
444// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
445// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800446 }
447 }
448
joshualitte5b74c62015-06-01 14:17:47 -0700449 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
450 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700451 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700452#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500453 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
454 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
455 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700456 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700457#else
cdalton397536c2016-03-25 12:15:03 -0700458 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700459#endif
joshualitte5b74c62015-06-01 14:17:47 -0700460 }
461
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000462 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000463 fNPOTTextureTileSupport = true;
464 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000465 } else {
466 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000467 // ES3 has no limitations.
468 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
469 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000470 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
471 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
472 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
473 // to alllow arbitrary wrap modes, however.
474 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000475 }
476
bsalomon@google.combcce8922013-03-25 15:38:39 +0000477 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
Adrienne Walker724afe82018-05-15 11:36:26 -0700478
479 if (fDriverBugWorkarounds.max_texture_size_limit_4096) {
480 fMaxTextureSize = SkTMin(fMaxTextureSize, 4096);
481 }
482
bsalomon@google.combcce8922013-03-25 15:38:39 +0000483 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
484 // Our render targets are always created with textures as the color
485 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000486 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700487 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
488
489 if (kARM_GrGLVendor == ctxInfo.vendor()) {
490 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
491 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
492 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000493
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000494 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
495
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000496 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700497 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000498
robertphillips1b8e1b52015-06-24 06:54:10 -0700499#if 0
500 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
501 kQualcomm_GrGLVendor != ctxInfo.vendor();
502#endif
503
csmartdalton9bc11872016-08-09 12:42:47 -0700504 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
505 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700506 }
507
robertphillips63926682015-08-20 09:39:02 -0700508#ifdef SK_BUILD_FOR_WIN
509 // On ANGLE deferring flushes can lead to GPU starvation
510 fPreferVRAMUseOverFlushes = !isANGLE;
511#endif
512
bsalomon7dea7b72015-08-19 08:26:51 -0700513 if (kChromium_GrGLDriver == ctxInfo.driver()) {
514 fMustClearUploadedBufferData = true;
515 }
516
bsalomond08ea5f2015-02-20 06:58:13 -0800517 if (kGL_GrGLStandard == standard) {
518 // ARB allows mixed size FBO attachments, EXT does not.
519 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
520 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
521 fOversizedStencilSupport = true;
522 } else {
523 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
524 }
525 } else {
526 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
527 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
528 }
529
joshualitt58001552015-06-26 12:46:36 -0700530 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700531 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
532 ctxInfo.hasExtension("GL_ARB_draw_indirect");
533 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
534 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700535 (fDrawIndirectSupport &&
536 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700537 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700538 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800539 } else {
540 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700541 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
542 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
543 fBaseInstanceSupport = fDrawIndirectSupport &&
544 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700545 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800546 }
547
jvanverth84741b32016-09-30 08:39:02 -0700548 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
549 if (kGL_GrGLStandard == standard) {
550 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
551 fFenceSyncSupport = true;
552 }
Brian Osman93a23462017-06-21 15:13:39 -0400553 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700554 fFenceSyncSupport = true;
555 }
556
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400557 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500558 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500559
Brian Osman499bf1a2018-09-17 11:32:42 -0400560 // Half float vertex attributes requires GL3 or ES3
561 // It can also work with OES_VERTEX_HALF_FLOAT, but that requires a different enum.
562 if (kGL_GrGLStandard == standard) {
563 if (version >= GR_GL_VER(3, 0)) {
564 fHalfFloatVertexAttributeSupport = true;
565 }
566 } else if (version >= GR_GL_VER(3, 0)) {
567 fHalfFloatVertexAttributeSupport = true;
568 }
569
Brian Salomonf7232642018-09-19 08:58:08 -0400570 fDynamicStateArrayGeometryProcessorTextureSupport = true;
571
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400572 if (kGL_GrGLStandard == standard) {
573 if (version >= GR_GL_VER(4, 1)) {
574 fProgramBinarySupport = true;
575 }
576 } else if (version >= GR_GL_VER(3, 0)) {
577 fProgramBinarySupport = true;
578 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400579 if (fProgramBinarySupport) {
580 GrGLint count;
Ethan Nicholasad77dce2018-07-11 13:59:03 -0400581 GR_GL_GetIntegerv(gli, GR_GL_NUM_PROGRAM_BINARY_FORMATS, &count);
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400582 fProgramBinarySupport = count > 0;
583 }
Brian Salomona2a94a42018-10-16 10:54:10 -0400584 if (kGL_GrGLStandard == standard) {
585 fSamplerObjectSupport =
586 version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_sampler_objects");
587 } else {
588 fSamplerObjectSupport = version >= GR_GL_VER(3,0);
589 }
bsalomoncdee0092016-01-08 13:20:12 -0800590 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
591 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800592 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700593
Brian Salomon01b476a2018-01-23 11:06:41 -0500594 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
595 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
596 }
597
cdalton4cd67132015-06-10 19:23:46 -0700598 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500599 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700600
Brian Salomon01b476a2018-01-23 11:06:41 -0500601 // For now these two are equivalent but we could have dst read in shader via some other method.
602 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000603}
604
egdaniel472d44e2015-10-22 08:20:00 -0700605const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
606 bool isCoreProfile) {
607 switch (generation) {
608 case k110_GrGLSLGeneration:
609 if (kGLES_GrGLStandard == standard) {
610 // ES2s shader language is based on version 1.20 but is version
611 // 1.00 of the ES language.
612 return "#version 100\n";
613 } else {
614 SkASSERT(kGL_GrGLStandard == standard);
615 return "#version 110\n";
616 }
617 case k130_GrGLSLGeneration:
618 SkASSERT(kGL_GrGLStandard == standard);
619 return "#version 130\n";
620 case k140_GrGLSLGeneration:
621 SkASSERT(kGL_GrGLStandard == standard);
622 return "#version 140\n";
623 case k150_GrGLSLGeneration:
624 SkASSERT(kGL_GrGLStandard == standard);
625 if (isCoreProfile) {
626 return "#version 150\n";
627 } else {
628 return "#version 150 compatibility\n";
629 }
630 case k330_GrGLSLGeneration:
631 if (kGLES_GrGLStandard == standard) {
632 return "#version 300 es\n";
633 } else {
634 SkASSERT(kGL_GrGLStandard == standard);
635 if (isCoreProfile) {
636 return "#version 330\n";
637 } else {
638 return "#version 330 compatibility\n";
639 }
640 }
cdalton33ad7012016-02-22 07:55:44 -0800641 case k400_GrGLSLGeneration:
642 SkASSERT(kGL_GrGLStandard == standard);
643 if (isCoreProfile) {
644 return "#version 400\n";
645 } else {
646 return "#version 400 compatibility\n";
647 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500648 case k420_GrGLSLGeneration:
649 SkASSERT(kGL_GrGLStandard == standard);
650 if (isCoreProfile) {
651 return "#version 420\n";
652 }
653 else {
654 return "#version 420 compatibility\n";
655 }
egdaniel472d44e2015-10-22 08:20:00 -0700656 case k310es_GrGLSLGeneration:
657 SkASSERT(kGLES_GrGLStandard == standard);
658 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800659 case k320es_GrGLSLGeneration:
660 SkASSERT(kGLES_GrGLStandard == standard);
661 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700662 }
663 return "<no version>";
664}
665
Chris Dalton47c8ed32017-11-15 18:27:09 -0700666bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
667 if (kGLES_GrGLStandard != ctxInfo.standard() &&
668 ctxInfo.version() < GR_GL_VER(4,1) &&
669 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
670 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
671 return true;
672 }
673 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
674 // geometry shaders don't have lower precision than vertex and fragment.
675 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
676 GrGLint range[2];
677 GrGLint bits;
678 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
679 if (range[0] < 127 || range[1] < 127 || bits < 23) {
680 return false;
681 }
682 }
683 return true;
684}
685
686void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700687 GrGLStandard standard = ctxInfo.standard();
688 GrGLVersion version = ctxInfo.version();
689
690 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500691 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700692 **************************************************************************/
693
Brian Salomon1edc5b92016-11-29 13:43:46 -0500694 GrShaderCaps* shaderCaps = fShaderCaps.get();
695 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700696 if (kGLES_GrGLStandard == standard) {
697 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500698 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
699 shaderCaps->fFBFetchSupport = true;
700 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
701 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700702 }
703 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
704 // 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 -0500705 shaderCaps->fFBFetchNeedsCustomOutput = false;
706 shaderCaps->fFBFetchSupport = true;
707 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
708 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700709 }
710 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
711 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500712 shaderCaps->fFBFetchNeedsCustomOutput = false;
713 shaderCaps->fFBFetchSupport = true;
714 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
715 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700716 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500717 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700718 }
719
cdaltonc08f1962016-02-12 12:14:06 -0800720 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500721 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800722 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500723 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800724 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
725 }
Michael Ludwig240af982018-12-03 16:16:18 -0500726 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530). ANGLE
727 // Avoid on ANGLE too, it inserts a geometry shader into the pipeline to implement flat interp.
Brian Salomon41274562017-09-15 09:40:03 -0700728 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
Michael Ludwig240af982018-12-03 16:16:18 -0500729 kQualcomm_GrGLVendor != ctxInfo.vendor() &&
730 kANGLE_GrGLDriver != ctxInfo.driver();
cdaltonc08f1962016-02-12 12:14:06 -0800731 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500732 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800733 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
734 } else {
Brian Osman71a69952018-05-07 17:07:35 -0400735 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation") &&
736 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration /* GLSL ES 3.0 */) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500737 shaderCaps->fNoPerspectiveInterpolationSupport = true;
738 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800739 "GL_NV_shader_noperspective_interpolation";
740 }
741 }
742
Brian Salomon1edc5b92016-11-29 13:43:46 -0500743 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
744 shaderCaps->fGLSLGeneration,
745 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800746
Brian Salomon1edc5b92016-11-29 13:43:46 -0500747 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
748 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800749 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800750
751 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500752 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800753 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
754 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500755 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800756 }
757
758 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500759 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800760 }
761
cdalton9c3f1432016-03-11 10:07:37 -0800762 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400763 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
764 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400765 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400766 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
767 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
768 // At least one driver has been found that has this extension without the "GL_" prefix.
769 shaderCaps->fExternalTextureSupport = true;
770 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800771 }
772 }
773
cdaltonc04ce672016-03-11 14:07:38 -0800774 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600775 shaderCaps->fVertexIDSupport = true;
776 } else {
777 // Desktop GLSL 3.30 == ES GLSL 3.00.
778 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
779 }
780
Chris Dalton7c7ff032018-03-28 20:09:58 -0600781 if (kGL_GrGLStandard == standard) {
782 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
783 } else {
784 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
785 }
786
Chris Dalton47c8ed32017-11-15 18:27:09 -0700787 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
788 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400789
790 // Unsigned integers only supported in and after GLSL 1.30.
791 shaderCaps->fUnsignedSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Daltona7086182018-11-16 09:33:43 -0500792
793 if (kGL_GrGLStandard == standard) {
794 shaderCaps->fBuiltinFMASupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
795 } else {
796 shaderCaps->fBuiltinFMASupport = ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration;
797 }
egdaniel472d44e2015-10-22 08:20:00 -0700798}
799
kkinnunencfe62e32015-07-01 02:58:50 -0700800bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700801 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
802
803 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700804 return false;
805 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700806
kkinnunencfe62e32015-07-01 02:58:50 -0700807 if (kGL_GrGLStandard == ctxInfo.standard()) {
808 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
809 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
810 return false;
811 }
812 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700813 if (!hasChromiumPathRendering &&
814 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700815 return false;
816 }
817 }
818 // We only support v1.3+ of GL_NV_path_rendering which allows us to
819 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
820 // additions are detected by checking the existence of the function.
821 // We also use *Then* functions that not all drivers might have. Check
822 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800823 if (!gli->fFunctions.fStencilThenCoverFillPath ||
824 !gli->fFunctions.fStencilThenCoverStrokePath ||
825 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
826 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
827 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700828 return false;
829 }
830 return true;
831}
bsalomon1aa20292016-01-22 08:16:09 -0800832
Brian Salomon71d9d842016-11-03 13:42:00 -0400833bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800834 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800835 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800836 std::function<bool ()> bindRenderTarget,
837 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400838 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800839 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400840 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800841 return false;
842 }
bsalomon7928ef62016-01-05 10:26:39 -0800843
bsalomon76148af2016-01-12 11:13:47 -0800844 GrGLenum readFormat;
845 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400846 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800847 return false;
848 }
849
bsalomon1aa20292016-01-22 08:16:09 -0800850 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800851 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
852 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
853 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
854 // 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 -0500855 // The manual does not seem to fully match the spec as the spec allows integer formats
856 // when the bound color buffer is an integer buffer. It doesn't specify which integer
857 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500858 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
859 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
860 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800861 return false;
862 }
863 // There is also a set of allowed types, but all the types we use are in the set:
864 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
865 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
866 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
867 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
868 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
869 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
870 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800871 return true;
piotaixre4b23142014-10-02 10:57:53 -0700872 }
bsalomon7928ef62016-01-05 10:26:39 -0800873
bsalomon76148af2016-01-12 11:13:47 -0800874 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500875 switch (fConfigTable[surfaceConfig].fFormatType) {
876 case kNormalizedFixedPoint_FormatType:
877 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
878 return true;
879 }
880 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500881 case kFloat_FormatType:
882 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
883 return true;
884 }
885 break;
bsalomon7928ef62016-01-05 10:26:39 -0800886 }
887
Brian Salomon71d9d842016-11-03 13:42:00 -0400888 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800889 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400890 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800891 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800892 if (!bindRenderTarget()) {
893 return false;
894 }
895 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
896 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800897 rpFormat->fFormat = format;
898 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800899 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800900 }
901
Brian Salomon71d9d842016-11-03 13:42:00 -0400902 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
903 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700904}
905
Eric Karl5c779752017-05-08 12:02:07 -0700906void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
907 const GrGLInterface* gli) {
908 // We need dual source blending and the ability to disable multisample in order to support mixed
909 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
910 // renderer is available and enabled; no other path renderers support this feature.
911 if (fMultisampleDisableSupport &&
912 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400913 this->shaderCaps()->pathRenderingSupport()
914#if GR_TEST_UTILS
915 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
916#endif
917 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700918 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400919 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700920 }
921
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000922 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400923 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
924 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
925 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
926 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
927 fAlpha8IsRenderable = true;
928 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500929 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
930 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
931 // mixed samples we can't use multisampled-render-to-texture.
932 if (fUsesMixedSamples) {
933 fMSFBOType = kMixedSamples_MSFBOType;
934 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000935 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
936 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
937 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400938 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
939 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400940 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400941 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400942 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400943 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000944 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
945 fMSFBOType = kES_Apple_MSFBOType;
946 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000947 } else {
egdanieleed519e2016-01-15 11:36:18 -0800948 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700949 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400950 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
951 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400952
Brian Salomon00731b42016-10-14 11:30:51 -0400953 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400954 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
955 // Core profile removes ALPHA8 support.
956 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
957 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
958 // present.
959 fAlpha8IsRenderable = true;
960 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000961 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
962 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400963 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000964 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000965 }
Eric Karl5c779752017-05-08 12:02:07 -0700966
Brian Salomon01b476a2018-01-23 11:06:41 -0500967 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400968 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
969 fMSFBOType = kNone_MSFBOType;
970 }
971
Eric Karl5c779752017-05-08 12:02:07 -0700972 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
973 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
974 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700975 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000976}
977
cdalton1dd05422015-06-12 09:01:18 -0700978void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500979 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -0700980
Greg Daniel210883c2017-11-27 15:14:01 -0500981 bool layoutQualifierSupport = false;
982 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
983 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
984 layoutQualifierSupport = true;
985 }
986
cdalton1dd05422015-06-12 09:01:18 -0700987 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
988 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500989 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -0500990 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
991 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -0700992 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500993 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -0700994 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
995 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500996 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -0500997 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -0700998 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500999 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001000 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1001 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001002 }
cdalton1dd05422015-06-12 09:01:18 -07001003}
1004
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001005namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001006const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001007}
1008
Eric Karl5c779752017-05-08 12:02:07 -07001009void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001010
1011 // Build up list of legal stencil formats (though perhaps not supported on
1012 // the particular gpu/driver) from most preferred to least.
1013
1014 // these consts are in order of most preferred to least preferred
1015 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1016
1017 static const StencilFormat
1018 // internal Format stencil bits total bits packed?
1019 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1020 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1021 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1022 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001023 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001024 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1025
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001026 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001027 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001028 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001029 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1030 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1031
1032 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1033 // require FBO support we can expect these are legal formats and don't
1034 // check. These also all support the unsized GL_STENCIL_INDEX.
1035 fStencilFormats.push_back() = gS8;
1036 fStencilFormats.push_back() = gS16;
1037 if (supportsPackedDS) {
1038 fStencilFormats.push_back() = gD24S8;
1039 }
1040 fStencilFormats.push_back() = gS4;
1041 if (supportsPackedDS) {
1042 fStencilFormats.push_back() = gDS;
1043 }
1044 } else {
1045 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1046 // for other formats.
1047 // ES doesn't support using the unsized format.
1048
1049 fStencilFormats.push_back() = gS8;
1050 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001051 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1052 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001053 fStencilFormats.push_back() = gD24S8;
1054 }
1055 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1056 fStencilFormats.push_back() = gS4;
1057 }
1058 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001059}
1060
Kevin Lubickf4def342018-10-04 12:52:50 -04001061#ifdef SK_ENABLE_DUMP_GPU
Brian Osman71a18892017-08-10 10:23:25 -04001062void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001063
Brian Osman71a18892017-08-10 10:23:25 -04001064 // We are called by the base class, which has already called beginObject(). We choose to nest
1065 // all of our caps information in a named sub-object.
1066 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001067
Brian Osman71a18892017-08-10 10:23:25 -04001068 writer->beginArray("Stencil Formats");
1069
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001070 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001071 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001072 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1073 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1074 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001075 }
1076
Brian Osman71a18892017-08-10 10:23:25 -04001077 writer->endArray();
1078
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001079 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001080 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001081 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001082 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001083 "IMG MS To Texture",
1084 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001085 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001086 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001087 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001088 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1089 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1090 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1091 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1092 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001093 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001094
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001095 static const char* kInvalidateFBTypeStr[] = {
1096 "None",
1097 "Discard",
1098 "Invalidate",
1099 };
1100 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1101 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1102 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1103 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001104
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001105 static const char* kMapBufferTypeStr[] = {
1106 "None",
1107 "MapBuffer",
1108 "MapBufferRange",
1109 "Chromium",
1110 };
1111 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1112 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1113 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1114 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1115 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1116
Brian Osman71a18892017-08-10 10:23:25 -04001117 writer->appendBool("Core Profile", fIsCoreProfile);
1118 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1119 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1120 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1121 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1122 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1123 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1124 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1125 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001126
Brian Osman71a18892017-08-10 10:23:25 -04001127 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001128 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1129 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1130 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001131 writer->appendBool("Debug support", fDebugSupport);
1132 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1133 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1134 writer->appendBool("Base instance support", fBaseInstanceSupport);
1135 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1136 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1137 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1138 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1139 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1140 writer->appendBool("BGRA to RGBA readback conversions are slow",
1141 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001142 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001143 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1144 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001145 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1146 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1147 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1148 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Dalton1b4ad762018-10-04 11:58:09 -06001149 writer->appendBool("Max instances per draw without crashing (or zero)",
1150 fMaxInstancesPerDrawWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001151
Brian Osman71a18892017-08-10 10:23:25 -04001152 writer->beginArray("configs");
1153
bsalomon41e4384e2016-01-08 09:12:44 -08001154 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001155 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001156 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1157 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1158 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001159 writer->appendHexU32("e_format_read_pixels",
1160 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001161 writer->appendHexU32(
1162 "e_format_teximage",
1163 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1164 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1165 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1166 writer->appendHexU32("i_for_renderbuffer",
1167 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1168 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001169 }
1170
Brian Osman71a18892017-08-10 10:23:25 -04001171 writer->endArray();
1172 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001173}
Kevin Lubickf4def342018-10-04 12:52:50 -04001174#else
1175void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const { }
1176#endif
jvanverthe9c0fc62015-04-29 11:18:05 -07001177
bsalomon41e4384e2016-01-08 09:12:44 -08001178bool GrGLCaps::bgraIsInternalFormat() const {
1179 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1180}
1181
bsalomon76148af2016-01-12 11:13:47 -08001182bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1183 GrGLenum* internalFormat, GrGLenum* externalFormat,
1184 GrGLenum* externalType) const {
1185 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1186 externalFormat, externalType)) {
1187 return false;
1188 }
1189 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1190 return true;
1191}
1192
bsalomon76148af2016-01-12 11:13:47 -08001193bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1194 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001195 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001196 externalFormat, externalType)) {
1197 return false;
1198 }
1199 return true;
1200}
1201
Brian Salomon93348dd2018-08-29 12:56:23 -04001202void GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001203 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
Brian Salomon93348dd2018-08-29 12:56:23 -04001204}
1205
1206void GrGLCaps::getSizedInternalFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1207 *internalFormat = fConfigTable[config].fFormats.fSizedInternalFormat;
bsalomon76148af2016-01-12 11:13:47 -08001208}
1209
1210bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1211 ExternalFormatUsage usage, GrGLenum* externalFormat,
1212 GrGLenum* externalType) const {
1213 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001214
1215 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1216 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1217
1218 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001219 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1220 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001221 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1222 return false;
1223 }
1224
1225 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1226 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1227
bsalomone9573312016-01-25 14:33:25 -08001228 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1229 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1230 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1231 // texture, not the red component.
1232 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001233 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001234 *externalFormat = GR_GL_ALPHA;
1235 }
1236 }
1237
bsalomon76148af2016-01-12 11:13:47 -08001238 return true;
1239}
1240
brianosman20471892016-12-02 06:43:32 -08001241void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1242 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001243 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001244 /*
1245 Comments on renderability of configs on various GL versions.
1246 OpenGL < 3.0:
1247 no built in support for render targets.
1248 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1249 format RGB, RGBA and NV float formats we don't use.
1250 This is the following:
1251 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1252 RGB10_A2, RGBA12,RGBA16
1253 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1254 since they aren't required by later standards and the driver can simply return
1255 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1256 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1257 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1258 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1259 This adds a lot of additional renderable sized formats, including ALPHA8.
1260 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1261 16F, 32I, 32UI, and 32F variants).
1262 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1263
1264 For both the above extensions we limit ourselves to those that are also required by
1265 OpenGL 3.0.
1266
1267 OpenGL 3.0:
1268 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1269 but are not required to be supported as renderable textures/renderbuffer.
1270 Required renderable color formats:
1271 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1272 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1273 RGB10_A2.
1274 - R11F_G11F_B10F.
1275 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1276 and RG8UI.
1277 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1278 - ALPHA8
1279
1280 OpenGL 3.1, 3.2, 3.3
1281 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1282 OpengGL 3.3, 4.0, 4.1
1283 Adds RGB10_A2UI.
1284 OpengGL 4.2
1285 Adds
1286 - RGB5_A1, RGBA4
1287 - RGB565
1288 OpenGL 4.4
1289 Does away with the separate list and adds a column to the sized internal color format
1290 table. However, no new formats become required color renderable.
1291
1292 ES 2.0
1293 color renderable: RGBA4, RGB5_A1, RGB565
Jim Van Verth69e57852018-12-05 13:38:59 -05001294 GL_EXT_texture_rg adds support for R8, RG8 as a color render target
bsalomon41e4384e2016-01-08 09:12:44 -08001295 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1296 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1297 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1298 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1299 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1300
1301 ES 3.0
1302 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1303 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1304 RGB5_A1.
1305 - RGB8 and RGB565.
1306 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1307 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1308 ES 3.1
1309 Adds RGB10_A2, RGB10_A2UI,
1310 ES 3.2
1311 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1312 */
Brian Salomon44804c02018-01-23 16:51:28 -05001313
1314 // Correctness workarounds.
1315 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001316 bool disableSRGBForX86PowerVR = false;
1317 bool disableSRGBWriteControlForAdreno4xx = false;
1318 bool disableR8TexStorageForANGLEGL = false;
1319 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001320 bool disableRGB8ForMali400 = false;
Greg Daniel09c94002018-06-08 22:11:51 +00001321 bool disableGrayLumFBOForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001322
1323 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1324 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1325 // and GL_RG on FBO textures.
1326 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1327
Greg Daniel09c94002018-06-08 22:11:51 +00001328 disableGrayLumFBOForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1329
Brian Salomon44804c02018-01-23 16:51:28 -05001330 bool isX86PowerVR = false;
1331#if defined(SK_CPU_X86)
1332 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1333 isX86PowerVR = true;
1334 }
1335#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001336 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1337 // blacklist that device (and any others that might be sharing the same driver).
1338 disableSRGBForX86PowerVR = isX86PowerVR;
Chris Dalton1214be92018-06-28 19:06:27 -06001339 disableSRGBWriteControlForAdreno4xx =
1340 (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
1341 kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer());
Brian Salomon44804c02018-01-23 16:51:28 -05001342
1343 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1344 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1345 // check that we are not going to OpenGL.
1346 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1347
1348 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1349#if defined(SK_BUILD_FOR_MAC)
1350 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1351#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001352 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1353 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001354 }
1355
Brian Salomon71d9d842016-11-03 13:42:00 -04001356 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1357 ConfigInfo::kFBOColorAttachment_Flag;
1358 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001359 if (kNone_MSFBOType != fMSFBOType) {
1360 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1361 }
bsalomon41e4384e2016-01-08 09:12:44 -08001362 GrGLStandard standard = ctxInfo.standard();
1363 GrGLVersion version = ctxInfo.version();
1364
cblume790d5132016-02-29 11:13:29 -08001365 bool texStorageSupported = false;
1366 if (kGL_GrGLStandard == standard) {
1367 // The EXT version can apply to either GL or GLES.
1368 texStorageSupported = version >= GR_GL_VER(4,2) ||
1369 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1370 ctxInfo.hasExtension("GL_EXT_texture_storage");
1371 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001372 texStorageSupported = version >= GR_GL_VER(3,0) ||
1373 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001374 }
Adrienne Walker70e468f2018-08-22 16:05:27 -07001375 if (fDriverBugWorkarounds.disable_texture_storage) {
1376 texStorageSupported = false;
1377 }
cblume790d5132016-02-29 11:13:29 -08001378
Brian Salomone609e812018-01-17 14:00:47 -05001379 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001380
1381 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001382 if (kGL_GrGLStandard == standard) {
1383 textureRedSupport =
1384 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1385 } else {
1386 textureRedSupport =
1387 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1388 }
1389 }
1390
bsalomon30447372015-12-21 09:03:05 -08001391 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1392 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001393 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001394 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001395 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001396 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001397
1398 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1399 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001400 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001401 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001402 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001403 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001404 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1405 if (kGL_GrGLStandard == standard) {
1406 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1407 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001408 } else {
Kevin Lubick217056c2018-09-20 17:39:31 -04001409 bool isWebGL = false;
1410 // hack for skbug:8378
1411 #if IS_WEBGL==1
1412 isWebGL = true;
1413 #endif
1414 if (isWebGL || version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
bsalomon41e4384e2016-01-08 09:12:44 -08001415 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1416 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1417 }
egdaniel4999df82016-01-07 17:06:04 -08001418 }
cblume790d5132016-02-29 11:13:29 -08001419 if (texStorageSupported) {
1420 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1421 }
bsalomoncdee0092016-01-08 13:20:12 -08001422 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001423
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001424 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1425 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1426 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1427 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1428 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1429 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1430 // supportedReadPixelsColorType never returns it.
1431 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1432 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1433 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1434 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1435 if (kGL_GrGLStandard == standard) {
1436 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1437 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1438 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1439 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1440 // becomes an issue.
1441 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1442 // but we don't support that just for simplicity's sake.
1443 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1444 } else {
1445 // 3.0 and the extension support this as a render buffer format.
1446 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1447 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1448 }
1449 }
1450 if (texStorageSupported) {
1451 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1452 }
1453 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1454 if (disableRGB8ForMali400) {
1455 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1456 }
1457
Jim Van Verth69e57852018-12-05 13:38:59 -05001458 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1459 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1460 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1461
1462 fConfigTable[kRG_88_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RG;
1463 fConfigTable[kRG_88_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RG8;
1464 fConfigTable[kRG_88_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
1465 GR_GL_RG;
1466 fConfigTable[kRG_88_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1467 fConfigTable[kRG_88_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1468 if (textureRedSupport) {
1469 fConfigTable[kRG_88_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag | allRenderFlags;
1470 // ES2 Command Buffer does not allow TexStorage with RG8_EXT
1471 if (texStorageSupported && !isCommandBufferES2) {
1472 fConfigTable[kRG_88_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1473 }
1474 } else {
1475 fConfigTable[kRG_88_GrPixelConfig].fFlags = 0;
1476 }
1477 fConfigTable[kRG_88_GrPixelConfig].fSwizzle = GrSwizzle::RGRG();
1478
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001479 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001480 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001481 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001482 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001483
1484 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1485 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1486 // GL_EXT_texture_format_BGRA8888.
1487 bool supportsBGRATexStorage = false;
1488
bsalomon41e4384e2016-01-08 09:12:44 -08001489 if (kGL_GrGLStandard == standard) {
1490 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1491 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1492 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1493 // Since the internal format is RGBA8, it is also renderable.
1494 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1495 allRenderFlags;
1496 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001497 // Since we are using RGBA8 we can use tex storage.
1498 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001499 } else {
1500 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1501 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001502 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1503 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1504 nonMSAARenderFlags;
1505
1506 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1507 supportsBGRATexStorage = true;
1508 }
1509 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1510 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1511 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1512 ConfigInfo::kRenderableWithMSAA_Flag;
1513 }
1514 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001515 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1516 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1517 // driver remembers the external format when the texture is created (with TexImage).
1518 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1519 // We could work around this, but it adds even more state tracking to code that is
1520 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1521 // This also side-steps some ambiguous interactions with the texture storage extension.
1522 if (version >= GR_GL_VER(3,0)) {
1523 // The APPLE extension doesn't make this renderable.
1524 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001525 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001526 }
bsalomon41e4384e2016-01-08 09:12:44 -08001527 }
1528 }
Brian Osman48c99192017-06-02 08:45:06 -04001529
Greg Daniel0ff79b22018-02-15 12:33:33 -05001530 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001531 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001532 }
bsalomoncdee0092016-01-08 13:20:12 -08001533 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001534
Brian Osman2b23c4b2018-06-01 12:25:08 -04001535 // We only enable srgb support if both textures and FBOs support srgb.
bsalomon41e4384e2016-01-08 09:12:44 -08001536 if (kGL_GrGLStandard == standard) {
1537 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001538 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001539 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1540 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1541 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001542 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001543 }
1544 }
1545 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001546 if (fSRGBSupport) {
1547 fSRGBWriteControl = true;
1548 }
bsalomon41e4384e2016-01-08 09:12:44 -08001549 } else {
brianosman20471892016-12-02 06:43:32 -08001550 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001551 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001552 fSRGBSupport = false;
1553 }
bsalomon41e4384e2016-01-08 09:12:44 -08001554 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1555 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001556 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001557 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001558 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001559 }
brianosman20471892016-12-02 06:43:32 -08001560
1561 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1562 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1563 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1564 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1565 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1566 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1567 // affects Windows.
1568 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1569 fSRGBSupport = false;
1570 }
1571
Brian Osman67999392017-05-31 16:19:34 -04001572 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001573 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001574 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1575 }
Brian Osman67999392017-05-31 16:19:34 -04001576
bsalomon30447372015-12-21 09:03:05 -08001577 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1578 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1579 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1580 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001581 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001582 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001583 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001584 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001585 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001586 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001587 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001588 }
Brian Osman48c99192017-06-02 08:45:06 -04001589 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1590 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001591 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1592 }
bsalomoncdee0092016-01-08 13:20:12 -08001593 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001594 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1595 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1596 // is in this format, for example).
1597 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1598 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1599 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1600 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001601 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001602 GR_GL_BGRA;
1603 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1604 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001605 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001606 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001607 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001608 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001609
brianosmana6359362016-03-21 06:55:37 -07001610 if (texStorageSupported) {
1611 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1612 }
1613 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1614
bsalomon30447372015-12-21 09:03:05 -08001615 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1616 if (this->ES2CompatibilitySupport()) {
1617 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1618 } else {
1619 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1620 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001621 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001622 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001623 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001624 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001625 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1626 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001627 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001628 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1629 }
1630 } else {
1631 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1632 }
cblume790d5132016-02-29 11:13:29 -08001633 // 565 is not a sized internal format on desktop GL. So on desktop with
1634 // 565 we always use an unsized internal format to let the system pick
1635 // the best sized format to convert the 565 data to. Since TexStorage
1636 // only allows sized internal formats we disallow it.
1637 //
1638 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1639 // update.
1640 if (texStorageSupported && kGL_GrGLStandard != standard) {
1641 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1642 }
bsalomoncdee0092016-01-08 13:20:12 -08001643 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001644
1645 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1646 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001647 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001648 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001649 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001650 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001651 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1652 if (kGL_GrGLStandard == standard) {
1653 if (version >= GR_GL_VER(4, 2)) {
1654 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1655 }
1656 } else {
1657 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1658 }
cblume790d5132016-02-29 11:13:29 -08001659 if (texStorageSupported) {
1660 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1661 }
bsalomoncdee0092016-01-08 13:20:12 -08001662 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001663
Brian Osman10fc6fd2018-03-02 11:01:10 -05001664 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1665 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001666 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001667 GR_GL_RGBA;
1668 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1669 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1670 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1671 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1672 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1673 allRenderFlags;
1674 }
1675 if (texStorageSupported) {
1676 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1677 }
Brian Osman10fc6fd2018-03-02 11:01:10 -05001678 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1679
Greg Danielef59d872017-11-17 16:47:21 -05001680 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1681 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1682
1683 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1684 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1685 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1686 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1687 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001688 }
Greg Danielef59d872017-11-17 16:47:21 -05001689 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1690 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001691 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001692 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1693 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1694 alphaInfo.fFlags |= allRenderFlags;
1695 }
1696
1697 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1698 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1699 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1700 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1701 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001702 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001703 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001704
Brian Osman48c99192017-06-02 08:45:06 -04001705 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1706 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001707 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001708 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1709 }
1710 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1711 }
1712
Brian Salomone609e812018-01-17 14:00:47 -05001713 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001714 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
Greg Danielef59d872017-11-17 16:47:21 -05001715 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1716 } else {
1717 redInfo.fFlags = 0;
1718
1719 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001720 }
bsalomon41e4384e2016-01-08 09:12:44 -08001721
Greg Daniel7af060a2017-12-05 16:27:11 -05001722 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1723 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1724 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1725 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1726 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001727 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001728 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1729 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1730 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1731 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001732 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001733
1734 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1735 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1736 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1737 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1738 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001739 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001740 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1741 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1742
Greg Daniel09c94002018-06-08 22:11:51 +00001743 // Leaving Gray8 as non-renderable, to keep things simple and match raster. However, we do
1744 // enable the FBOColorAttachment_Flag so that we can bind it to an FBO for copies.
Brian Salomon23356442018-11-30 15:33:19 -05001745 grayRedInfo.fFlags |= ConfigInfo::kFBOColorAttachment_Flag;
Greg Daniel09c94002018-06-08 22:11:51 +00001746 if (kStandard_MSFBOType == this->msFBOType() && kGL_GrGLStandard == standard &&
1747 !disableGrayLumFBOForMesa) {
Brian Osman986563b2017-01-10 14:20:02 -05001748 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1749 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1750 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
Brian Salomon23356442018-11-30 15:33:19 -05001751 grayLumInfo.fFlags |= ConfigInfo::kFBOColorAttachment_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001752 }
Brian Osman48c99192017-06-02 08:45:06 -04001753 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001754 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001755 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1756 }
1757 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1758 }
1759
Brian Salomone609e812018-01-17 14:00:47 -05001760 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001761 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1762 } else {
1763 grayRedInfo.fFlags = 0;
1764 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001765 }
1766
bsalomon41e4384e2016-01-08 09:12:44 -08001767 // Check for [half] floating point texture support
1768 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1769 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1770 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
Chris Daltoneff01a72018-07-19 17:06:39 -06001771 bool hasFP32Textures = false;
1772 bool hasFP16Textures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001773 bool rgIsTexturable = false;
Chris Daltoneff01a72018-07-19 17:06:39 -06001774 bool hasFP32RenderTargets = false;
Brian Salomon75975512018-10-02 12:21:38 -04001775 enum class HalfFPRenderTargetSupport { kNone, kRGBAOnly, kAll };
1776 HalfFPRenderTargetSupport halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kNone;
bsalomon41e4384e2016-01-08 09:12:44 -08001777 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001778 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001779
1780 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001781 if (version >= GR_GL_VER(3, 0)) {
Chris Daltoneff01a72018-07-19 17:06:39 -06001782 hasFP32Textures = true;
1783 hasFP16Textures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001784 rgIsTexturable = true;
Chris Daltoneff01a72018-07-19 17:06:39 -06001785 hasFP32RenderTargets = true;
Brian Salomon75975512018-10-02 12:21:38 -04001786 halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kAll;
bsalomon41e4384e2016-01-08 09:12:44 -08001787 }
1788 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001789 if (version >= GR_GL_VER(3, 0)) {
Chris Daltoneff01a72018-07-19 17:06:39 -06001790 hasFP32Textures = true;
1791 hasFP16Textures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001792 rgIsTexturable = true;
Chris Daltoneff01a72018-07-19 17:06:39 -06001793 } else if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1794 ctxInfo.hasExtension("GL_OES_texture_float")) {
1795 hasFP32Textures = true;
1796 hasFP16Textures = true;
1797 } else if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1798 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1799 hasFP16Textures = true;
1800 }
1801
1802 if (version >= GR_GL_VER(3, 2)) {
1803 // For now we only enable rendering to fp32 on desktop, because on ES we'd have to solve
1804 // many precision issues and no clients actually want this yet.
1805 // hasFP32RenderTargets = true;
Brian Salomon75975512018-10-02 12:21:38 -04001806 halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kAll;
Chris Daltoneff01a72018-07-19 17:06:39 -06001807 } else if (ctxInfo.hasExtension("GL_EXT_color_buffer_float")) {
1808 // For now we only enable rendering to fp32 on desktop, because on ES we'd have to
1809 // solve many precision issues and no clients actually want this yet.
1810 // hasFP32RenderTargets = true;
Brian Salomon75975512018-10-02 12:21:38 -04001811 halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kAll;
Chris Daltoneff01a72018-07-19 17:06:39 -06001812 } else if (ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
Brian Salomon75975512018-10-02 12:21:38 -04001813 // This extension only enables half float support rendering for RGBA.
1814 halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kRGBAOnly;
bsalomon41e4384e2016-01-08 09:12:44 -08001815 }
1816 }
bsalomon30447372015-12-21 09:03:05 -08001817
csmartdalton6aa0e112017-02-08 16:14:11 -05001818 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1819 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1820 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1821 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1822 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001823 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001824 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1825 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
Chris Daltoneff01a72018-07-19 17:06:39 -06001826 if (hasFP32Textures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001827 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
Chris Daltoneff01a72018-07-19 17:06:39 -06001828 if (hasFP32RenderTargets) {
csmartdalton6aa0e112017-02-08 16:14:11 -05001829 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1830 }
bsalomon41e4384e2016-01-08 09:12:44 -08001831 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001832 if (texStorageSupported) {
1833 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1834 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001835 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001836 }
bsalomon30447372015-12-21 09:03:05 -08001837
Greg Danielef59d872017-11-17 16:47:21 -05001838 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001839 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001840 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001841 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001842 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001843 }
Greg Danielef59d872017-11-17 16:47:21 -05001844 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1845 redHalf.fFormats.fExternalType = redHalfExternalType;
1846 redHalf.fFormatType = kFloat_FormatType;
1847 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1848 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001849 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001850 redHalf.fSwizzle = GrSwizzle::RRRR();
Chris Daltoneff01a72018-07-19 17:06:39 -06001851 if (textureRedSupport && hasFP16Textures) {
Greg Danielef59d872017-11-17 16:47:21 -05001852 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1853
Brian Salomon75975512018-10-02 12:21:38 -04001854 if (halfFPRenderTargetSupport == HalfFPRenderTargetSupport::kAll) {
Greg Danielef59d872017-11-17 16:47:21 -05001855 redHalf.fFlags |= fpRenderFlags;
1856 }
1857
1858 if (texStorageSupported && !isCommandBufferES2) {
1859 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1860 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001861 }
Greg Danielef59d872017-11-17 16:47:21 -05001862 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001863
1864 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1865 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001866 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001867 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001868 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001869 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1870 } else {
1871 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1872 }
bsalomon7928ef62016-01-05 10:26:39 -08001873 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
Chris Daltoneff01a72018-07-19 17:06:39 -06001874 if (hasFP16Textures) {
bsalomon41e4384e2016-01-08 09:12:44 -08001875 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1876 // ES requires 3.2 or EXT_color_buffer_half_float.
Brian Salomon75975512018-10-02 12:21:38 -04001877 if (halfFPRenderTargetSupport != HalfFPRenderTargetSupport::kNone) {
bsalomon41e4384e2016-01-08 09:12:44 -08001878 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1879 }
1880 }
cblume790d5132016-02-29 11:13:29 -08001881 if (texStorageSupported) {
1882 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1883 }
bsalomoncdee0092016-01-08 13:20:12 -08001884 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001885
bsalomon30447372015-12-21 09:03:05 -08001886 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1887
1888 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001889 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1890 ctxInfo.version() >= GR_GL_VER(3,0));
1891 // All ES versions (thus far) require sized internal formats for render buffers.
1892 // TODO: Always use sized internal format?
1893 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1894
bsalomon30447372015-12-21 09:03:05 -08001895 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001896 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1897 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001898 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001899 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001900 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1901 fConfigTable[i].fFormats.fSizedInternalFormat :
1902 fConfigTable[i].fFormats.fBaseInternalFormat;
1903 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001904 fConfigTable[i].fFormats.fSizedInternalFormat :
1905 fConfigTable[i].fFormats.fBaseInternalFormat;
1906 }
Brian Salomon44804c02018-01-23 16:51:28 -05001907 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1908 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1909 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1910 // in ES.
1911 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1912 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1913 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1914 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001915 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1916 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001917 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1918 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001919 }
1920
bsalomon30447372015-12-21 09:03:05 -08001921 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1922 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1923 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1924 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1925 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001926 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001927 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001928
1929 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1930 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1931 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1932 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001933 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001934 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1935 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1936 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1937 // slot.
1938 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1939 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001940
1941 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1942 // as a base format.
1943 // GL_EXT_texture_format_BGRA8888:
1944 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1945 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1946 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001947 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001948 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1949 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1950 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001951 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001952 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1953 }
1954
bsalomoncdee0092016-01-08 13:20:12 -08001955 // If we don't have texture swizzle support then the shader generator must insert the
1956 // swizzle into shader code.
1957 if (!this->textureSwizzleSupport()) {
1958 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001959 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001960 }
1961 }
1962
bsalomon7f9b2e42016-01-12 13:29:26 -08001963 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1964 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1965 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001966 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001967 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1968 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1969 if (GrPixelConfigIsAlphaOnly(config) &&
1970 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001971 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001972 }
1973 }
1974 }
1975
Greg Daniel81e7bf82017-07-19 14:47:42 -04001976 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1977 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001978 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1979 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001980 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001981 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1982 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001983 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001984 int count;
1985 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1986 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1987 1, &count);
1988 if (count) {
1989 int* temp = new int[count];
1990 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1991 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001992 // GL has a concept of MSAA rasterization with a single sample but we do not.
1993 if (count && temp[count - 1] == 1) {
1994 --count;
1995 SkASSERT(!count || temp[count -1] > 1);
1996 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001997 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001998 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04001999 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002000 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002001 for (int j = 0; j < count; ++j) {
2002 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2003 }
2004 delete[] temp;
2005 }
2006 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002007 // Fake out the table using some semi-standard counts up to the max allowed sample
2008 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002009 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002010 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2011 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2012 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2013 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2014 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002015 // Chrome has a mock GL implementation that returns 0.
2016 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002017
Brian Salomonbdecacf2018-02-02 20:32:49 -05002018 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002019 int count = SK_ARRAY_COUNT(kDefaultSamples);
2020 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002021 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002022 break;
2023 }
2024 }
2025 if (count > 0) {
2026 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2027 }
2028 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002029 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2030 fConfigTable[i].fColorSampleCounts.setCount(1);
2031 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002032 }
2033 }
2034
bsalomon30447372015-12-21 09:03:05 -08002035#ifdef SK_DEBUG
2036 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002037 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002038 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002039 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2040 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002041 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2042 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2043 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2044 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002045 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2046 fConfigTable[i].fFormats.fBaseInternalFormat);
2047 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002048 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002049 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2050 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2051 fConfigTable[i].fFormats.fExternalFormat[j]);
2052 }
2053 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002054 }
2055#endif
2056}
2057
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002058bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
2059 bool dstIsTextureable, bool dstIsGLTexture2D,
2060 GrSurfaceOrigin dstOrigin,
2061 GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
2062 bool srcIsTextureable, bool srcIsGLTexture2D,
2063 GrSurfaceOrigin srcOrigin) const {
2064 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2065 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2066 // many drivers would allow it to work, but ANGLE does not.
2067 if (kGLES_GrGLStandard == fStandard && this->bgraIsInternalFormat() &&
2068 (kBGRA_8888_GrPixelConfig == dstConfig || kBGRA_8888_GrPixelConfig == srcConfig)) {
2069 return false;
2070 }
2071
2072 // CopyTexSubImage is invalid or doesn't copy what we want when we have msaa render buffers.
2073 if (dstHasMSAARenderBuffer || srcHasMSAARenderBuffer) {
2074 return false;
2075 }
2076
2077 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
2078 // texture.
2079 if (!dstIsTextureable) {
2080 return false;
2081 }
2082
2083 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
2084 // is required
2085 if (this->canConfigBeFBOColorAttachment(srcConfig) &&
2086 (!srcIsTextureable || srcIsGLTexture2D) &&
2087 dstIsGLTexture2D &&
2088 dstOrigin == srcOrigin) {
2089 return true;
2090 } else {
2091 return false;
2092 }
2093}
2094
2095bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
2096 bool dstIsTextureable, bool dstIsGLTexture2D,
2097 GrSurfaceOrigin dstOrigin,
2098 GrPixelConfig srcConfig, int srcSampleCnt,
2099 bool srcIsTextureable, bool srcIsGLTexture2D,
2100 GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
2101 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
2102 auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
2103 if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
2104 !this->canConfigBeFBOColorAttachment(srcConfig)) {
2105 return false;
2106 }
2107
2108 if (dstIsTextureable && !dstIsGLTexture2D) {
2109 return false;
2110 }
2111 if (srcIsTextureable && !srcIsGLTexture2D) {
2112 return false;
2113 }
2114
2115 if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
2116 return false;
2117 }
2118 if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
2119 // We would mirror to compensate for origin changes. Note that copySurface is
2120 // specified such that the src and dst rects are the same.
2121 if (dstOrigin != srcOrigin) {
2122 return false;
2123 }
2124 }
2125
2126 if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
2127 if (srcSampleCnt > 1) {
2128 if (1 == dstSampleCnt) {
2129 return false;
2130 }
2131 if (SkRect::Make(srcRect) != srcBounds) {
2132 return false;
2133 }
2134 }
2135 }
2136
2137 if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) {
2138 if (dstSampleCnt > 1) {
2139 return false;
2140 }
2141 }
2142
2143 if (GrGLCaps::kNoFormatConversion_BlitFramebufferFlag & blitFramebufferFlags) {
2144 if (dstConfig != srcConfig) {
2145 return false;
2146 }
2147 } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2148 if (srcSampleCnt > 1 && dstConfig != srcConfig) {
2149 return false;
2150 }
2151 }
2152
2153 if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) {
2154 if (srcSampleCnt > 1) {
2155 if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
2156 return false;
2157 }
2158 if (dstOrigin != srcOrigin) {
2159 return false;
2160 }
2161 }
2162 }
2163 return true;
2164}
2165
2166bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
2167 return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
2168}
2169
2170static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
2171 const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
2172 if (!rt) {
2173 return false;
2174 }
2175 // A RT has a separate MSAA renderbuffer if:
2176 // 1) It's multisampled
2177 // 2) We're using an extension with separate MSAA renderbuffers
2178 // 3) It's not FBO 0, which is special and always auto-resolves
2179 return rt->numColorSamples() > 1 &&
2180 glCaps.usesMSAARenderBuffers() &&
2181 !rt->rtPriv().glRTFBOIDIs0();
2182}
2183
Brian Salomonc67c31c2018-12-06 10:00:03 -05002184bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
2185 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002186 GrSurfaceOrigin dstOrigin = dst->origin();
2187 GrSurfaceOrigin srcOrigin = src->origin();
2188
2189 GrPixelConfig dstConfig = dst->config();
2190 GrPixelConfig srcConfig = src->config();
2191
2192 int dstSampleCnt = 0;
2193 int srcSampleCnt = 0;
2194 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
2195 dstSampleCnt = rtProxy->numColorSamples();
2196 }
2197 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
2198 srcSampleCnt = rtProxy->numColorSamples();
2199 }
2200 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
2201 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
2202
2203 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
2204 // swizzle.
2205 if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
2206 this->shaderCaps()->configOutputSwizzle(dst->config())) {
2207 return false;
2208 }
2209
2210 const GrTextureProxy* dstTex = dst->asTextureProxy();
2211 const GrTextureProxy* srcTex = src->asTextureProxy();
2212
Brian Salomonfd98c2c2018-07-31 17:25:29 -04002213 bool dstIsTex2D = dstTex ? (dstTex->textureType() == GrTextureType::k2D) : false;
2214 bool srcIsTex2D = srcTex ? (srcTex->textureType() == GrTextureType::k2D) : false;
Greg Daniel26dbe3b2018-05-03 10:35:42 -04002215
2216 // One of the possible requirements for copy as blit is that the srcRect must match the bounds
2217 // of the src surface. If we have a approx fit surface we can't know for sure what the src
2218 // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
2219 // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
2220 // know we will at least be able to do it as a draw.
2221#ifdef SK_DEBUG
2222 if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2223 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2224 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
2225 !src->priv().isExact()) {
2226 SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
2227 }
2228#endif
2229
2230 return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
2231 SkToBool(dstTex), dstIsTex2D, dstOrigin,
2232 srcConfig, has_msaa_render_buffer(src, *this),
2233 SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
2234 this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
2235 dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
2236 srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
2237 dstPoint) ||
2238 this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
2239}
2240
Robert Phillipsbf25d432017-04-07 10:08:53 -04002241bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002242 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2243 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002244 // By default, we don't require rects to match.
2245 *rectsMustMatch = false;
2246
2247 // By default, we allow subrects.
2248 *disallowSubrect = false;
2249
Brian Salomon467921e2017-03-06 16:17:12 -05002250 // If the src is a texture, we can implement the blit as a draw assuming the config is
2251 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002252 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002253 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002254 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2255 desc->fConfig = src->config();
2256 return true;
2257 }
2258
Robert Phillipsbf25d432017-04-07 10:08:53 -04002259 {
2260 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2261 // wrapped. In that case the proxy would already be instantiated.
Brian Salomonfd98c2c2018-07-31 17:25:29 -04002262 const GrTexture* srcTexture = src->peekTexture();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002263 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2264 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2265 // Not supported for FBO blit or CopyTexSubImage
2266 return false;
2267 }
Brian Salomon467921e2017-03-06 16:17:12 -05002268 }
2269
2270 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2271 // possible and we return false to fallback to creating a render target dst for render-to-
2272 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2273 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002274 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002275 bool rectsMustMatchForBlitFramebuffer = false;
2276 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002277 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002278 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2279 rectsMustMatchForBlitFramebuffer = true;
2280 disallowSubrectForBlitFramebuffer = true;
2281 // Mirroring causes rects to mismatch later, don't allow it.
2282 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002283 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2284 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002285 rectsMustMatchForBlitFramebuffer = true;
2286 // Mirroring causes rects to mismatch later, don't allow it.
2287 originForBlitFramebuffer = src->origin();
2288 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002289 originForBlitFramebuffer = src->origin();
2290 }
2291
2292 // Check for format issues with glCopyTexSubImage2D
2293 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2294 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2295 // then we set up for that, otherwise fail.
2296 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002297 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002298 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002299 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2300 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002301 return true;
2302 }
2303 return false;
2304 }
2305
Robert Phillipsbf25d432017-04-07 10:08:53 -04002306 {
Brian Salomon63e79732017-05-15 21:23:13 -04002307 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2308 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002309 if (srcIsMSAARenderbuffer) {
2310 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2311 // blit or fail.
2312 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002313 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002314 desc->fConfig = src->config();
2315 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2316 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2317 return true;
2318 }
2319 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002320 }
Brian Salomon467921e2017-03-06 16:17:12 -05002321 }
2322
2323 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002324 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002325 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002326 desc->fFlags = kNone_GrSurfaceFlags;
2327 return true;
2328}
2329
Greg Daniel691f5e72018-02-28 14:21:34 -05002330void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2331 const GrContextOptions& contextOptions,
2332 GrShaderCaps* shaderCaps) {
Brian Salomondc829942018-10-23 16:07:24 -04002333 bool isX86PowerVRRogue = false;
2334#if defined(SK_CPU_X86)
2335 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2336 isX86PowerVRRogue = true;
2337 }
2338#endif
2339
Brian Salomon01b476a2018-01-23 11:06:41 -05002340 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2341 // Thus we are blacklisting this extension for now on Adreno4xx devices.
Chris Dalton1214be92018-06-28 19:06:27 -06002342 if (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
2343 kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer() ||
Adrienne Walker0e383942018-05-15 11:33:47 -07002344 fDriverBugWorkarounds.disable_discard_framebuffer) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002345 fDiscardRenderTargetSupport = false;
2346 fInvalidateFBType = kNone_InvalidateFBType;
2347 }
2348
2349 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2350 // 340.96 and 367.57.
2351 if (kGL_GrGLStandard == ctxInfo.standard() &&
2352 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002353 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002354 fClearTextureSupport = false;
2355 }
2356
Brian Salomondc829942018-10-23 16:07:24 -04002357 // Calling glClearTexImage crashes on the NexusPlayer. TODO: Use isX86PowerVRRogue?
Brian Salomon01b476a2018-01-23 11:06:41 -05002358 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2359 fClearTextureSupport = false;
2360 }
2361
Brian Salomon01b476a2018-01-23 11:06:41 -05002362#ifdef SK_BUILD_FOR_MAC
Chris Dalton6989ba42018-10-03 10:34:09 -06002363 // Radeon MacBooks hit a crash in glReadPixels() when using geometry shaders.
2364 // http://skbug.com/8097
2365 if (kATI_GrGLVendor == ctxInfo.vendor()) {
2366 shaderCaps->fGeometryShaderSupport = false;
Brian Salomon01b476a2018-01-23 11:06:41 -05002367 }
Chris Dalton6989ba42018-10-03 10:34:09 -06002368 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2369 shaderCaps->fGSInvocationsSupport = false;
Brian Salomon01b476a2018-01-23 11:06:41 -05002370#endif
2371
2372 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2373 // shaders. @127.0 is the earliest verified driver to not crash.
2374 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002375 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002376 shaderCaps->fGeometryShaderSupport = false;
2377 }
2378
2379#if defined(__has_feature)
2380#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2381 // See skbug.com/7058
2382 fMapBufferType = kNone_MapBufferType;
2383 fMapBufferFlags = kNone_MapFlags;
2384#endif
2385#endif
2386
2387 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2388 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2389 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2390 // unclear whether this really affects a wide range of devices.
2391 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002392 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002393 fMapBufferType = kNone_MapBufferType;
2394 fMapBufferFlags = kNone_MapFlags;
2395 }
2396
2397 // TODO: re-enable for ANGLE
2398 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2399 fTransferBufferType = kNone_TransferBufferType;
2400 }
2401
2402 // Using MIPs on this GPU seems to be a source of trouble.
2403 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2404 fMipMapSupport = false;
2405 }
2406
Brian Salomondc829942018-10-23 16:07:24 -04002407 // TODO: Use isX86PowerVRRogue?
Brian Salomon01b476a2018-01-23 11:06:41 -05002408 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2409 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2410 // around a driver bug related to gl_FragCoord.
2411 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2412 fMaxClipAnalyticFPs = 0;
2413 }
2414
2415#ifndef SK_BUILD_FOR_IOS
2416 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2417 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2418 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2419 ctxInfo.driver() != kChromium_GrGLDriver)) {
2420 fUseDrawToClearColor = true;
2421 }
2422#endif
2423
2424 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2425 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2426 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2427 fUseDrawToClearColor = true;
2428 }
2429
2430#ifdef SK_BUILD_FOR_MAC
2431 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2432 // full screen clears
2433 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2434 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002435 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2436 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2437 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2438 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002439 fUseDrawToClearColor = true;
2440 }
2441#endif
2442
2443 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2444 // bugs seems to involve clearing too much and not skipping the clear.
2445 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2446 // but only for D3D11 ANGLE.
2447 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2448 fUseDrawToClearColor = true;
2449 }
2450
Chris Dalton1214be92018-06-28 19:06:27 -06002451 if (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
2452 kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002453 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002454 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002455 fUseDrawToClearStencilClip = true;
2456 }
2457 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2458 }
2459
Adrienne Walker94f585e2018-05-15 11:47:07 -07002460 if (fDriverBugWorkarounds.gl_clear_broken) {
2461 fUseDrawToClearColor = true;
2462 fUseDrawToClearStencilClip = true;
2463 }
2464
Brian Salomon01b476a2018-01-23 11:06:41 -05002465 // This was reproduced on the following configurations:
2466 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2467 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2468 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2469 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2470 // and not produced on:
2471 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2472 // The particular lines that get dropped from test images varies across different devices.
2473 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002474 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002475 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2476 }
2477
Brian Osman1348ed02018-09-12 09:08:39 -04002478 // This was reproduced on a Pixel 1, but the unit test + config + options that exercise it are
2479 // only tested on very specific bots. The driver claims that ReadPixels is an invalid operation
2480 // when reading from an auto-resolving MSAA framebuffer that has stencil attached.
2481 if (kQualcomm_GrGLDriver == ctxInfo.driver()) {
2482 fDetachStencilFromMSAABuffersBeforeReadPixels = true;
2483 }
2484
Brian Salomondc829942018-10-23 16:07:24 -04002485 // TODO: Don't apply this on iOS?
Brian Salomon01b476a2018-01-23 11:06:41 -05002486 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
Chris Dalton1b4ad762018-10-04 11:58:09 -06002487 // Our Chromebook with kPowerVRRogue_GrGLRenderer crashes on large instanced draws. The
2488 // current minimum number of instances observed to crash is somewhere between 2^14 and 2^15.
2489 // Keep the number of instances below 1000, just to be safe.
2490 fMaxInstancesPerDrawWithoutCrashing = 999;
Adrienne Walker001cae02018-05-15 11:38:44 -07002491 } else if (fDriverBugWorkarounds.disallow_large_instanced_draw) {
Chris Dalton1b4ad762018-10-04 11:58:09 -06002492 fMaxInstancesPerDrawWithoutCrashing = 0x4000000;
Brian Salomon01b476a2018-01-23 11:06:41 -05002493 }
2494
2495 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002496 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002497 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2498 fUseDrawInsteadOfAllRenderTargetWrites = true;
2499 }
2500
Brian Salomon01b476a2018-01-23 11:06:41 -05002501#ifdef SK_BUILD_FOR_MAC
2502 static constexpr bool isMAC = true;
2503#else
2504 static constexpr bool isMAC = false;
2505#endif
2506
2507 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2508 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2509 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2510 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2511 if (fMipMapLevelAndLodControlSupport &&
2512 (contextOptions.fDoManualMipmapping ||
2513 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2514 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2515 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2516 fDoManualMipmapping = true;
2517 }
2518
2519 // See http://crbug.com/710443
2520#ifdef SK_BUILD_FOR_MAC
2521 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2522 fClearToBoundaryValuesIsBroken = true;
2523 }
2524#endif
2525 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2526 fDrawArraysBaseVertexIsBroken = true;
2527 }
2528
Brian Salomon01b476a2018-01-23 11:06:41 -05002529 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2530 // Galaxy S7.
2531 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2532 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2533 shaderCaps->fFBFetchSupport = false;
2534 }
2535
Brian Salomon01b476a2018-01-23 11:06:41 -05002536 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2537 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2538
2539 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2540 // function that may require a gradient calculation inside a conditional block may return
2541 // undefined results". This appears to be an issue with the 'any' call since even the simple
2542 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2543 // from our GrTextureDomain processor.
2544 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2545
2546 // Known issue on at least some Intel platforms:
2547 // http://code.google.com/p/skia/issues/detail?id=946
2548 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2549 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2550 }
2551
Chris Dalton0090ef62018-03-28 17:35:00 -06002552 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002553 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2554 // so we must do the abs first in a separate expression.
2555 shaderCaps->fCanUseMinAndAbsTogether = false;
2556
2557 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2558 // must avoid this condition.
2559 shaderCaps->fCanUseFractForNegativeValues = false;
2560 }
2561
2562 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2563 // thus must us -1.0 * %s.x to work correctly
2564 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2565 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2566 }
2567
2568 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2569 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2570 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2571 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2572 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2573 }
2574
2575 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2576 // the original dst color when reading the outColor even after being written to. By using a
2577 // local outColor we can work around this bug.
2578 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2579 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2580 }
2581
2582 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2583 // color, and that uniform contains an opaque color, and the output of the shader is only based
2584 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2585 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2586 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2587 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2588 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2589 shaderCaps->fMustObfuscateUniformColor = true;
2590 }
2591#ifdef SK_BUILD_FOR_WIN
2592 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2593 //
2594 // Basically, if a shader has a construct like:
2595 //
2596 // float x = someCondition ? someValue : 0;
2597 // float2 result = (0 == x) ? float2(x, x)
2598 // : float2(2 * x / x, 0);
2599 //
2600 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2601 // we've explicitly guarded the division with a check against zero. This manifests in much
2602 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2603 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2604 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2605 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2606 }
2607#endif
2608
2609 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
Michael Ludwig5e1f6ea2018-12-03 15:14:50 -05002610 // (rare) situations. It's sporadic, and mostly on older drivers. Additionally, old Adreno
2611 // compilers (see crbug.com/skia/4078) crash when accessing .zw of gl_FragCoord, so just bypass
2612 // using gl_FragCoord at all to get around it.
Brian Salomon01b476a2018-01-23 11:06:41 -05002613 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2614 shaderCaps->fCanUseFragCoord = false;
Brian Salomon01b476a2018-01-23 11:06:41 -05002615 }
2616
Chris Dalton0090ef62018-03-28 17:35:00 -06002617 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2618 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2619 shaderCaps->fCanUseFragCoord = false;
2620 }
2621
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002622 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2623 // (Are they implemented with fp16?)
2624 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2625 shaderCaps->fIncompleteShortIntPrecision = true;
2626 }
2627
Adrienne Walkeree8295c2018-08-21 10:56:30 -07002628 if (fDriverBugWorkarounds.add_and_true_to_loop_condition) {
2629 shaderCaps->fAddAndTrueToLoopCondition = true;
2630 }
2631
Adrienne Walkerc02165f2018-08-21 11:08:11 -07002632 if (fDriverBugWorkarounds.unfold_short_circuit_as_ternary_operation) {
2633 shaderCaps->fUnfoldShortCircuitAsTernary = true;
2634 }
2635
Adrienne Walker92b161f2018-08-22 10:41:52 -07002636 if (fDriverBugWorkarounds.emulate_abs_int_function) {
2637 shaderCaps->fEmulateAbsIntFunction = true;
2638 }
2639
Adrienne Walker8b23ca62018-08-22 10:45:41 -07002640 if (fDriverBugWorkarounds.rewrite_do_while_loops) {
2641 shaderCaps->fRewriteDoWhileLoops = true;
2642 }
2643
Adrienne Walker2f4c09b2018-08-22 16:04:57 -07002644 if (fDriverBugWorkarounds.remove_pow_with_constant_exponent) {
2645 shaderCaps->fRemovePowWithConstantExponent = true;
2646 }
2647
Brian Salomon01b476a2018-01-23 11:06:41 -05002648 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2649 // for now until its own blacklists can be updated.
Chris Dalton1214be92018-06-28 19:06:27 -06002650 if (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||
2651 kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer() ||
Brian Salomon01b476a2018-01-23 11:06:41 -05002652 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2653 kIntel_GrGLDriver == ctxInfo.driver() ||
2654 kChromium_GrGLDriver == ctxInfo.driver()) {
2655 fBlendEquationSupport = kBasic_BlendEquationSupport;
2656 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2657 }
2658
2659 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2660 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002661 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002662 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002663 fBlendEquationSupport = kBasic_BlendEquationSupport;
2664 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2665 }
2666
Adrienne Walker68314842018-05-14 14:02:53 -07002667 if (fDriverBugWorkarounds.disable_blend_equation_advanced) {
2668 fBlendEquationSupport = kBasic_BlendEquationSupport;
2669 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2670 }
2671
Brian Salomon01b476a2018-01-23 11:06:41 -05002672 if (this->advancedBlendEquationSupport()) {
2673 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002674 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002675 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2676 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2677 (1 << kColorBurn_GrBlendEquation);
2678 }
2679 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2680 // Blacklist color-burn on ARM until the fix is released.
2681 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2682 }
2683 }
2684
2685 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2686 if (fMultisampleDisableSupport &&
2687 this->shaderCaps()->dualSourceBlendingSupport() &&
2688 this->shaderCaps()->pathRenderingSupport() &&
2689 fUsesMixedSamples &&
2690#if GR_TEST_UTILS
2691 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2692#endif
2693 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2694 kChromium_GrGLDriver == ctxInfo.driver())) {
2695 fDiscardRenderTargetSupport = false;
2696 fInvalidateFBType = kNone_InvalidateFBType;
2697 }
Brian Osmanc585e202018-04-04 14:08:27 -04002698
Brian Osman061020e2018-04-17 14:22:15 -04002699 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2700 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2701 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2702 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002703 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2704 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002705 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002706 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002707 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2708 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002709 }
Brian Osman2fa53742018-05-03 15:05:12 -04002710
2711#ifdef SK_BUILD_FOR_IOS
2712 // iOS drivers appear to implement TexSubImage by creating a staging buffer, and copying
2713 // UNPACK_ROW_LENGTH * height bytes. That's unsafe in several scenarios, and the simplest fix
2714 // is to just blacklist the feature.
2715 // https://github.com/flutter/flutter/issues/16718
2716 // https://bugreport.apple.com/web/?problemID=39948888
2717 fUnpackRowLengthSupport = false;
2718#endif
Brian Salomondc829942018-10-23 16:07:24 -04002719
2720 if (isX86PowerVRRogue) {
2721 // On Nexus Player we get incorrect filter modes when using sampler objects.
2722 fSamplerObjectSupport = false;
2723 }
Chris Dalton32262da2018-11-05 17:18:42 +00002724
2725 // CCPR edge AA is busted on Mesa, Sandy Bridge/Bay Trail.
2726 // http://skbug.com/8162
2727 if (kMesa_GrGLDriver == ctxInfo.driver() &&
2728 (kIntelSandyBridge_GrGLRenderer == ctxInfo.renderer() ||
2729 kIntelBayTrail_GrGLRenderer == ctxInfo.renderer())) {
2730 fBlacklistCoverageCounting = true;
2731 }
Brian Salomonb4f37a62018-11-20 08:50:56 -05002732
Brian Salomonfc06f982018-11-27 13:04:21 -05002733#ifdef SK_BUILD_FOR_ANDROID
Brian Salomonf3841932018-11-29 09:13:37 -05002734 // Older versions of Android have problems with setting GL_TEXTURE_BASE_LEVEL or
2735 // GL_TEXTURE_MAX_LEVEL on GL_TEXTURE_EXTERTNAL_OES textures. We just leave them as is and hope
2736 // the client never changes them either.
2737 fDontSetBaseOrMaxLevelForExternalTextures = true;
Brian Salomonfc06f982018-11-27 13:04:21 -05002738#endif
Brian Salomon01b476a2018-01-23 11:06:41 -05002739}
2740
csmartdaltone0d36292016-07-29 08:14:20 -07002741void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002742 if (options.fDisableDriverCorrectnessWorkarounds) {
2743 SkASSERT(!fDoManualMipmapping);
2744 SkASSERT(!fClearToBoundaryValuesIsBroken);
Chris Dalton1b4ad762018-10-04 11:58:09 -06002745 SkASSERT(0 == fMaxInstancesPerDrawWithoutCrashing);
Brian Salomon01b476a2018-01-23 11:06:41 -05002746 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2747 SkASSERT(!fUseDrawToClearColor);
2748 SkASSERT(!fUseDrawToClearStencilClip);
2749 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2750 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2751 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Brian Osman1348ed02018-09-12 09:08:39 -04002752 SkASSERT(!fDetachStencilFromMSAABuffersBeforeReadPixels);
Brian Salomon01b476a2018-01-23 11:06:41 -05002753 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002754 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2755 fUseDrawToClearColor = false;
2756 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2757 fUseDrawToClearColor = true;
2758 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002759 if (options.fDoManualMipmapping) {
2760 fDoManualMipmapping = true;
2761 }
csmartdaltone0d36292016-07-29 08:14:20 -07002762}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002763
Brian Salomonc67c31c2018-12-06 10:00:03 -05002764bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
Brian Salomon3d86a192018-02-27 16:46:11 -05002765 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2766 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2767 if (tex->hasBaseLevelBeenBoundToFBO()) {
2768 return false;
2769 }
2770 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002771 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002772 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2773 return false;
2774 }
2775 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2776 return false;
2777 }
2778 return SkToBool(surface->asTexture());
2779 }
2780 return true;
2781}
2782
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002783bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2784 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2785 // We don't support reading pixels directly from EXTERNAL textures as it would require
2786 // binding the texture to a FBO.
2787 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2788 return false;
2789 }
2790 }
2791 return true;
2792}
2793
2794GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2795 GrColorType dstColorType) const {
2796 // For now, we mostly report the read back format that is required by the ES spec without
2797 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2798 // this as makes sense to increase performance and correctness.
2799 switch (fConfigTable[config].fFormatType) {
2800 case kNormalizedFixedPoint_FormatType:
2801 return GrColorType::kRGBA_8888;
2802 case kFloat_FormatType:
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002803 if ((kAlpha_half_GrPixelConfig == config ||
2804 kAlpha_half_as_Red_GrPixelConfig == config) &&
2805 GrColorType::kAlpha_F16 == dstColorType) {
2806 return GrColorType::kAlpha_F16;
2807 }
2808 // And similar for full float RG.
2809 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2810 return GrColorType::kRG_F32;
2811 }
2812 return GrColorType::kRGBA_F32;
2813 }
2814 return GrColorType::kUnknown;
2815}
2816
Greg Daniel2a303902018-02-20 10:25:54 -05002817bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002818 GrGLFramebufferInfo fbInfo;
2819 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002820 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002821 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002822}
2823
Brian Salomonbdecacf2018-02-02 20:32:49 -05002824int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2825 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002826 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002827 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002828 return 0;
2829 }
2830
Brian Salomonbdecacf2018-02-02 20:32:49 -05002831 if (1 == requestedCount) {
2832 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2833 }
2834
Greg Daniel81e7bf82017-07-19 14:47:42 -04002835 for (int i = 0; i < count; ++i) {
2836 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
Adrienne Walkerd7c79782018-05-15 11:41:24 -07002837 int count = fConfigTable[config].fColorSampleCounts[i];
2838 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
2839 count = SkTMin(count, 4);
2840 }
2841 return count;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002842 }
2843 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002844 return 0;
2845}
2846
2847int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2848 const auto& table = fConfigTable[config].fColorSampleCounts;
2849 if (!table.count()) {
2850 return 0;
2851 }
Adrienne Walker3a69c742018-05-21 11:05:48 -07002852 int count = table[table.count() - 1];
2853 if (fDriverBugWorkarounds.max_msaa_sample_count_4) {
2854 count = SkTMin(count, 4);
2855 }
2856 return count;
Brian Salomond653cac2018-02-01 13:58:00 -05002857}
2858
Greg Danielfaa095e2017-12-19 13:15:02 -05002859bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2860 GrGLStandard standard) {
2861 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002862
2863 switch (ct) {
2864 case kUnknown_SkColorType:
2865 return false;
2866 case kAlpha_8_SkColorType:
2867 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002868 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002869 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002870 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002871 }
2872 break;
2873 case kRGB_565_SkColorType:
2874 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002875 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002876 }
2877 break;
2878 case kARGB_4444_SkColorType:
2879 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002880 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002881 }
2882 break;
2883 case kRGBA_8888_SkColorType:
2884 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002885 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002886 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002887 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002888 }
2889 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002890 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002891 if (GR_GL_RGB8 == format) {
2892 *config = kRGB_888_GrPixelConfig;
2893 }
2894 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002895 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002896 if (GR_GL_RGBA8 == format) {
2897 if (kGL_GrGLStandard == standard) {
2898 *config = kBGRA_8888_GrPixelConfig;
2899 }
2900 } else if (GR_GL_BGRA8 == format) {
2901 if (kGLES_GrGLStandard == standard) {
2902 *config = kBGRA_8888_GrPixelConfig;
2903 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002904 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002905 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002906 }
2907 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002908 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002909 if (GR_GL_RGB10_A2 == format) {
2910 *config = kRGBA_1010102_GrPixelConfig;
2911 }
2912 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002913 case kRGB_101010x_SkColorType:
2914 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002915 case kGray_8_SkColorType:
2916 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002917 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002918 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002919 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002920 }
2921 break;
2922 case kRGBA_F16_SkColorType:
2923 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002924 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002925 }
2926 break;
Mike Klein37854712018-06-26 11:43:06 -04002927 case kRGBA_F32_SkColorType:
2928 if (GR_GL_RGBA32F == format) {
2929 *config = kRGBA_float_GrPixelConfig;
2930 }
2931 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002932 }
2933
Greg Danielfaa095e2017-12-19 13:15:02 -05002934 return kUnknown_GrPixelConfig != *config;
2935}
2936
2937bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2938 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002939 GrGLTextureInfo texInfo;
2940 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002941 return false;
2942 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002943 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002944}
2945
2946bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2947 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002948 GrGLFramebufferInfo fbInfo;
2949 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002950 return false;
2951 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002952 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002953}
2954
Robert Phillipsfc711a22018-02-13 17:03:00 -05002955bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2956 GrPixelConfig* config) const {
2957 const GrGLenum* glFormat = format.getGLFormat();
2958 if (!glFormat) {
2959 return false;
2960 }
2961 return validate_sized_format(*glFormat, ct, config, fStandard);
2962}
Ravi Mistry35b40ce2018-05-30 20:54:40 +00002963
Jim Van Verth9bf81202018-10-30 15:53:36 -04002964static bool get_yuva_config(GrGLenum format, GrPixelConfig* config) {
2965 *config = kUnknown_GrPixelConfig;
Jim Van Verthb7f0b9c2018-10-22 14:12:03 -04002966
Jim Van Verth9bf81202018-10-30 15:53:36 -04002967 switch (format) {
Jim Van Verthb7f0b9c2018-10-22 14:12:03 -04002968 case GR_GL_ALPHA8:
2969 *config = kAlpha_8_as_Alpha_GrPixelConfig;
2970 break;
2971 case GR_GL_R8:
2972 *config = kAlpha_8_as_Red_GrPixelConfig;
2973 break;
Jim Van Verth69e57852018-12-05 13:38:59 -05002974 case GR_GL_RG8:
2975 *config = kRG_88_GrPixelConfig;
2976 break;
Jim Van Verthb7f0b9c2018-10-22 14:12:03 -04002977 case GR_GL_RGBA8:
2978 *config = kRGBA_8888_GrPixelConfig;
2979 break;
2980 case GR_GL_RGB8:
2981 *config = kRGB_888_GrPixelConfig;
2982 break;
2983 case GR_GL_BGRA8:
2984 *config = kBGRA_8888_GrPixelConfig;
2985 break;
2986 default:
2987 return false;
2988 }
2989
2990 return true;
2991}
2992
Jim Van Verth9bf81202018-10-30 15:53:36 -04002993bool GrGLCaps::getYUVAConfigFromBackendTexture(const GrBackendTexture& tex,
2994 GrPixelConfig* config) const {
2995 GrGLTextureInfo texInfo;
2996 if (!tex.getGLTextureInfo(&texInfo)) {
2997 return false;
2998 }
2999 return get_yuva_config(texInfo.fFormat, config);
3000}
3001
3002bool GrGLCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
3003 GrPixelConfig* config) const {
3004 const GrGLenum* glFormat = format.getGLFormat();
3005 if (!glFormat) {
3006 return false;
3007 }
3008 return get_yuva_config(*glFormat, config);
3009}
3010
Timothy Liang036fdfe2018-06-28 15:50:36 -04003011GrBackendFormat GrGLCaps::onCreateFormatFromBackendTexture(
3012 const GrBackendTexture& backendTex) const {
3013 GrGLTextureInfo glInfo;
3014 SkAssertResult(backendTex.getGLTextureInfo(&glInfo));
3015 return GrBackendFormat::MakeGL(glInfo.fFormat, glInfo.fTarget);
3016}
Greg Daniel4065d452018-11-16 15:43:41 -05003017
3018GrBackendFormat GrGLCaps::getBackendFormatFromGrColorType(GrColorType ct,
3019 GrSRGBEncoded srgbEncoded) const {
3020 GrPixelConfig config = GrColorTypeToPixelConfig(ct, srgbEncoded);
3021 if (config == kUnknown_GrPixelConfig) {
3022 return GrBackendFormat();
3023 }
3024 return GrBackendFormat::MakeGL(this->configSizedInternalFormat(config), GR_GL_TEXTURE_2D);
3025}
3026