blob: 3bd857d53ab601ff2515adc761707b99095c8d0e [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;
Chris Daltonda40cd22018-04-16 13:19:58 -060062 fRequiresFlushBetweenNonAndInstancedDraws = false;
Ethan Nicholas06d55fb2017-11-08 09:48:50 -050063 fProgramBinarySupport = false;
piotaixre4b23142014-10-02 10:57:53 -070064
Brian Salomone5e7eb12016-10-14 16:18:33 -040065 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
Chris Daltoncc604e52017-10-06 16:27:32 -060066 fMaxInstancesPerDrawArraysWithoutCrashing = 0;
bsalomon083617b2016-02-12 12:10:14 -080067
Brian Salomon94efbf52016-11-29 13:43:05 -050068 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070069
cdalton4cd67132015-06-10 19:23:46 -070070 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000071}
72
cdalton4cd67132015-06-10 19:23:46 -070073void GrGLCaps::init(const GrContextOptions& contextOptions,
74 const GrGLContextInfo& ctxInfo,
75 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000076 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000077 GrGLVersion version = ctxInfo.version();
78
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000079 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000080 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
81 &fMaxFragmentUniformVectors);
82 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000083 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000084 GrGLint max;
85 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
86 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000087 if (version >= GR_GL_VER(3, 2)) {
88 GrGLint profileMask;
89 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
90 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
91 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000092 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000093 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000095 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000096 fUnpackRowLengthSupport = true;
97 fUnpackFlipYSupport = false;
98 fPackRowLengthSupport = true;
99 fPackFlipYSupport = false;
100 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000101 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
102 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000103 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000104 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
105 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000106 fPackFlipYSupport =
107 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
108 }
109
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000110 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000111 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
112
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000113 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700114 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
115 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
116 ctxInfo.hasExtension("GL_NV_texture_barrier");
117 } else {
118 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
119 }
120
Robert Phillips7f861922018-01-30 13:13:42 +0000121 if (kGL_GrGLStandard == standard) {
122 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
123 ctxInfo.hasExtension("GL_ARB_texture_multisample");
124 } else {
125 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
126 }
127
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000128 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000129 ctxInfo.hasExtension("GL_ARB_imaging");
130
Brian Salomon01b476a2018-01-23 11:06:41 -0500131 if (((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
egdaniel9250d242015-05-18 13:04:26 -0700132 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
133 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000134 fDiscardRenderTargetSupport = true;
135 fInvalidateFBType = kInvalidate_InvalidateFBType;
136 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
137 fDiscardRenderTargetSupport = true;
138 fInvalidateFBType = kDiscard_InvalidateFBType;
139 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000140
Chris Dalton27059d32018-01-23 14:06:50 -0700141 // For future reference on Desktop GL, GL_PRIMITIVE_RESTART_FIXED_INDEX appears in 4.3, and
142 // GL_PRIMITIVE_RESTART (where the client must call glPrimitiveRestartIndex) appears in 3.1.
143 if (kGLES_GrGLStandard == standard) {
144 // Primitive restart can cause a 3x slowdown on Adreno. Enable conservatively.
145 // TODO: Evaluate on PowerVR.
146 // FIXME: Primitive restart would likely be a win on iOS if we had an enum value for it.
147 if (kARM_GrGLVendor == ctxInfo.vendor()) {
148 fUsePrimitiveRestart = version >= GR_GL_VER(3,0);
149 }
150 }
151
Chris Dalton344e9032017-12-11 15:42:09 -0700152 if (kARM_GrGLVendor == ctxInfo.vendor() ||
153 kImagination_GrGLVendor == ctxInfo.vendor() ||
154 kQualcomm_GrGLVendor == ctxInfo.vendor() ) {
155 fPreferFullscreenClears = true;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000156 }
157
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000158 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000159 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800160 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
161 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000162 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000163 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
164 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000165 }
166
cdalton626e1ff2015-06-12 13:56:46 -0700167 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
168 fDebugSupport = true;
169 } else {
170 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
171 }
172
jvanverth3f801cb2014-12-16 09:49:38 -0800173 if (kGL_GrGLStandard == standard) {
174 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
175 }
176 else {
177 fES2CompatibilitySupport = true;
178 }
179
cdalton0edea2c2015-05-21 08:27:44 -0700180 if (kGL_GrGLStandard == standard) {
181 fMultisampleDisableSupport = true;
182 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700183 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700184 }
185
kkinnunend94708e2015-07-30 22:47:04 -0700186 if (kGL_GrGLStandard == standard) {
Chris Dalton1d616352017-05-31 12:51:23 -0600187 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
188 // instanced arrays, but we could make this more granular if we wanted
189 fInstanceAttribSupport =
190 version >= GR_GL_VER(3, 2) ||
191 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
192 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
193 } else {
194 fInstanceAttribSupport =
195 version >= GR_GL_VER(3, 0) ||
196 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
197 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
198 }
199
200 if (kGL_GrGLStandard == standard) {
kkinnunend94708e2015-07-30 22:47:04 -0700201 if (version >= GR_GL_VER(3, 0)) {
202 fBindFragDataLocationSupport = true;
203 }
204 } else {
205 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
206 fBindFragDataLocationSupport = true;
207 }
joshualittc1f56b52015-06-22 12:31:31 -0700208 }
209
joshualitt7bdd70a2015-10-01 06:28:11 -0700210 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
211
kkinnunene06ed252016-02-16 23:15:40 -0800212 if (kGL_GrGLStandard == standard) {
213 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
214 // We also require textureSize() support for rectangle 2D samplers which was added in
215 // GLSL 1.40.
216 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
217 fRectangleTextureSupport = true;
218 }
bsalomone179a912016-01-20 06:18:10 -0800219 }
kkinnunene06ed252016-02-16 23:15:40 -0800220 } else {
221 // Command buffer exposes this in GL ES context for Chromium reasons,
222 // but it should not be used. Also, at the time of writing command buffer
223 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800224 }
225
bsalomoncdee0092016-01-08 13:20:12 -0800226 if (kGL_GrGLStandard == standard) {
227 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
228 fTextureSwizzleSupport = true;
229 }
230 } else {
231 if (version >= GR_GL_VER(3,0)) {
232 fTextureSwizzleSupport = true;
233 }
234 }
235
cblume09bd2c02016-03-01 14:08:28 -0800236 if (kGL_GrGLStandard == standard) {
237 fMipMapLevelAndLodControlSupport = true;
238 } else if (kGLES_GrGLStandard == standard) {
239 if (version >= GR_GL_VER(3,0)) {
240 fMipMapLevelAndLodControlSupport = true;
241 }
242 }
243
bsalomon88c7b982015-07-31 11:20:16 -0700244#ifdef SK_BUILD_FOR_WIN
245 // We're assuming that on Windows Chromium we're using ANGLE.
246 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
247 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700248 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700249 fRGBA8888PixelsOpsAreSlow = isANGLE;
250 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
251 // check DX11 ANGLE.
252 fPartialFBOReadIsSlow = isANGLE;
253#endif
254
ericrkb4ecabd2016-03-11 15:18:20 -0800255 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
256 bool isMAC = false;
257#ifdef SK_BUILD_FOR_MAC
258 isMAC = true;
259#endif
260
261 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
262 // vis-versa.
263 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
264
Robert Phillipsf2ec0242018-03-01 16:51:25 -0500265 if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
266 fUseBufferDataNullHint = false;
267 } else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
268 fUseBufferDataNullHint = true;
269 }
270
Brian Salomond17b4a62017-05-23 16:53:47 -0400271 if (kGL_GrGLStandard == standard) {
272 if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
Brian Salomond17b4a62017-05-23 16:53:47 -0400273 fClearTextureSupport = true;
274 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500275 } else if (ctxInfo.hasExtension("GL_EXT_clear_texture")) {
276 fClearTextureSupport = true;
Brian Salomond17b4a62017-05-23 16:53:47 -0400277 }
278
cdalton4cd67132015-06-10 19:23:46 -0700279 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700280 * GrShaderCaps fields
281 **************************************************************************/
282
egdaniel0a482332015-10-26 08:59:10 -0700283 // This must be called after fCoreProfile is set on the GrGLCaps
Chris Dalton47c8ed32017-11-15 18:27:09 -0700284 this->initGLSL(ctxInfo, gli);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500285 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700286
Brian Osman195c05b2017-08-30 15:14:04 -0400287 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
288#if GR_TEST_UTILS
289 if (contextOptions.fSuppressPathRendering) {
290 shaderCaps->fPathRenderingSupport = false;
csmartdalton008b9d82017-02-22 12:00:42 -0700291 }
Brian Osman195c05b2017-08-30 15:14:04 -0400292#endif
egdaniel05ded892015-10-26 07:38:05 -0700293
egdaniel05ded892015-10-26 07:38:05 -0700294 // Enable supported shader-related caps
295 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500296 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700297 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
298 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600299
Brian Salomon1edc5b92016-11-29 13:43:46 -0500300 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600301
egdaniel05ded892015-10-26 07:38:05 -0700302 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500303 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700304 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600305 if (shaderCaps->fGeometryShaderSupport) {
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600306 if (ctxInfo.glslGeneration() >= k400_GrGLSLGeneration) {
307 shaderCaps->fGSInvocationsSupport = true;
308 } else if (ctxInfo.hasExtension("GL_ARB_gpu_shader5")) {
309 shaderCaps->fGSInvocationsSupport = true;
310 shaderCaps->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
311 }
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600312 }
313
Brian Salomon1edc5b92016-11-29 13:43:46 -0500314 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800315 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
Chris Dalton8fd79552018-01-11 00:46:14 -0500316 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500317 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700318
Brian Salomon1edc5b92016-11-29 13:43:46 -0500319 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700320 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800321
Chris Daltonfaca00d2018-01-19 15:56:07 -0700322 // Mali has support for geometry shaders, but in practice with ccpr they are slower than the
323 // backup impl that only uses vertex shaders.
324 if (kARM_GrGLVendor != ctxInfo.vendor()) {
325 if (ctxInfo.version() >= GR_GL_VER(3,2)) {
326 shaderCaps->fGeometryShaderSupport = true;
327 } else if (ctxInfo.hasExtension("GL_EXT_geometry_shader")) {
328 shaderCaps->fGeometryShaderSupport = true;
329 shaderCaps->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
330 }
Chris Daltonfaca00d2018-01-19 15:56:07 -0700331 shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
Chris Dalton8fd79552018-01-11 00:46:14 -0500332 }
csmartdalton1d2aed02017-02-15 21:43:20 -0700333
Brian Salomon1edc5b92016-11-29 13:43:46 -0500334 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800335 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700336 }
337
cdalton9c3f1432016-03-11 10:07:37 -0800338 // Protect ourselves against tracking huge amounts of texture state.
339 static const uint8_t kMaxSaneSamplers = 32;
340 GrGLint maxSamplers;
341 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500342 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
343 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800344 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500345 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800346 }
347 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500348 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800349 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500350 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800351
Brian Salomonbbf05752017-11-30 11:30:48 -0500352 // This is all *very* approximate.
353 switch (ctxInfo.vendor()) {
354 case kNVIDIA_GrGLVendor:
355 // We've seen a range from 100 x 100 (TegraK1, GTX660) up to 300 x 300 (GTX 1070)
356 // but it doesn't clearly align with Pascal vs Maxwell vs Kepler.
357 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 150 * 150;
358 break;
Brian Salomon64fa70a2017-11-30 11:56:25 -0500359 case kImagination_GrGLVendor:
360 // Two PowerVR Rogues, Nexus Player and Chromebook Cb5-312T (PowerVR GX6250), show that
361 // it is always a win to use multitexturing.
362 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
363 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold =
364 std::numeric_limits<size_t>::max();
365 }
366 break;
Brian Salomon0c56d472017-12-04 08:37:44 -0500367 case kATI_GrGLVendor:
368 // So far no AMD GPU shows a performance difference. A tie goes to disabling
369 // multitexturing for simplicity's sake.
370 fShaderCaps->fDisableImageMultitexturingDstRectAreaThreshold = 0;
371 break;
Brian Salomonbbf05752017-11-30 11:30:48 -0500372 default:
373 break;
374 }
375
csmartdalton485a1202016-07-13 10:16:32 -0700376 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
377 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
378 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
379 // limit this decision to specific GPU families rather than basing it on the vendor alone.
380 if (!GR_GL_MUST_USE_VBO &&
381 !fIsCoreProfile &&
382 (kARM_GrGLVendor == ctxInfo.vendor() ||
383 kImagination_GrGLVendor == ctxInfo.vendor() ||
384 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
385 fPreferClientSideDynamicBuffers = true;
386 }
387
Eric Karl5c779752017-05-08 12:02:07 -0700388 if (!contextOptions.fAvoidStencilBuffers) {
389 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
390 this->initFSAASupport(contextOptions, ctxInfo, gli);
391 this->initStencilSupport(ctxInfo);
392 }
Greg Danielcd2f5122017-05-25 10:50:40 -0400393
394 // Setup blit framebuffer
395 if (kGL_GrGLStandard != ctxInfo.standard()) {
396 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
397 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
398 kNoMSAADst_BlitFramebufferFlag |
399 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
400 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
401 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
402 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
403 // limitations.
404 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
405 kResolveMustBeFull_BlitFrambufferFlag |
406 kNoMSAADst_BlitFramebufferFlag |
407 kNoFormatConversion_BlitFramebufferFlag |
408 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
409 }
410 } else {
411 if (fUsesMixedSamples ||
412 ctxInfo.version() >= GR_GL_VER(3,0) ||
413 ctxInfo.hasExtension("GL_ARB_framebuffer_object") ||
414 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
415 fBlitFramebufferFlags = 0;
416 }
417 }
418
cdalton1dd05422015-06-12 09:01:18 -0700419 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000420
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000421 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000422 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
423 // extension includes glMapBuffer.
424 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
425 fMapBufferFlags |= kSubset_MapFlag;
426 fMapBufferType = kMapBufferRange_MapBufferType;
427 } else {
428 fMapBufferType = kMapBuffer_MapBufferType;
429 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000430 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000431 // Unextended GLES2 doesn't have any buffer mapping.
432 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800433 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800434 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
435 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800436 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
437 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
438 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000439 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
440 fMapBufferFlags = kCanMap_MapFlag;
441 fMapBufferType = kMapBuffer_MapBufferType;
442 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000443 }
444
jvanverthd7a2c1f2015-12-07 07:36:44 -0800445 if (kGL_GrGLStandard == standard) {
446 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
447 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700448 }
Brian Salomon01b476a2018-01-23 11:06:41 -0500449 } else {
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400450 if (version >= GR_GL_VER(3, 0) ||
451 (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
452 // GL_EXT_unpack_subimage needed to support subtexture rectangles
453 ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
jvanverthd7a2c1f2015-12-07 07:36:44 -0800454 fTransferBufferType = kPBO_TransferBufferType;
Jim Van Verth2e5eaf02017-06-21 15:55:46 -0400455// TODO: get transfer buffers working in Chrome
456// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
457// fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800458 }
459 }
460
joshualitte5b74c62015-06-01 14:17:47 -0700461 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
462 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700463 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700464#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500465 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
466 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
467 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700468 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700469#else
cdalton397536c2016-03-25 12:15:03 -0700470 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700471#endif
joshualitte5b74c62015-06-01 14:17:47 -0700472 }
473
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000474 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000475 fNPOTTextureTileSupport = true;
476 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000477 } else {
478 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000479 // ES3 has no limitations.
480 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
481 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000482 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
483 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
484 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
485 // to alllow arbitrary wrap modes, however.
486 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000487 }
488
bsalomon@google.combcce8922013-03-25 15:38:39 +0000489 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
490 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
491 // Our render targets are always created with textures as the color
492 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000493 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
Chris Dalton2612bae2018-02-22 13:41:37 -0700494 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
495
496 if (kARM_GrGLVendor == ctxInfo.vendor()) {
497 // On Mali G71, RT's above 4k have been observed to incur a performance cost.
498 fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize);
499 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000500
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000501 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
502
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000503 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700504 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000505
robertphillips1b8e1b52015-06-24 06:54:10 -0700506#if 0
507 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
508 kQualcomm_GrGLVendor != ctxInfo.vendor();
509#endif
510
csmartdalton9bc11872016-08-09 12:42:47 -0700511 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
512 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700513 }
514
robertphillips63926682015-08-20 09:39:02 -0700515#ifdef SK_BUILD_FOR_WIN
516 // On ANGLE deferring flushes can lead to GPU starvation
517 fPreferVRAMUseOverFlushes = !isANGLE;
518#endif
519
bsalomon7dea7b72015-08-19 08:26:51 -0700520 if (kChromium_GrGLDriver == ctxInfo.driver()) {
521 fMustClearUploadedBufferData = true;
522 }
523
bsalomond08ea5f2015-02-20 06:58:13 -0800524 if (kGL_GrGLStandard == standard) {
525 // ARB allows mixed size FBO attachments, EXT does not.
526 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
527 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
528 fOversizedStencilSupport = true;
529 } else {
530 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
531 }
532 } else {
533 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
534 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
535 }
536
joshualitt58001552015-06-26 12:46:36 -0700537 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700538 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
539 ctxInfo.hasExtension("GL_ARB_draw_indirect");
540 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
541 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700542 (fDrawIndirectSupport &&
543 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700544 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700545 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800546 } else {
547 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700548 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
549 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
550 fBaseInstanceSupport = fDrawIndirectSupport &&
551 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700552 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800553 }
554
ethannicholas28ef4452016-03-25 09:26:03 -0700555 if (kGL_GrGLStandard == standard) {
Brian Salomon01b476a2018-01-23 11:06:41 -0500556 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading"))) {
ethannicholas28ef4452016-03-25 09:26:03 -0700557 fSampleShadingSupport = true;
558 }
559 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
560 fSampleShadingSupport = true;
561 }
562
jvanverth84741b32016-09-30 08:39:02 -0700563 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
564 if (kGL_GrGLStandard == standard) {
565 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
566 fFenceSyncSupport = true;
567 }
Brian Osman93a23462017-06-21 15:13:39 -0400568 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_APPLE_sync")) {
jvanverth84741b32016-09-30 08:39:02 -0700569 fFenceSyncSupport = true;
570 }
571
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400572 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500573 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500574
brianosman20471892016-12-02 06:43:32 -0800575 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
Brian Salomon01b476a2018-01-23 11:06:41 -0500576
brianosman851c2382016-12-07 10:03:25 -0800577 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
578 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800579
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400580 if (kGL_GrGLStandard == standard) {
581 if (version >= GR_GL_VER(4, 1)) {
582 fProgramBinarySupport = true;
583 }
584 } else if (version >= GR_GL_VER(3, 0)) {
585 fProgramBinarySupport = true;
586 }
Ethan Nicholas98ad5b72018-03-13 09:53:02 -0400587 if (fProgramBinarySupport) {
588 GrGLint count;
589 GR_GL_GetIntegerv(gli, GR_GL_NUM_SHADER_BINARY_FORMATS, &count);
590 fProgramBinarySupport = count > 0;
591 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400592
bsalomoncdee0092016-01-08 13:20:12 -0800593 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
594 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800595 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700596
Brian Salomon01b476a2018-01-23 11:06:41 -0500597 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
598 this->applyDriverCorrectnessWorkarounds(ctxInfo, contextOptions, shaderCaps);
599 }
600
cdalton4cd67132015-06-10 19:23:46 -0700601 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500602 shaderCaps->applyOptionsOverrides(contextOptions);
Chris Dalton0a94e4c2018-01-18 15:06:50 -0700603
Brian Salomon01b476a2018-01-23 11:06:41 -0500604 // For now these two are equivalent but we could have dst read in shader via some other method.
605 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000606}
607
egdaniel472d44e2015-10-22 08:20:00 -0700608const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
609 bool isCoreProfile) {
610 switch (generation) {
611 case k110_GrGLSLGeneration:
612 if (kGLES_GrGLStandard == standard) {
613 // ES2s shader language is based on version 1.20 but is version
614 // 1.00 of the ES language.
615 return "#version 100\n";
616 } else {
617 SkASSERT(kGL_GrGLStandard == standard);
618 return "#version 110\n";
619 }
620 case k130_GrGLSLGeneration:
621 SkASSERT(kGL_GrGLStandard == standard);
622 return "#version 130\n";
623 case k140_GrGLSLGeneration:
624 SkASSERT(kGL_GrGLStandard == standard);
625 return "#version 140\n";
626 case k150_GrGLSLGeneration:
627 SkASSERT(kGL_GrGLStandard == standard);
628 if (isCoreProfile) {
629 return "#version 150\n";
630 } else {
631 return "#version 150 compatibility\n";
632 }
633 case k330_GrGLSLGeneration:
634 if (kGLES_GrGLStandard == standard) {
635 return "#version 300 es\n";
636 } else {
637 SkASSERT(kGL_GrGLStandard == standard);
638 if (isCoreProfile) {
639 return "#version 330\n";
640 } else {
641 return "#version 330 compatibility\n";
642 }
643 }
cdalton33ad7012016-02-22 07:55:44 -0800644 case k400_GrGLSLGeneration:
645 SkASSERT(kGL_GrGLStandard == standard);
646 if (isCoreProfile) {
647 return "#version 400\n";
648 } else {
649 return "#version 400 compatibility\n";
650 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500651 case k420_GrGLSLGeneration:
652 SkASSERT(kGL_GrGLStandard == standard);
653 if (isCoreProfile) {
654 return "#version 420\n";
655 }
656 else {
657 return "#version 420 compatibility\n";
658 }
egdaniel472d44e2015-10-22 08:20:00 -0700659 case k310es_GrGLSLGeneration:
660 SkASSERT(kGLES_GrGLStandard == standard);
661 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800662 case k320es_GrGLSLGeneration:
663 SkASSERT(kGLES_GrGLStandard == standard);
664 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700665 }
666 return "<no version>";
667}
668
Chris Dalton47c8ed32017-11-15 18:27:09 -0700669bool is_float_fp32(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, GrGLenum precision) {
670 if (kGLES_GrGLStandard != ctxInfo.standard() &&
671 ctxInfo.version() < GR_GL_VER(4,1) &&
672 !ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
673 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
674 return true;
675 }
676 // glGetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Hopefully the
677 // geometry shaders don't have lower precision than vertex and fragment.
678 for (GrGLenum shader : {GR_GL_FRAGMENT_SHADER, GR_GL_VERTEX_SHADER}) {
679 GrGLint range[2];
680 GrGLint bits;
681 GR_GL_GetShaderPrecisionFormat(gli, shader, precision, range, &bits);
682 if (range[0] < 127 || range[1] < 127 || bits < 23) {
683 return false;
684 }
685 }
686 return true;
687}
688
689void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
egdaniel472d44e2015-10-22 08:20:00 -0700690 GrGLStandard standard = ctxInfo.standard();
691 GrGLVersion version = ctxInfo.version();
692
693 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500694 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700695 **************************************************************************/
696
Brian Salomon1edc5b92016-11-29 13:43:46 -0500697 GrShaderCaps* shaderCaps = fShaderCaps.get();
698 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700699 if (kGLES_GrGLStandard == standard) {
700 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500701 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
702 shaderCaps->fFBFetchSupport = true;
703 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
704 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700705 }
706 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
707 // 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 -0500708 shaderCaps->fFBFetchNeedsCustomOutput = false;
709 shaderCaps->fFBFetchSupport = true;
710 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
711 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700712 }
713 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
714 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500715 shaderCaps->fFBFetchNeedsCustomOutput = false;
716 shaderCaps->fFBFetchSupport = true;
717 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
718 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700719 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500720 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700721 }
722
cdaltonc08f1962016-02-12 12:14:06 -0800723 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500724 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800725 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500726 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800727 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
728 }
Brian Salomon41274562017-09-15 09:40:03 -0700729 // Flat interpolation appears to be slow on Qualcomm GPUs (tested Adreno 405 and 530).
730 shaderCaps->fPreferFlatInterpolation = shaderCaps->fFlatInterpolationSupport &&
731 kQualcomm_GrGLVendor != ctxInfo.vendor();
cdaltonc08f1962016-02-12 12:14:06 -0800732 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500733 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800734 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
735 } else {
736 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500737 shaderCaps->fNoPerspectiveInterpolationSupport = true;
738 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800739 "GL_NV_shader_noperspective_interpolation";
740 }
741 }
742
Brian Salomon1edc5b92016-11-29 13:43:46 -0500743 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
744 shaderCaps->fGLSLGeneration,
745 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800746
Brian Salomon1edc5b92016-11-29 13:43:46 -0500747 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
748 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800749 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800750
751 // Frag Coords Convention support is not part of ES
Brian Salomon01b476a2018-01-23 11:06:41 -0500752 if (kGLES_GrGLStandard != standard &&
egdaniel8dcdedc2015-11-11 06:27:20 -0800753 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
754 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500755 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800756 }
757
758 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500759 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800760 }
761
cdalton9c3f1432016-03-11 10:07:37 -0800762 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
Brian Osmanc585e202018-04-04 14:08:27 -0400763 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
764 shaderCaps->fExternalTextureSupport = true;
Brian Osman91fba612018-03-15 14:12:04 -0400765 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
Brian Osmanc585e202018-04-04 14:08:27 -0400766 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
767 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
768 // At least one driver has been found that has this extension without the "GL_" prefix.
769 shaderCaps->fExternalTextureSupport = true;
770 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800771 }
772 }
773
cdaltonc04ce672016-03-11 14:07:38 -0800774 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500775 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800776 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500777 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700778 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
779 }
780
Brian Salomon1edc5b92016-11-29 13:43:46 -0500781 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700782 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500783 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700784 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
785 } else {
786 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
787 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500788 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700789 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500790 shaderCaps->fTexelBufferSupport = true;
791 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700792 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500793 shaderCaps->fTexelBufferSupport = true;
794 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700795 }
cdaltonc04ce672016-03-11 14:07:38 -0800796 }
797 }
798
Chris Dalton1d616352017-05-31 12:51:23 -0600799 if (kGL_GrGLStandard == standard) {
800 shaderCaps->fVertexIDSupport = true;
801 } else {
802 // Desktop GLSL 3.30 == ES GLSL 3.00.
803 shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
804 }
805
Chris Dalton7c7ff032018-03-28 20:09:58 -0600806 if (kGL_GrGLStandard == standard) {
807 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
808 } else {
809 shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration;
810 }
811
Chris Dalton47c8ed32017-11-15 18:27:09 -0700812 shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT);
813 shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT);
egdaniel472d44e2015-10-22 08:20:00 -0700814}
815
kkinnunencfe62e32015-07-01 02:58:50 -0700816bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700817 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
818
819 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700820 return false;
821 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700822
kkinnunencfe62e32015-07-01 02:58:50 -0700823 if (kGL_GrGLStandard == ctxInfo.standard()) {
824 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
825 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
826 return false;
827 }
828 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700829 if (!hasChromiumPathRendering &&
830 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700831 return false;
832 }
833 }
834 // We only support v1.3+ of GL_NV_path_rendering which allows us to
835 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
836 // additions are detected by checking the existence of the function.
837 // We also use *Then* functions that not all drivers might have. Check
838 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800839 if (!gli->fFunctions.fStencilThenCoverFillPath ||
840 !gli->fFunctions.fStencilThenCoverStrokePath ||
841 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
842 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
843 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700844 return false;
845 }
846 return true;
847}
bsalomon1aa20292016-01-22 08:16:09 -0800848
Brian Salomon71d9d842016-11-03 13:42:00 -0400849bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800850 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800851 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800852 std::function<bool ()> bindRenderTarget,
853 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400854 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800855 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400856 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800857 return false;
858 }
bsalomon7928ef62016-01-05 10:26:39 -0800859
bsalomon76148af2016-01-12 11:13:47 -0800860 GrGLenum readFormat;
861 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400862 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800863 return false;
864 }
865
bsalomon1aa20292016-01-22 08:16:09 -0800866 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800867 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
868 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
869 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
870 // 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 -0500871 // The manual does not seem to fully match the spec as the spec allows integer formats
872 // when the bound color buffer is an integer buffer. It doesn't specify which integer
873 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500874 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
875 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
876 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800877 return false;
878 }
879 // There is also a set of allowed types, but all the types we use are in the set:
880 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
881 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
882 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
883 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
884 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
885 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
886 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800887 return true;
piotaixre4b23142014-10-02 10:57:53 -0700888 }
bsalomon7928ef62016-01-05 10:26:39 -0800889
bsalomon76148af2016-01-12 11:13:47 -0800890 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500891 switch (fConfigTable[surfaceConfig].fFormatType) {
892 case kNormalizedFixedPoint_FormatType:
893 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
894 return true;
895 }
896 break;
Brian Salomonbf7b6202016-11-11 16:08:03 -0500897 case kFloat_FormatType:
898 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
899 return true;
900 }
901 break;
bsalomon7928ef62016-01-05 10:26:39 -0800902 }
903
Brian Salomon71d9d842016-11-03 13:42:00 -0400904 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800905 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400906 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800907 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800908 if (!bindRenderTarget()) {
909 return false;
910 }
911 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
912 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800913 rpFormat->fFormat = format;
914 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800915 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800916 }
917
Brian Salomon71d9d842016-11-03 13:42:00 -0400918 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
919 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700920}
921
Eric Karl5c779752017-05-08 12:02:07 -0700922void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
923 const GrGLInterface* gli) {
924 // We need dual source blending and the ability to disable multisample in order to support mixed
925 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
926 // renderer is available and enabled; no other path renderers support this feature.
927 if (fMultisampleDisableSupport &&
928 this->shaderCaps()->dualSourceBlendingSupport() &&
Brian Osman195c05b2017-08-30 15:14:04 -0400929 this->shaderCaps()->pathRenderingSupport()
930#if GR_TEST_UTILS
931 && (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover)
932#endif
933 ) {
Eric Karl5c779752017-05-08 12:02:07 -0700934 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
Robert Phillips3b3307f2017-05-24 07:44:02 -0400935 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
Eric Karl5c779752017-05-08 12:02:07 -0700936 }
937
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000938 if (kGL_GrGLStandard != ctxInfo.standard()) {
Greg Daniel25019172017-10-26 13:32:33 -0400939 if (ctxInfo.version() >= GR_GL_VER(3,0) &&
940 ctxInfo.renderer() != kGalliumLLVM_GrGLRenderer) {
941 // The gallium llvmpipe renderer for es3.0 does not have textureRed support even though
942 // it is part of the spec. Thus alpha8 will not be renderable for those devices.
943 fAlpha8IsRenderable = true;
944 }
Brian Salomon25d07fc2018-03-07 09:01:05 -0500945 // We prefer multisampled-render-to-texture extensions over ES3 MSAA because we've observed
946 // ES3 driver bugs on at least one device with a tiled GPU (N10). However, if we're using
947 // mixed samples we can't use multisampled-render-to-texture.
948 if (fUsesMixedSamples) {
949 fMSFBOType = kMixedSamples_MSFBOType;
950 } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000951 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
952 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
953 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400954 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
955 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400956 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400957 fMSFBOType = kStandard_MSFBOType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400958 } else if (ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400959 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000960 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
961 fMSFBOType = kES_Apple_MSFBOType;
962 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000963 } else {
egdanieleed519e2016-01-15 11:36:18 -0800964 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700965 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400966 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
967 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400968
Brian Salomon00731b42016-10-14 11:30:51 -0400969 fMSFBOType = kStandard_MSFBOType;
Robert Phillips5ab72762017-06-07 12:04:18 -0400970 if (!fIsCoreProfile && ctxInfo.renderer() != kOSMesa_GrGLRenderer) {
971 // Core profile removes ALPHA8 support.
972 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
973 // However, osmesa fails if it is used even when GL_ARB_framebuffer_object is
974 // present.
975 fAlpha8IsRenderable = true;
976 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000977 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
978 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Robert Phillips5ab72762017-06-07 12:04:18 -0400979 fMSFBOType = kStandard_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000980 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000981 }
Eric Karl5c779752017-05-08 12:02:07 -0700982
Brian Salomon01b476a2018-01-23 11:06:41 -0500983 // We disable MSAA across the board for Intel GPUs for performance reasons.
Robert Phillips3b3307f2017-05-24 07:44:02 -0400984 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
985 fMSFBOType = kNone_MSFBOType;
986 }
987
Eric Karl5c779752017-05-08 12:02:07 -0700988 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
989 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
990 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
Eric Karl5c779752017-05-08 12:02:07 -0700991 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000992}
993
cdalton1dd05422015-06-12 09:01:18 -0700994void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500995 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -0700996
Greg Daniel210883c2017-11-27 15:14:01 -0500997 bool layoutQualifierSupport = false;
998 if ((kGL_GrGLStandard == fStandard && shaderCaps->generation() >= k140_GrGLSLGeneration) ||
999 (kGLES_GrGLStandard == fStandard && shaderCaps->generation() >= k330_GrGLSLGeneration)) {
1000 layoutQualifierSupport = true;
1001 }
1002
cdalton1dd05422015-06-12 09:01:18 -07001003 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1004 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001005 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001006 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") &&
1007 layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001008 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001009 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001010 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1011 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001012 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
Greg Daniel210883c2017-11-27 15:14:01 -05001013 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") && layoutQualifierSupport) {
cdalton1dd05422015-06-12 09:01:18 -07001014 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001015 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001016 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1017 // slow on a particular platform.
joel.liang9764c402015-07-09 19:46:18 -07001018 }
cdalton1dd05422015-06-12 09:01:18 -07001019}
1020
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001021namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001022const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001023}
1024
Eric Karl5c779752017-05-08 12:02:07 -07001025void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001026
1027 // Build up list of legal stencil formats (though perhaps not supported on
1028 // the particular gpu/driver) from most preferred to least.
1029
1030 // these consts are in order of most preferred to least preferred
1031 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1032
1033 static const StencilFormat
1034 // internal Format stencil bits total bits packed?
1035 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1036 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1037 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1038 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001039 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001040 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1041
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001042 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001043 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001044 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001045 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1046 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1047
1048 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1049 // require FBO support we can expect these are legal formats and don't
1050 // check. These also all support the unsized GL_STENCIL_INDEX.
1051 fStencilFormats.push_back() = gS8;
1052 fStencilFormats.push_back() = gS16;
1053 if (supportsPackedDS) {
1054 fStencilFormats.push_back() = gD24S8;
1055 }
1056 fStencilFormats.push_back() = gS4;
1057 if (supportsPackedDS) {
1058 fStencilFormats.push_back() = gDS;
1059 }
1060 } else {
1061 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1062 // for other formats.
1063 // ES doesn't support using the unsized format.
1064
1065 fStencilFormats.push_back() = gS8;
1066 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001067 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1068 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001069 fStencilFormats.push_back() = gD24S8;
1070 }
1071 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1072 fStencilFormats.push_back() = gS4;
1073 }
1074 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001075}
1076
Brian Osman71a18892017-08-10 10:23:25 -04001077void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001078
Brian Osman71a18892017-08-10 10:23:25 -04001079 // We are called by the base class, which has already called beginObject(). We choose to nest
1080 // all of our caps information in a named sub-object.
1081 writer->beginObject("GL caps");
bsalomon@google.combcce8922013-03-25 15:38:39 +00001082
Brian Osman71a18892017-08-10 10:23:25 -04001083 writer->beginArray("Stencil Formats");
1084
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001085 for (int i = 0; i < fStencilFormats.count(); ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001086 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001087 writer->appendS32("stencil bits", fStencilFormats[i].fStencilBits);
1088 writer->appendS32("total bits", fStencilFormats[i].fTotalBits);
1089 writer->endObject();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001090 }
1091
Brian Osman71a18892017-08-10 10:23:25 -04001092 writer->endArray();
1093
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001094 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001095 "None",
Brian Salomon00731b42016-10-14 11:30:51 -04001096 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001097 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001098 "IMG MS To Texture",
1099 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001100 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001101 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001102 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Robert Phillips5ab72762017-06-07 12:04:18 -04001103 GR_STATIC_ASSERT(1 == kStandard_MSFBOType);
1104 GR_STATIC_ASSERT(2 == kES_Apple_MSFBOType);
1105 GR_STATIC_ASSERT(3 == kES_IMG_MsToTexture_MSFBOType);
1106 GR_STATIC_ASSERT(4 == kES_EXT_MsToTexture_MSFBOType);
1107 GR_STATIC_ASSERT(5 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001108 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001109
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001110 static const char* kInvalidateFBTypeStr[] = {
1111 "None",
1112 "Discard",
1113 "Invalidate",
1114 };
1115 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1116 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1117 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1118 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001119
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001120 static const char* kMapBufferTypeStr[] = {
1121 "None",
1122 "MapBuffer",
1123 "MapBufferRange",
1124 "Chromium",
1125 };
1126 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1127 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1128 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1129 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1130 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1131
Brian Osman71a18892017-08-10 10:23:25 -04001132 writer->appendBool("Core Profile", fIsCoreProfile);
1133 writer->appendString("MSAA Type", kMSFBOExtStr[fMSFBOType]);
1134 writer->appendString("Invalidate FB Type", kInvalidateFBTypeStr[fInvalidateFBType]);
1135 writer->appendString("Map Buffer Type", kMapBufferTypeStr[fMapBufferType]);
1136 writer->appendS32("Max FS Uniform Vectors", fMaxFragmentUniformVectors);
1137 writer->appendBool("Unpack Row length support", fUnpackRowLengthSupport);
1138 writer->appendBool("Unpack Flip Y support", fUnpackFlipYSupport);
1139 writer->appendBool("Pack Row length support", fPackRowLengthSupport);
1140 writer->appendBool("Pack Flip Y support", fPackFlipYSupport);
bsalomon@google.combcce8922013-03-25 15:38:39 +00001141
Brian Osman71a18892017-08-10 10:23:25 -04001142 writer->appendBool("Texture Usage support", fTextureUsageSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001143 writer->appendBool("Alpha8 is renderable", fAlpha8IsRenderable);
1144 writer->appendBool("GL_ARB_imaging support", fImagingSupport);
1145 writer->appendBool("Vertex array object support", fVertexArrayObjectSupport);
Brian Osman71a18892017-08-10 10:23:25 -04001146 writer->appendBool("Debug support", fDebugSupport);
1147 writer->appendBool("Draw indirect support", fDrawIndirectSupport);
1148 writer->appendBool("Multi draw indirect support", fMultiDrawIndirectSupport);
1149 writer->appendBool("Base instance support", fBaseInstanceSupport);
1150 writer->appendBool("RGBA 8888 pixel ops are slow", fRGBA8888PixelsOpsAreSlow);
1151 writer->appendBool("Partial FBO read is slow", fPartialFBOReadIsSlow);
1152 writer->appendBool("Bind uniform location support", fBindUniformLocationSupport);
1153 writer->appendBool("Rectangle texture support", fRectangleTextureSupport);
1154 writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
1155 writer->appendBool("BGRA to RGBA readback conversions are slow",
1156 fRGBAToBGRAReadbackConversionsAreSlow);
Robert Phillipsf2ec0242018-03-01 16:51:25 -05001157 writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
Brian Salomon43f8bf02017-10-18 08:33:29 -04001158 writer->appendBool("Draw To clear color", fUseDrawToClearColor);
1159 writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
Brian Osman71a18892017-08-10 10:23:25 -04001160 writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",
1161 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
1162 writer->appendBool("Intermediate texture for all updates of textures bound to FBOs",
1163 fUseDrawInsteadOfAllRenderTargetWrites);
Chris Daltoncc604e52017-10-06 16:27:32 -06001164 writer->appendBool("Max instances per glDrawArraysInstanced without crashing (or zero)",
1165 fMaxInstancesPerDrawArraysWithoutCrashing);
bsalomon41e4384e2016-01-08 09:12:44 -08001166
Brian Osman71a18892017-08-10 10:23:25 -04001167 writer->beginArray("configs");
1168
bsalomon41e4384e2016-01-08 09:12:44 -08001169 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Osman80488222017-08-10 13:29:30 -04001170 writer->beginObject(nullptr, false);
Brian Osman71a18892017-08-10 10:23:25 -04001171 writer->appendHexU32("flags", fConfigTable[i].fFlags);
1172 writer->appendHexU32("b_internal", fConfigTable[i].fFormats.fBaseInternalFormat);
1173 writer->appendHexU32("s_internal", fConfigTable[i].fFormats.fSizedInternalFormat);
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001174 writer->appendHexU32("e_format_read_pixels",
1175 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage]);
Brian Osman71a18892017-08-10 10:23:25 -04001176 writer->appendHexU32(
1177 "e_format_teximage",
1178 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage]);
1179 writer->appendHexU32("e_type", fConfigTable[i].fFormats.fExternalType);
1180 writer->appendHexU32("i_for_teximage", fConfigTable[i].fFormats.fInternalFormatTexImage);
1181 writer->appendHexU32("i_for_renderbuffer",
1182 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
1183 writer->endObject();
bsalomon41e4384e2016-01-08 09:12:44 -08001184 }
1185
Brian Osman71a18892017-08-10 10:23:25 -04001186 writer->endArray();
1187 writer->endObject();
jvanverthe9c0fc62015-04-29 11:18:05 -07001188}
1189
bsalomon41e4384e2016-01-08 09:12:44 -08001190bool GrGLCaps::bgraIsInternalFormat() const {
1191 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1192}
1193
bsalomon76148af2016-01-12 11:13:47 -08001194bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1195 GrGLenum* internalFormat, GrGLenum* externalFormat,
1196 GrGLenum* externalType) const {
1197 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1198 externalFormat, externalType)) {
1199 return false;
1200 }
1201 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1202 return true;
1203}
1204
bsalomon76148af2016-01-12 11:13:47 -08001205bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1206 GrGLenum* externalFormat, GrGLenum* externalType) const {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001207 if (!this->getExternalFormat(surfaceConfig, externalConfig, kReadPixels_ExternalFormatUsage,
bsalomon76148af2016-01-12 11:13:47 -08001208 externalFormat, externalType)) {
1209 return false;
1210 }
1211 return true;
1212}
1213
1214bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
bsalomon76148af2016-01-12 11:13:47 -08001215 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1216 return true;
1217}
1218
1219bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1220 ExternalFormatUsage usage, GrGLenum* externalFormat,
1221 GrGLenum* externalType) const {
1222 SkASSERT(externalFormat && externalType);
bsalomon76148af2016-01-12 11:13:47 -08001223
1224 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1225 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1226
1227 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
Brian Salomon19eaf2d2018-03-19 16:06:44 -04001228 // made to work. However, this is complicated by the use of GL_RED for alpha-only textures but
1229 // is not needed currently.
bsalomon76148af2016-01-12 11:13:47 -08001230 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1231 return false;
1232 }
1233
1234 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1235 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1236
bsalomone9573312016-01-25 14:33:25 -08001237 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1238 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1239 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1240 // texture, not the red component.
1241 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
Brian Salomone609e812018-01-17 14:00:47 -05001242 if (GR_GL_RED == *externalFormat) {
bsalomone9573312016-01-25 14:33:25 -08001243 *externalFormat = GR_GL_ALPHA;
1244 }
1245 }
1246
bsalomon76148af2016-01-12 11:13:47 -08001247 return true;
1248}
1249
brianosman20471892016-12-02 06:43:32 -08001250void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1251 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001252 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001253 /*
1254 Comments on renderability of configs on various GL versions.
1255 OpenGL < 3.0:
1256 no built in support for render targets.
1257 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1258 format RGB, RGBA and NV float formats we don't use.
1259 This is the following:
1260 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1261 RGB10_A2, RGBA12,RGBA16
1262 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1263 since they aren't required by later standards and the driver can simply return
1264 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1265 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1266 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1267 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1268 This adds a lot of additional renderable sized formats, including ALPHA8.
1269 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1270 16F, 32I, 32UI, and 32F variants).
1271 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1272
1273 For both the above extensions we limit ourselves to those that are also required by
1274 OpenGL 3.0.
1275
1276 OpenGL 3.0:
1277 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1278 but are not required to be supported as renderable textures/renderbuffer.
1279 Required renderable color formats:
1280 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1281 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1282 RGB10_A2.
1283 - R11F_G11F_B10F.
1284 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1285 and RG8UI.
1286 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1287 - ALPHA8
1288
1289 OpenGL 3.1, 3.2, 3.3
1290 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1291 OpengGL 3.3, 4.0, 4.1
1292 Adds RGB10_A2UI.
1293 OpengGL 4.2
1294 Adds
1295 - RGB5_A1, RGBA4
1296 - RGB565
1297 OpenGL 4.4
1298 Does away with the separate list and adds a column to the sized internal color format
1299 table. However, no new formats become required color renderable.
1300
1301 ES 2.0
1302 color renderable: RGBA4, RGB5_A1, RGB565
1303 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1304 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1305 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1306 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1307 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1308 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1309
1310 ES 3.0
1311 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1312 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1313 RGB5_A1.
1314 - RGB8 and RGB565.
1315 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1316 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1317 ES 3.1
1318 Adds RGB10_A2, RGB10_A2UI,
1319 ES 3.2
1320 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1321 */
Brian Salomon44804c02018-01-23 16:51:28 -05001322
1323 // Correctness workarounds.
1324 bool disableTextureRedForMesa = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001325 bool disableSRGBForX86PowerVR = false;
1326 bool disableSRGBWriteControlForAdreno4xx = false;
1327 bool disableR8TexStorageForANGLEGL = false;
1328 bool disableSRGBRenderWithMSAAForMacAMD = false;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001329 bool disableRGB8ForMali400 = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001330
1331 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
1332 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
1333 // and GL_RG on FBO textures.
1334 disableTextureRedForMesa = kOSMesa_GrGLRenderer == ctxInfo.renderer();
1335
1336 bool isX86PowerVR = false;
1337#if defined(SK_CPU_X86)
1338 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1339 isX86PowerVR = true;
1340 }
1341#endif
Brian Salomon44804c02018-01-23 16:51:28 -05001342 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1343 // blacklist that device (and any others that might be sharing the same driver).
1344 disableSRGBForX86PowerVR = isX86PowerVR;
1345 disableSRGBWriteControlForAdreno4xx = kAdreno4xx_GrGLRenderer == ctxInfo.renderer();
1346
1347 // Angle with es2->GL has a bug where it will hang trying to call TexSubImage on GL_R8
1348 // formats on miplevels > 0. We already disable texturing on gles > 2.0 so just need to
1349 // check that we are not going to OpenGL.
1350 disableR8TexStorageForANGLEGL = GrGLANGLEBackend::kOpenGL == ctxInfo.angleBackend();
1351
1352 // MacPro devices with AMD cards fail to create MSAA sRGB render buffers.
1353#if defined(SK_BUILD_FOR_MAC)
1354 disableSRGBRenderWithMSAAForMacAMD = kATI_GrGLVendor == ctxInfo.vendor();
1355#endif
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001356 // Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
1357 disableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
Brian Salomon44804c02018-01-23 16:51:28 -05001358 }
1359
Brian Salomon71d9d842016-11-03 13:42:00 -04001360 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1361 ConfigInfo::kFBOColorAttachment_Flag;
1362 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001363 if (kNone_MSFBOType != fMSFBOType) {
1364 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1365 }
bsalomon41e4384e2016-01-08 09:12:44 -08001366 GrGLStandard standard = ctxInfo.standard();
1367 GrGLVersion version = ctxInfo.version();
1368
cblume790d5132016-02-29 11:13:29 -08001369 bool texStorageSupported = false;
1370 if (kGL_GrGLStandard == standard) {
1371 // The EXT version can apply to either GL or GLES.
1372 texStorageSupported = version >= GR_GL_VER(4,2) ||
1373 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1374 ctxInfo.hasExtension("GL_EXT_texture_storage");
1375 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001376 texStorageSupported = version >= GR_GL_VER(3,0) ||
1377 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001378 }
1379
cdalton74b8d322016-04-11 14:47:28 -07001380 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1381
Brian Salomone609e812018-01-17 14:00:47 -05001382 bool textureRedSupport = false;
Brian Salomon44804c02018-01-23 16:51:28 -05001383
1384 if (!disableTextureRedForMesa) {
Brian Salomone609e812018-01-17 14:00:47 -05001385 if (kGL_GrGLStandard == standard) {
1386 textureRedSupport =
1387 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_rg");
1388 } else {
1389 textureRedSupport =
1390 version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_texture_rg");
1391 }
1392 }
1393
bsalomon30447372015-12-21 09:03:05 -08001394 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1395 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001396 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001397 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001398 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001399 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001400
1401 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1402 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001403 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001404 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001405 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001406 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001407 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1408 if (kGL_GrGLStandard == standard) {
1409 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1410 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001411 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001412 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1413 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1414 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1415 }
egdaniel4999df82016-01-07 17:06:04 -08001416 }
cblume790d5132016-02-29 11:13:29 -08001417 if (texStorageSupported) {
1418 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1419 }
cdalton74b8d322016-04-11 14:47:28 -07001420 if (texelBufferSupport) {
1421 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1422 }
bsalomoncdee0092016-01-08 13:20:12 -08001423 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001424
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001425 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1426 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB8;
1427 // Our external RGB data always has a byte where alpha would be. When calling read pixels we
1428 // want to read to kRGB_888x color type and ensure that gets 0xFF written. Using GL_RGB would
1429 // read back unaligned 24bit RGB color values. Note that this all a bit moot as we don't
1430 // currently expect to ever read back GrColorType::kRGB_888x because our implementation of
1431 // supportedReadPixelsColorType never returns it.
1432 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
1433 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1434 fConfigTable[kRGB_888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1435 fConfigTable[kRGB_888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1436 if (kGL_GrGLStandard == standard) {
1437 // Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be a
1438 // supported render buffer format. Since we usually use render buffers for MSAA on non-ES GL
1439 // we don't support MSAA for GL_RGB8. On 4.2+ we could check using
1440 // glGetInternalFormativ(GL_RENDERBUFFER, GL_RGB8, GL_INTERNALFORMAT_SUPPORTED, ...) if this
1441 // becomes an issue.
1442 // This also would probably work in mixed-samples mode where there is no MSAA color buffer
1443 // but we don't support that just for simplicity's sake.
1444 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= nonMSAARenderFlags;
1445 } else {
1446 // 3.0 and the extension support this as a render buffer format.
1447 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8")) {
1448 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= allRenderFlags;
1449 }
1450 }
1451 if (texStorageSupported) {
1452 fConfigTable[kRGB_888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1453 }
1454 fConfigTable[kRGB_888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1455 if (disableRGB8ForMali400) {
1456 fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
1457 }
1458
1459 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001460 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001461 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001462 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001463
1464 // TexStorage requires using a sized internal format and BGRA8 is only supported if we have the
1465 // GL_APPLE_texture_format_BGRA8888 extension or if we have GL_EXT_texutre_storage and
1466 // GL_EXT_texture_format_BGRA8888.
1467 bool supportsBGRATexStorage = false;
1468
bsalomon41e4384e2016-01-08 09:12:44 -08001469 if (kGL_GrGLStandard == standard) {
1470 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1471 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1472 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1473 // Since the internal format is RGBA8, it is also renderable.
1474 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1475 allRenderFlags;
1476 }
Greg Daniel0ff79b22018-02-15 12:33:33 -05001477 // Since we are using RGBA8 we can use tex storage.
1478 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001479 } else {
1480 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1481 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
Alexis Hetu0e90f982018-03-15 10:08:42 -04001482 if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1483 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1484 nonMSAARenderFlags;
1485
1486 if (ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1487 supportsBGRATexStorage = true;
1488 }
1489 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1490 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
1491 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1492 ConfigInfo::kRenderableWithMSAA_Flag;
1493 }
1494 } else if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
Brian Osman48c99192017-06-02 08:45:06 -04001495 // This APPLE extension introduces complexity on ES2. It leaves the internal format
1496 // as RGBA, but allows BGRA as the external format. From testing, it appears that the
1497 // driver remembers the external format when the texture is created (with TexImage).
1498 // If you then try to upload data in the other swizzle (with TexSubImage), it fails.
1499 // We could work around this, but it adds even more state tracking to code that is
1500 // already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
1501 // This also side-steps some ambiguous interactions with the texture storage extension.
1502 if (version >= GR_GL_VER(3,0)) {
1503 // The APPLE extension doesn't make this renderable.
1504 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Greg Daniel0ff79b22018-02-15 12:33:33 -05001505 supportsBGRATexStorage = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001506 }
bsalomon41e4384e2016-01-08 09:12:44 -08001507 }
1508 }
Brian Osman48c99192017-06-02 08:45:06 -04001509
Greg Daniel0ff79b22018-02-15 12:33:33 -05001510 if (texStorageSupported && supportsBGRATexStorage) {
Brian Salomon44804c02018-01-23 16:51:28 -05001511 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
cblume790d5132016-02-29 11:13:29 -08001512 }
bsalomoncdee0092016-01-08 13:20:12 -08001513 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001514
brianosmana6359362016-03-21 06:55:37 -07001515 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001516 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001517 if (kGL_GrGLStandard == standard) {
1518 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001519 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001520 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1521 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1522 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001523 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001524 }
1525 }
1526 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001527 if (fSRGBSupport) {
1528 fSRGBWriteControl = true;
1529 }
bsalomon41e4384e2016-01-08 09:12:44 -08001530 } else {
brianosman20471892016-12-02 06:43:32 -08001531 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
Brian Salomon44804c02018-01-23 16:51:28 -05001532 if (disableSRGBForX86PowerVR) {
brianosman20471892016-12-02 06:43:32 -08001533 fSRGBSupport = false;
1534 }
bsalomon41e4384e2016-01-08 09:12:44 -08001535 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1536 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001537 // See https://bug.skia.org/5329 for Adreno4xx issue.
Brian Salomon44804c02018-01-23 16:51:28 -05001538 fSRGBWriteControl = !disableSRGBWriteControlForAdreno4xx &&
brianosmanc9986b62016-05-23 06:23:27 -07001539 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001540 }
brianosman20471892016-12-02 06:43:32 -08001541 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1542 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1543 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001544 fSRGBSupport = false;
1545 }
brianosman20471892016-12-02 06:43:32 -08001546
1547 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1548 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1549 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1550 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1551 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1552 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1553 // affects Windows.
1554 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1555 fSRGBSupport = false;
1556 }
1557
Brian Osman48c99192017-06-02 08:45:06 -04001558 // ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
1559 // not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
1560 bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
1561
Brian Osman67999392017-05-31 16:19:34 -04001562 uint32_t srgbRenderFlags = allRenderFlags;
Brian Salomon44804c02018-01-23 16:51:28 -05001563 if (disableSRGBRenderWithMSAAForMacAMD) {
Brian Osman67999392017-05-31 16:19:34 -04001564 srgbRenderFlags &= ~ConfigInfo::kRenderableWithMSAA_Flag;
1565 }
Brian Osman67999392017-05-31 16:19:34 -04001566
bsalomon30447372015-12-21 09:03:05 -08001567 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1568 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1569 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1570 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001571 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001572 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001573 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001574 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001575 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001576 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001577 srgbRenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001578 }
Brian Osman48c99192017-06-02 08:45:06 -04001579 // ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
1580 if (texStorageSupported && !isCommandBufferES2) {
cblume790d5132016-02-29 11:13:29 -08001581 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1582 }
bsalomoncdee0092016-01-08 13:20:12 -08001583 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
brianosmana6359362016-03-21 06:55:37 -07001584 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1585 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1586 // is in this format, for example).
1587 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1588 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1589 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1590 // external format is GL_BGRA.
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001591 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
brianosmana6359362016-03-21 06:55:37 -07001592 GR_GL_BGRA;
1593 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1594 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001595 if (fSRGBSupport && kGL_GrGLStandard == standard) {
brianosmana6359362016-03-21 06:55:37 -07001596 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Osman67999392017-05-31 16:19:34 -04001597 srgbRenderFlags;
brianosmana6359362016-03-21 06:55:37 -07001598 }
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001599
brianosmana6359362016-03-21 06:55:37 -07001600 if (texStorageSupported) {
1601 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1602 }
1603 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1604
bsalomon30447372015-12-21 09:03:05 -08001605 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1606 if (this->ES2CompatibilitySupport()) {
1607 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1608 } else {
1609 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1610 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001611 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001612 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001613 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001614 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001615 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1616 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001617 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001618 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1619 }
1620 } else {
1621 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1622 }
cblume790d5132016-02-29 11:13:29 -08001623 // 565 is not a sized internal format on desktop GL. So on desktop with
1624 // 565 we always use an unsized internal format to let the system pick
1625 // the best sized format to convert the 565 data to. Since TexStorage
1626 // only allows sized internal formats we disallow it.
1627 //
1628 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1629 // update.
1630 if (texStorageSupported && kGL_GrGLStandard != standard) {
1631 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1632 }
bsalomoncdee0092016-01-08 13:20:12 -08001633 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001634
1635 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1636 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001637 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001638 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001639 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001640 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001641 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1642 if (kGL_GrGLStandard == standard) {
1643 if (version >= GR_GL_VER(4, 2)) {
1644 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1645 }
1646 } else {
1647 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1648 }
cblume790d5132016-02-29 11:13:29 -08001649 if (texStorageSupported) {
1650 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1651 }
bsalomoncdee0092016-01-08 13:20:12 -08001652 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001653
Brian Osman10fc6fd2018-03-02 11:01:10 -05001654 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1655 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB10_A2;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001656 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
Brian Osman10fc6fd2018-03-02 11:01:10 -05001657 GR_GL_RGBA;
1658 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormats.fExternalType =
1659 GR_GL_UNSIGNED_INT_2_10_10_10_REV;
1660 fConfigTable[kRGBA_1010102_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1661 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 0)) {
1662 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1663 allRenderFlags;
1664 }
1665 if (texStorageSupported) {
1666 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1667 }
1668 if (texelBufferSupport) {
1669 fConfigTable[kRGBA_1010102_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1670 }
1671 fConfigTable[kRGBA_1010102_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1672
Greg Danielef59d872017-11-17 16:47:21 -05001673 bool alpha8IsValidForGL = kGL_GrGLStandard == standard &&
1674 (!fIsCoreProfile || version <= GR_GL_VER(3, 0));
1675
1676 ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
1677 alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1678 alphaInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1679 if (alpha8IsValidForGL || (kGL_GrGLStandard != standard && version < GR_GL_VER(3, 0))) {
1680 alphaInfo.fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001681 }
Greg Danielef59d872017-11-17 16:47:21 -05001682 alphaInfo.fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1683 alphaInfo.fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001684 alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
Greg Danielef59d872017-11-17 16:47:21 -05001685 alphaInfo.fSwizzle = GrSwizzle::AAAA();
1686 if (fAlpha8IsRenderable && alpha8IsValidForGL) {
1687 alphaInfo.fFlags |= allRenderFlags;
1688 }
1689
1690 ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
1691 redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1692 redInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1693 redInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1694 redInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001695 redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001696 redInfo.fSwizzle = GrSwizzle::RRRR();
Robert Phillips5ab72762017-06-07 12:04:18 -04001697
Brian Osman48c99192017-06-02 08:45:06 -04001698 // ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
1699 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001700 if (!disableR8TexStorageForANGLEGL) {
Greg Danielef59d872017-11-17 16:47:21 -05001701 alphaInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1702 }
1703 redInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1704 }
1705
Brian Salomone609e812018-01-17 14:00:47 -05001706 if (textureRedSupport) {
Greg Danielef59d872017-11-17 16:47:21 -05001707 redInfo.fFlags |= ConfigInfo::kTextureable_Flag | allRenderFlags;
1708 if (texelBufferSupport) {
1709 redInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1710 }
1711
1712 fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
1713 } else {
1714 redInfo.fFlags = 0;
1715
1716 fConfigTable[kAlpha_8_GrPixelConfig] = alphaInfo;
cblume790d5132016-02-29 11:13:29 -08001717 }
bsalomon41e4384e2016-01-08 09:12:44 -08001718
Greg Daniel7af060a2017-12-05 16:27:11 -05001719 ConfigInfo& grayLumInfo = fConfigTable[kGray_8_as_Lum_GrPixelConfig];
1720 grayLumInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1721 grayLumInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1722 grayLumInfo.fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1723 grayLumInfo.fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001724 grayLumInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
Greg Daniel7af060a2017-12-05 16:27:11 -05001725 grayLumInfo.fSwizzle = GrSwizzle::RGBA();
1726 if ((standard == kGL_GrGLStandard && version <= GR_GL_VER(3, 0)) ||
1727 (standard == kGLES_GrGLStandard && version < GR_GL_VER(3, 0))) {
1728 grayLumInfo.fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001729 }
Greg Daniel7af060a2017-12-05 16:27:11 -05001730
1731 ConfigInfo& grayRedInfo = fConfigTable[kGray_8_as_Red_GrPixelConfig];
1732 grayRedInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1733 grayRedInfo.fFormatType = kNormalizedFixedPoint_FormatType;
1734 grayRedInfo.fFormats.fBaseInternalFormat = GR_GL_RED;
1735 grayRedInfo.fFormats.fSizedInternalFormat = GR_GL_R8;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001736 grayRedInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Daniel7af060a2017-12-05 16:27:11 -05001737 grayRedInfo.fSwizzle = GrSwizzle::RRRA();
1738 grayRedInfo.fFlags = ConfigInfo::kTextureable_Flag;
1739
1740#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster. Needs to be
1741 // updated to support Gray8_as_Lum and Gray8_as_red if this is ever enabled.
Brian Osman986563b2017-01-10 14:20:02 -05001742 if (this->textureRedSupport() ||
1743 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1744 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1745 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1746 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1747 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1748 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1749 }
1750#endif
Brian Osman48c99192017-06-02 08:45:06 -04001751 if (texStorageSupported && !isCommandBufferES2) {
Brian Salomon44804c02018-01-23 16:51:28 -05001752 if (!disableR8TexStorageForANGLEGL) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001753 grayLumInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1754 }
1755 grayRedInfo.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1756 }
1757
Brian Salomone609e812018-01-17 14:00:47 -05001758 if (textureRedSupport) {
Greg Daniel7af060a2017-12-05 16:27:11 -05001759 if (texelBufferSupport) {
1760 grayRedInfo.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1761 }
1762 fConfigTable[kGray_8_GrPixelConfig] = grayRedInfo;
1763 } else {
1764 grayRedInfo.fFlags = 0;
1765 fConfigTable[kGray_8_GrPixelConfig] = grayLumInfo;
Brian Osman986563b2017-01-10 14:20:02 -05001766 }
1767
bsalomon41e4384e2016-01-08 09:12:44 -08001768 // Check for [half] floating point texture support
1769 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1770 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1771 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1772 bool hasFPTextures = false;
1773 bool hasHalfFPTextures = false;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001774 bool rgIsTexturable = false;
bsalomon41e4384e2016-01-08 09:12:44 -08001775 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001776 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001777
1778 if (kGL_GrGLStandard == standard) {
Greg Danielef59d872017-11-17 16:47:21 -05001779 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001780 hasFPTextures = true;
1781 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001782 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001783 }
1784 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001785 if (version >= GR_GL_VER(3, 0)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001786 hasFPTextures = true;
1787 hasHalfFPTextures = true;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001788 rgIsTexturable = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001789 } else {
1790 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1791 ctxInfo.hasExtension("GL_OES_texture_float")) {
1792 hasFPTextures = true;
1793 }
1794 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1795 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1796 hasHalfFPTextures = true;
1797 }
1798 }
1799 }
bsalomon30447372015-12-21 09:03:05 -08001800
csmartdalton6aa0e112017-02-08 16:14:11 -05001801 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1802 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1803 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1804 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1805 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001806 fConfigTable[fpconfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = format;
csmartdalton6aa0e112017-02-08 16:14:11 -05001807 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1808 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1809 if (hasFPTextures) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001810 fConfigTable[fpconfig].fFlags = rgIsTexturable ? ConfigInfo::kTextureable_Flag : 0;
csmartdalton6aa0e112017-02-08 16:14:11 -05001811 // For now we only enable rendering to float on desktop, because on ES we'd have to
1812 // solve many precision issues and no clients actually want this yet.
1813 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1814 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1815 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1816 }
bsalomon41e4384e2016-01-08 09:12:44 -08001817 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001818 if (texStorageSupported) {
1819 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1820 }
1821 if (texelBufferSupport) {
1822 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1823 }
1824 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001825 }
bsalomon30447372015-12-21 09:03:05 -08001826
Greg Danielef59d872017-11-17 16:47:21 -05001827 GrGLenum redHalfExternalType;
Brian Osmanb092cea2017-11-17 19:14:55 +00001828 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
Greg Danielef59d872017-11-17 16:47:21 -05001829 redHalfExternalType = GR_GL_HALF_FLOAT;
Brian Osmanb092cea2017-11-17 19:14:55 +00001830 } else {
Greg Danielef59d872017-11-17 16:47:21 -05001831 redHalfExternalType = GR_GL_HALF_FLOAT_OES;
Brian Osmanb092cea2017-11-17 19:14:55 +00001832 }
Greg Danielef59d872017-11-17 16:47:21 -05001833 ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
1834 redHalf.fFormats.fExternalType = redHalfExternalType;
1835 redHalf.fFormatType = kFloat_FormatType;
1836 redHalf.fFormats.fBaseInternalFormat = GR_GL_RED;
1837 redHalf.fFormats.fSizedInternalFormat = GR_GL_R16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001838 redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
Greg Danielef59d872017-11-17 16:47:21 -05001839 redHalf.fSwizzle = GrSwizzle::RRRR();
Brian Salomone609e812018-01-17 14:00:47 -05001840 if (textureRedSupport && hasHalfFPTextures) {
Greg Danielef59d872017-11-17 16:47:21 -05001841 redHalf.fFlags = ConfigInfo::kTextureable_Flag;
1842
csmartdalton6aa0e112017-02-08 16:14:11 -05001843 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
Brian Salomone609e812018-01-17 14:00:47 -05001844 (textureRedSupport && ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
Greg Danielef59d872017-11-17 16:47:21 -05001845 redHalf.fFlags |= fpRenderFlags;
1846 }
1847
1848 if (texStorageSupported && !isCommandBufferES2) {
1849 redHalf.fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1850 }
1851
1852 if (texelBufferSupport) {
1853 redHalf.fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
csmartdalton6aa0e112017-02-08 16:14:11 -05001854 }
1855 }
Greg Danielef59d872017-11-17 16:47:21 -05001856 fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
bsalomon30447372015-12-21 09:03:05 -08001857
1858 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1859 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001860 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
bsalomon76148af2016-01-12 11:13:47 -08001861 GR_GL_RGBA;
Geoff Lang4b050002017-09-28 15:16:50 -04001862 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
bsalomon30447372015-12-21 09:03:05 -08001863 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1864 } else {
1865 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1866 }
bsalomon7928ef62016-01-05 10:26:39 -08001867 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001868 if (hasHalfFPTextures) {
1869 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1870 // ES requires 3.2 or EXT_color_buffer_half_float.
1871 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1872 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1873 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1874 }
1875 }
cblume790d5132016-02-29 11:13:29 -08001876 if (texStorageSupported) {
1877 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1878 }
cdalton74b8d322016-04-11 14:47:28 -07001879 if (texelBufferSupport) {
1880 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1881 }
bsalomoncdee0092016-01-08 13:20:12 -08001882 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001883
bsalomon30447372015-12-21 09:03:05 -08001884 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1885
1886 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001887 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1888 ctxInfo.version() >= GR_GL_VER(3,0));
1889 // All ES versions (thus far) require sized internal formats for render buffers.
1890 // TODO: Always use sized internal format?
1891 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1892
bsalomon30447372015-12-21 09:03:05 -08001893 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001894 // Almost always we want to pass fExternalFormat[kReadPixels_ExternalFormatUsage] as the
1895 // <format> param to glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001896 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001897 fConfigTable[i].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage];
bsalomon76148af2016-01-12 11:13:47 -08001898 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1899 fConfigTable[i].fFormats.fSizedInternalFormat :
1900 fConfigTable[i].fFormats.fBaseInternalFormat;
1901 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001902 fConfigTable[i].fFormats.fSizedInternalFormat :
1903 fConfigTable[i].fFormats.fBaseInternalFormat;
1904 }
Brian Salomon44804c02018-01-23 16:51:28 -05001905 // If we're on ES 3.0+ but because of a driver workaround selected GL_ALPHA to implement the
1906 // kAlpha_8_GrPixelConfig then we actually have to use a base internal format rather than a
1907 // sized internal format. This is because there is no valid 8 bit alpha sized internal format
1908 // in ES.
1909 if (useSizedTexFormats && kGLES_GrGLStandard == ctxInfo.standard() && !textureRedSupport) {
1910 SkASSERT(fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_ALPHA8);
1911 SkASSERT(fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat ==
1912 GR_GL_ALPHA8);
Greg Daniel8713b882017-10-26 15:15:47 -04001913 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fInternalFormatTexImage =
1914 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Danielef59d872017-11-17 16:47:21 -05001915 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fInternalFormatTexImage =
1916 fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig].fFormats.fBaseInternalFormat;
Greg Daniel8713b882017-10-26 15:15:47 -04001917 }
1918
bsalomon30447372015-12-21 09:03:05 -08001919 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1920 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1921 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1922 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1923 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001924 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001925 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001926
1927 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1928 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1929 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1930 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001931 }
Brian Salomon5fba7ad2018-03-22 10:01:16 -04001932 // On ES 2.0 we have to use GL_RGB with glTexImage as the internal/external formats must
1933 // be the same. Moreover, if we write kRGB_888x data to a texture format on non-ES2 we want to
1934 // be sure that we write 1 for alpha not whatever happens to be in the client provided the 'x'
1935 // slot.
1936 fConfigTable[kRGB_888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1937 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001938
1939 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1940 // as a base format.
1941 // GL_EXT_texture_format_BGRA8888:
1942 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1943 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1944 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001945 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001946 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1947 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1948 // glTexImage (just for glTexStorage).
Greg Daniel0ff79b22018-02-15 12:33:33 -05001949 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001950 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1951 }
1952
bsalomoncdee0092016-01-08 13:20:12 -08001953 // If we don't have texture swizzle support then the shader generator must insert the
1954 // swizzle into shader code.
1955 if (!this->textureSwizzleSupport()) {
1956 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001957 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08001958 }
1959 }
1960
bsalomon7f9b2e42016-01-12 13:29:26 -08001961 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1962 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1963 // gets written to the single component.
Brian Salomone609e812018-01-17 14:00:47 -05001964 if (textureRedSupport) {
bsalomon7f9b2e42016-01-12 13:29:26 -08001965 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1966 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1967 if (GrPixelConfigIsAlphaOnly(config) &&
1968 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001969 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08001970 }
1971 }
1972 }
1973
Greg Daniel81e7bf82017-07-19 14:47:42 -04001974 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1975 if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001976 // We assume that MSAA rendering is supported only if we support non-MSAA rendering.
1977 SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags);
Greg Daniel6bd729d2017-07-31 09:38:23 -04001978 if ((kGL_GrGLStandard == ctxInfo.standard() &&
Greg Daniel81e7bf82017-07-19 14:47:42 -04001979 (ctxInfo.version() >= GR_GL_VER(4,2) ||
1980 ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
Greg Daniel6bd729d2017-07-31 09:38:23 -04001981 (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0))) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001982 int count;
1983 GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
1984 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
1985 1, &count);
1986 if (count) {
1987 int* temp = new int[count];
1988 GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
1989 temp);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001990 // GL has a concept of MSAA rasterization with a single sample but we do not.
1991 if (count && temp[count - 1] == 1) {
1992 --count;
1993 SkASSERT(!count || temp[count -1] > 1);
1994 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001995 fConfigTable[i].fColorSampleCounts.setCount(count+1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001996 // We initialize our supported values with 1 (no msaa) and reverse the order
Greg Daniel81e7bf82017-07-19 14:47:42 -04001997 // returned by GL so that the array is ascending.
Brian Salomonbdecacf2018-02-02 20:32:49 -05001998 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04001999 for (int j = 0; j < count; ++j) {
2000 fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
2001 }
2002 delete[] temp;
2003 }
2004 } else {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002005 // Fake out the table using some semi-standard counts up to the max allowed sample
2006 // count.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002007 int maxSampleCnt = 1;
Brian Salomon7f1a0742018-01-29 14:24:19 -05002008 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
2009 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt);
2010 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
2011 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt);
2012 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002013 // Chrome has a mock GL implementation that returns 0.
2014 maxSampleCnt = SkTMax(1, maxSampleCnt);
Brian Salomon7f1a0742018-01-29 14:24:19 -05002015
Brian Salomonbdecacf2018-02-02 20:32:49 -05002016 static constexpr int kDefaultSamples[] = {1, 2, 4, 8};
Greg Daniel81e7bf82017-07-19 14:47:42 -04002017 int count = SK_ARRAY_COUNT(kDefaultSamples);
2018 for (; count > 0; --count) {
Brian Salomon7f1a0742018-01-29 14:24:19 -05002019 if (kDefaultSamples[count - 1] <= maxSampleCnt) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002020 break;
2021 }
2022 }
2023 if (count > 0) {
2024 fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
2025 }
2026 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002027 } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) {
2028 fConfigTable[i].fColorSampleCounts.setCount(1);
2029 fConfigTable[i].fColorSampleCounts[0] = 1;
Greg Daniel81e7bf82017-07-19 14:47:42 -04002030 }
2031 }
2032
bsalomon30447372015-12-21 09:03:05 -08002033#ifdef SK_DEBUG
2034 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002035 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002036 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002037 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2038 // renderable.
Ben Wagnerf8a131d2018-03-13 16:56:43 -04002039 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag) &&
2040 !(fConfigTable[i].fFlags & ConfigInfo::kFBOColorAttachment_Flag)));
2041 SkASSERT(!((fConfigTable[i].fFlags & ConfigInfo::kRenderableWithMSAA_Flag) &&
2042 !(fConfigTable[i].fFlags & ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002043 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2044 fConfigTable[i].fFormats.fBaseInternalFormat);
2045 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002046 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002047 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2048 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2049 fConfigTable[i].fFormats.fExternalFormat[j]);
2050 }
2051 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002052 }
2053#endif
2054}
2055
Robert Phillipsbf25d432017-04-07 10:08:53 -04002056bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Brian Salomon2a4f9832018-03-03 22:43:43 -05002057 GrSurfaceOrigin* origin, bool* rectsMustMatch,
2058 bool* disallowSubrect) const {
Eric Karl74480882017-04-03 14:49:05 -07002059 // By default, we don't require rects to match.
2060 *rectsMustMatch = false;
2061
2062 // By default, we allow subrects.
2063 *disallowSubrect = false;
2064
Brian Salomon467921e2017-03-06 16:17:12 -05002065 // If the src is a texture, we can implement the blit as a draw assuming the config is
2066 // renderable.
Brian Salomonbdecacf2018-02-02 20:32:49 -05002067 if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002068 *origin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002069 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2070 desc->fConfig = src->config();
2071 return true;
2072 }
2073
Robert Phillipsbf25d432017-04-07 10:08:53 -04002074 {
2075 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2076 // wrapped. In that case the proxy would already be instantiated.
2077 const GrTexture* srcTexture = src->priv().peekTexture();
2078 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2079 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2080 // Not supported for FBO blit or CopyTexSubImage
2081 return false;
2082 }
Brian Salomon467921e2017-03-06 16:17:12 -05002083 }
2084
2085 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2086 // possible and we return false to fallback to creating a render target dst for render-to-
2087 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2088 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04002089 GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002090 bool rectsMustMatchForBlitFramebuffer = false;
2091 bool disallowSubrectForBlitFramebuffer = false;
Brian Salomonbdecacf2018-02-02 20:32:49 -05002092 if (src->numColorSamples() > 1 &&
Eric Karl74480882017-04-03 14:49:05 -07002093 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2094 rectsMustMatchForBlitFramebuffer = true;
2095 disallowSubrectForBlitFramebuffer = true;
2096 // Mirroring causes rects to mismatch later, don't allow it.
2097 originForBlitFramebuffer = src->origin();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002098 } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
2099 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
Eric Karl74480882017-04-03 14:49:05 -07002100 rectsMustMatchForBlitFramebuffer = true;
2101 // Mirroring causes rects to mismatch later, don't allow it.
2102 originForBlitFramebuffer = src->origin();
2103 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002104 originForBlitFramebuffer = src->origin();
2105 }
2106
2107 // Check for format issues with glCopyTexSubImage2D
2108 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2109 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2110 // then we set up for that, otherwise fail.
2111 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002112 *origin = originForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002113 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002114 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2115 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002116 return true;
2117 }
2118 return false;
2119 }
2120
Robert Phillipsbf25d432017-04-07 10:08:53 -04002121 {
Brian Salomon63e79732017-05-15 21:23:13 -04002122 bool srcIsMSAARenderbuffer = GrFSAAType::kUnifiedMSAA == src->fsaaType() &&
2123 this->usesMSAARenderBuffers();
Robert Phillipsbf25d432017-04-07 10:08:53 -04002124 if (srcIsMSAARenderbuffer) {
2125 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2126 // blit or fail.
2127 if (this->canConfigBeFBOColorAttachment(src->config())) {
Brian Salomon2a4f9832018-03-03 22:43:43 -05002128 *origin = originForBlitFramebuffer;
Robert Phillipsbf25d432017-04-07 10:08:53 -04002129 desc->fConfig = src->config();
2130 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2131 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2132 return true;
2133 }
2134 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002135 }
Brian Salomon467921e2017-03-06 16:17:12 -05002136 }
2137
2138 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
Brian Salomon2a4f9832018-03-03 22:43:43 -05002139 *origin = src->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05002140 desc->fConfig = src->config();
Brian Salomon467921e2017-03-06 16:17:12 -05002141 desc->fFlags = kNone_GrSurfaceFlags;
2142 return true;
2143}
2144
Greg Daniel691f5e72018-02-28 14:21:34 -05002145void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
2146 const GrContextOptions& contextOptions,
2147 GrShaderCaps* shaderCaps) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002148 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
2149 // Thus we are blacklisting this extension for now on Adreno4xx devices.
2150 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2151 fDiscardRenderTargetSupport = false;
2152 fInvalidateFBType = kNone_InvalidateFBType;
2153 }
2154
2155 // glClearTexImage seems to have a bug in NVIDIA drivers that was fixed sometime between
2156 // 340.96 and 367.57.
2157 if (kGL_GrGLStandard == ctxInfo.standard() &&
2158 ctxInfo.driver() == kNVIDIA_GrGLDriver &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002159 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(367, 57, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002160 fClearTextureSupport = false;
2161 }
2162
2163 // Calling glClearTexImage crashes on the NexusPlayer.
2164 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2165 fClearTextureSupport = false;
2166 }
2167
2168 // On at least some MacBooks, GLSL 4.0 geometry shaders break if we use invocations.
2169#ifdef SK_BUILD_FOR_MAC
2170 if (shaderCaps->fGeometryShaderSupport) {
2171 shaderCaps->fGSInvocationsSupport = false;
2172 }
2173#endif
2174
2175 // Qualcomm driver @103.0 has been observed to crash compiling ccpr geometry
2176 // shaders. @127.0 is the earliest verified driver to not crash.
2177 if (kQualcomm_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002178 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002179 shaderCaps->fGeometryShaderSupport = false;
2180 }
2181
2182#if defined(__has_feature)
2183#if defined(SK_BUILD_FOR_MAC) && __has_feature(thread_sanitizer)
2184 // See skbug.com/7058
2185 fMapBufferType = kNone_MapBufferType;
2186 fMapBufferFlags = kNone_MapFlags;
2187#endif
2188#endif
2189
2190 // We found that the Galaxy J5 with an Adreno 306 running 6.0.1 has a bug where
2191 // GL_INVALID_OPERATION thrown by glDrawArrays when using a buffer that was mapped. The same bug
2192 // did not reproduce on a Nexus7 2013 with a 320 running Android M with driver 127.0. It's
2193 // unclear whether this really affects a wide range of devices.
2194 if (ctxInfo.renderer() == kAdreno3xx_GrGLRenderer &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002195 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(127, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002196 fMapBufferType = kNone_MapBufferType;
2197 fMapBufferFlags = kNone_MapFlags;
2198 }
2199
2200 // TODO: re-enable for ANGLE
2201 if (kANGLE_GrGLDriver == ctxInfo.driver()) {
2202 fTransferBufferType = kNone_TransferBufferType;
2203 }
2204
2205 // Using MIPs on this GPU seems to be a source of trouble.
2206 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
2207 fMipMapSupport = false;
2208 }
2209
2210 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2211 // Temporarily disabling clip analytic fragments processors on Nexus player while we work
2212 // around a driver bug related to gl_FragCoord.
2213 // https://bugs.chromium.org/p/skia/issues/detail?id=7286
2214 fMaxClipAnalyticFPs = 0;
2215 }
2216
2217#ifndef SK_BUILD_FOR_IOS
2218 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
2219 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
2220 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
2221 ctxInfo.driver() != kChromium_GrGLDriver)) {
2222 fUseDrawToClearColor = true;
2223 }
2224#endif
2225
2226 // A lot of GPUs have trouble with full screen clears (skbug.com/7195)
2227 if (kAMDRadeonHD7xxx_GrGLRenderer == ctxInfo.renderer() ||
2228 kAMDRadeonR9M4xx_GrGLRenderer == ctxInfo.renderer()) {
2229 fUseDrawToClearColor = true;
2230 }
2231
2232#ifdef SK_BUILD_FOR_MAC
2233 // crbug.com/768134 - On MacBook Pros, the Intel Iris Pro doesn't always perform
2234 // full screen clears
2235 // crbug.com/773107 - On MacBook Pros, a wide range of Intel GPUs don't always
2236 // perform full screen clears.
Brian Salomon9a544bc2018-04-04 16:12:31 -04002237 // Update on 4/4/2018 - This appears to be fixed on driver 10.30.12 on a macOS 10.13.2 on a
2238 // Retina MBP Early 2015 with Iris 6100. It is possibly fixed on earlier drivers as well.
2239 if (kIntel_GrGLVendor == ctxInfo.vendor() &&
2240 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(10, 30, 12)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002241 fUseDrawToClearColor = true;
2242 }
2243#endif
2244
2245 // See crbug.com/755871. This could probably be narrowed to just partial clears as the driver
2246 // bugs seems to involve clearing too much and not skipping the clear.
2247 // See crbug.com/768134. This is also needed for full clears and was seen on an nVidia K620
2248 // but only for D3D11 ANGLE.
2249 if (GrGLANGLEBackend::kD3D11 == ctxInfo.angleBackend()) {
2250 fUseDrawToClearColor = true;
2251 }
2252
2253 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
2254 // This is known to be fixed sometime between driver 145.0 and 219.0
Brian Salomon9a544bc2018-04-04 16:12:31 -04002255 if (ctxInfo.driverVersion() <= GR_GL_DRIVER_VER(219, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002256 fUseDrawToClearStencilClip = true;
2257 }
2258 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2259 }
2260
2261 // This was reproduced on the following configurations:
2262 // - A Galaxy J5 (Adreno 306) running Android 6 with driver 140.0
2263 // - A Nexus 7 2013 (Adreno 320) running Android 5 with driver 104.0
2264 // - A Nexus 7 2013 (Adreno 320) running Android 6 with driver 127.0
2265 // - A Nexus 5 (Adreno 330) running Android 6 with driver 127.0
2266 // and not produced on:
2267 // - A Nexus 7 2013 (Adreno 320) running Android 4 with driver 53.0
2268 // The particular lines that get dropped from test images varies across different devices.
2269 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002270 ctxInfo.driverVersion() > GR_GL_DRIVER_VER(53, 0, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002271 fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines = true;
2272 }
2273
Chris Dalton6f5e77a2018-04-23 21:14:42 -06002274 if (kIntelSkylake_GrGLRenderer == ctxInfo.renderer() ||
2275 (kANGLE_GrGLRenderer == ctxInfo.renderer() &&
2276 GrGLANGLERenderer::kSkylake == ctxInfo.angleRenderer())) {
Chris Daltonda40cd22018-04-16 13:19:58 -06002277 fRequiresFlushBetweenNonAndInstancedDraws = true;
2278 }
2279
Brian Salomon01b476a2018-01-23 11:06:41 -05002280 // Our Chromebook with kPowerVRRogue_GrGLRenderer seems to crash when glDrawArraysInstanced is
2281 // given 1 << 15 or more instances.
2282 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
2283 fMaxInstancesPerDrawArraysWithoutCrashing = 0x7fff;
2284 }
2285
2286 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
Chris Dalton0090ef62018-03-28 17:35:00 -06002287 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002288 fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
2289 fUseDrawInsteadOfAllRenderTargetWrites = true;
2290 }
2291
2292 if (kGL_GrGLStandard == ctxInfo.standard() && kIntel_GrGLVendor == ctxInfo.vendor() ) {
2293 fSampleShadingSupport = false;
2294 }
2295
2296#ifdef SK_BUILD_FOR_MAC
2297 static constexpr bool isMAC = true;
2298#else
2299 static constexpr bool isMAC = false;
2300#endif
2301
2302 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
2303 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
2304 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
2305 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
2306 if (fMipMapLevelAndLodControlSupport &&
2307 (contextOptions.fDoManualMipmapping ||
2308 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
2309 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
2310 (kATI_GrGLVendor == ctxInfo.vendor()))) {
2311 fDoManualMipmapping = true;
2312 }
2313
2314 // See http://crbug.com/710443
2315#ifdef SK_BUILD_FOR_MAC
2316 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
2317 fClearToBoundaryValuesIsBroken = true;
2318 }
2319#endif
2320 if (kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2321 fDrawArraysBaseVertexIsBroken = true;
2322 }
2323
Brian Salomon01b476a2018-01-23 11:06:41 -05002324 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
2325 // Galaxy S7.
2326 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
2327 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
2328 shaderCaps->fFBFetchSupport = false;
2329 }
2330
Brian Salomon01b476a2018-01-23 11:06:41 -05002331 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
2332 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
2333
2334 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
2335 // function that may require a gradient calculation inside a conditional block may return
2336 // undefined results". This appears to be an issue with the 'any' call since even the simple
2337 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
2338 // from our GrTextureDomain processor.
2339 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
2340
2341 // Known issue on at least some Intel platforms:
2342 // http://code.google.com/p/skia/issues/detail?id=946
2343 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2344 shaderCaps->fFragCoordConventionsExtensionString = nullptr;
2345 }
2346
Chris Dalton0090ef62018-03-28 17:35:00 -06002347 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002348 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
2349 // so we must do the abs first in a separate expression.
2350 shaderCaps->fCanUseMinAndAbsTogether = false;
2351
2352 // Tegra3 fract() seems to trigger undefined behavior for negative values, so we
2353 // must avoid this condition.
2354 shaderCaps->fCanUseFractForNegativeValues = false;
2355 }
2356
2357 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
2358 // thus must us -1.0 * %s.x to work correctly
2359 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2360 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
2361 }
2362
2363 // On some Intel GPUs there is an issue where the driver outputs bogus values in the shader
2364 // when floor and abs are called on the same line. Thus we must execute an Op between them to
2365 // make sure the compiler doesn't re-inline them even if we break the calls apart.
2366 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
2367 shaderCaps->fMustDoOpBetweenFloorAndAbs = true;
2368 }
2369
2370 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
2371 // the original dst color when reading the outColor even after being written to. By using a
2372 // local outColor we can work around this bug.
2373 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
2374 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
2375 }
2376
2377 // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
2378 // color, and that uniform contains an opaque color, and the output of the shader is only based
2379 // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
2380 // that the shader always outputs opaque values. In that case, it appears to remove the shader
2381 // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
2382 // insert an extra bit of math on the uniform that confuses the compiler just enough...
2383 if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
2384 shaderCaps->fMustObfuscateUniformColor = true;
2385 }
2386#ifdef SK_BUILD_FOR_WIN
2387 // Check for ANGLE on Windows, so we can workaround a bug in D3D itself (anglebug.com/2098).
2388 //
2389 // Basically, if a shader has a construct like:
2390 //
2391 // float x = someCondition ? someValue : 0;
2392 // float2 result = (0 == x) ? float2(x, x)
2393 // : float2(2 * x / x, 0);
2394 //
2395 // ... the compiler will produce an error 'NaN and infinity literals not allowed', even though
2396 // we've explicitly guarded the division with a check against zero. This manifests in much
2397 // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
2398 // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
2399 if (kANGLE_GrGLDriver == ctxInfo.driver() || kChromium_GrGLDriver == ctxInfo.driver()) {
2400 shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
2401 }
2402#endif
2403
2404 // We've seen Adreno 3xx devices produce incorrect (flipped) values for gl_FragCoord, in some
2405 // (rare) situations. It's sporadic, and mostly on older drivers. It also seems to be the case
2406 // that the interpolation of vertex shader outputs is quite inaccurate.
2407 if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
2408 shaderCaps->fCanUseFragCoord = false;
2409 shaderCaps->fInterpolantsAreInaccurate = true;
2410 }
2411
Chris Dalton0090ef62018-03-28 17:35:00 -06002412 // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
2413 if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
2414 shaderCaps->fCanUseFragCoord = false;
2415 }
2416
Chris Daltonc2d0dd62018-03-07 07:46:10 -07002417 // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
2418 // (Are they implemented with fp16?)
2419 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2420 shaderCaps->fIncompleteShortIntPrecision = true;
2421 }
2422
Brian Salomon01b476a2018-01-23 11:06:41 -05002423 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
2424 // for now until its own blacklists can be updated.
2425 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
2426 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
2427 kIntel_GrGLDriver == ctxInfo.driver() ||
2428 kChromium_GrGLDriver == ctxInfo.driver()) {
2429 fBlendEquationSupport = kBasic_BlendEquationSupport;
2430 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2431 }
2432
2433 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
2434 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002435 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337, 00, 0) &&
Brian Salomon4e69f142018-01-24 09:28:28 -05002436 kAdvanced_BlendEquationSupport == fBlendEquationSupport) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002437 fBlendEquationSupport = kBasic_BlendEquationSupport;
2438 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
2439 }
2440
2441 if (this->advancedBlendEquationSupport()) {
2442 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
Brian Salomon9a544bc2018-04-04 16:12:31 -04002443 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355, 00, 0)) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002444 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
2445 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
2446 (1 << kColorBurn_GrBlendEquation);
2447 }
2448 if (kARM_GrGLVendor == ctxInfo.vendor()) {
2449 // Blacklist color-burn on ARM until the fix is released.
2450 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
2451 }
2452 }
2453
2454 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
2455 if (fMultisampleDisableSupport &&
2456 this->shaderCaps()->dualSourceBlendingSupport() &&
2457 this->shaderCaps()->pathRenderingSupport() &&
2458 fUsesMixedSamples &&
2459#if GR_TEST_UTILS
2460 (contextOptions.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) &&
2461#endif
2462 (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
2463 kChromium_GrGLDriver == ctxInfo.driver())) {
2464 fDiscardRenderTargetSupport = false;
2465 fInvalidateFBType = kNone_InvalidateFBType;
2466 }
Brian Osmanc585e202018-04-04 14:08:27 -04002467
Brian Osman061020e2018-04-17 14:22:15 -04002468 // Many ES3 drivers only advertise the ES2 image_external extension, but support the _essl3
2469 // extension, and require that it be enabled to work with ESSL3. Other devices require the ES2
2470 // extension to be enabled, even when using ESSL3. Enabling both extensions fixes both cases.
2471 // skbug.com/7713
Brian Osmanc585e202018-04-04 14:08:27 -04002472 if (ctxInfo.hasExtension("GL_OES_EGL_image_external") &&
2473 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration &&
Brian Osman061020e2018-04-17 14:22:15 -04002474 !shaderCaps->fExternalTextureSupport) { // i.e. Missing the _essl3 extension
Brian Osmanc585e202018-04-04 14:08:27 -04002475 shaderCaps->fExternalTextureSupport = true;
Brian Osman061020e2018-04-17 14:22:15 -04002476 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
2477 shaderCaps->fSecondExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
Brian Osmanc585e202018-04-04 14:08:27 -04002478 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002479}
2480
csmartdaltone0d36292016-07-29 08:14:20 -07002481void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
Brian Salomon01b476a2018-01-23 11:06:41 -05002482 if (options.fDisableDriverCorrectnessWorkarounds) {
2483 SkASSERT(!fDoManualMipmapping);
2484 SkASSERT(!fClearToBoundaryValuesIsBroken);
2485 SkASSERT(0 == fMaxInstancesPerDrawArraysWithoutCrashing);
2486 SkASSERT(!fDrawArraysBaseVertexIsBroken);
2487 SkASSERT(!fUseDrawToClearColor);
2488 SkASSERT(!fUseDrawToClearStencilClip);
2489 SkASSERT(!fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO);
2490 SkASSERT(!fUseDrawInsteadOfAllRenderTargetWrites);
2491 SkASSERT(!fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines);
Chris Daltonda40cd22018-04-16 13:19:58 -06002492 SkASSERT(!fRequiresFlushBetweenNonAndInstancedDraws);
Brian Salomon01b476a2018-01-23 11:06:41 -05002493 }
Brian Salomon43f8bf02017-10-18 08:33:29 -04002494 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfGLClear) {
2495 fUseDrawToClearColor = false;
2496 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfGLClear) {
2497 fUseDrawToClearColor = true;
2498 }
Brian Salomon01b476a2018-01-23 11:06:41 -05002499 if (options.fDoManualMipmapping) {
2500 fDoManualMipmapping = true;
2501 }
csmartdaltone0d36292016-07-29 08:14:20 -07002502}
Greg Daniel81e7bf82017-07-19 14:47:42 -04002503
Brian Salomon3d86a192018-02-27 16:46:11 -05002504bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
2505 if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
2506 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2507 if (tex->hasBaseLevelBeenBoundToFBO()) {
2508 return false;
2509 }
2510 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002511 } if (auto rt = surface->asRenderTarget()) {
Brian Salomon3d86a192018-02-27 16:46:11 -05002512 if (fUseDrawInsteadOfAllRenderTargetWrites) {
2513 return false;
2514 }
2515 if (rt->numColorSamples() > 1 && this->usesMSAARenderBuffers()) {
2516 return false;
2517 }
2518 return SkToBool(surface->asTexture());
2519 }
2520 return true;
2521}
2522
Brian Salomon19eaf2d2018-03-19 16:06:44 -04002523bool GrGLCaps::surfaceSupportsReadPixels(const GrSurface* surface) const {
2524 if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
2525 // We don't support reading pixels directly from EXTERNAL textures as it would require
2526 // binding the texture to a FBO.
2527 if (tex->target() == GR_GL_TEXTURE_EXTERNAL) {
2528 return false;
2529 }
2530 }
2531 return true;
2532}
2533
2534GrColorType GrGLCaps::supportedReadPixelsColorType(GrPixelConfig config,
2535 GrColorType dstColorType) const {
2536 // For now, we mostly report the read back format that is required by the ES spec without
2537 // checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
2538 // this as makes sense to increase performance and correctness.
2539 switch (fConfigTable[config].fFormatType) {
2540 case kNormalizedFixedPoint_FormatType:
2541 return GrColorType::kRGBA_8888;
2542 case kFloat_FormatType:
2543 // We cheat a little here and allow F16 read back if the src and dst match.
2544 if (kRGBA_half_GrPixelConfig == config && GrColorType::kRGBA_F16 == dstColorType) {
2545 return GrColorType::kRGBA_F16;
2546 }
2547 if ((kAlpha_half_GrPixelConfig == config ||
2548 kAlpha_half_as_Red_GrPixelConfig == config) &&
2549 GrColorType::kAlpha_F16 == dstColorType) {
2550 return GrColorType::kAlpha_F16;
2551 }
2552 // And similar for full float RG.
2553 if (kRG_float_GrPixelConfig == config && GrColorType::kRG_F32 == dstColorType) {
2554 return GrColorType::kRG_F32;
2555 }
2556 return GrColorType::kRGBA_F32;
2557 }
2558 return GrColorType::kUnknown;
2559}
2560
Greg Daniel2a303902018-02-20 10:25:54 -05002561bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002562 GrGLFramebufferInfo fbInfo;
2563 SkAssertResult(backendRT.getGLFramebufferInfo(&fbInfo));
Greg Daniel2a303902018-02-20 10:25:54 -05002564 // Window Rectangles are not supported for FBO 0;
Greg Daniel323fbcf2018-04-10 13:46:30 -04002565 return fbInfo.fFBOID != 0;
Greg Daniel2a303902018-02-20 10:25:54 -05002566}
2567
Brian Salomonbdecacf2018-02-02 20:32:49 -05002568int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
2569 requestedCount = SkTMax(1, requestedCount);
Greg Daniel81e7bf82017-07-19 14:47:42 -04002570 int count = fConfigTable[config].fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05002571 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04002572 return 0;
2573 }
2574
Brian Salomonbdecacf2018-02-02 20:32:49 -05002575 if (1 == requestedCount) {
2576 return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0;
2577 }
2578
Greg Daniel81e7bf82017-07-19 14:47:42 -04002579 for (int i = 0; i < count; ++i) {
2580 if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
2581 return fConfigTable[config].fColorSampleCounts[i];
2582 }
2583 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05002584 return 0;
2585}
2586
2587int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
2588 const auto& table = fConfigTable[config].fColorSampleCounts;
2589 if (!table.count()) {
2590 return 0;
2591 }
2592 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05002593}
2594
Greg Danielfaa095e2017-12-19 13:15:02 -05002595bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
2596 GrGLStandard standard) {
2597 *config = kUnknown_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002598
2599 switch (ct) {
2600 case kUnknown_SkColorType:
2601 return false;
2602 case kAlpha_8_SkColorType:
2603 if (GR_GL_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002604 *config = kAlpha_8_as_Alpha_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002605 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002606 *config = kAlpha_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002607 }
2608 break;
2609 case kRGB_565_SkColorType:
2610 if (GR_GL_RGB565 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002611 *config = kRGB_565_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002612 }
2613 break;
2614 case kARGB_4444_SkColorType:
2615 if (GR_GL_RGBA4 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002616 *config = kRGBA_4444_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002617 }
2618 break;
2619 case kRGBA_8888_SkColorType:
2620 if (GR_GL_RGBA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002621 *config = kRGBA_8888_GrPixelConfig;
Greg Daniel7b219ac2017-12-18 14:49:04 -05002622 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002623 *config = kSRGBA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002624 }
2625 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002626 case kRGB_888x_SkColorType:
Brian Salomon5fba7ad2018-03-22 10:01:16 -04002627 if (GR_GL_RGB8 == format) {
2628 *config = kRGB_888_GrPixelConfig;
2629 }
2630 break;
Greg Danielf5d87582017-12-18 14:48:15 -05002631 case kBGRA_8888_SkColorType:
Greg Danielfaa095e2017-12-19 13:15:02 -05002632 if (GR_GL_RGBA8 == format) {
2633 if (kGL_GrGLStandard == standard) {
2634 *config = kBGRA_8888_GrPixelConfig;
2635 }
2636 } else if (GR_GL_BGRA8 == format) {
2637 if (kGLES_GrGLStandard == standard) {
2638 *config = kBGRA_8888_GrPixelConfig;
2639 }
Greg Daniel7b219ac2017-12-18 14:49:04 -05002640 } else if (GR_GL_SRGB8_ALPHA8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002641 *config = kSBGRA_8888_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002642 }
2643 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002644 case kRGBA_1010102_SkColorType:
Brian Osman10fc6fd2018-03-02 11:01:10 -05002645 if (GR_GL_RGB10_A2 == format) {
2646 *config = kRGBA_1010102_GrPixelConfig;
2647 }
2648 break;
Brian Salomone41e1762018-01-25 14:07:47 -05002649 case kRGB_101010x_SkColorType:
2650 return false;
Greg Danielf5d87582017-12-18 14:48:15 -05002651 case kGray_8_SkColorType:
2652 if (GR_GL_LUMINANCE8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002653 *config = kGray_8_as_Lum_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002654 } else if (GR_GL_R8 == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002655 *config = kGray_8_as_Red_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002656 }
2657 break;
2658 case kRGBA_F16_SkColorType:
2659 if (GR_GL_RGBA16F == format) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002660 *config = kRGBA_half_GrPixelConfig;
Greg Danielf5d87582017-12-18 14:48:15 -05002661 }
2662 break;
2663 }
2664
Greg Danielfaa095e2017-12-19 13:15:02 -05002665 return kUnknown_GrPixelConfig != *config;
2666}
2667
2668bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
2669 GrPixelConfig* config) const {
Greg Daniel52e16d92018-04-10 09:34:07 -04002670 GrGLTextureInfo texInfo;
2671 if (!tex.getGLTextureInfo(&texInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002672 return false;
2673 }
Greg Daniel52e16d92018-04-10 09:34:07 -04002674 return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
Greg Danielfaa095e2017-12-19 13:15:02 -05002675}
2676
2677bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
2678 GrPixelConfig* config) const {
Greg Daniel323fbcf2018-04-10 13:46:30 -04002679 GrGLFramebufferInfo fbInfo;
2680 if (!rt.getGLFramebufferInfo(&fbInfo)) {
Greg Danielfaa095e2017-12-19 13:15:02 -05002681 return false;
2682 }
Greg Daniel323fbcf2018-04-10 13:46:30 -04002683 return validate_sized_format(fbInfo.fFormat, ct, config, fStandard);
Greg Danielf5d87582017-12-18 14:48:15 -05002684}
2685
Robert Phillipsfc711a22018-02-13 17:03:00 -05002686bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct,
2687 GrPixelConfig* config) const {
2688 const GrGLenum* glFormat = format.getGLFormat();
2689 if (!glFormat) {
2690 return false;
2691 }
2692 return validate_sized_format(*glFormat, ct, config, fStandard);
2693}
2694
2695