blob: b8ddebc6ee40c6c959e475b2d0ad99d86eec2725 [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"
Brian Salomon94efbf52016-11-29 13:43:05 -050013#include "GrShaderCaps.h"
Robert Phillipsbf25d432017-04-07 10:08:53 -040014#include "GrSurfaceProxyPriv.h"
Brian Osman71a18892017-08-10 10:23:25 -040015#include "SkJSONWriter.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000016#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000017#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000018
bsalomon682c2692015-05-22 14:01:46 -070019GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
20 const GrGLContextInfo& ctxInfo,
21 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080022 fStandard = ctxInfo.standard();
23
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000024 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000026 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000027 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080028 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000029 fMaxFragmentUniformVectors = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000030 fUnpackRowLengthSupport = false;
31 fUnpackFlipYSupport = false;
32 fPackRowLengthSupport = false;
33 fPackFlipYSupport = false;
34 fTextureUsageSupport = false;
Robert Phillips5ab72762017-06-07 12:04:18 -040035 fAlpha8IsRenderable = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000036 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000037 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070038 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080039 fES2CompatibilitySupport = false;
cdalton06604b92016-02-05 10:09:51 -080040 fDrawIndirectSupport = false;
41 fMultiDrawIndirectSupport = false;
42 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000043 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070044 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080045 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080046 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070047 fRGBA8888PixelsOpsAreSlow = false;
48 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080049 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080050 fRGBAToBGRAReadbackConversionsAreSlow = false;
Robert Phillipsf2ec0242018-03-01 16:51:25 -050051 fUseBufferDataNullHint = SkToBool(GR_GL_USE_BUFFER_DATA_NULL_HINT);
brianosman09563ce2016-06-02 08:59:34 -070052 fDoManualMipmapping = false;
brianosman851c2382016-12-07 10:03:25 -080053 fSRGBDecodeDisableAffectsMipmaps = false;
Eric Karlaeaf22b2017-05-18 15:08:09 -070054 fClearToBoundaryValuesIsBroken = false;
Brian Salomond17b4a62017-05-23 16:53:47 -040055 fClearTextureSupport = false;
Chris Dalton9926f4b2017-05-17 15:15:50 -060056 fDrawArraysBaseVertexIsBroken = false;
Brian Salomon43f8bf02017-10-18 08:33:29 -040057 fUseDrawToClearColor = false;
Mike Klein31550db2017-06-06 23:29:53 +000058 fUseDrawToClearStencilClip = false;
Brian Salomon9bada542017-06-12 12:09:30 -040059 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = false;
60 fUseDrawInsteadOfAllRenderTargetWrites = false;
Brian Salomon6d9c88b2017-06-12 10:24:42 -040061 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050062 fProgramBinarySupport = false;
piotaixre4b23142014-10-02 10:57:53 -070063
Brian Salomone5e7eb12016-10-14 16:18:33 -040064 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060065 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080066
Brian Salomon94efbf52016-11-29 13:43:05 -050067 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070068
cdalton4cd67132015-06-10 19:23:46 -070069 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000070}
71
cdalton4cd67132015-06-10 19:23:46 -070072void GrGLCaps::init(const GrContextOptions& contextOptions,
73 const GrGLContextInfo& ctxInfo,
74 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000075 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000076 GrGLVersion version = ctxInfo.version();
77
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000078 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000079 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
80 &fMaxFragmentUniformVectors);
81 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000082 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000083 GrGLint max;
84 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
85 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000086 if (version >= GR_GL_VER(3, 2)) {
87 GrGLint profileMask;
88 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
89 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
90 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000091 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000092 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000093
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000094 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000095 fUnpackRowLengthSupport = true;
96 fUnpackFlipYSupport = false;
97 fPackRowLengthSupport = true;
98 fPackFlipYSupport = false;
99 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000100 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
101 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000102 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000103 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
104 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000105 fPackFlipYSupport =
106 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
107 }
108
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000109 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000110 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
111
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000112 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700113 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
114 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
115 ctxInfo.hasExtension("GL_NV_texture_barrier");
116 } else {
117 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
118 }
119
Robert Phillips7f861922018-01-30 13:13:42 +0000120 if (kGL_GrGLStandard == standard) {
121 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
122 ctxInfo.hasExtension("GL_ARB_texture_multisample");
123 } else {
124 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
125 }
126
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000127 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000128 ctxInfo.hasExtension("GL_ARB_imaging");
129
Brian Salomon01b476a2018-01-23 11:06:41 -0500130 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700131 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
132 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000133 fDiscardRenderTargetSupport = true;
134 fInvalidateFBType = kInvalidate_InvalidateFBType;
135 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
136 fDiscardRenderTargetSupport = true;
137 fInvalidateFBType = kDiscard_InvalidateFBType;
138 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000139
Chris Dalton27059d32018-01-23 14:06:50 -0700140 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
141 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
142 if (kGLES_GrGLStandard == standard) {
143 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
144 // TODO: Evaluate on PowerVR.
145 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
146 if (kARM_GrGLVendor == ctxInfo.vendor()) {
147 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
148 }
149 }
150
Chris Dalton344e9032017-12-11 15:42:09 -0700151 if (kARM_GrGLVendor == ctxInfo.vendor() ||
152 kImagination_GrGLVendor == ctxInfo.vendor() ||
153 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
154 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000155 }
156
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000157 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000158 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800159 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
160 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000161 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000162 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
163 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000164 }
165
cdalton626e1ff2015-06-12 13:56:46 -0700166 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
167 fDebugSupport = true;
168 } else {
169 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
170 }
171
jvanverth3f801cb2014-12-16 09:49:38 -0800172 if (kGL_GrGLStandard == standard) {
173 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
174 }
175 else {
176 fES2CompatibilitySupport = true;
177 }
178
cdalton0edea2c2015-05-21 08:27:44 -0700179 if (kGL_GrGLStandard == standard) {
180 fMultisampleDisableSupport = true;
181 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700182 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700183 }
184
kkinnunend94708e2015-07-30 22:47:04 -0700185 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600186 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
187 // instanced arrays, but we could make this more granular if we wanted
188 fInstanceAttribSupport =
189 version >= GR_GL_VER(3, 2) ||
190 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
191 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
192 } else {
193 fInstanceAttribSupport =
194 version >= GR_GL_VER(3, 0) ||
195 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
196 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
197 }
198
199 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700200 if (version >= GR_GL_VER(3, 0)) {
201 fBindFragDataLocationSupport = true;
202 }
203 } else {
204 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
205 fBindFragDataLocationSupport = true;
206 }
joshualittc1f56b52015-06-22 12:31:31 -0700207 }
208
joshualitt7bdd70a2015-10-01 06:28:11 -0700209 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
210
kkinnunene06ed252016-02-16 23:15:40 -0800211 if (kGL_GrGLStandard == standard) {
212 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
213 // We also require textureSize() support for rectangle 2D samplers which was added in
214 // GLSL 1.40.
215 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
216 fRectangleTextureSupport = true;
217 }
bsalomone179a912016-01-20 06:18:10 -0800218 }
kkinnunene06ed252016-02-16 23:15:40 -0800219 } else {
220 // Command buffer exposes this in GL ES context for Chromium reasons,
221 // but it should not be used. Also, at the time of writing command buffer
222 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800223 }
224
bsalomoncdee0092016-01-08 13:20:12 -0800225 if (kGL_GrGLStandard == standard) {
226 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
227 fTextureSwizzleSupport = true;
228 }
229 } else {
230 if (version >= GR_GL_VER(3,0)) {
231 fTextureSwizzleSupport = true;
232 }
233 }
234
cblume09bd2c02016-03-01 14:08:28 -0800235 if (kGL_GrGLStandard == standard) {
236 fMipMapLevelAndLodControlSupport = true;
237 } else if (kGLES_GrGLStandard == standard) {
238 if (version >= GR_GL_VER(3,0)) {
239 fMipMapLevelAndLodControlSupport = true;
240 }
241 }
242
bsalomon88c7b982015-07-31 11:20:16 -0700243#ifdef SK_BUILD_FOR_WIN
244 // We're assuming that on Windows Chromium we're using ANGLE.
245 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
246 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700247 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700248 fRGBA8888PixelsOpsAreSlow = isANGLE;
249 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
250 // check DX11 ANGLE.
251 fPartialFBOReadIsSlow = isANGLE;
252#endif
253
ericrkb4ecabd2016-03-11 15:18:20 -0800254 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
255 bool isMAC = false;
256#ifdef SK_BUILD_FOR_MAC
257 isMAC = true;
258#endif
259
260 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
261 // vis-versa.
262 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
263
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500264 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
265 fUseBufferDataNullHint = false;
266 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
267 fUseBufferDataNullHint = true;
268 }
269
Brian Salomond17b4a62017-05-23 16:53:47 -0400270 if (kGL_GrGLStandard == standard) {
271 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400272 fClearTextureSupport = true;
273 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500274 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
275 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400276 }
277
cdalton4cd67132015-06-10 19:23:46 -0700278 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700279 * GrShaderCaps fields
280 **************************************************************************/
281
egdaniel0a482332015-10-26 08:59:10 -0700282 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700283 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500284 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700285
Brian Osman195c05b2017-08-30 15:14:04 -0400286 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
287#if GR_TEST_UTILS
288 if (contextOptions.fSuppressPathRendering) {
289 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700290 }
Brian Osman195c05b2017-08-30 15:14:04 -0400291#endif
egdaniel05ded892015-10-26 07:38:05 -0700292
egdaniel05ded892015-10-26 07:38:05 -0700293 // Enable supported shader-related caps
294 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500295 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700296 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
297 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600298
Brian Salomon1edc5b92016-11-29 13:43:46 -0500299 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600300
egdaniel05ded892015-10-26 07:38:05 -0700301 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500302 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700303 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600304 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600305 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
306 shaderCaps->fGSInvocationsSupport = true;
307 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
308 shaderCaps->fGSInvocationsSupport = true;
309 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
310 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600311 }
312
Brian Salomon1edc5b92016-11-29 13:43:46 -0500313 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800314 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500315 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500316 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700317
Brian Salomon1edc5b92016-11-29 13:43:46 -0500318 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700319 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800320
Chris Daltonfaca00d2018-01-19 15:56:07 -0700321 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
322 // backup impl that only uses vertex shaders.
323 if (kARM_GrGLVendor != ctxInfo.vendor()) {
324 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
325 shaderCaps->fGeometryShaderSupport = true;
326 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
327 shaderCaps->fGeometryShaderSupport = true;
328 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
329 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700330 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500331 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700332
Brian Salomon1edc5b92016-11-29 13:43:46 -0500333 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800334 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700335 }
336
cdalton9c3f1432016-03-11 10:07:37 -0800337 // Protect ourselves against tracking huge amounts of texture state.
338 static const uint8_t kMaxSaneSamplers = 32;
339 GrGLint maxSamplers;
340 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500341 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
342 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800343 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500344 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800345 }
346 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500347 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800348 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500349 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800350
Brian Salomonbbf05752017-11-30 11:30:48 -0500351 // This is all *very* approximate.
352 switch (ctxInfo.vendor()) {
353 case kNVIDIA_GrGLVendor:
354 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
355 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
356 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
357 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500358 case kImagination_GrGLVendor:
359 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
360 // it is always a win to use multitexturing.
361 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
362 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
363 std::numeric_limits<size_t>::max();
364 }
365 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500366 case kATI_GrGLVendor:
367 // So far no AMD GPU shows a performance difference. A tie goes to disabling
368 // multitexturing for simplicity's sake.
369 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
370 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500371 default:
372 break;
373 }
374
csmartdalton485a1202016-07-13 10:16:32 -0700375 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
376 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
377 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
378 // limit this decision to specific GPU families rather than basing it on the vendor alone.
379 if (!GR_GL_MUST_USE_VBO &&
380 !fIsCoreProfile &&
381 (kARM_GrGLVendor == ctxInfo.vendor() ||
382 kImagination_GrGLVendor == ctxInfo.vendor() ||
383 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
384 fPreferClientSideDynamicBuffers = true;
385 }
386
Eric Karl5c779752017-05-08 12:02:07 -0700387 if (!contextOptions.fAvoidStencilBuffers) {
388 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
389 this->initFSAASupport(contextOptions, ctxInfo, gli);
390 this->initStencilSupport(ctxInfo);
391 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400392
393 // Setup blit framebuffer
394 if (kGL_GrGLStandard != ctxInfo.standard()) {
395 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
396 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
397 kNoMSAADst_BlitFramebufferFlag |
398 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
399 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
400 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
401 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
402 // limitations.
403 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
404 kResolveMustBeFull_BlitFrambufferFlag |
405 kNoMSAADst_BlitFramebufferFlag |
406 kNoFormatConversion_BlitFramebufferFlag |
407 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
408 }
409 } else {
410 if (fUsesMixedSamples ||
411 ctxInfo.version() >= GR_GL_VER(3,0) ||
412 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
413 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
414 fBlitFramebufferFlags = 0;
415 }
416 }
417
cdalton1dd05422015-06-12 09:01:18 -0700418 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000419
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000420 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000421 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
422 // extension includes glMapBuffer.
423 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
424 fMapBufferFlags |= kSubset_MapFlag;
425 fMapBufferType = kMapBufferRange_MapBufferType;
426 } else {
427 fMapBufferType = kMapBuffer_MapBufferType;
428 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000429 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000430 // Unextended GLES2 doesn't have any buffer mapping.
431 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800432 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800433 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
434 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800435 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
436 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
437 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000438 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
439 fMapBufferFlags = kCanMap_MapFlag;
440 fMapBufferType = kMapBuffer_MapBufferType;
441 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000442 }
443
jvanverthd7a2c1f2015-12-07 07:36:44 -0800444 if (kGL_GrGLStandard == standard) {
445 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
446 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700447 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500448 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400449 if (version >= GR_GL_VER(3, 0) ||
450 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
451 // GL_EXT_unpack_subimage needed to support subtexture rectangles
452 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800453 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400454// TODO: get transfer buffers working in Chrome
455// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
456// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800457 }
458 }
459
joshualitte5b74c62015-06-01 14:17:47 -0700460 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
461 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700462 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700463#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500464 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
465 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
466 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700467 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700468#else
cdalton397536c2016-03-25 12:15:03 -0700469 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700470#endif
joshualitte5b74c62015-06-01 14:17:47 -0700471 }
472
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000473 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000474 fNPOTTextureTileSupport = true;
475 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000476 } else {
477 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000478 // ES3 has no limitations.
479 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
480 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000481 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
482 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
483 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
484 // to alllow arbitrary wrap modes, however.
485 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000486 }
487
bsalomon@google.combcce8922013-03-25 15:38:39 +0000488 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
489 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
490 // Our render targets are always created with textures as the color
491 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000492 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700493 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
494
495 if (kARM_GrGLVendor == ctxInfo.vendor()) {
496 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
497 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
498 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000499
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000500 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
501
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000502 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700503 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000504
robertphillips1b8e1b52015-06-24 06:54:10 -0700505#if 0
506 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
507 kQualcomm_GrGLVendor != ctxInfo.vendor();
508#endif
509
csmartdalton9bc11872016-08-09 12:42:47 -0700510 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
511 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700512 }
513
robertphillips63926682015-08-20 09:39:02 -0700514#ifdef SK_BUILD_FOR_WIN
515 // On ANGLE deferring flushes can lead to GPU starvation
516 fPreferVRAMUseOverFlushes = !isANGLE;
517#endif
518
bsalomon7dea7b72015-08-19 08:26:51 -0700519 if (kChromium_GrGLDriver == ctxInfo.driver()) {
520 fMustClearUploadedBufferData = true;
521 }
522
bsalomond08ea5f2015-02-20 06:58:13 -0800523 if (kGL_GrGLStandard == standard) {
524 // ARB allows mixed size FBO attachments, EXT does not.
525 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
526 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
527 fOversizedStencilSupport = true;
528 } else {
529 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
530 }
531 } else {
532 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
533 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
534 }
535
joshualitt58001552015-06-26 12:46:36 -0700536 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700537 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
538 ctxInfo.hasExtension("GL_ARB_draw_indirect");
539 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
540 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700541 (fDrawIndirectSupport &&
542 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700543 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700544 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800545 } else {
546 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700547 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
548 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
549 fBaseInstanceSupport = fDrawIndirectSupport &&
550 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700551 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800552 }
553
ethannicholas28ef4452016-03-25 09:26:03 -0700554 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500555 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700556 fSampleShadingSupport = true;
557 }
558 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
559 fSampleShadingSupport = true;
560 }
561
jvanverth84741b32016-09-30 08:39:02 -0700562 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
563 if (kGL_GrGLStandard == standard) {
564 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
565 fFenceSyncSupport = true;
566 }
Brian Osman93a23462017-06-21 15:13:39 -0400567 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700568 fFenceSyncSupport = true;
569 }
570
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400571 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500572 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500573
brianosman20471892016-12-02 06:43:32 -0800574 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500575
brianosman851c2382016-12-07 10:03:25 -0800576 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
577 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800578
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400579 if (kGL_GrGLStandard == standard) {
580 if (version >= GR_GL_VER(4, 1)) {
581 fProgramBinarySupport = true;
582 }
583 } else if (version >= GR_GL_VER(3, 0)) {
584 fProgramBinarySupport = true;
585 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400586 if (fProgramBinarySupport) {
587 GrGLint count;
588 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
589 fProgramBinarySupport = count > 0;
590 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400591
bsalomoncdee0092016-01-08 13:20:12 -0800592 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
593 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800594 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700595
Brian Salomon01b476a2018-01-23 11:06:41 -0500596 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
597 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
598 }
599
cdalton4cd67132015-06-10 19:23:46 -0700600 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500601 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700602
Brian Salomon01b476a2018-01-23 11:06:41 -0500603 // For now these two are equivalent but we could have dst read in shader via some other method.
604 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000605}
606
egdaniel472d44e2015-10-22 08:20:00 -0700607const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
608 bool isCoreProfile) {
609 switch (generation) {
610 case k110_GrGLSLGeneration:
611 if (kGLES_GrGLStandard == standard) {
612 // ES2s shader language is based on version 1.20 but is version
613 // 1.00 of the ES language.
614 return "#version 100\n";
615 } else {
616 SkASSERT(kGL_GrGLStandard == standard);
617 return "#version 110\n";
618 }
619 case k130_GrGLSLGeneration:
620 SkASSERT(kGL_GrGLStandard == standard);
621 return "#version 130\n";
622 case k140_GrGLSLGeneration:
623 SkASSERT(kGL_GrGLStandard == standard);
624 return "#version 140\n";
625 case k150_GrGLSLGeneration:
626 SkASSERT(kGL_GrGLStandard == standard);
627 if (isCoreProfile) {
628 return "#version 150\n";
629 } else {
630 return "#version 150 compatibility\n";
631 }
632 case k330_GrGLSLGeneration:
633 if (kGLES_GrGLStandard == standard) {
634 return "#version 300 es\n";
635 } else {
636 SkASSERT(kGL_GrGLStandard == standard);
637 if (isCoreProfile) {
638 return "#version 330\n";
639 } else {
640 return "#version 330 compatibility\n";
641 }
642 }
cdalton33ad7012016-02-22 07:55:44 -0800643 case k400_GrGLSLGeneration:
644 SkASSERT(kGL_GrGLStandard == standard);
645 if (isCoreProfile) {
646 return "#version 400\n";
647 } else {
648 return "#version 400 compatibility\n";
649 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500650 case k420_GrGLSLGeneration:
651 SkASSERT(kGL_GrGLStandard == standard);
652 if (isCoreProfile) {
653 return "#version 420\n";
654 }
655 else {
656 return "#version 420 compatibility\n";
657 }
egdaniel472d44e2015-10-22 08:20:00 -0700658 case k310es_GrGLSLGeneration:
659 SkASSERT(kGLES_GrGLStandard == standard);
660 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800661 case k320es_GrGLSLGeneration:
662 SkASSERT(kGLES_GrGLStandard == standard);
663 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700664 }
665 return "<no version>";
666}
667
Chris Dalton47c8ed32017-11-15 18:27:09 -0700668bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
669 if (kGLES_GrGLStandard != ctxInfo.standard() &&
670 ctxInfo.version() < GR_GL_VER(4,1) &&
671 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
672 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
673 return true;
674 }
675 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
676 // geometry shaders don't have lower precision than vertex and fragment.
677 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
678 GrGLint range[2];
679 GrGLint bits;
680 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
681 if (range[0] < 127 || range[1] < 127 || bits < 23) {
682 return false;
683 }
684 }
685 return true;
686}
687
688void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700689 GrGLStandard standard = ctxInfo.standard();
690 GrGLVersion version = ctxInfo.version();
691
692 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500693 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700694 **************************************************************************/
695
Brian Salomon1edc5b92016-11-29 13:43:46 -0500696 GrShaderCaps* shaderCaps = fShaderCaps.get();
697 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700698 if (kGLES_GrGLStandard == standard) {
699 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500700 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
701 shaderCaps->fFBFetchSupport = true;
702 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
703 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700704 }
705 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
706 // 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 -0500707 shaderCaps->fFBFetchNeedsCustomOutput = false;
708 shaderCaps->fFBFetchSupport = true;
709 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
710 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700711 }
712 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
713 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500714 shaderCaps->fFBFetchNeedsCustomOutput = false;
715 shaderCaps->fFBFetchSupport = true;
716 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
717 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700718 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500719 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700720 }
721
cdaltonc08f1962016-02-12 12:14:06 -0800722 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500723 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800724 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500725 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800726 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
727 }
Brian Salomon41274562017-09-15 09:40:03 -0700728 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
729 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
730 kQualcomm_GrGLVendor != ctxInfo.vendor();
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 {
735 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500736 shaderCaps->fNoPerspectiveInterpolationSupport = true;
737 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800738 "GL_NV_shader_noperspective_interpolation";
739 }
740 }
741
Brian Salomon1edc5b92016-11-29 13:43:46 -0500742 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
743 shaderCaps->fGLSLGeneration,
744 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800745
Brian Salomon1edc5b92016-11-29 13:43:46 -0500746 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
747 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800748 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800749
750 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500751 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800752 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
753 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500754 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800755 }
756
757 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500758 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800759 }
760
cdalton9c3f1432016-03-11 10:07:37 -0800761 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400762 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
763 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400764 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400765 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
766 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
767 // At least one driver has been found that has this extension without the "GL_" prefix.
768 shaderCaps->fExternalTextureSupport = true;
769 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800770 }
771 }
772
cdaltonc04ce672016-03-11 14:07:38 -0800773 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500774 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800775 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500776 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700777 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
778 }
779
Brian Salomon1edc5b92016-11-29 13:43:46 -0500780 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700781 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500782 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700783 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
784 } else {
785 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
786 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500787 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700788 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500789 shaderCaps->fTexelBufferSupport = true;
790 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700791 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500792 shaderCaps->fTexelBufferSupport = true;
793 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700794 }
cdaltonc04ce672016-03-11 14:07:38 -0800795 }
796 }
797
Chris Dalton1d616352017-05-31 12:51:23 -0600798 if (kGL_GrGLStandard == standard) {
799 shaderCaps->fVertexIDSupport = true;
800 } else {
801 // Desktop GLSL 3.30 == ES GLSL 3.00.
802 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
803 }
804
Chris Dalton7c7ff032018-03-28 20:09:58 -0600805 if (kGL_GrGLStandard == standard) {
806 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
807 } else {
808 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
809 }
810
Chris Dalton47c8ed32017-11-15 18:27:09 -0700811 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
812 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700813}
814
kkinnunencfe62e32015-07-01 02:58:50 -0700815bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700816 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
817
818 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700819 return false;
820 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700821
kkinnunencfe62e32015-07-01 02:58:50 -0700822 if (kGL_GrGLStandard == ctxInfo.standard()) {
823 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
824 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
825 return false;
826 }
827 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700828 if (!hasChromiumPathRendering &&
829 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700830 return false;
831 }
832 }
833 // We only support v1.3+ of GL_NV_path_rendering which allows us to
834 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
835 // additions are detected by checking the existence of the function.
836 // We also use *Then* functions that not all drivers might have. Check
837 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800838 if (!gli->fFunctions.fStencilThenCoverFillPath ||
839 !gli->fFunctions.fStencilThenCoverStrokePath ||
840 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
841 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
842 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700843 return false;
844 }
845 return true;
846}
bsalomon1aa20292016-01-22 08:16:09 -0800847
Brian Salomon71d9d842016-11-03 13:42:00 -0400848bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800849 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800850 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800851 std::function<bool ()> bindRenderTarget,
852 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400853 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800854 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400855 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800856 return false;
857 }
bsalomon7928ef62016-01-05 10:26:39 -0800858
bsalomon76148af2016-01-12 11:13:47 -0800859 GrGLenum readFormat;
860 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400861 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800862 return false;
863 }
864
bsalomon1aa20292016-01-22 08:16:09 -0800865 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800866 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
867 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
868 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
869 // 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 -0500870 // The manual does not seem to fully match the spec as the spec allows integer formats
871 // when the bound color buffer is an integer buffer. It doesn't specify which integer
872 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500873 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
874 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
875 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800876 return false;
877 }
878 // There is also a set of allowed types, but all the types we use are in the set:
879 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
880 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
881 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
882 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
883 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
884 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
885 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800886 return true;
piotaixre4b23142014-10-02 10:57:53 -0700887 }
bsalomon7928ef62016-01-05 10:26:39 -0800888
bsalomon76148af2016-01-12 11:13:47 -0800889 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500890 switch (fConfigTable[surfaceConfig].fFormatType) {
891 case kNormalizedFixedPoint_FormatType:
892 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
893 return true;
894 }
895 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500896 case kFloat_FormatType:
897 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
898 return true;
899 }
900 break;
bsalomon7928ef62016-01-05 10:26:39 -0800901 }
902
Brian Salomon71d9d842016-11-03 13:42:00 -0400903 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800904 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400905 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800906 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800907 if (!bindRenderTarget()) {
908 return false;
909 }
910 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
911 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800912 rpFormat->fFormat = format;
913 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800914 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800915 }
916
Brian Salomon71d9d842016-11-03 13:42:00 -0400917 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
918 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700919}
920
Eric Karl5c779752017-05-08 12:02:07 -0700921void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
922 const GrGLInterface* gli) {
923 // We need dual source blending and the ability to disable multisample in order to support mixed
924 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
925 // renderer is available and enabled; no other path renderers support this feature.
926 if (fMultisampleDisableSupport &&
927 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400928 this->shaderCaps()->pathRenderingSupport()
929#if GR_TEST_UTILS
930 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
931#endif
932 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700933 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400934 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700935 }
936
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000937 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400938 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
939 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
940 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
941 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
942 fAlpha8IsRenderable = true;
943 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500944 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
945 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
946 // mixed samples we can't use multisampled-render-to-texture.
947 if (fUsesMixedSamples) {
948 fMSFBOType = kMixedSamples_MSFBOType;
949 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000950 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
951 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
952 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400953 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
954 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400955 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400956 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400957 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400958 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000959 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
960 fMSFBOType = kES_Apple_MSFBOType;
961 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000962 } else {
egdanieleed519e2016-01-15 11:36:18 -0800963 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700964 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400965 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
966 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400967
Brian Salomon00731b42016-10-14 11:30:51 -0400968 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400969 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
970 // Core profile removes ALPHA8 support.
971 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
972 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
973 // present.
974 fAlpha8IsRenderable = true;
975 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000976 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
977 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400978 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000979 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000980 }
Eric Karl5c779752017-05-08 12:02:07 -0700981
Brian Salomon01b476a2018-01-23 11:06:41 -0500982 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400983 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
984 fMSFBOType = kNone_MSFBOType;
985 }
986
Eric Karl5c779752017-05-08 12:02:07 -0700987 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
988 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
989 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700990 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000991}
992
cdalton1dd05422015-06-12 09:01:18 -0700993void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500994 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -0700995
Greg Daniel210883c2017-11-27 15:14:01 -0500996 bool layoutQualifierSupport = false;
997 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
998 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
999 layoutQualifierSupport = true;
1000 }
1001
cdalton1dd05422015-06-12 09:01:18 -07001002 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1003 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001004 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001005 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1006 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001007 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001008 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001009 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1010 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001011 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001012 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001013 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001014 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001015 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1016 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001017 }
cdalton1dd05422015-06-12 09:01:18 -07001018}
1019
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001020namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001021const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001022}
1023
Eric Karl5c779752017-05-08 12:02:07 -07001024void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001025
1026 // Build up list of legal stencil formats (though perhaps not supported on
1027 // the particular gpu/driver) from most preferred to least.
1028
1029 // these consts are in order of most preferred to least preferred
1030 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1031
1032 static const StencilFormat
1033 // internal Format stencil bits total bits packed?
1034 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1035 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1036 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1037 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001038 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001039 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1040
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001041 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001042 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001043 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001044 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1045 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1046
1047 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1048 // require FBO support we can expect these are legal formats and don't
1049 // check. These also all support the unsized GL_STENCIL_INDEX.
1050 fStencilFormats.push_back() = gS8;
1051 fStencilFormats.push_back() = gS16;
1052 if (supportsPackedDS) {
1053 fStencilFormats.push_back() = gD24S8;
1054 }
1055 fStencilFormats.push_back() = gS4;
1056 if (supportsPackedDS) {
1057 fStencilFormats.push_back() = gDS;
1058 }
1059 } else {
1060 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1061 // for other formats.
1062 // ES doesn't support using the unsized format.
1063
1064 fStencilFormats.push_back() = gS8;
1065 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001066 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1067 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001068 fStencilFormats.push_back() = gD24S8;
1069 }
1070 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1071 fStencilFormats.push_back() = gS4;
1072 }
1073 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001074}
1075
Brian Osman71a18892017-08-10 10:23:25 -04001076void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001077
Brian Osman71a18892017-08-10 10:23:25 -04001078 // We are called by the base class, which has already called beginObject(). We choose to nest
1079 // all of our caps information in a named sub-object.
1080 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001081
Brian Osman71a18892017-08-10 10:23:25 -04001082 writer->beginArray("Stencil Formats");
1083
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001084 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001085 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001086 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1087 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1088 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001089 }
1090
Brian Osman71a18892017-08-10 10:23:25 -04001091 writer->endArray();
1092
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001093 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001094 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001095 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001096 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001097 "IMG MS To Texture",
1098 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001099 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001100 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001101 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001102 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1103 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1104 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1105 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1106 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001107 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001108
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001109 static const char* kInvalidateFBTypeStr[] = {
1110 "None",
1111 "Discard",
1112 "Invalidate",
1113 };
1114 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1115 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1116 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1117 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001118
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001119 static const char* kMapBufferTypeStr[] = {
1120 "None",
1121 "MapBuffer",
1122 "MapBufferRange",
1123 "Chromium",
1124 };
1125 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1126 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1127 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1128 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1129 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1130
Brian Osman71a18892017-08-10 10:23:25 -04001131 writer->appendBool("Core Profile", fIsCoreProfile);
1132 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1133 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1134 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1135 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1136 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1137 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1138 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1139 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001140
Brian Osman71a18892017-08-10 10:23:25 -04001141 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001142 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1143 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1144 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001145 writer->appendBool("Debug support", fDebugSupport);
1146 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1147 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1148 writer->appendBool("Base instance support", fBaseInstanceSupport);
1149 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1150 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1151 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1152 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1153 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1154 writer->appendBool("BGRA to RGBA readback conversions are slow",
1155 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001156 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001157 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1158 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001159 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1160 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1161 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1162 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001163 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1164 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001165
Brian Osman71a18892017-08-10 10:23:25 -04001166 writer->beginArray("configs");
1167
bsalomon41e4384e2016-01-08 09:12:44 -08001168 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001169 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001170 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1171 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1172 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001173 writer->appendHexU32("e_format_read_pixels",
1174 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001175 writer->appendHexU32(
1176 "e_format_teximage",
1177 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1178 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1179 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1180 writer->appendHexU32("i_for_renderbuffer",
1181 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1182 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001183 }
1184
Brian Osman71a18892017-08-10 10:23:25 -04001185 writer->endArray();
1186 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001187}
1188
bsalomon41e4384e2016-01-08 09:12:44 -08001189bool GrGLCaps::bgraIsInternalFormat() const {
1190 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1191}
1192
bsalomon76148af2016-01-12 11:13:47 -08001193bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1194 GrGLenum* internalFormat, GrGLenum* externalFormat,
1195 GrGLenum* externalType) const {
1196 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1197 externalFormat, externalType)) {
1198 return false;
1199 }
1200 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1201 return true;
1202}
1203
bsalomon76148af2016-01-12 11:13:47 -08001204bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1205 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001206 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001207 externalFormat, externalType)) {
1208 return false;
1209 }
1210 return true;
1211}
1212
1213bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001214 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1215 return true;
1216}
1217
1218bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1219 ExternalFormatUsage usage, GrGLenum* externalFormat,
1220 GrGLenum* externalType) const {
1221 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001222
1223 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1224 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1225
1226 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001227 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1228 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001229 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1230 return false;
1231 }
1232
1233 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1234 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1235
bsalomone9573312016-01-25 14:33:25 -08001236 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1237 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1238 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1239 // texture, not the red component.
1240 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001241 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001242 *externalFormat = GR_GL_ALPHA;
1243 }
1244 }
1245
bsalomon76148af2016-01-12 11:13:47 -08001246 return true;
1247}
1248
brianosman20471892016-12-02 06:43:32 -08001249void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1250 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001251 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001252 /*
1253 Comments on renderability of configs on various GL versions.
1254 OpenGL < 3.0:
1255 no built in support for render targets.
1256 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1257 format RGB, RGBA and NV float formats we don't use.
1258 This is the following:
1259 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1260 RGB10_A2, RGBA12,RGBA16
1261 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1262 since they aren't required by later standards and the driver can simply return
1263 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1264 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1265 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1266 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1267 This adds a lot of additional renderable sized formats, including ALPHA8.
1268 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1269 16F, 32I, 32UI, and 32F variants).
1270 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1271
1272 For both the above extensions we limit ourselves to those that are also required by
1273 OpenGL 3.0.
1274
1275 OpenGL 3.0:
1276 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1277 but are not required to be supported as renderable textures/renderbuffer.
1278 Required renderable color formats:
1279 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1280 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1281 RGB10_A2.
1282 - R11F_G11F_B10F.
1283 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1284 and RG8UI.
1285 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1286 - ALPHA8
1287
1288 OpenGL 3.1, 3.2, 3.3
1289 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1290 OpengGL 3.3, 4.0, 4.1
1291 Adds RGB10_A2UI.
1292 OpengGL 4.2
1293 Adds
1294 - RGB5_A1, RGBA4
1295 - RGB565
1296 OpenGL 4.4
1297 Does away with the separate list and adds a column to the sized internal color format
1298 table. However, no new formats become required color renderable.
1299
1300 ES 2.0
1301 color renderable: RGBA4, RGB5_A1, RGB565
1302 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1303 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1304 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1305 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1306 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1307 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1308
1309 ES 3.0
1310 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1311 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1312 RGB5_A1.
1313 - RGB8 and RGB565.
1314 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1315 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1316 ES 3.1
1317 Adds RGB10_A2, RGB10_A2UI,
1318 ES 3.2
1319 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1320 */
Brian Salomon44804c02018-01-23 16:51:28 -05001321
1322 // Correctness workarounds.
1323 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001324 bool disableSRGBForX86PowerVR = false;
1325 bool disableSRGBWriteControlForAdreno4xx = false;
1326 bool disableR8TexStorageForANGLEGL = false;
1327 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001328 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001329
1330 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1331 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1332 // and GL_RG on FBO textures.
1333 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1334
1335 bool isX86PowerVR = false;
1336#if defined(SK_CPU_X86)
1337 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1338 isX86PowerVR = true;
1339 }
1340#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001341 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1342 // blacklist that device (and any others that might be sharing the same driver).
1343 disableSRGBForX86PowerVR = isX86PowerVR;
1344 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1345
1346 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1347 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1348 // check that we are not going to OpenGL.
1349 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1350
1351 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1352#if defined(SK_BUILD_FOR_MAC)
1353 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1354#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001355 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1356 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001357 }
1358
Brian Salomon71d9d842016-11-03 13:42:00 -04001359 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1360 ConfigInfo::kFBOColorAttachment_Flag;
1361 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001362 if (kNone_MSFBOType != fMSFBOType) {
1363 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1364 }
bsalomon41e4384e2016-01-08 09:12:44 -08001365 GrGLStandard standard = ctxInfo.standard();
1366 GrGLVersion version = ctxInfo.version();
1367
cblume790d5132016-02-29 11:13:29 -08001368 bool texStorageSupported = false;
1369 if (kGL_GrGLStandard == standard) {
1370 // The EXT version can apply to either GL or GLES.
1371 texStorageSupported = version >= GR_GL_VER(4,2) ||
1372 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1373 ctxInfo.hasExtension("GL_EXT_texture_storage");
1374 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001375 texStorageSupported = version >= GR_GL_VER(3,0) ||
1376 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001377 }
1378
cdalton74b8d322016-04-11 14:47:28 -07001379 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1380
Brian Salomone609e812018-01-17 14:00:47 -05001381 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001382
1383 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001384 if (kGL_GrGLStandard == standard) {
1385 textureRedSupport =
1386 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1387 } else {
1388 textureRedSupport =
1389 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1390 }
1391 }
1392
bsalomon30447372015-12-21 09:03:05 -08001393 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1394 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001395 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001396 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001397 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001398 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001399
1400 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1401 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001402 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001403 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001404 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001405 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001406 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1407 if (kGL_GrGLStandard == standard) {
1408 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1409 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001410 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001411 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1412 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1413 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1414 }
egdaniel4999df82016-01-07 17:06:04 -08001415 }
cblume790d5132016-02-29 11:13:29 -08001416 if (texStorageSupported) {
1417 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1418 }
cdalton74b8d322016-04-11 14:47:28 -07001419 if (texelBufferSupport) {
1420 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_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
1458 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001459 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001460 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001461 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001462
1463 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1464 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1465 // GL_EXT_texture_format_BGRA8888.
1466 bool supportsBGRATexStorage = false;
1467
bsalomon41e4384e2016-01-08 09:12:44 -08001468 if (kGL_GrGLStandard == standard) {
1469 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1470 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1471 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1472 // Since the internal format is RGBA8, it is also renderable.
1473 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1474 allRenderFlags;
1475 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001476 // Since we are using RGBA8 we can use tex storage.
1477 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001478 } else {
1479 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1480 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001481 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1482 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1483 nonMSAARenderFlags;
1484
1485 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1486 supportsBGRATexStorage = true;
1487 }
1488 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1489 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1490 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1491 ConfigInfo::kRenderableWithMSAA_Flag;
1492 }
1493 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001494 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1495 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1496 // driver remembers the external format when the texture is created (with TexImage).
1497 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1498 // We could work around this, but it adds even more state tracking to code that is
1499 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1500 // This also side-steps some ambiguous interactions with the texture storage extension.
1501 if (version >= GR_GL_VER(3,0)) {
1502 // The APPLE extension doesn't make this renderable.
1503 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001504 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001505 }
bsalomon41e4384e2016-01-08 09:12:44 -08001506 }
1507 }
Brian Osman48c99192017-06-02 08:45:06 -04001508
Greg Daniel0ff79b22018-02-15 12:33:33 -05001509 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001510 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001511 }
bsalomoncdee0092016-01-08 13:20:12 -08001512 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001513
brianosmana6359362016-03-21 06:55:37 -07001514 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001515 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001516 if (kGL_GrGLStandard == standard) {
1517 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001518 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001519 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1520 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1521 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001522 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001523 }
1524 }
1525 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001526 if (fSRGBSupport) {
1527 fSRGBWriteControl = true;
1528 }
bsalomon41e4384e2016-01-08 09:12:44 -08001529 } else {
brianosman20471892016-12-02 06:43:32 -08001530 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001531 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001532 fSRGBSupport = false;
1533 }
bsalomon41e4384e2016-01-08 09:12:44 -08001534 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1535 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001536 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001537 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001538 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001539 }
brianosman20471892016-12-02 06:43:32 -08001540 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1541 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1542 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001543 fSRGBSupport = false;
1544 }
brianosman20471892016-12-02 06:43:32 -08001545
1546 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1547 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1548 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1549 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1550 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1551 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1552 // affects Windows.
1553 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1554 fSRGBSupport = false;
1555 }
1556
Brian Osman48c99192017-06-02 08:45:06 -04001557 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1558 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1559 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1560
Brian Osman67999392017-05-31 16:19:34 -04001561 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001562 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001563 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1564 }
Brian Osman67999392017-05-31 16:19:34 -04001565
bsalomon30447372015-12-21 09:03:05 -08001566 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1567 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1568 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1569 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001570 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001571 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001572 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001573 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001574 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001575 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001576 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001577 }
Brian Osman48c99192017-06-02 08:45:06 -04001578 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1579 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001580 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1581 }
bsalomoncdee0092016-01-08 13:20:12 -08001582 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001583 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1584 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1585 // is in this format, for example).
1586 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1587 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1588 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1589 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001590 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001591 GR_GL_BGRA;
1592 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1593 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001594 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001595 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001596 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001597 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001598
brianosmana6359362016-03-21 06:55:37 -07001599 if (texStorageSupported) {
1600 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1601 }
1602 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1603
bsalomon30447372015-12-21 09:03:05 -08001604 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1605 if (this->ES2CompatibilitySupport()) {
1606 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1607 } else {
1608 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1609 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001610 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001611 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001612 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001613 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001614 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1615 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001616 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001617 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1618 }
1619 } else {
1620 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1621 }
cblume790d5132016-02-29 11:13:29 -08001622 // 565 is not a sized internal format on desktop GL. So on desktop with
1623 // 565 we always use an unsized internal format to let the system pick
1624 // the best sized format to convert the 565 data to. Since TexStorage
1625 // only allows sized internal formats we disallow it.
1626 //
1627 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1628 // update.
1629 if (texStorageSupported && kGL_GrGLStandard != standard) {
1630 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1631 }
bsalomoncdee0092016-01-08 13:20:12 -08001632 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001633
1634 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1635 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001636 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001637 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001638 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001639 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001640 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1641 if (kGL_GrGLStandard == standard) {
1642 if (version >= GR_GL_VER(4, 2)) {
1643 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1644 }
1645 } else {
1646 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1647 }
cblume790d5132016-02-29 11:13:29 -08001648 if (texStorageSupported) {
1649 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1650 }
bsalomoncdee0092016-01-08 13:20:12 -08001651 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001652
Brian Osman10fc6fd2018-03-02 11:01:10 -05001653 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1654 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001655 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001656 GR_GL_RGBA;
1657 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1658 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1659 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1660 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1661 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1662 allRenderFlags;
1663 }
1664 if (texStorageSupported) {
1665 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1666 }
1667 if (texelBufferSupport) {
1668 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1669 }
1670 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1671
Greg Danielef59d872017-11-17 16:47:21 -05001672 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1673 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1674
1675 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1676 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1677 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1678 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1679 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001680 }
Greg Danielef59d872017-11-17 16:47:21 -05001681 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1682 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001683 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001684 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1685 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1686 alphaInfo.fFlags |= allRenderFlags;
1687 }
1688
1689 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1690 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1691 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1692 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1693 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001694 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001695 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001696
Brian Osman48c99192017-06-02 08:45:06 -04001697 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1698 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001699 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001700 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1701 }
1702 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1703 }
1704
Brian Salomone609e812018-01-17 14:00:47 -05001705 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001706 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1707 if (texelBufferSupport) {
1708 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1709 }
1710
1711 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1712 } else {
1713 redInfo.fFlags = 0;
1714
1715 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001716 }
bsalomon41e4384e2016-01-08 09:12:44 -08001717
Greg Daniel7af060a2017-12-05 16:27:11 -05001718 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1719 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1720 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1721 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1722 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001723 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001724 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1725 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1726 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1727 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001728 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001729
1730 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1731 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1732 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1733 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1734 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001735 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001736 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1737 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1738
1739#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1740 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001741 if (this->textureRedSupport() ||
1742 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1743 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1744 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1745 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1746 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1747 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1748 }
1749#endif
Brian Osman48c99192017-06-02 08:45:06 -04001750 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001751 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001752 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1753 }
1754 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1755 }
1756
Brian Salomone609e812018-01-17 14:00:47 -05001757 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001758 if (texelBufferSupport) {
1759 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1760 }
1761 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.
1771 bool hasFPTextures = false;
1772 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001773 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001774 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001775 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001776
1777 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001778 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001779 hasFPTextures = true;
1780 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001781 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001782 }
1783 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001784 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001785 hasFPTextures = true;
1786 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001787 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001788 } else {
1789 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1790 ctxInfo.hasExtension("GL_OES_texture_float")) {
1791 hasFPTextures = true;
1792 }
1793 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1794 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1795 hasHalfFPTextures = true;
1796 }
1797 }
1798 }
bsalomon30447372015-12-21 09:03:05 -08001799
csmartdalton6aa0e112017-02-08 16:14:11 -05001800 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1801 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1802 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1803 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1804 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001805 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001806 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1807 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1808 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001809 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001810 // For now we only enable rendering to float on desktop, because on ES we'd have to
1811 // solve many precision issues and no clients actually want this yet.
1812 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1813 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1814 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1815 }
bsalomon41e4384e2016-01-08 09:12:44 -08001816 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001817 if (texStorageSupported) {
1818 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1819 }
1820 if (texelBufferSupport) {
1821 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1822 }
1823 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001824 }
bsalomon30447372015-12-21 09:03:05 -08001825
Greg Danielef59d872017-11-17 16:47:21 -05001826 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001827 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001828 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001829 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001830 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001831 }
Greg Danielef59d872017-11-17 16:47:21 -05001832 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1833 redHalf.fFormats.fExternalType = redHalfExternalType;
1834 redHalf.fFormatType = kFloat_FormatType;
1835 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1836 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001837 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001838 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001839 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001840 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1841
csmartdalton6aa0e112017-02-08 16:14:11 -05001842 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001843 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001844 redHalf.fFlags |= fpRenderFlags;
1845 }
1846
1847 if (texStorageSupported && !isCommandBufferES2) {
1848 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1849 }
1850
1851 if (texelBufferSupport) {
1852 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001853 }
1854 }
Greg Danielef59d872017-11-17 16:47:21 -05001855 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001856
1857 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1858 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001859 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001860 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001861 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001862 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1863 } else {
1864 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1865 }
bsalomon7928ef62016-01-05 10:26:39 -08001866 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001867 if (hasHalfFPTextures) {
1868 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1869 // ES requires 3.2 or EXT_color_buffer_half_float.
1870 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1871 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1872 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1873 }
1874 }
cblume790d5132016-02-29 11:13:29 -08001875 if (texStorageSupported) {
1876 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1877 }
cdalton74b8d322016-04-11 14:47:28 -07001878 if (texelBufferSupport) {
1879 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1880 }
bsalomoncdee0092016-01-08 13:20:12 -08001881 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001882
bsalomon30447372015-12-21 09:03:05 -08001883 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1884
1885 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001886 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1887 ctxInfo.version() >= GR_GL_VER(3,0));
1888 // All ES versions (thus far) require sized internal formats for render buffers.
1889 // TODO: Always use sized internal format?
1890 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1891
bsalomon30447372015-12-21 09:03:05 -08001892 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001893 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1894 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001895 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001896 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001897 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1898 fConfigTable[i].fFormats.fSizedInternalFormat :
1899 fConfigTable[i].fFormats.fBaseInternalFormat;
1900 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001901 fConfigTable[i].fFormats.fSizedInternalFormat :
1902 fConfigTable[i].fFormats.fBaseInternalFormat;
1903 }
Brian Salomon44804c02018-01-23 16:51:28 -05001904 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1905 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1906 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1907 // in ES.
1908 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1909 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1910 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1911 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001912 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1913 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001914 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1915 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001916 }
1917
bsalomon30447372015-12-21 09:03:05 -08001918 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1919 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1920 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1921 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1922 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001923 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001924 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001925
1926 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1927 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1928 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1929 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001930 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001931 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1932 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1933 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1934 // slot.
1935 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1936 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001937
1938 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1939 // as a base format.
1940 // GL_EXT_texture_format_BGRA8888:
1941 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1942 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1943 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001944 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001945 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1946 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1947 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001948 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001949 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1950 }
1951
bsalomoncdee0092016-01-08 13:20:12 -08001952 // If we don't have texture swizzle support then the shader generator must insert the
1953 // swizzle into shader code.
1954 if (!this->textureSwizzleSupport()) {
1955 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001956 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001957 }
1958 }
1959
bsalomon7f9b2e42016-01-12 13:29:26 -08001960 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1961 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1962 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001963 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001964 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1965 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1966 if (GrPixelConfigIsAlphaOnly(config) &&
1967 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001968 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001969 }
1970 }
1971 }
1972
Greg Daniel81e7bf82017-07-19 14:47:42 -04001973 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1974 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001975 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1976 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001977 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001978 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1979 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001980 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001981 int count;
1982 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1983 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1984 1, &count);
1985 if (count) {
1986 int* temp = new int[count];
1987 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1988 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001989 // GL has a concept of MSAA rasterization with a single sample but we do not.
1990 if (count && temp[count - 1] == 1) {
1991 --count;
1992 SkASSERT(!count || temp[count -1] > 1);
1993 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001994 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001995 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04001996 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05001997 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04001998 for (int j = 0; j < count; ++j) {
1999 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2000 }
2001 delete[] temp;
2002 }
2003 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002004 // Fake out the table using some semi-standard counts up to the max allowed sample
2005 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002006 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002007 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2008 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2009 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2010 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2011 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002012 // Chrome has a mock GL implementation that returns 0.
2013 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002014
Brian Salomonbdecacf2018-02-02 20:32:49 -05002015 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002016 int count = SK_ARRAY_COUNT(kDefaultSamples);
2017 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002018 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002019 break;
2020 }
2021 }
2022 if (count > 0) {
2023 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2024 }
2025 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002026 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2027 fConfigTable[i].fColorSampleCounts.setCount(1);
2028 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002029 }
2030 }
2031
bsalomon30447372015-12-21 09:03:05 -08002032#ifdef SK_DEBUG
2033 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002034 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002035 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002036 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2037 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002038 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2039 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2040 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2041 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002042 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2043 fConfigTable[i].fFormats.fBaseInternalFormat);
2044 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002045 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002046 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2047 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2048 fConfigTable[i].fFormats.fExternalFormat[j]);
2049 }
2050 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002051 }
2052#endif
2053}
2054
Robert Phillipsbf25d432017-04-07 10:08:53 -04002055bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002056 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2057 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002058 // By default, we don't require rects to match.
2059 *rectsMustMatch = false;
2060
2061 // By default, we allow subrects.
2062 *disallowSubrect = false;
2063
Brian Salomon467921e2017-03-06 16:17:12 -05002064 // If the src is a texture, we can implement the blit as a draw assuming the config is
2065 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002066 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002067 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002068 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2069 desc->fConfig = src->config();
2070 return true;
2071 }
2072
Robert Phillipsbf25d432017-04-07 10:08:53 -04002073 {
2074 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2075 // wrapped. In that case the proxy would already be instantiated.
2076 const GrTexture* srcTexture = src->priv().peekTexture();
2077 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2078 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2079 // Not supported for FBO blit or CopyTexSubImage
2080 return false;
2081 }
Brian Salomon467921e2017-03-06 16:17:12 -05002082 }
2083
2084 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2085 // possible and we return false to fallback to creating a render target dst for render-to-
2086 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2087 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002088 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002089 bool rectsMustMatchForBlitFramebuffer = false;
2090 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002091 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002092 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2093 rectsMustMatchForBlitFramebuffer = true;
2094 disallowSubrectForBlitFramebuffer = true;
2095 // Mirroring causes rects to mismatch later, don't allow it.
2096 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002097 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2098 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002099 rectsMustMatchForBlitFramebuffer = true;
2100 // Mirroring causes rects to mismatch later, don't allow it.
2101 originForBlitFramebuffer = src->origin();
2102 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002103 originForBlitFramebuffer = src->origin();
2104 }
2105
2106 // Check for format issues with glCopyTexSubImage2D
2107 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2108 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2109 // then we set up for that, otherwise fail.
2110 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002111 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002112 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002113 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2114 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002115 return true;
2116 }
2117 return false;
2118 }
2119
Robert Phillipsbf25d432017-04-07 10:08:53 -04002120 {
Brian Salomon63e79732017-05-15 21:23:13 -04002121 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2122 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002123 if (srcIsMSAARenderbuffer) {
2124 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2125 // blit or fail.
2126 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002127 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002128 desc->fConfig = src->config();
2129 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2130 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2131 return true;
2132 }
2133 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002134 }
Brian Salomon467921e2017-03-06 16:17:12 -05002135 }
2136
2137 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002138 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002139 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002140 desc->fFlags = kNone_GrSurfaceFlags;
2141 return true;
2142}
2143
Greg Daniel691f5e72018-02-28 14:21:34 -05002144void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2145 const GrContextOptions& contextOptions,
2146 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002147 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2148 // Thus we are blacklisting this extension for now on Adreno4xx devices.
2149 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2150 fDiscardRenderTargetSupport = false;
2151 fInvalidateFBType = kNone_InvalidateFBType;
2152 }
2153
2154 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2155 // 340.96 and 367.57.
2156 if (kGL_GrGLStandard == ctxInfo.standard() &&
2157 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002158 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002159 fClearTextureSupport = false;
2160 }
2161
2162 // Calling glClearTexImage crashes on the NexusPlayer.
2163 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2164 fClearTextureSupport = false;
2165 }
2166
2167 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2168#ifdef SK_BUILD_FOR_MAC
2169 if (shaderCaps->fGeometryShaderSupport) {
2170 shaderCaps->fGSInvocationsSupport = false;
2171 }
2172#endif
2173
2174 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2175 // shaders. @127.0 is the earliest verified driver to not crash.
2176 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002177 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002178 shaderCaps->fGeometryShaderSupport = false;
2179 }
2180
2181#if defined(__has_feature)
2182#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2183 // See skbug.com/7058
2184 fMapBufferType = kNone_MapBufferType;
2185 fMapBufferFlags = kNone_MapFlags;
2186#endif
2187#endif
2188
2189 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2190 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2191 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2192 // unclear whether this really affects a wide range of devices.
2193 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002194 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002195 fMapBufferType = kNone_MapBufferType;
2196 fMapBufferFlags = kNone_MapFlags;
2197 }
2198
2199 // TODO: re-enable for ANGLE
2200 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2201 fTransferBufferType = kNone_TransferBufferType;
2202 }
2203
2204 // Using MIPs on this GPU seems to be a source of trouble.
2205 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2206 fMipMapSupport = false;
2207 }
2208
2209 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2210 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2211 // around a driver bug related to gl_FragCoord.
2212 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2213 fMaxClipAnalyticFPs = 0;
2214 }
2215
2216#ifndef SK_BUILD_FOR_IOS
2217 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2218 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2219 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2220 ctxInfo.driver() != kChromium_GrGLDriver)) {
2221 fUseDrawToClearColor = true;
2222 }
2223#endif
2224
2225 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2226 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2227 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2228 fUseDrawToClearColor = true;
2229 }
2230
2231#ifdef SK_BUILD_FOR_MAC
2232 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2233 // full screen clears
2234 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2235 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002236 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2237 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2238 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2239 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002240 fUseDrawToClearColor = true;
2241 }
2242#endif
2243
2244 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2245 // bugs seems to involve clearing too much and not skipping the clear.
2246 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2247 // but only for D3D11 ANGLE.
2248 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2249 fUseDrawToClearColor = true;
2250 }
2251
2252 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2253 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002254 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002255 fUseDrawToClearStencilClip = true;
2256 }
2257 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2258 }
2259
2260 // This was reproduced on the following configurations:
2261 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2262 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2263 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2264 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2265 // and not produced on:
2266 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2267 // The particular lines that get dropped from test images varies across different devices.
2268 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002269 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002270 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2271 }
2272
2273 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2274 // given 1 << 15 or more instances.
2275 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2276 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
2277 }
2278
2279 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002280 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002281 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2282 fUseDrawInsteadOfAllRenderTargetWrites = true;
2283 }
2284
2285 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2286 fSampleShadingSupport = false;
2287 }
2288
2289#ifdef SK_BUILD_FOR_MAC
2290 static constexpr bool isMAC = true;
2291#else
2292 static constexpr bool isMAC = false;
2293#endif
2294
2295 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2296 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2297 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2298 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2299 if (fMipMapLevelAndLodControlSupport &&
2300 (contextOptions.fDoManualMipmapping ||
2301 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2302 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2303 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2304 fDoManualMipmapping = true;
2305 }
2306
2307 // See http://crbug.com/710443
2308#ifdef SK_BUILD_FOR_MAC
2309 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2310 fClearToBoundaryValuesIsBroken = true;
2311 }
2312#endif
2313 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2314 fDrawArraysBaseVertexIsBroken = true;
2315 }
2316
2317 // The ccpr vertex-shader implementation does not work on this platform. Only allow CCPR with
2318 // GS.
2319
2320 if (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2321 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer()) {
2322 bool gsSupport = fShaderCaps->geometryShaderSupport();
2323#if GR_TEST_UTILS
2324 gsSupport &= !contextOptions.fSuppressGeometryShaders;
2325#endif
2326 fBlacklistCoverageCounting = !gsSupport;
2327 }
2328 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2329 // Galaxy S7.
2330 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2331 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2332 shaderCaps->fFBFetchSupport = false;
2333 }
2334
Brian Salomon01b476a2018-01-23 11:06:41 -05002335 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2336 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2337
2338 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2339 // function that may require a gradient calculation inside a conditional block may return
2340 // undefined results". This appears to be an issue with the 'any' call since even the simple
2341 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2342 // from our GrTextureDomain processor.
2343 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2344
2345 // Known issue on at least some Intel platforms:
2346 // http://code.google.com/p/skia/issues/detail?id=946
2347 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2348 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2349 }
2350
Chris Dalton0090ef62018-03-28 17:35:00 -06002351 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002352 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2353 // so we must do the abs first in a separate expression.
2354 shaderCaps->fCanUseMinAndAbsTogether = false;
2355
2356 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2357 // must avoid this condition.
2358 shaderCaps->fCanUseFractForNegativeValues = false;
2359 }
2360
2361 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2362 // thus must us -1.0 * %s.x to work correctly
2363 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2364 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2365 }
2366
2367 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2368 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2369 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2370 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2371 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2372 }
2373
2374 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2375 // the original dst color when reading the outColor even after being written to. By using a
2376 // local outColor we can work around this bug.
2377 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2378 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2379 }
2380
2381 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2382 // color, and that uniform contains an opaque color, and the output of the shader is only based
2383 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2384 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2385 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2386 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2387 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2388 shaderCaps->fMustObfuscateUniformColor = true;
2389 }
2390#ifdef SK_BUILD_FOR_WIN
2391 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2392 //
2393 // Basically, if a shader has a construct like:
2394 //
2395 // float x = someCondition ? someValue : 0;
2396 // float2 result = (0 == x) ? float2(x, x)
2397 // : float2(2 * x / x, 0);
2398 //
2399 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2400 // we've explicitly guarded the division with a check against zero. This manifests in much
2401 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2402 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2403 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2404 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2405 }
2406#endif
2407
2408 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2409 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2410 // that the interpolation of vertex shader outputs is quite inaccurate.
2411 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2412 shaderCaps->fCanUseFragCoord = false;
2413 shaderCaps->fInterpolantsAreInaccurate = true;
2414 }
2415
Chris Dalton0090ef62018-03-28 17:35:00 -06002416 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2417 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2418 shaderCaps->fCanUseFragCoord = false;
2419 }
2420
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002421 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2422 // (Are they implemented with fp16?)
2423 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2424 shaderCaps->fIncompleteShortIntPrecision = true;
2425 }
2426
Brian Salomon01b476a2018-01-23 11:06:41 -05002427 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2428 // for now until its own blacklists can be updated.
2429 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2430 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2431 kIntel_GrGLDriver == ctxInfo.driver() ||
2432 kChromium_GrGLDriver == ctxInfo.driver()) {
2433 fBlendEquationSupport = kBasic_BlendEquationSupport;
2434 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2435 }
2436
2437 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2438 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002439 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002440 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002441 fBlendEquationSupport = kBasic_BlendEquationSupport;
2442 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2443 }
2444
2445 if (this->advancedBlendEquationSupport()) {
2446 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002447 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002448 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2449 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2450 (1 << kColorBurn_GrBlendEquation);
2451 }
2452 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2453 // Blacklist color-burn on ARM until the fix is released.
2454 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2455 }
2456 }
2457
2458 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2459 if (fMultisampleDisableSupport &&
2460 this->shaderCaps()->dualSourceBlendingSupport() &&
2461 this->shaderCaps()->pathRenderingSupport() &&
2462 fUsesMixedSamples &&
2463#if GR_TEST_UTILS
2464 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2465#endif
2466 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2467 kChromium_GrGLDriver == ctxInfo.driver())) {
2468 fDiscardRenderTargetSupport = false;
2469 fInvalidateFBType = kNone_InvalidateFBType;
2470 }
Brian Osmanc585e202018-04-04 14:08:27 -04002471
2472 // Various Samsung devices (Note4, S7, ...) don't advertise the image_external_essl3 extension,
2473 // (only the base image_external extension), but do support it, and require that it be enabled
2474 // to work with ESSL3. This has been seen on both Mali and Adreno devices. skbug.com/7713
2475 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2476 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
2477 !shaderCaps->fExternalTextureSupport && // i.e. Missing the _essl3 extension
2478 (kARM_GrGLVendor == ctxInfo.vendor() || kQualcomm_GrGLVendor == ctxInfo.vendor())) {
2479 shaderCaps->fExternalTextureSupport = true;
2480 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
2481 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002482}
2483
csmartdaltone0d36292016-07-29 08:14:20 -07002484void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002485 if (options.fDisableDriverCorrectnessWorkarounds) {
2486 SkASSERT(!fDoManualMipmapping);
2487 SkASSERT(!fClearToBoundaryValuesIsBroken);
2488 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2489 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2490 SkASSERT(!fUseDrawToClearColor);
2491 SkASSERT(!fUseDrawToClearStencilClip);
2492 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2493 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2494 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
2495 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002496 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2497 fUseDrawToClearColor = false;
2498 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2499 fUseDrawToClearColor = true;
2500 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002501 if (options.fDoManualMipmapping) {
2502 fDoManualMipmapping = true;
2503 }
csmartdaltone0d36292016-07-29 08:14:20 -07002504}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002505
Brian Salomon3d86a192018-02-27 16:46:11 -05002506bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2507 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2508 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2509 if (tex->hasBaseLevelBeenBoundToFBO()) {
2510 return false;
2511 }
2512 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002513 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002514 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2515 return false;
2516 }
2517 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2518 return false;
2519 }
2520 return SkToBool(surface->asTexture());
2521 }
2522 return true;
2523}
2524
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002525bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2526 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2527 // We don't support reading pixels directly from EXTERNAL textures as it would require
2528 // binding the texture to a FBO.
2529 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2530 return false;
2531 }
2532 }
2533 return true;
2534}
2535
2536GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2537 GrColorType dstColorType) const {
2538 // For now, we mostly report the read back format that is required by the ES spec without
2539 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2540 // this as makes sense to increase performance and correctness.
2541 switch (fConfigTable[config].fFormatType) {
2542 case kNormalizedFixedPoint_FormatType:
2543 return GrColorType::kRGBA_8888;
2544 case kFloat_FormatType:
2545 // We cheat a little here and allow F16 read back if the src and dst match.
2546 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2547 return GrColorType::kRGBA_F16;
2548 }
2549 if ((kAlpha_half_GrPixelConfig == config ||
2550 kAlpha_half_as_Red_GrPixelConfig == config) &&
2551 GrColorType::kAlpha_F16 == dstColorType) {
2552 return GrColorType::kAlpha_F16;
2553 }
2554 // And similar for full float RG.
2555 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2556 return GrColorType::kRG_F32;
2557 }
2558 return GrColorType::kRGBA_F32;
2559 }
2560 return GrColorType::kUnknown;
2561}
2562
Greg Daniel2a303902018-02-20 10:25:54 -05002563bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002564 GrGLFramebufferInfo fbInfo;
2565 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002566 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002567 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002568}
2569
Brian Salomonbdecacf2018-02-02 20:32:49 -05002570int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2571 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002572 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002573 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002574 return 0;
2575 }
2576
Brian Salomonbdecacf2018-02-02 20:32:49 -05002577 if (1 == requestedCount) {
2578 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2579 }
2580
Greg Daniel81e7bf82017-07-19 14:47:42 -04002581 for (int i = 0; i < count; ++i) {
2582 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2583 return fConfigTable[config].fColorSampleCounts[i];
2584 }
2585 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002586 return 0;
2587}
2588
2589int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2590 const auto& table = fConfigTable[config].fColorSampleCounts;
2591 if (!table.count()) {
2592 return 0;
2593 }
2594 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002595}
2596
Greg Danielfaa095e2017-12-19 13:15:02 -05002597bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2598 GrGLStandard standard) {
2599 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002600
2601 switch (ct) {
2602 case kUnknown_SkColorType:
2603 return false;
2604 case kAlpha_8_SkColorType:
2605 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002606 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002607 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002608 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002609 }
2610 break;
2611 case kRGB_565_SkColorType:
2612 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002613 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002614 }
2615 break;
2616 case kARGB_4444_SkColorType:
2617 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002618 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002619 }
2620 break;
2621 case kRGBA_8888_SkColorType:
2622 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002623 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002624 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002625 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002626 }
2627 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002628 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002629 if (GR_GL_RGB8 == format) {
2630 *config = kRGB_888_GrPixelConfig;
2631 }
2632 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002633 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002634 if (GR_GL_RGBA8 == format) {
2635 if (kGL_GrGLStandard == standard) {
2636 *config = kBGRA_8888_GrPixelConfig;
2637 }
2638 } else if (GR_GL_BGRA8 == format) {
2639 if (kGLES_GrGLStandard == standard) {
2640 *config = kBGRA_8888_GrPixelConfig;
2641 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002642 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002643 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002644 }
2645 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002646 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002647 if (GR_GL_RGB10_A2 == format) {
2648 *config = kRGBA_1010102_GrPixelConfig;
2649 }
2650 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002651 case kRGB_101010x_SkColorType:
2652 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002653 case kGray_8_SkColorType:
2654 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002655 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002656 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002657 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002658 }
2659 break;
2660 case kRGBA_F16_SkColorType:
2661 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002662 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002663 }
2664 break;
2665 }
2666
Greg Danielfaa095e2017-12-19 13:15:02 -05002667 return kUnknown_GrPixelConfig != *config;
2668}
2669
2670bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2671 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002672 GrGLTextureInfo texInfo;
2673 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002674 return false;
2675 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002676 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002677}
2678
2679bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2680 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002681 GrGLFramebufferInfo fbInfo;
2682 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002683 return false;
2684 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002685 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002686}
2687
Robert Phillipsfc711a22018-02-13 17:03:00 -05002688bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2689 GrPixelConfig* config) const {
2690 const GrGLenum* glFormat = format.getGLFormat();
2691 if (!glFormat) {
2692 return false;
2693 }
2694 return validate_sized_format(*glFormat, ct, config, fStandard);
2695}
2696
2697