blob: 49274d7498edcb3c3d16960137d8880551b08575 [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"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000015#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000016#include "SkTSort.h"
Brian Salomon467921e2017-03-06 16:17:12 -050017#include "instanced/GLInstancedRendering.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;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000035 fTextureRedSupport = 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 fDirectStateAccessSupport = false;
39 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080040 fES2CompatibilitySupport = false;
csmartdalton4c18b622016-07-29 12:19:28 -070041 fDrawInstancedSupport = false;
cdalton06604b92016-02-05 10:09:51 -080042 fDrawIndirectSupport = false;
43 fMultiDrawIndirectSupport = false;
44 fBaseInstanceSupport = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000045 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070046 fBindFragDataLocationSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080047 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080048 fTextureSwizzleSupport = false;
bsalomon88c7b982015-07-31 11:20:16 -070049 fRGBA8888PixelsOpsAreSlow = false;
50 fPartialFBOReadIsSlow = false;
cblume09bd2c02016-03-01 14:08:28 -080051 fMipMapLevelAndLodControlSupport = false;
ericrkb4ecabd2016-03-11 15:18:20 -080052 fRGBAToBGRAReadbackConversionsAreSlow = false;
brianosman09563ce2016-06-02 08:59:34 -070053 fDoManualMipmapping = false;
brianosman20471892016-12-02 06:43:32 -080054 fSRGBDecodeDisableSupport = false;
brianosman851c2382016-12-07 10:03:25 -080055 fSRGBDecodeDisableAffectsMipmaps = false;
Brian Salomon028a9a52017-05-11 11:39:08 -040056 fClearToOpaqueBlackIsBroken = false;
piotaixre4b23142014-10-02 10:57:53 -070057
Brian Salomone5e7eb12016-10-14 16:18:33 -040058 fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
bsalomon083617b2016-02-12 12:10:14 -080059
Brian Salomon94efbf52016-11-29 13:43:05 -050060 fShaderCaps.reset(new GrShaderCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070061
cdalton4cd67132015-06-10 19:23:46 -070062 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000063}
64
cdalton4cd67132015-06-10 19:23:46 -070065void GrGLCaps::init(const GrContextOptions& contextOptions,
66 const GrGLContextInfo& ctxInfo,
67 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000068 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000069 GrGLVersion version = ctxInfo.version();
70
bsalomon@google.combcce8922013-03-25 15:38:39 +000071 /**************************************************************************
72 * Caps specific to GrGLCaps
73 **************************************************************************/
74
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000075 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000076 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
77 &fMaxFragmentUniformVectors);
78 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000079 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000080 GrGLint max;
81 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
82 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000083 if (version >= GR_GL_VER(3, 2)) {
84 GrGLint profileMask;
85 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
86 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
87 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000088 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000089 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000090
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000091 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000092 fUnpackRowLengthSupport = true;
93 fUnpackFlipYSupport = false;
94 fPackRowLengthSupport = true;
95 fPackFlipYSupport = false;
96 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000097 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
98 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000099 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000100 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
101 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000102 fPackFlipYSupport =
103 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
104 }
105
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000106 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000107 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
108
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000109 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700110 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
111 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
112 ctxInfo.hasExtension("GL_NV_texture_barrier");
113 } else {
114 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
115 }
116
cdaltoneb79eea2016-02-26 10:39:34 -0800117 if (kGL_GrGLStandard == standard) {
118 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
119 ctxInfo.hasExtension("GL_ARB_texture_multisample");
120 } else {
121 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
122 }
123
Brian Salomon0ee6f952017-01-19 15:52:24 -0500124 // ARB_texture_rg is part of OpenGL 3.0, but osmesa doesn't support GL_RED
hendrikwa0d5ad72014-12-02 07:30:30 -0800125 // and GL_RG on FBO textures.
Brian Salomon0ee6f952017-01-19 15:52:24 -0500126 if (kOSMesa_GrGLRenderer != ctxInfo.renderer()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800127 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000128 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
129 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800130 } else {
131 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
132 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000133 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000134 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000135 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000136 ctxInfo.hasExtension("GL_ARB_imaging");
137
egdaniel9250d242015-05-18 13:04:26 -0700138 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
139 // Thus we are blacklisting this extension for now on Adreno4xx devices.
140 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
141 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
142 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
143 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000144 fDiscardRenderTargetSupport = true;
145 fInvalidateFBType = kInvalidate_InvalidateFBType;
146 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
147 fDiscardRenderTargetSupport = true;
148 fInvalidateFBType = kDiscard_InvalidateFBType;
149 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000150
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000151 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
152 fFullClearIsFree = true;
153 }
154
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000155 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000156 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800157 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
158 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000159 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000160 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
161 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000162 }
163
cdalton626e1ff2015-06-12 13:56:46 -0700164 if (kGL_GrGLStandard == standard) {
165 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
166 } else {
167 fDirectStateAccessSupport = false;
168 }
169
170 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
171 fDebugSupport = true;
172 } else {
173 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
174 }
175
jvanverth3f801cb2014-12-16 09:49:38 -0800176 if (kGL_GrGLStandard == standard) {
177 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
178 }
179 else {
180 fES2CompatibilitySupport = true;
181 }
182
cdalton0edea2c2015-05-21 08:27:44 -0700183 if (kGL_GrGLStandard == standard) {
184 fMultisampleDisableSupport = true;
185 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700186 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700187 }
188
kkinnunend94708e2015-07-30 22:47:04 -0700189 if (kGL_GrGLStandard == standard) {
190 if (version >= GR_GL_VER(3, 0)) {
191 fBindFragDataLocationSupport = true;
192 }
193 } else {
194 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
195 fBindFragDataLocationSupport = true;
196 }
joshualittc1f56b52015-06-22 12:31:31 -0700197 }
198
joshualitt7bdd70a2015-10-01 06:28:11 -0700199 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
200
kkinnunene06ed252016-02-16 23:15:40 -0800201 if (kGL_GrGLStandard == standard) {
202 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
203 // We also require textureSize() support for rectangle 2D samplers which was added in
204 // GLSL 1.40.
205 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
206 fRectangleTextureSupport = true;
207 }
bsalomone179a912016-01-20 06:18:10 -0800208 }
kkinnunene06ed252016-02-16 23:15:40 -0800209 } else {
210 // Command buffer exposes this in GL ES context for Chromium reasons,
211 // but it should not be used. Also, at the time of writing command buffer
212 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800213 }
214
bsalomoncdee0092016-01-08 13:20:12 -0800215 if (kGL_GrGLStandard == standard) {
216 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
217 fTextureSwizzleSupport = true;
218 }
219 } else {
220 if (version >= GR_GL_VER(3,0)) {
221 fTextureSwizzleSupport = true;
222 }
223 }
224
cblume09bd2c02016-03-01 14:08:28 -0800225 if (kGL_GrGLStandard == standard) {
226 fMipMapLevelAndLodControlSupport = true;
227 } else if (kGLES_GrGLStandard == standard) {
228 if (version >= GR_GL_VER(3,0)) {
229 fMipMapLevelAndLodControlSupport = true;
230 }
231 }
232
bsalomon88c7b982015-07-31 11:20:16 -0700233#ifdef SK_BUILD_FOR_WIN
234 // We're assuming that on Windows Chromium we're using ANGLE.
235 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
236 kChromium_GrGLDriver == ctxInfo.driver();
halcanary9d524f22016-03-29 09:03:52 -0700237 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
bsalomon88c7b982015-07-31 11:20:16 -0700238 fRGBA8888PixelsOpsAreSlow = isANGLE;
239 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
240 // check DX11 ANGLE.
241 fPartialFBOReadIsSlow = isANGLE;
242#endif
243
ericrkb4ecabd2016-03-11 15:18:20 -0800244 bool isMESA = kMesa_GrGLDriver == ctxInfo.driver();
245 bool isMAC = false;
246#ifdef SK_BUILD_FOR_MAC
247 isMAC = true;
248#endif
249
250 // Both mesa and mac have reduced performance if reading back an RGBA framebuffer as BGRA or
251 // vis-versa.
252 fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
253
cdalton4cd67132015-06-10 19:23:46 -0700254 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700255 * GrShaderCaps fields
256 **************************************************************************/
257
egdaniel0a482332015-10-26 08:59:10 -0700258 // This must be called after fCoreProfile is set on the GrGLCaps
259 this->initGLSL(ctxInfo);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500260 GrShaderCaps* shaderCaps = fShaderCaps.get();
egdaniel0a482332015-10-26 08:59:10 -0700261
csmartdalton008b9d82017-02-22 12:00:42 -0700262 if (!contextOptions.fSuppressPathRendering) {
263 shaderCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
264 }
egdaniel05ded892015-10-26 07:38:05 -0700265
266 // For now these two are equivalent but we could have dst read in shader via some other method.
267 // Before setting this, initGLSL() must have been called.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500268 shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
egdaniel05ded892015-10-26 07:38:05 -0700269
270 // Enable supported shader-related caps
271 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500272 shaderCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
egdaniel05ded892015-10-26 07:38:05 -0700273 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
274 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
Brian Salomon1edc5b92016-11-29 13:43:46 -0500275 shaderCaps->fShaderDerivativeSupport = true;
egdaniel05ded892015-10-26 07:38:05 -0700276 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
Brian Salomon1edc5b92016-11-29 13:43:46 -0500277 shaderCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
egdaniel05ded892015-10-26 07:38:05 -0700278 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500279 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800280 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700281 }
282 else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500283 shaderCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
egdaniel05ded892015-10-26 07:38:05 -0700284
Brian Salomon1edc5b92016-11-29 13:43:46 -0500285 shaderCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
egdaniel05ded892015-10-26 07:38:05 -0700286 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800287
csmartdalton1d2aed02017-02-15 21:43:20 -0700288 shaderCaps->fGeometryShaderSupport = ctxInfo.hasExtension("GL_EXT_geometry_shader");
289
Brian Salomon1edc5b92016-11-29 13:43:46 -0500290 shaderCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
cdalton793dc262016-02-08 10:11:47 -0800291 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700292 }
293
cdalton9c3f1432016-03-11 10:07:37 -0800294 // Protect ourselves against tracking huge amounts of texture state.
295 static const uint8_t kMaxSaneSamplers = 32;
296 GrGLint maxSamplers;
297 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500298 shaderCaps->fMaxVertexSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
299 if (shaderCaps->fGeometryShaderSupport) {
cdalton9c3f1432016-03-11 10:07:37 -0800300 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500301 shaderCaps->fMaxGeometrySamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800302 }
303 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500304 shaderCaps->fMaxFragmentSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800305 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxSamplers);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500306 shaderCaps->fMaxCombinedSamplers = SkTMin<GrGLint>(kMaxSaneSamplers, maxSamplers);
cdalton9c3f1432016-03-11 10:07:37 -0800307
Brian Salomonf26f7a02016-11-15 14:05:01 -0500308 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500309 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(4, 2);
310 if (!shaderCaps->fImageLoadStoreSupport &&
Brian Salomonf26f7a02016-11-15 14:05:01 -0500311 ctxInfo.hasExtension("GL_ARB_shader_image_load_store")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500312 shaderCaps->fImageLoadStoreSupport = true;
313 shaderCaps->fImageLoadStoreExtensionString = "GL_ARB_shader_image_load_store";
Brian Salomonf26f7a02016-11-15 14:05:01 -0500314 }
315 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500316 shaderCaps->fImageLoadStoreSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500317 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500318 if (shaderCaps->fImageLoadStoreSupport) {
Brian Salomonf26f7a02016-11-15 14:05:01 -0500319 // Protect ourselves against tracking huge amounts of image state.
320 static constexpr int kMaxSaneImages = 4;
321 GrGLint maxUnits;
322 GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
Brian Salomonf9f45122016-11-29 11:59:17 -0500323 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500324 &shaderCaps->fMaxVertexImageStorages);
325 if (shaderCaps->fGeometryShaderSupport) {
Brian Salomonf9f45122016-11-29 11:59:17 -0500326 GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500327 &shaderCaps->fMaxGeometryImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500328 }
329 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500330 &shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf9f45122016-11-29 11:59:17 -0500331 GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500332 &shaderCaps->fMaxCombinedImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500333 // We use one unit for every image uniform
Brian Salomon1edc5b92016-11-29 13:43:46 -0500334 shaderCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(shaderCaps->fMaxCombinedImageStorages,
335 maxUnits), kMaxSaneImages);
336 shaderCaps->fMaxVertexImageStorages = SkTMin(maxUnits,
337 shaderCaps->fMaxVertexImageStorages);
338 shaderCaps->fMaxGeometryImageStorages = SkTMin(maxUnits,
339 shaderCaps->fMaxGeometryImageStorages);
340 shaderCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
341 shaderCaps->fMaxFragmentImageStorages);
Brian Salomonf26f7a02016-11-15 14:05:01 -0500342 }
343
egdaniel05ded892015-10-26 07:38:05 -0700344 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700345 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000346 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700347
csmartdalton485a1202016-07-13 10:16:32 -0700348 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
349 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
350 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
351 // limit this decision to specific GPU families rather than basing it on the vendor alone.
352 if (!GR_GL_MUST_USE_VBO &&
353 !fIsCoreProfile &&
354 (kARM_GrGLVendor == ctxInfo.vendor() ||
355 kImagination_GrGLVendor == ctxInfo.vendor() ||
356 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
357 fPreferClientSideDynamicBuffers = true;
358 }
359
Eric Karl5c779752017-05-08 12:02:07 -0700360 if (!contextOptions.fAvoidStencilBuffers) {
361 // To reduce surface area, if we avoid stencil buffers, we also disable MSAA.
362 this->initFSAASupport(contextOptions, ctxInfo, gli);
363 this->initStencilSupport(ctxInfo);
364 }
cdalton1dd05422015-06-12 09:01:18 -0700365 this->initBlendEqationSupport(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000366
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000367 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000368 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
369 // extension includes glMapBuffer.
370 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
371 fMapBufferFlags |= kSubset_MapFlag;
372 fMapBufferType = kMapBufferRange_MapBufferType;
373 } else {
374 fMapBufferType = kMapBuffer_MapBufferType;
375 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000376 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000377 // Unextended GLES2 doesn't have any buffer mapping.
378 fMapBufferFlags = kNone_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800379 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
kkinnunen45c2c812016-02-25 02:03:43 -0800380 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
381 fMapBufferType = kChromium_MapBufferType;
kkinnunenf655e932016-03-03 07:39:48 -0800382 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
383 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
384 fMapBufferType = kMapBufferRange_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000385 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
386 fMapBufferFlags = kCanMap_MapFlag;
387 fMapBufferType = kMapBuffer_MapBufferType;
388 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000389 }
390
jvanverthd7a2c1f2015-12-07 07:36:44 -0800391 if (kGL_GrGLStandard == standard) {
392 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
393 fTransferBufferType = kPBO_TransferBufferType;
halcanary9d524f22016-03-29 09:03:52 -0700394 }
jvanverthd7a2c1f2015-12-07 07:36:44 -0800395 } else {
396 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
397 fTransferBufferType = kPBO_TransferBufferType;
jvanverthc3d706f2016-04-20 10:33:27 -0700398 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
399 fTransferBufferType = kChromium_TransferBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -0800400 }
401 }
402
joshualitte5b74c62015-06-01 14:17:47 -0700403 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
404 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
cdalton397536c2016-03-25 12:15:03 -0700405 if (fBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700406#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500407 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
408 // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
409 // using a small subset.
cdalton397536c2016-03-25 12:15:03 -0700410 fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700411#else
cdalton397536c2016-03-25 12:15:03 -0700412 fBufferMapThreshold = SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700413#endif
joshualitte5b74c62015-06-01 14:17:47 -0700414 }
415
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000416 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000417 fNPOTTextureTileSupport = true;
418 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000419 } else {
420 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000421 // ES3 has no limitations.
422 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
423 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000424 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
425 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
426 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
427 // to alllow arbitrary wrap modes, however.
428 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000429 }
430
bsalomone72bd022015-10-26 07:33:03 -0700431 // Using MIPs on this GPU seems to be a source of trouble.
432 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
433 fMipMapSupport = false;
434 }
435
bsalomon@google.combcce8922013-03-25 15:38:39 +0000436 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
437 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
438 // Our render targets are always created with textures as the color
439 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000440 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000441
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000442 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
443
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000444 // Disable scratch texture reuse on Mali and Adreno devices
brianosman5702c862016-08-09 14:02:13 -0700445 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000446
robertphillips1b8e1b52015-06-24 06:54:10 -0700447#if 0
448 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
449 kQualcomm_GrGLVendor != ctxInfo.vendor();
450#endif
451
csmartdalton9bc11872016-08-09 12:42:47 -0700452 if (ctxInfo.hasExtension("GL_EXT_window_rectangles")) {
453 GR_GL_GetIntegerv(gli, GR_GL_MAX_WINDOW_RECTANGLES, &fMaxWindowRectangles);
csmartdalton9bc11872016-08-09 12:42:47 -0700454 }
455
bsalomon63b21962014-11-05 07:05:34 -0800456 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800457 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
Brian Salomon1b52df32017-03-24 18:49:09 -0400458 (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() &&
459 ctxInfo.driver() != kChromium_GrGLDriver)) {
bsalomon63b21962014-11-05 07:05:34 -0800460 fUseDrawInsteadOfClear = true;
461 }
462
joshualitt83bc2292015-06-18 14:18:02 -0700463 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
464 fUseDrawInsteadOfPartialRenderTargetWrite = true;
465 }
466
bsalomonbabafcc2016-02-16 11:36:47 -0800467 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
468 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
469 fUseDrawInsteadOfPartialRenderTargetWrite = true;
470 fUseDrawInsteadOfAllRenderTargetWrites = true;
471 }
472
robertphillips63926682015-08-20 09:39:02 -0700473#ifdef SK_BUILD_FOR_WIN
474 // On ANGLE deferring flushes can lead to GPU starvation
475 fPreferVRAMUseOverFlushes = !isANGLE;
476#endif
477
bsalomon7dea7b72015-08-19 08:26:51 -0700478 if (kChromium_GrGLDriver == ctxInfo.driver()) {
479 fMustClearUploadedBufferData = true;
480 }
481
bsalomond08ea5f2015-02-20 06:58:13 -0800482 if (kGL_GrGLStandard == standard) {
483 // ARB allows mixed size FBO attachments, EXT does not.
484 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
485 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
486 fOversizedStencilSupport = true;
487 } else {
488 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
489 }
490 } else {
491 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
492 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
493 }
494
joshualitt58001552015-06-26 12:46:36 -0700495 if (kGL_GrGLStandard == standard) {
496 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
497 // instanced arrays, but we could make this more granular if we wanted
csmartdalton4c18b622016-07-29 12:19:28 -0700498 fDrawInstancedSupport =
joshualitt58001552015-06-26 12:46:36 -0700499 version >= GR_GL_VER(3, 2) ||
500 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
501 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
502 } else {
csmartdalton4c18b622016-07-29 12:19:28 -0700503 fDrawInstancedSupport =
joshualitt58001552015-06-26 12:46:36 -0700504 version >= GR_GL_VER(3, 0) ||
505 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
506 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
507 }
508
cdalton06604b92016-02-05 10:09:51 -0800509 if (kGL_GrGLStandard == standard) {
csmartdalton5cebf8c2016-06-03 08:28:47 -0700510 fDrawIndirectSupport = version >= GR_GL_VER(4,0) ||
511 ctxInfo.hasExtension("GL_ARB_draw_indirect");
512 fBaseInstanceSupport = version >= GR_GL_VER(4,2);
513 fMultiDrawIndirectSupport = version >= GR_GL_VER(4,3) ||
csmartdalton4c18b622016-07-29 12:19:28 -0700514 (fDrawIndirectSupport &&
515 !fBaseInstanceSupport && // The ARB extension has no base inst.
csmartdalton5cebf8c2016-06-03 08:28:47 -0700516 ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
bsalomonfc9527a2016-08-29 09:18:39 -0700517 fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
cdalton06604b92016-02-05 10:09:51 -0800518 } else {
519 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
csmartdalton4c18b622016-07-29 12:19:28 -0700520 fMultiDrawIndirectSupport = fDrawIndirectSupport &&
521 ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
522 fBaseInstanceSupport = fDrawIndirectSupport &&
523 ctxInfo.hasExtension("GL_EXT_base_instance");
bsalomonfc9527a2016-08-29 09:18:39 -0700524 fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
cdalton06604b92016-02-05 10:09:51 -0800525 }
526
Brian Salomon1edc5b92016-11-29 13:43:46 -0500527 this->initShaderPrecisionTable(ctxInfo, gli, shaderCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800528
529 if (contextOptions.fUseShaderSwizzling) {
530 fTextureSwizzleSupport = false;
531 }
532
ethannicholas28ef4452016-03-25 09:26:03 -0700533 if (kGL_GrGLStandard == standard) {
ethannicholas6536ae52016-05-02 12:16:49 -0700534 if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
535 ctxInfo.vendor() != kIntel_GrGLVendor) {
ethannicholas28ef4452016-03-25 09:26:03 -0700536 fSampleShadingSupport = true;
537 }
538 } else if (ctxInfo.hasExtension("GL_OES_sample_shading")) {
539 fSampleShadingSupport = true;
540 }
541
jvanverth84741b32016-09-30 08:39:02 -0700542 // TODO: support CHROMIUM_sync_point and maybe KHR_fence_sync
543 if (kGL_GrGLStandard == standard) {
544 if (version >= GR_GL_VER(3, 2) || ctxInfo.hasExtension("GL_ARB_sync")) {
545 fFenceSyncSupport = true;
546 }
547 } else if (version >= GR_GL_VER(3, 0)) {
548 fFenceSyncSupport = true;
549 }
550
Brian Osman0eb4ecb2017-05-16 13:30:11 -0400551 // Safely moving textures between contexts requires fences.
Brian Osman2c2bc112017-02-28 10:02:49 -0500552 fCrossContextTextureSupport = fFenceSyncSupport;
Brian Osman2c2bc112017-02-28 10:02:49 -0500553
brianosman131ff132016-06-07 14:22:44 -0700554 // We support manual mip-map generation (via iterative downsampling draw calls). This fixes
555 // bugs on some cards/drivers that produce incorrect mip-maps for sRGB textures when using
556 // glGenerateMipmap. Our implementation requires mip-level sampling control. Additionally,
557 // it can be much slower (especially on mobile GPUs), so we opt-in only when necessary:
brianosman09563ce2016-06-02 08:59:34 -0700558 if (fMipMapLevelAndLodControlSupport &&
brianosman9a3fbf72016-06-09 13:11:08 -0700559 (contextOptions.fDoManualMipmapping ||
560 (kIntel_GrGLVendor == ctxInfo.vendor()) ||
brianosman131ff132016-06-07 14:22:44 -0700561 (kNVIDIA_GrGLDriver == ctxInfo.driver() && isMAC) ||
562 (kATI_GrGLVendor == ctxInfo.vendor()))) {
brianosman09563ce2016-06-02 08:59:34 -0700563 fDoManualMipmapping = true;
564 }
565
brianosman20471892016-12-02 06:43:32 -0800566 fSRGBDecodeDisableSupport = ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode");
brianosman851c2382016-12-07 10:03:25 -0800567 fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
568 kChromium_GrGLDriver != ctxInfo.driver();
brianosman20471892016-12-02 06:43:32 -0800569
Brian Salomon028a9a52017-05-11 11:39:08 -0400570 // See http://crbug.com/710443
571#ifdef SK_BUILD_FOR_MAC
572 if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
573 fClearToOpaqueBlackIsBroken = true;
574 }
575#endif
576
bsalomoncdee0092016-01-08 13:20:12 -0800577 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
578 // already been detected.
brianosman20471892016-12-02 06:43:32 -0800579 this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
cdalton4cd67132015-06-10 19:23:46 -0700580
581 this->applyOptionsOverrides(contextOptions);
Brian Salomon1edc5b92016-11-29 13:43:46 -0500582 shaderCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000583}
584
egdaniel472d44e2015-10-22 08:20:00 -0700585const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
586 bool isCoreProfile) {
587 switch (generation) {
588 case k110_GrGLSLGeneration:
589 if (kGLES_GrGLStandard == standard) {
590 // ES2s shader language is based on version 1.20 but is version
591 // 1.00 of the ES language.
592 return "#version 100\n";
593 } else {
594 SkASSERT(kGL_GrGLStandard == standard);
595 return "#version 110\n";
596 }
597 case k130_GrGLSLGeneration:
598 SkASSERT(kGL_GrGLStandard == standard);
599 return "#version 130\n";
600 case k140_GrGLSLGeneration:
601 SkASSERT(kGL_GrGLStandard == standard);
602 return "#version 140\n";
603 case k150_GrGLSLGeneration:
604 SkASSERT(kGL_GrGLStandard == standard);
605 if (isCoreProfile) {
606 return "#version 150\n";
607 } else {
608 return "#version 150 compatibility\n";
609 }
610 case k330_GrGLSLGeneration:
611 if (kGLES_GrGLStandard == standard) {
612 return "#version 300 es\n";
613 } else {
614 SkASSERT(kGL_GrGLStandard == standard);
615 if (isCoreProfile) {
616 return "#version 330\n";
617 } else {
618 return "#version 330 compatibility\n";
619 }
620 }
cdalton33ad7012016-02-22 07:55:44 -0800621 case k400_GrGLSLGeneration:
622 SkASSERT(kGL_GrGLStandard == standard);
623 if (isCoreProfile) {
624 return "#version 400\n";
625 } else {
626 return "#version 400 compatibility\n";
627 }
Brian Salomond327e8c2016-11-15 13:26:08 -0500628 case k420_GrGLSLGeneration:
629 SkASSERT(kGL_GrGLStandard == standard);
630 if (isCoreProfile) {
631 return "#version 420\n";
632 }
633 else {
634 return "#version 420 compatibility\n";
635 }
egdaniel472d44e2015-10-22 08:20:00 -0700636 case k310es_GrGLSLGeneration:
637 SkASSERT(kGLES_GrGLStandard == standard);
638 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800639 case k320es_GrGLSLGeneration:
640 SkASSERT(kGLES_GrGLStandard == standard);
641 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700642 }
643 return "<no version>";
644}
645
egdaniel05ded892015-10-26 07:38:05 -0700646void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700647 GrGLStandard standard = ctxInfo.standard();
648 GrGLVersion version = ctxInfo.version();
649
650 /**************************************************************************
Brian Salomon1edc5b92016-11-29 13:43:46 -0500651 * Caps specific to GrShaderCaps
egdaniel472d44e2015-10-22 08:20:00 -0700652 **************************************************************************/
653
Brian Salomon1edc5b92016-11-29 13:43:46 -0500654 GrShaderCaps* shaderCaps = fShaderCaps.get();
655 shaderCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700656 if (kGLES_GrGLStandard == standard) {
657 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500658 shaderCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
659 shaderCaps->fFBFetchSupport = true;
660 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
661 shaderCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700662 }
663 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
664 // 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 -0500665 shaderCaps->fFBFetchNeedsCustomOutput = false;
666 shaderCaps->fFBFetchSupport = true;
667 shaderCaps->fFBFetchColorName = "gl_LastFragData[0]";
668 shaderCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700669 }
670 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
671 // The arm extension also requires an additional flag which we will set onResetContext
Brian Salomon1edc5b92016-11-29 13:43:46 -0500672 shaderCaps->fFBFetchNeedsCustomOutput = false;
673 shaderCaps->fFBFetchSupport = true;
674 shaderCaps->fFBFetchColorName = "gl_LastFragColorARM";
675 shaderCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
egdaniel472d44e2015-10-22 08:20:00 -0700676 }
Brian Salomon1edc5b92016-11-29 13:43:46 -0500677 shaderCaps->fUsesPrecisionModifiers = true;
egdaniel472d44e2015-10-22 08:20:00 -0700678 }
679
egdaniel7517e452016-09-20 13:00:26 -0700680 // Currently the extension is advertised but fb fetch is broken on 500 series Adrenos like the
681 // Galaxy S7.
682 // TODO: Once this is fixed we can update the check here to look at a driver version number too.
683 if (kAdreno5xx_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500684 shaderCaps->fFBFetchSupport = false;
egdaniel7517e452016-09-20 13:00:26 -0700685 }
686
Brian Salomon1edc5b92016-11-29 13:43:46 -0500687 shaderCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
egdaniel472d44e2015-10-22 08:20:00 -0700688
cdaltonc08f1962016-02-12 12:14:06 -0800689 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500690 shaderCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc08f1962016-02-12 12:14:06 -0800691 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500692 shaderCaps->fFlatInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800693 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
694 }
695
696 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500697 shaderCaps->fNoPerspectiveInterpolationSupport =
cdaltonc08f1962016-02-12 12:14:06 -0800698 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
699 } else {
700 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500701 shaderCaps->fNoPerspectiveInterpolationSupport = true;
702 shaderCaps->fNoPerspectiveInterpolationExtensionString =
cdaltonc08f1962016-02-12 12:14:06 -0800703 "GL_NV_shader_noperspective_interpolation";
704 }
705 }
706
cdalton33ad7012016-02-22 07:55:44 -0800707 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500708 shaderCaps->fMultisampleInterpolationSupport =
cdalton4a98cdb2016-03-01 12:12:20 -0800709 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
710 } else {
711 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500712 shaderCaps->fMultisampleInterpolationSupport = true;
cdalton4a98cdb2016-03-01 12:12:20 -0800713 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500714 shaderCaps->fMultisampleInterpolationSupport = true;
715 shaderCaps->fMultisampleInterpolationExtensionString =
cdalton4a98cdb2016-03-01 12:12:20 -0800716 "GL_OES_shader_multisample_interpolation";
717 }
718 }
719
720 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500721 shaderCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
cdalton33ad7012016-02-22 07:55:44 -0800722 } else {
723 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500724 shaderCaps->fSampleVariablesSupport = true;
cdalton33ad7012016-02-22 07:55:44 -0800725 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500726 shaderCaps->fSampleVariablesSupport = true;
727 shaderCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
cdalton33ad7012016-02-22 07:55:44 -0800728 }
729 }
730
Brian Salomon1edc5b92016-11-29 13:43:46 -0500731 if (shaderCaps->fSampleVariablesSupport &&
csmartdaltonf848c9c2016-06-15 12:42:13 -0700732 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage")) {
733 // Pre-361 NVIDIA has a bug with NV_sample_mask_override_coverage.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500734 shaderCaps->fSampleMaskOverrideCoverageSupport =
csmartdaltonf848c9c2016-06-15 12:42:13 -0700735 kNVIDIA_GrGLDriver != ctxInfo.driver() ||
736 ctxInfo.driverVersion() >= GR_GL_DRIVER_VER(361,00);
cdalton33ad7012016-02-22 07:55:44 -0800737 }
738
egdaniel472d44e2015-10-22 08:20:00 -0700739 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
Brian Salomon1edc5b92016-11-29 13:43:46 -0500740 shaderCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700741
742 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
743 // function that may require a gradient calculation inside a conditional block may return
744 // undefined results". This appears to be an issue with the 'any' call since even the simple
745 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
746 // from our GrTextureDomain processor.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500747 shaderCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
egdaniel472d44e2015-10-22 08:20:00 -0700748
Brian Salomon1edc5b92016-11-29 13:43:46 -0500749 shaderCaps->fVersionDeclString = get_glsl_version_decl_string(standard,
750 shaderCaps->fGLSLGeneration,
751 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800752
Brian Salomon1edc5b92016-11-29 13:43:46 -0500753 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == shaderCaps->fGLSLGeneration) {
754 shaderCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
egdaniel574a4c12015-11-02 06:22:44 -0800755 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800756
757 // Frag Coords Convention support is not part of ES
758 // Known issue on at least some Intel platforms:
759 // http://code.google.com/p/skia/issues/detail?id=946
760 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
761 kGLES_GrGLStandard != standard &&
762 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
763 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500764 shaderCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
egdaniel8dcdedc2015-11-11 06:27:20 -0800765 }
766
767 if (kGLES_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500768 shaderCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
egdaniel8dcdedc2015-11-11 06:27:20 -0800769 }
770
cdalton9c3f1432016-03-11 10:07:37 -0800771 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
772 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500773 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800774 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
775 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
776 // At least one driver has been found that has this extension without the "GL_" prefix.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500777 shaderCaps->fExternalTextureSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800778 }
779 }
780
Brian Salomon1edc5b92016-11-29 13:43:46 -0500781 if (shaderCaps->fExternalTextureSupport) {
bsalomon7ea33f52015-11-22 14:51:00 -0800782 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500783 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
bsalomon7ea33f52015-11-22 14:51:00 -0800784 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500785 shaderCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
bsalomon7ea33f52015-11-22 14:51:00 -0800786 }
787 }
788
cdaltonc04ce672016-03-11 14:07:38 -0800789 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500790 shaderCaps->fTexelFetchSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
cdaltonc04ce672016-03-11 14:07:38 -0800791 } else {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500792 shaderCaps->fTexelFetchSupport =
cdaltonf8a6ce82016-04-11 13:02:05 -0700793 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
794 }
795
Brian Salomon1edc5b92016-11-29 13:43:46 -0500796 if (shaderCaps->fTexelFetchSupport) {
cdaltonf8a6ce82016-04-11 13:02:05 -0700797 if (kGL_GrGLStandard == standard) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500798 shaderCaps->fTexelBufferSupport = ctxInfo.version() >= GR_GL_VER(3, 1) &&
cdaltonf8a6ce82016-04-11 13:02:05 -0700799 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration;
800 } else {
801 if (ctxInfo.version() >= GR_GL_VER(3, 2) &&
802 ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500803 shaderCaps->fTexelBufferSupport = true;
cdaltonf8a6ce82016-04-11 13:02:05 -0700804 } else if (ctxInfo.hasExtension("GL_OES_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500805 shaderCaps->fTexelBufferSupport = true;
806 shaderCaps->fTexelBufferExtensionString = "GL_OES_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700807 } else if (ctxInfo.hasExtension("GL_EXT_texture_buffer")) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500808 shaderCaps->fTexelBufferSupport = true;
809 shaderCaps->fTexelBufferExtensionString = "GL_EXT_texture_buffer";
cdaltonf8a6ce82016-04-11 13:02:05 -0700810 }
cdaltonc04ce672016-03-11 14:07:38 -0800811 }
812 }
813
egdaniel8dcdedc2015-11-11 06:27:20 -0800814 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
815 // the abs first in a separate expression.
816 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500817 shaderCaps->fCanUseMinAndAbsTogether = false;
egdaniel8dcdedc2015-11-11 06:27:20 -0800818 }
819
bsalomon7ea33f52015-11-22 14:51:00 -0800820 // On Intel GPU there is an issue where it reads the second argument to atan "- %s.x" as an int
egdaniel8dcdedc2015-11-11 06:27:20 -0800821 // thus must us -1.0 * %s.x to work correctly
822 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500823 shaderCaps->fMustForceNegatedAtanParamToFloat = true;
egdaniel8dcdedc2015-11-11 06:27:20 -0800824 }
egdaniel138c2632016-08-17 10:59:00 -0700825
826 // On Adreno devices with framebuffer fetch support, there is a bug where they always return
827 // the original dst color when reading the outColor even after being written to. By using a
828 // local outColor we can work around this bug.
Brian Salomon1edc5b92016-11-29 13:43:46 -0500829 if (shaderCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
830 shaderCaps->fRequiresLocalOutputColorForFBFetch = true;
egdaniel138c2632016-08-17 10:59:00 -0700831 }
csmartdalton2e777ea2017-02-15 10:41:27 -0700832
833#ifdef SK_BUILD_FOR_MAC
834 // On at least some MacBooks, geometry shaders fall apart if we use more than one invocation. To
835 // work around this, we always use a single invocation and wrap the shader in a loop. The long-
836 // term plan for this WAR is for it to eventually be baked into SkSL.
837 shaderCaps->fMustImplementGSInvocationsWithLoop = true;
838#endif
egdaniel472d44e2015-10-22 08:20:00 -0700839}
840
kkinnunencfe62e32015-07-01 02:58:50 -0700841bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700842 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
843
844 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700845 return false;
846 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700847
kkinnunencfe62e32015-07-01 02:58:50 -0700848 if (kGL_GrGLStandard == ctxInfo.standard()) {
849 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
850 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
851 return false;
852 }
853 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700854 if (!hasChromiumPathRendering &&
855 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700856 return false;
857 }
858 }
859 // We only support v1.3+ of GL_NV_path_rendering which allows us to
860 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
861 // additions are detected by checking the existence of the function.
862 // We also use *Then* functions that not all drivers might have. Check
863 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800864 if (!gli->fFunctions.fStencilThenCoverFillPath ||
865 !gli->fFunctions.fStencilThenCoverStrokePath ||
866 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
867 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
868 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700869 return false;
870 }
871 return true;
872}
bsalomon1aa20292016-01-22 08:16:09 -0800873
Brian Salomon71d9d842016-11-03 13:42:00 -0400874bool GrGLCaps::readPixelsSupported(GrPixelConfig surfaceConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800875 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800876 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
bsalomon2c3db322016-11-08 13:26:24 -0800877 std::function<bool ()> bindRenderTarget,
878 std::function<void ()> unbindRenderTarget) const {
Brian Salomon71d9d842016-11-03 13:42:00 -0400879 // If it's not possible to even have a color attachment of surfaceConfig then read pixels is
bsalomone9573312016-01-25 14:33:25 -0800880 // not supported regardless of readConfig.
Brian Salomon71d9d842016-11-03 13:42:00 -0400881 if (!this->canConfigBeFBOColorAttachment(surfaceConfig)) {
bsalomone9573312016-01-25 14:33:25 -0800882 return false;
883 }
bsalomon7928ef62016-01-05 10:26:39 -0800884
Brian Salomonbf7b6202016-11-11 16:08:03 -0500885 if (GrPixelConfigIsSint(surfaceConfig) != GrPixelConfigIsSint(readConfig)) {
886 return false;
887 }
888
bsalomon76148af2016-01-12 11:13:47 -0800889 GrGLenum readFormat;
890 GrGLenum readType;
Brian Salomon71d9d842016-11-03 13:42:00 -0400891 if (!this->getReadPixelsFormat(surfaceConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800892 return false;
893 }
894
bsalomon1aa20292016-01-22 08:16:09 -0800895 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800896 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
897 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
898 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
899 // 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 -0500900 // The manual does not seem to fully match the spec as the spec allows integer formats
901 // when the bound color buffer is an integer buffer. It doesn't specify which integer
902 // formats are allowed, so perhaps all of them are. We only use GL_RGBA_INTEGER currently.
csmartdalton6aa0e112017-02-08 16:14:11 -0500903 if (readFormat != GR_GL_RED && readFormat != GR_GL_RG && readFormat != GR_GL_RGB &&
904 readFormat != GR_GL_RGBA && readFormat != GR_GL_BGRA &&
905 readFormat != GR_GL_RGBA_INTEGER) {
bsalomone9573312016-01-25 14:33:25 -0800906 return false;
907 }
908 // There is also a set of allowed types, but all the types we use are in the set:
909 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
910 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
911 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
912 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
913 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
914 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
915 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800916 return true;
piotaixre4b23142014-10-02 10:57:53 -0700917 }
bsalomon7928ef62016-01-05 10:26:39 -0800918
bsalomon76148af2016-01-12 11:13:47 -0800919 // See Section 16.1.2 in the ES 3.2 specification.
Brian Salomonbf7b6202016-11-11 16:08:03 -0500920 switch (fConfigTable[surfaceConfig].fFormatType) {
921 case kNormalizedFixedPoint_FormatType:
922 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
923 return true;
924 }
925 break;
926 case kInteger_FormatType:
927 if (GR_GL_RGBA_INTEGER == readFormat && GR_GL_INT == readType) {
928 return true;
929 }
930 break;
931 case kFloat_FormatType:
932 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
933 return true;
934 }
935 break;
bsalomon7928ef62016-01-05 10:26:39 -0800936 }
937
Brian Salomon71d9d842016-11-03 13:42:00 -0400938 if (0 == fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800939 ReadPixelsFormat* rpFormat =
Brian Salomon71d9d842016-11-03 13:42:00 -0400940 const_cast<ReadPixelsFormat*>(&fConfigTable[surfaceConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800941 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800942 if (!bindRenderTarget()) {
943 return false;
944 }
945 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
946 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800947 rpFormat->fFormat = format;
948 rpFormat->fType = type;
bsalomon2c3db322016-11-08 13:26:24 -0800949 unbindRenderTarget();
bsalomon7928ef62016-01-05 10:26:39 -0800950 }
951
Brian Salomon71d9d842016-11-03 13:42:00 -0400952 return fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
953 fConfigTable[surfaceConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700954}
955
Eric Karl5c779752017-05-08 12:02:07 -0700956void GrGLCaps::initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
957 const GrGLInterface* gli) {
958 // We need dual source blending and the ability to disable multisample in order to support mixed
959 // samples in every corner case. We only use mixed samples if the stencil-and-cover path
960 // renderer is available and enabled; no other path renderers support this feature.
961 if (fMultisampleDisableSupport &&
962 this->shaderCaps()->dualSourceBlendingSupport() &&
963 this->shaderCaps()->pathRenderingSupport() &&
964 (contextOptions.fGpuPathRenderers & GrContextOptions::GpuPathRenderers::kStencilAndCover)) {
965 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
966 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
967 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
968 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
969 kChromium_GrGLDriver == ctxInfo.driver())) {
970 fDiscardRenderTargetSupport = false;
971 fInvalidateFBType = kNone_InvalidateFBType;
972 }
973 }
974
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000975 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000976 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
977 // ES3 driver bugs on at least one device with a tiled GPU (N10).
978 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
979 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
980 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
981 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800982 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700983 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomon00731b42016-10-14 11:30:51 -0400984 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
Brian Salomonc5eceb02016-10-18 10:21:43 -0400985 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
986 ctxInfo.hasExtension("GL_ANGLE_framebuffer_multisample")) {
Brian Salomon00731b42016-10-14 11:30:51 -0400987 fMSFBOType = kStandard_MSFBOType;
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000988 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
989 fMSFBOType = kES_Apple_MSFBOType;
990 }
bsalomon083617b2016-02-12 12:10:14 -0800991
992 // Above determined the preferred MSAA approach, now decide whether glBlitFramebuffer
993 // is available.
994 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
Brian Salomone5e7eb12016-10-14 16:18:33 -0400995 fBlitFramebufferFlags = kNoFormatConversionForMSAASrc_BlitFramebufferFlag |
Eric Karl74480882017-04-03 14:49:05 -0700996 kNoMSAADst_BlitFramebufferFlag |
Brian Salomone5e7eb12016-10-14 16:18:33 -0400997 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
Brian Salomonc5eceb02016-10-18 10:21:43 -0400998 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample") ||
999 ctxInfo.hasExtension("GL_ANGLE_framebuffer_blit")) {
bsalomon083617b2016-02-12 12:10:14 -08001000 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
1001 // limitations.
Brian Salomone5e7eb12016-10-14 16:18:33 -04001002 fBlitFramebufferFlags = kNoScalingOrMirroring_BlitFramebufferFlag |
1003 kResolveMustBeFull_BlitFrambufferFlag |
1004 kNoMSAADst_BlitFramebufferFlag |
Eric Karl74480882017-04-03 14:49:05 -07001005 kNoFormatConversion_BlitFramebufferFlag |
1006 kRectsMustMatchForMSAASrc_BlitFramebufferFlag;
bsalomon083617b2016-02-12 12:10:14 -08001007 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001008 } else {
egdanieleed519e2016-01-15 11:36:18 -08001009 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -07001010 fMSFBOType = kMixedSamples_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -04001011 fBlitFramebufferFlags = 0;
Brian Salomon00731b42016-10-14 11:30:51 -04001012 } else if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1013 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
1014 fMSFBOType = kStandard_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -04001015 fBlitFramebufferFlags = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001016 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
1017 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
Brian Salomon00731b42016-10-14 11:30:51 -04001018 fMSFBOType = kEXT_MSFBOType;
Brian Salomone5e7eb12016-10-14 16:18:33 -04001019 fBlitFramebufferFlags = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001020 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001021 }
Eric Karl5c779752017-05-08 12:02:07 -07001022
1023 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
1024 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
1025 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
1026 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
1027 }
1028 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
1029 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
1030 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
1031 // This is to guard against platforms that may not support as many samples for
1032 // glRasterSamples as they do for framebuffers.
1033 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
1034 }
1035 fMaxColorSampleCount = fMaxStencilSampleCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001036}
1037
cdalton1dd05422015-06-12 09:01:18 -07001038void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001039 GrShaderCaps* shaderCaps = static_cast<GrShaderCaps*>(fShaderCaps.get());
cdalton1dd05422015-06-12 09:01:18 -07001040
1041 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
1042 // for now until its own blacklists can be updated.
1043 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
Greg Daniel0ea7d432016-10-27 16:55:52 -04001044 kAdreno5xx_GrGLRenderer == ctxInfo.renderer() ||
cdalton1dd05422015-06-12 09:01:18 -07001045 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -07001046 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -07001047 return;
1048 }
1049
1050 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
1051 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001052 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001053 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
1054 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001055 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001056 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1057 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
1058 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
1059 return;
1060 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
1061 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001062 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001063 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
1064 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001065 shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kGeneralEnable_AdvBlendEqInteraction;
cdalton1dd05422015-06-12 09:01:18 -07001066 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
1067 // slow on a particular platform.
1068 } else {
1069 return; // No advanced blend support.
1070 }
1071
1072 SkASSERT(this->advancedBlendEquationSupport());
1073
csmartdalton3b88a032016-08-04 14:43:49 -07001074 if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
1075 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(355,00)) {
1076 // Blacklist color-dodge and color-burn on pre-355.00 NVIDIA.
cdalton1dd05422015-06-12 09:01:18 -07001077 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
1078 (1 << kColorBurn_GrBlendEquation);
1079 }
joel.liang9764c402015-07-09 19:46:18 -07001080 if (kARM_GrGLVendor == ctxInfo.vendor()) {
1081 // Blacklist color-burn on ARM until the fix is released.
1082 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
1083 }
cdalton1dd05422015-06-12 09:01:18 -07001084}
1085
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001086namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -07001087const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001088}
1089
Eric Karl5c779752017-05-08 12:02:07 -07001090void GrGLCaps::initStencilSupport(const GrGLContextInfo& ctxInfo) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001091
1092 // Build up list of legal stencil formats (though perhaps not supported on
1093 // the particular gpu/driver) from most preferred to least.
1094
1095 // these consts are in order of most preferred to least preferred
1096 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
1097
1098 static const StencilFormat
1099 // internal Format stencil bits total bits packed?
1100 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
1101 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
1102 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
1103 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +00001104 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001105 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
1106
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +00001107 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001108 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +00001109 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001110 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
1111 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
1112
1113 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
1114 // require FBO support we can expect these are legal formats and don't
1115 // check. These also all support the unsized GL_STENCIL_INDEX.
1116 fStencilFormats.push_back() = gS8;
1117 fStencilFormats.push_back() = gS16;
1118 if (supportsPackedDS) {
1119 fStencilFormats.push_back() = gD24S8;
1120 }
1121 fStencilFormats.push_back() = gS4;
1122 if (supportsPackedDS) {
1123 fStencilFormats.push_back() = gDS;
1124 }
1125 } else {
1126 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
1127 // for other formats.
1128 // ES doesn't support using the unsized format.
1129
1130 fStencilFormats.push_back() = gS8;
1131 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +00001132 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
1133 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001134 fStencilFormats.push_back() = gD24S8;
1135 }
1136 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
1137 fStencilFormats.push_back() = gS4;
1138 }
1139 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001140}
1141
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001142SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +00001143
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001144 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +00001145
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001146 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001147 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001148 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001149 i,
1150 fStencilFormats[i].fStencilBits,
1151 fStencilFormats[i].fTotalBits);
1152 }
1153
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001154 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001155 "None",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001156 "EXT",
Brian Salomon00731b42016-10-14 11:30:51 -04001157 "Standard",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001158 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +00001159 "IMG MS To Texture",
1160 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -07001161 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001162 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001163 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
Brian Salomon00731b42016-10-14 11:30:51 -04001164 GR_STATIC_ASSERT(1 == kEXT_MSFBOType);
1165 GR_STATIC_ASSERT(2 == kStandard_MSFBOType);
1166 GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
1167 GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
1168 GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
1169 GR_STATIC_ASSERT(6 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001170 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001171
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001172 static const char* kInvalidateFBTypeStr[] = {
1173 "None",
1174 "Discard",
1175 "Invalidate",
1176 };
1177 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1178 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1179 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1180 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001181
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001182 static const char* kMapBufferTypeStr[] = {
1183 "None",
1184 "MapBuffer",
1185 "MapBufferRange",
1186 "Chromium",
1187 };
1188 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1189 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1190 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1191 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1192 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1193
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001194 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001195 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001196 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001197 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001198 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001199 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
1200 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
1201 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
1202 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +00001203
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001204 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001205 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
1206 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001207 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -07001208 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
1209 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
csmartdalton4c18b622016-07-29 12:19:28 -07001210 r.appendf("Draw instanced support: %s\n", (fDrawInstancedSupport ? "YES" : "NO"));
cdalton06604b92016-02-05 10:09:51 -08001211 r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
1212 r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
1213 r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -07001214 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
1215 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -07001216 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -08001217 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -08001218 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
halcanary9d524f22016-03-29 09:03:52 -07001219 r.appendf("BGRA to RGBA readback conversions are slow: %s\n",
ericrkb4ecabd2016-03-11 15:18:20 -08001220 (fRGBAToBGRAReadbackConversionsAreSlow ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -08001221
1222 r.append("Configs\n-------\n");
1223 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1224 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -08001225 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
1226 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -08001227 i,
1228 fConfigTable[i].fFlags,
1229 fConfigTable[i].fFormats.fBaseInternalFormat,
1230 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -08001231 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
1232 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -08001233 fConfigTable[i].fFormats.fExternalType,
1234 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -08001235 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -08001236 }
1237
jvanverthe9c0fc62015-04-29 11:18:05 -07001238 return r;
1239}
1240
jvanverthe9c0fc62015-04-29 11:18:05 -07001241static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1242 switch (p) {
1243 case kLow_GrSLPrecision:
1244 return GR_GL_LOW_FLOAT;
1245 case kMedium_GrSLPrecision:
1246 return GR_GL_MEDIUM_FLOAT;
1247 case kHigh_GrSLPrecision:
1248 return GR_GL_HIGH_FLOAT;
Brian Osman33aa2c72017-04-05 09:26:15 -04001249 default:
1250 SkFAIL("Unexpected precision type.");
1251 return -1;
jvanverthe9c0fc62015-04-29 11:18:05 -07001252 }
jvanverthe9c0fc62015-04-29 11:18:05 -07001253}
1254
1255static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1256 switch (type) {
1257 case kVertex_GrShaderType:
1258 return GR_GL_VERTEX_SHADER;
1259 case kGeometry_GrShaderType:
1260 return GR_GL_GEOMETRY_SHADER;
1261 case kFragment_GrShaderType:
1262 return GR_GL_FRAGMENT_SHADER;
1263 }
1264 SkFAIL("Unknown shader type.");
1265 return -1;
1266}
1267
jvanverthcba99b82015-06-24 06:59:57 -07001268void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
halcanary9d524f22016-03-29 09:03:52 -07001269 const GrGLInterface* intf,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001270 GrShaderCaps* shaderCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001271 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1272 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1273 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1274 if (kGeometry_GrShaderType != s) {
1275 GrShaderType shaderType = static_cast<GrShaderType>(s);
1276 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001277 GrShaderCaps::PrecisionInfo* first = nullptr;
Brian Salomon1edc5b92016-11-29 13:43:46 -05001278 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001279 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1280 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1281 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1282 GrGLint range[2];
1283 GrGLint bits;
1284 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1285 if (bits) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001286 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1287 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1288 shaderCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001289 if (!first) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001290 first = &shaderCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001291 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001292 else if (!shaderCaps->fShaderPrecisionVaries) {
1293 shaderCaps->fShaderPrecisionVaries =
1294 (*first != shaderCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001295 }
1296 }
1297 }
1298 }
1299 }
1300 }
1301 else {
1302 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001303 shaderCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001304 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1305 if (kGeometry_GrShaderType != s) {
1306 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001307 shaderCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1308 shaderCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1309 shaderCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001310 }
1311 }
1312 }
1313 }
1314 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1315 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1316 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1317 // are recommended against.
Brian Salomon1edc5b92016-11-29 13:43:46 -05001318 if (shaderCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001319 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05001320 shaderCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1321 shaderCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001322 }
1323 }
Brian Salomon1edc5b92016-11-29 13:43:46 -05001324 shaderCaps->initSamplerPrecisionTable();
jvanverthe9c0fc62015-04-29 11:18:05 -07001325}
1326
bsalomon41e4384e2016-01-08 09:12:44 -08001327bool GrGLCaps::bgraIsInternalFormat() const {
1328 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1329}
1330
bsalomon76148af2016-01-12 11:13:47 -08001331bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1332 GrGLenum* internalFormat, GrGLenum* externalFormat,
1333 GrGLenum* externalType) const {
1334 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1335 externalFormat, externalType)) {
1336 return false;
1337 }
1338 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1339 return true;
1340}
1341
1342bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1343 GrGLenum* internalFormat) const {
1344 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1345 return false;
1346 }
1347 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1348 return true;
1349}
1350
1351bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1352 GrGLenum* externalFormat, GrGLenum* externalType) const {
1353 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1354 externalFormat, externalType)) {
1355 return false;
1356 }
1357 return true;
1358}
1359
1360bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1361 if (GrPixelConfigIsCompressed(config)) {
1362 return false;
1363 }
1364 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1365 return true;
1366}
1367
1368bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1369 ExternalFormatUsage usage, GrGLenum* externalFormat,
1370 GrGLenum* externalType) const {
1371 SkASSERT(externalFormat && externalType);
sylvestre.ledruf0cbfb32016-09-01 08:17:02 -07001372 if (GrPixelConfigIsCompressed(memoryConfig)) {
bsalomon76148af2016-01-12 11:13:47 -08001373 return false;
1374 }
1375
1376 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1377 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1378
1379 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1380 // made to work in many cases using glPixelStore and what not but is not needed currently.
1381 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1382 return false;
1383 }
1384
1385 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1386 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1387
bsalomone9573312016-01-25 14:33:25 -08001388 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1389 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1390 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1391 // texture, not the red component.
1392 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1393 if (this->textureRedSupport()) {
1394 SkASSERT(GR_GL_RED == *externalFormat);
1395 *externalFormat = GR_GL_ALPHA;
1396 }
1397 }
1398
bsalomon76148af2016-01-12 11:13:47 -08001399 return true;
1400}
1401
brianosman20471892016-12-02 06:43:32 -08001402void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
1403 const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
Brian Salomon1edc5b92016-11-29 13:43:46 -05001404 GrShaderCaps* shaderCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001405 /*
1406 Comments on renderability of configs on various GL versions.
1407 OpenGL < 3.0:
1408 no built in support for render targets.
1409 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1410 format RGB, RGBA and NV float formats we don't use.
1411 This is the following:
1412 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1413 RGB10_A2, RGBA12,RGBA16
1414 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1415 since they aren't required by later standards and the driver can simply return
1416 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1417 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1418 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1419 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1420 This adds a lot of additional renderable sized formats, including ALPHA8.
1421 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1422 16F, 32I, 32UI, and 32F variants).
1423 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1424
1425 For both the above extensions we limit ourselves to those that are also required by
1426 OpenGL 3.0.
1427
1428 OpenGL 3.0:
1429 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1430 but are not required to be supported as renderable textures/renderbuffer.
1431 Required renderable color formats:
1432 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1433 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1434 RGB10_A2.
1435 - R11F_G11F_B10F.
1436 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1437 and RG8UI.
1438 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1439 - ALPHA8
1440
1441 OpenGL 3.1, 3.2, 3.3
1442 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1443 OpengGL 3.3, 4.0, 4.1
1444 Adds RGB10_A2UI.
1445 OpengGL 4.2
1446 Adds
1447 - RGB5_A1, RGBA4
1448 - RGB565
1449 OpenGL 4.4
1450 Does away with the separate list and adds a column to the sized internal color format
1451 table. However, no new formats become required color renderable.
1452
1453 ES 2.0
1454 color renderable: RGBA4, RGB5_A1, RGB565
1455 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1456 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1457 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1458 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1459 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1460 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1461
1462 ES 3.0
1463 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1464 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1465 RGB5_A1.
1466 - RGB8 and RGB565.
1467 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1468 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1469 ES 3.1
1470 Adds RGB10_A2, RGB10_A2UI,
1471 ES 3.2
1472 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1473 */
Brian Salomon71d9d842016-11-03 13:42:00 -04001474 uint32_t nonMSAARenderFlags = ConfigInfo::kRenderable_Flag |
1475 ConfigInfo::kFBOColorAttachment_Flag;
1476 uint32_t allRenderFlags = nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001477 if (kNone_MSFBOType != fMSFBOType) {
1478 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1479 }
bsalomon41e4384e2016-01-08 09:12:44 -08001480 GrGLStandard standard = ctxInfo.standard();
1481 GrGLVersion version = ctxInfo.version();
1482
cblume790d5132016-02-29 11:13:29 -08001483 bool texStorageSupported = false;
1484 if (kGL_GrGLStandard == standard) {
1485 // The EXT version can apply to either GL or GLES.
1486 texStorageSupported = version >= GR_GL_VER(4,2) ||
1487 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1488 ctxInfo.hasExtension("GL_EXT_texture_storage");
1489 } else {
Brian Salomon3ab83e22016-11-28 13:14:00 -05001490 texStorageSupported = version >= GR_GL_VER(3,0) ||
1491 ctxInfo.hasExtension("GL_EXT_texture_storage");
cblume790d5132016-02-29 11:13:29 -08001492 }
1493
1494 // TODO: remove after command buffer supports full ES 3.0
1495 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1496 kChromium_GrGLDriver == ctxInfo.driver()) {
1497 texStorageSupported = false;
1498 }
1499
cdalton74b8d322016-04-11 14:47:28 -07001500 bool texelBufferSupport = this->shaderCaps()->texelBufferSupport();
1501
bsalomon30447372015-12-21 09:03:05 -08001502 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1503 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001504 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001505 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001506 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001507 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001508
1509 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1510 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001511 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1512 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001513 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001514 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001515 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1516 if (kGL_GrGLStandard == standard) {
1517 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1518 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001519 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001520 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1521 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1522 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1523 }
egdaniel4999df82016-01-07 17:06:04 -08001524 }
cblume790d5132016-02-29 11:13:29 -08001525 if (texStorageSupported) {
1526 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1527 }
cdalton74b8d322016-04-11 14:47:28 -07001528 if (texelBufferSupport) {
1529 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1530 }
bsalomoncdee0092016-01-08 13:20:12 -08001531 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001532
bsalomon76148af2016-01-12 11:13:47 -08001533 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1534 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001535 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001536 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001537 if (kGL_GrGLStandard == standard) {
1538 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1539 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1540 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1541 // Since the internal format is RGBA8, it is also renderable.
1542 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1543 allRenderFlags;
1544 }
1545 } else {
1546 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1547 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1548 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1549 // The APPLE extension doesn't make this renderable.
1550 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1551 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1552 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1553 // Though, that seems to not be the case if the texture storage extension is
1554 // present. The specs don't exactly make that clear.
1555 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1556 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1557 }
1558 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1559 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
Brian Salomon71d9d842016-11-03 13:42:00 -04001560 nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001561 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001562 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001563 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1564 ConfigInfo::kRenderableWithMSAA_Flag;
1565 }
1566 }
1567 }
cblume790d5132016-02-29 11:13:29 -08001568 if (texStorageSupported) {
1569 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1570 }
bsalomoncdee0092016-01-08 13:20:12 -08001571 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001572
brianosmana6359362016-03-21 06:55:37 -07001573 // We only enable srgb support if both textures and FBOs support srgb,
brianosman35b784d2016-05-05 11:52:53 -07001574 // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
bsalomon41e4384e2016-01-08 09:12:44 -08001575 if (kGL_GrGLStandard == standard) {
1576 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
brianosmana6359362016-03-21 06:55:37 -07001577 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001578 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1579 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1580 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
brianosmana6359362016-03-21 06:55:37 -07001581 fSRGBSupport = true;
bsalomon41e4384e2016-01-08 09:12:44 -08001582 }
1583 }
1584 // All the above srgb extensions support toggling srgb writes
bsalomon44d427e2016-05-10 09:05:06 -07001585 if (fSRGBSupport) {
1586 fSRGBWriteControl = true;
1587 }
bsalomon41e4384e2016-01-08 09:12:44 -08001588 } else {
brianosman20471892016-12-02 06:43:32 -08001589 fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
1590#if defined(SK_CPU_X86)
1591 if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
1592 // NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
1593 // blacklist that device (and any others that might be sharing the same driver).
1594 fSRGBSupport = false;
1595 }
1596#endif
bsalomon41e4384e2016-01-08 09:12:44 -08001597 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1598 // sRGB writing for destinations.
brianosmanc9986b62016-05-23 06:23:27 -07001599 // See https://bug.skia.org/5329 for Adreno4xx issue.
1600 fSRGBWriteControl = kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
1601 ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
bsalomon41e4384e2016-01-08 09:12:44 -08001602 }
brianosman20471892016-12-02 06:43:32 -08001603 if (contextOptions.fRequireDecodeDisableForSRGB && !fSRGBDecodeDisableSupport) {
1604 // To support "legacy" L32 mode, we require the ability to turn off sRGB decode. Clients
1605 // can opt-out of that requirement, if they intend to always do linear blending.
brianosmana6359362016-03-21 06:55:37 -07001606 fSRGBSupport = false;
1607 }
brianosman20471892016-12-02 06:43:32 -08001608
1609 // This is very conservative, if we're on a platform where N32 is BGRA, and using ES, disable
1610 // all sRGB support. Too much code relies on creating surfaces with N32 + sRGB colorspace,
1611 // and sBGRA is basically impossible to support on any version of ES (with our current code).
1612 // In particular, ES2 doesn't support sBGRA at all, and even in ES3, there is no valid pair
1613 // of formats that can be used for TexImage calls to upload BGRA data to sRGBA (which is what
1614 // we *have* to use as the internal format, because sBGRA doesn't exist). This primarily
1615 // affects Windows.
1616 if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig && kGLES_GrGLStandard == standard) {
1617 fSRGBSupport = false;
1618 }
1619
bsalomon30447372015-12-21 09:03:05 -08001620 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1621 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1622 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1623 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001624 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1625 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001626 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001627 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
brianosmana6359362016-03-21 06:55:37 -07001628 if (fSRGBSupport) {
bsalomon41e4384e2016-01-08 09:12:44 -08001629 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1630 allRenderFlags;
1631 }
cblume790d5132016-02-29 11:13:29 -08001632 if (texStorageSupported) {
1633 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1634 }
bsalomoncdee0092016-01-08 13:20:12 -08001635 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001636
brianosmana6359362016-03-21 06:55:37 -07001637 // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
1638 // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
1639 // is in this format, for example).
1640 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1641 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1642 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1643 // external format is GL_BGRA.
1644 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1645 GR_GL_BGRA;
1646 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1647 fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1648 if (fSRGBSupport) {
1649 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1650 allRenderFlags;
1651 }
1652 if (texStorageSupported) {
1653 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1654 }
1655 fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1656
Brian Salomonbf7b6202016-11-11 16:08:03 -05001657 bool hasIntegerTextures;
1658 if (standard == kGL_GrGLStandard) {
1659 hasIntegerTextures = version >= GR_GL_VER(3, 0) ||
1660 ctxInfo.hasExtension("GL_EXT_texture_integer");
1661 } else {
1662 hasIntegerTextures = (version >= GR_GL_VER(3, 0));
1663 }
1664 // We may have limited GLSL to an earlier version that doesn't have integer sampler types.
1665 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
1666 hasIntegerTextures = false;
1667 }
1668 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA_INTEGER;
1669 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8I;
1670 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RGBA_INTEGER;
1671 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormats.fExternalType = GR_GL_BYTE;
1672 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFormatType = kInteger_FormatType;
1673 // We currently only support using integer textures as srcs, not for rendering (even though GL
1674 // allows it).
1675 if (hasIntegerTextures) {
1676 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1677 ConfigInfo::kFBOColorAttachment_Flag;
1678 if (texStorageSupported) {
1679 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
1680 ConfigInfo::kCanUseTexStorage_Flag;
1681 }
1682 }
1683
bsalomon30447372015-12-21 09:03:05 -08001684 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1685 if (this->ES2CompatibilitySupport()) {
1686 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1687 } else {
1688 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1689 }
bsalomon76148af2016-01-12 11:13:47 -08001690 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1691 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001692 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001693 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001694 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1695 if (kGL_GrGLStandard == standard) {
elementala6759102016-11-18 23:11:29 +01001696 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
bsalomon41e4384e2016-01-08 09:12:44 -08001697 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1698 }
1699 } else {
1700 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1701 }
cblume790d5132016-02-29 11:13:29 -08001702 // 565 is not a sized internal format on desktop GL. So on desktop with
1703 // 565 we always use an unsized internal format to let the system pick
1704 // the best sized format to convert the 565 data to. Since TexStorage
1705 // only allows sized internal formats we disallow it.
1706 //
1707 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1708 // update.
1709 if (texStorageSupported && kGL_GrGLStandard != standard) {
1710 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1711 }
bsalomoncdee0092016-01-08 13:20:12 -08001712 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001713
1714 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1715 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001716 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1717 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001718 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001719 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001720 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1721 if (kGL_GrGLStandard == standard) {
1722 if (version >= GR_GL_VER(4, 2)) {
1723 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1724 }
1725 } else {
1726 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1727 }
cblume790d5132016-02-29 11:13:29 -08001728 if (texStorageSupported) {
1729 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1730 }
bsalomoncdee0092016-01-08 13:20:12 -08001731 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001732
Brian Osmanf4faccd2017-01-10 16:53:58 -05001733 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1734 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1735 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
bsalomon30447372015-12-21 09:03:05 -08001736 if (this->textureRedSupport()) {
1737 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1738 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001739 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1740 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001741 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001742 if (texelBufferSupport) {
1743 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1744 }
bsalomon30447372015-12-21 09:03:05 -08001745 } else {
1746 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1747 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001748 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1749 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001750 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001751 }
bsalomon40170072016-05-05 14:40:03 -07001752 if (this->textureRedSupport() ||
Brian Salomon00731b42016-10-14 11:30:51 -04001753 (kStandard_MSFBOType == this->msFBOType() && ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1754 // OpenGL 3.0+ (and GL_ARB_framebuffer_object) supports ALPHA8 as renderable.
bsalomon40170072016-05-05 14:40:03 -07001755 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
bsalomon41e4384e2016-01-08 09:12:44 -08001756 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1757 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1758 }
cblume790d5132016-02-29 11:13:29 -08001759 if (texStorageSupported) {
1760 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1761 }
bsalomon41e4384e2016-01-08 09:12:44 -08001762
Brian Osmanf4faccd2017-01-10 16:53:58 -05001763 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
1764 fConfigTable[kGray_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1765 fConfigTable[kGray_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
Brian Osman986563b2017-01-10 14:20:02 -05001766 if (this->textureRedSupport()) {
1767 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1768 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
1769 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1770 GR_GL_RED;
1771 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRA();
1772 if (texelBufferSupport) {
1773 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1774 }
1775 } else {
1776 fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
1777 fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
1778 fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1779 GR_GL_LUMINANCE;
1780 fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
1781 }
Brian Osman986563b2017-01-10 14:20:02 -05001782#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster
1783 if (this->textureRedSupport() ||
1784 (kDesktop_ARB_MSFBOType == this->msFBOType() &&
1785 ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
1786 // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
1787 // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
1788 // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
1789 fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
1790 }
1791#endif
1792 if (texStorageSupported) {
1793 fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1794 }
1795
bsalomon41e4384e2016-01-08 09:12:44 -08001796 // Check for [half] floating point texture support
1797 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1798 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1799 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1800 bool hasFPTextures = false;
1801 bool hasHalfFPTextures = false;
1802 // for now we don't support floating point MSAA on ES
Brian Salomon71d9d842016-11-03 13:42:00 -04001803 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ? allRenderFlags : nonMSAARenderFlags;
bsalomon41e4384e2016-01-08 09:12:44 -08001804
1805 if (kGL_GrGLStandard == standard) {
1806 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1807 hasFPTextures = true;
1808 hasHalfFPTextures = true;
1809 }
1810 } else {
1811 if (version >= GR_GL_VER(3, 1)) {
1812 hasFPTextures = true;
1813 hasHalfFPTextures = true;
1814 } else {
1815 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1816 ctxInfo.hasExtension("GL_OES_texture_float")) {
1817 hasFPTextures = true;
1818 }
1819 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1820 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1821 hasHalfFPTextures = true;
1822 }
1823 }
1824 }
bsalomon30447372015-12-21 09:03:05 -08001825
csmartdalton6aa0e112017-02-08 16:14:11 -05001826 for (auto fpconfig : {kRGBA_float_GrPixelConfig, kRG_float_GrPixelConfig}) {
1827 const GrGLenum format = kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA : GR_GL_RG;
1828 fConfigTable[fpconfig].fFormats.fBaseInternalFormat = format;
1829 fConfigTable[fpconfig].fFormats.fSizedInternalFormat =
1830 kRGBA_float_GrPixelConfig == fpconfig ? GR_GL_RGBA32F : GR_GL_RG32F;
1831 fConfigTable[fpconfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = format;
1832 fConfigTable[fpconfig].fFormats.fExternalType = GR_GL_FLOAT;
1833 fConfigTable[fpconfig].fFormatType = kFloat_FormatType;
1834 if (hasFPTextures) {
1835 fConfigTable[fpconfig].fFlags = ConfigInfo::kTextureable_Flag;
1836 // For now we only enable rendering to float on desktop, because on ES we'd have to
1837 // solve many precision issues and no clients actually want this yet.
1838 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1839 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1840 fConfigTable[fpconfig].fFlags |= fpRenderFlags;
1841 }
bsalomon41e4384e2016-01-08 09:12:44 -08001842 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001843 if (texStorageSupported) {
1844 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1845 }
1846 if (texelBufferSupport) {
1847 fConfigTable[fpconfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1848 }
1849 fConfigTable[fpconfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001850 }
bsalomon30447372015-12-21 09:03:05 -08001851
1852 if (this->textureRedSupport()) {
1853 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1854 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001855 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1856 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001857 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
cdalton74b8d322016-04-11 14:47:28 -07001858 if (texelBufferSupport) {
1859 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |=
1860 ConfigInfo::kCanUseWithTexelBuffer_Flag;
1861 }
bsalomon30447372015-12-21 09:03:05 -08001862 } else {
1863 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1864 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001865 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1866 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001867 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001868 }
Brian Osman3a887252016-11-17 13:27:31 -05001869 // ANGLE always returns GL_HALF_FLOAT_OES for GL_IMPLEMENTATION_COLOR_READ_TYPE, even though
1870 // ES3 would typically return GL_HALF_FLOAT. The correct fix is for us to respect the value
1871 // returned when we query, but that turns into a bigger refactor, so just work around it.
1872 if (kGL_GrGLStandard == ctxInfo.standard() ||
1873 (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
bsalomon30447372015-12-21 09:03:05 -08001874 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1875 } else {
1876 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1877 }
bsalomon7928ef62016-01-05 10:26:39 -08001878 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
cblume790d5132016-02-29 11:13:29 -08001879 if (texStorageSupported) {
1880 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1881 }
csmartdalton6aa0e112017-02-08 16:14:11 -05001882 if (hasHalfFPTextures) {
1883 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1884 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1885 // GL_RED internal format.
1886 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3, 2) ||
1887 (this->textureRedSupport() &&
1888 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1889 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1890 }
1891 }
bsalomon30447372015-12-21 09:03:05 -08001892
1893 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1894 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001895 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1896 GR_GL_RGBA;
Brian Osman3a887252016-11-17 13:27:31 -05001897 // See comment above, re: ANGLE and ES3.
1898 if (kGL_GrGLStandard == ctxInfo.standard() ||
1899 (ctxInfo.version() >= GR_GL_VER(3, 0) && kANGLE_GrGLDriver != ctxInfo.driver())) {
bsalomon30447372015-12-21 09:03:05 -08001900 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1901 } else {
1902 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1903 }
bsalomon7928ef62016-01-05 10:26:39 -08001904 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001905 if (hasHalfFPTextures) {
1906 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1907 // ES requires 3.2 or EXT_color_buffer_half_float.
1908 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1909 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1910 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1911 }
1912 }
cblume790d5132016-02-29 11:13:29 -08001913 if (texStorageSupported) {
1914 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1915 }
cdalton74b8d322016-04-11 14:47:28 -07001916 if (texelBufferSupport) {
1917 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
1918 }
bsalomoncdee0092016-01-08 13:20:12 -08001919 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001920
1921 // Compressed texture support
1922
1923 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1924 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1925
1926 // TODO: Fix command buffer bindings and remove this.
1927 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001928
1929 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001930 // Below we set the external formats and types to 0.
Robert Phillipsb34727f2017-02-10 14:44:58 -05001931 {
1932 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1933 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat =
1934 GR_GL_COMPRESSED_ETC1_RGB8;
1935 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
1936 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
1937 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
1938 if (kGL_GrGLStandard == standard) {
1939 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1940 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1941 }
1942 } else {
1943 if (version >= GR_GL_VER(3, 0) ||
1944 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1945 // ETC2 is a superset of ETC1, so we can just check for that, too.
1946 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1947 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1948 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1949 }
bsalomon41e4384e2016-01-08 09:12:44 -08001950 }
Robert Phillipsb34727f2017-02-10 14:44:58 -05001951 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001952 }
bsalomon30447372015-12-21 09:03:05 -08001953
1954 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1955
1956 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001957 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1958 ctxInfo.version() >= GR_GL_VER(3,0));
1959 // All ES versions (thus far) require sized internal formats for render buffers.
1960 // TODO: Always use sized internal format?
1961 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1962
bsalomon30447372015-12-21 09:03:05 -08001963 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001964 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1965 // param to glTex[Sub]Image.
1966 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1967 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1968 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1969 fConfigTable[i].fFormats.fSizedInternalFormat :
1970 fConfigTable[i].fFormats.fBaseInternalFormat;
1971 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001972 fConfigTable[i].fFormats.fSizedInternalFormat :
1973 fConfigTable[i].fFormats.fBaseInternalFormat;
1974 }
1975 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1976 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1977 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1978 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1979 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001980 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001981 GR_GL_SRGB_ALPHA;
brianosmana6359362016-03-21 06:55:37 -07001982
1983 // Additionally, because we had to "invent" sBGRA, there is no way to make it work
1984 // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
1985 // unsupported. (If we have no sRGB support at all, this will get overwritten below).
1986 fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
bsalomon30447372015-12-21 09:03:05 -08001987 }
1988
1989 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1990 // as a base format.
1991 // GL_EXT_texture_format_BGRA8888:
1992 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1993 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1994 // formats.
halcanary9d524f22016-03-29 09:03:52 -07001995 // GL_APPLE_texture_format_BGRA8888:
bsalomon30447372015-12-21 09:03:05 -08001996 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1997 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1998 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001999 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08002000 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
2001 }
2002
bsalomoncdee0092016-01-08 13:20:12 -08002003 // If we don't have texture swizzle support then the shader generator must insert the
2004 // swizzle into shader code.
2005 if (!this->textureSwizzleSupport()) {
2006 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002007 shaderCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
bsalomoncdee0092016-01-08 13:20:12 -08002008 }
2009 }
2010
bsalomon7f9b2e42016-01-12 13:29:26 -08002011 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
2012 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
2013 // gets written to the single component.
2014 if (this->textureRedSupport()) {
2015 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
2016 GrPixelConfig config = static_cast<GrPixelConfig>(i);
2017 if (GrPixelConfigIsAlphaOnly(config) &&
2018 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
Brian Salomon1edc5b92016-11-29 13:43:46 -05002019 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
bsalomon7f9b2e42016-01-12 13:29:26 -08002020 }
2021 }
2022 }
2023
Brian Salomonf9f45122016-11-29 11:59:17 -05002024 // We currently only support images on rgba textures formats. We could add additional formats
2025 // if desired. The shader builder would have to be updated to add swizzles where appropriate
2026 // (e.g. where we use GL_RED textures to implement alpha configs).
2027 if (this->shaderCaps()->imageLoadStoreSupport()) {
2028 fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
2029 ConfigInfo::kCanUseAsImageStorage_Flag;
2030 // In OpenGL ES a texture may only be used with BindImageTexture if it has been made
2031 // immutable via TexStorage. We create non-integer textures as mutable textures using
2032 // TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
2033 // storage support for non-integer textures.
2034 if (kGL_GrGLStandard == ctxInfo.standard()) {
2035 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2036 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
2037 ConfigInfo::kCanUseAsImageStorage_Flag;
2038 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
2039 }
2040 }
2041
bsalomon30447372015-12-21 09:03:05 -08002042#ifdef SK_DEBUG
2043 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08002044 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08002045 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
Brian Salomon71d9d842016-11-03 13:42:00 -04002046 // Make sure we didn't set renderable and not blittable or renderable with msaa and not
2047 // renderable.
2048 SkASSERT(!((ConfigInfo::kRenderable_Flag) && !(ConfigInfo::kFBOColorAttachment_Flag)));
2049 SkASSERT(!((ConfigInfo::kRenderableWithMSAA_Flag) && !(ConfigInfo::kRenderable_Flag)));
bsalomon76148af2016-01-12 11:13:47 -08002050 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
2051 fConfigTable[i].fFormats.fBaseInternalFormat);
2052 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08002053 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08002054 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
2055 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
2056 fConfigTable[i].fFormats.fExternalFormat[j]);
2057 }
2058 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08002059 }
2060#endif
2061}
2062
Robert Phillipsbf25d432017-04-07 10:08:53 -04002063bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
Eric Karl74480882017-04-03 14:49:05 -07002064 bool* rectsMustMatch, bool* disallowSubrect) const {
2065 // By default, we don't require rects to match.
2066 *rectsMustMatch = false;
2067
2068 // By default, we allow subrects.
2069 *disallowSubrect = false;
2070
Brian Salomon467921e2017-03-06 16:17:12 -05002071 // If the src is a texture, we can implement the blit as a draw assuming the config is
2072 // renderable.
Robert Phillipsbf25d432017-04-07 10:08:53 -04002073 if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
2074 desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
Brian Salomon467921e2017-03-06 16:17:12 -05002075 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2076 desc->fConfig = src->config();
2077 return true;
2078 }
2079
Robert Phillipsbf25d432017-04-07 10:08:53 -04002080 {
2081 // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were
2082 // wrapped. In that case the proxy would already be instantiated.
2083 const GrTexture* srcTexture = src->priv().peekTexture();
2084 const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture);
2085 if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) {
2086 // Not supported for FBO blit or CopyTexSubImage
2087 return false;
2088 }
Brian Salomon467921e2017-03-06 16:17:12 -05002089 }
2090
2091 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2092 // possible and we return false to fallback to creating a render target dst for render-to-
2093 // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
2094 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
2095 GrSurfaceOrigin originForBlitFramebuffer = kDefault_GrSurfaceOrigin;
Eric Karl74480882017-04-03 14:49:05 -07002096 bool rectsMustMatchForBlitFramebuffer = false;
2097 bool disallowSubrectForBlitFramebuffer = false;
2098 if (src->numColorSamples() &&
2099 (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) {
2100 rectsMustMatchForBlitFramebuffer = true;
2101 disallowSubrectForBlitFramebuffer = true;
2102 // Mirroring causes rects to mismatch later, don't allow it.
2103 originForBlitFramebuffer = src->origin();
2104 } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() &
2105 kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
2106 rectsMustMatchForBlitFramebuffer = true;
2107 // Mirroring causes rects to mismatch later, don't allow it.
2108 originForBlitFramebuffer = src->origin();
2109 } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
Brian Salomon467921e2017-03-06 16:17:12 -05002110 originForBlitFramebuffer = src->origin();
2111 }
2112
2113 // Check for format issues with glCopyTexSubImage2D
2114 if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
2115 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2116 // then we set up for that, otherwise fail.
2117 if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
2118 desc->fOrigin = originForBlitFramebuffer;
2119 desc->fConfig = kBGRA_8888_GrPixelConfig;
Eric Karl74480882017-04-03 14:49:05 -07002120 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2121 *disallowSubrect = disallowSubrectForBlitFramebuffer;
Brian Salomon467921e2017-03-06 16:17:12 -05002122 return true;
2123 }
2124 return false;
2125 }
2126
Robert Phillipsbf25d432017-04-07 10:08:53 -04002127 {
2128 bool srcIsMSAARenderbuffer = src->desc().fSampleCnt > 0 && this->usesMSAARenderBuffers();
2129 if (srcIsMSAARenderbuffer) {
2130 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
2131 // blit or fail.
2132 if (this->canConfigBeFBOColorAttachment(src->config())) {
2133 desc->fOrigin = originForBlitFramebuffer;
2134 desc->fConfig = src->config();
2135 *rectsMustMatch = rectsMustMatchForBlitFramebuffer;
2136 *disallowSubrect = disallowSubrectForBlitFramebuffer;
2137 return true;
2138 }
2139 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05002140 }
Brian Salomon467921e2017-03-06 16:17:12 -05002141 }
2142
2143 // We'll do a CopyTexSubImage. Make the dst a plain old texture.
2144 desc->fConfig = src->config();
2145 desc->fOrigin = src->origin();
2146 desc->fFlags = kNone_GrSurfaceFlags;
2147 return true;
2148}
2149
csmartdaltone0d36292016-07-29 08:14:20 -07002150void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
2151 if (options.fEnableInstancedRendering) {
2152 fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
2153#ifndef SK_BUILD_FOR_MAC
2154 // OS X doesn't seem to write correctly to floating point textures when using
2155 // glDraw*Indirect, regardless of the underlying GPU.
2156 fAvoidInstancedDrawsToFPTargets = true;
2157#endif
2158 }
2159}