blob: 9a2a5acad9fe9142229cf6d7d76fa563cb864d95 [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
8
9#include "GrGLCaps.h"
joshualittb4384b92014-10-21 12:53:15 -070010
egdanielb7e7d572015-11-04 04:23:53 -080011#include "GrContextOptions.h"
robertphillips@google.com6177e692013-02-28 20:16:25 +000012#include "GrGLContext.h"
jvanverthcba99b82015-06-24 06:59:57 -070013#include "glsl/GrGLSLCaps.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000014#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000015#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000016
bsalomon682c2692015-05-22 14:01:46 -070017GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
18 const GrGLContextInfo& ctxInfo,
19 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000020 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000021 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000022 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000023 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080024 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000025 fMaxFragmentUniformVectors = 0;
bsalomon@google.com60da4172012-06-01 19:25:00 +000026 fMaxVertexAttributes = 0;
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000027 fMaxFragmentTextureUnits = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000028 fUnpackRowLengthSupport = false;
29 fUnpackFlipYSupport = false;
30 fPackRowLengthSupport = false;
31 fPackFlipYSupport = false;
32 fTextureUsageSupport = false;
33 fTexStorageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000034 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000035 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000036 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070037 fDirectStateAccessSupport = false;
38 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080039 fES2CompatibilitySupport = false;
cdaltond4727922015-11-10 12:49:06 -080040 fMultisampleDisableSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000041 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000042 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070043 fBindFragDataLocationSupport = false;
bsalomon7ea33f52015-11-22 14:51:00 -080044 fExternalTextureSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080045 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080046 fTextureSwizzleSupport = false;
bsalomon16921ec2015-07-30 15:34:56 -070047 fSRGBWriteControl = false;
bsalomon88c7b982015-07-31 11:20:16 -070048 fRGBA8888PixelsOpsAreSlow = false;
49 fPartialFBOReadIsSlow = false;
piotaixre4b23142014-10-02 10:57:53 -070050
halcanary385fe4d2015-08-26 13:07:48 -070051 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070052
cdalton4cd67132015-06-10 19:23:46 -070053 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000054}
55
cdalton4cd67132015-06-10 19:23:46 -070056void GrGLCaps::init(const GrContextOptions& contextOptions,
57 const GrGLContextInfo& ctxInfo,
58 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000059 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000060 GrGLVersion version = ctxInfo.version();
61
bsalomon@google.combcce8922013-03-25 15:38:39 +000062 /**************************************************************************
63 * Caps specific to GrGLCaps
64 **************************************************************************/
65
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000066 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000067 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
68 &fMaxFragmentUniformVectors);
69 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000070 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000071 GrGLint max;
72 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
73 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000074 if (version >= GR_GL_VER(3, 2)) {
75 GrGLint profileMask;
76 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
77 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
78 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000079 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000080 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000081 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000082
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000083 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000084 fUnpackRowLengthSupport = true;
85 fUnpackFlipYSupport = false;
86 fPackRowLengthSupport = true;
87 fPackFlipYSupport = false;
88 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000089 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
90 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000091 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000092 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
93 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094 fPackFlipYSupport =
95 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
96 }
97
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000098 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000099 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
100
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000101 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000102 // The EXT version can apply to either GL or GLES.
103 fTexStorageSupport = version >= GR_GL_VER(4,2) ||
104 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
105 ctxInfo.hasExtension("GL_EXT_texture_storage");
106 } else {
107 // Qualcomm Adreno drivers appear to have issues with texture storage.
108 fTexStorageSupport = (version >= GR_GL_VER(3,0) &&
109 kQualcomm_GrGLVendor != ctxInfo.vendor()) ||
110 ctxInfo.hasExtension("GL_EXT_texture_storage");
111 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000112
cdaltonfd4167d2015-04-21 11:45:56 -0700113 if (kGL_GrGLStandard == standard) {
114 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
115 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
116 ctxInfo.hasExtension("GL_NV_texture_barrier");
117 } else {
118 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
119 }
120
hendrikwa0d5ad72014-12-02 07:30:30 -0800121 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
122 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700123 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800124 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000125 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
126 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800127 } else {
128 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
129 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000130 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000131 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000132 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000133 ctxInfo.hasExtension("GL_ARB_imaging");
134
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000135 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
136 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
137 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
138 // limit this decision to specific GPU families rather than basing it on the vendor alone.
139 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700140 (kARM_GrGLVendor == ctxInfo.vendor() ||
141 kImagination_GrGLVendor == ctxInfo.vendor() ||
142 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000143 fUseNonVBOVertexAndIndexDynamicData = true;
144 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000145
egdaniel9250d242015-05-18 13:04:26 -0700146 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
147 // Thus we are blacklisting this extension for now on Adreno4xx devices.
148 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
149 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
150 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
151 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000152 fDiscardRenderTargetSupport = true;
153 fInvalidateFBType = kInvalidate_InvalidateFBType;
154 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
155 fDiscardRenderTargetSupport = true;
156 fInvalidateFBType = kDiscard_InvalidateFBType;
157 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000158
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000159 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
160 fFullClearIsFree = true;
161 }
162
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000163 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000164 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800165 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
166 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000167 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000168 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
169 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000170 }
171
cdalton626e1ff2015-06-12 13:56:46 -0700172 if (kGL_GrGLStandard == standard) {
173 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
174 } else {
175 fDirectStateAccessSupport = false;
176 }
177
178 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
179 fDebugSupport = true;
180 } else {
181 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
182 }
183
jvanverth3f801cb2014-12-16 09:49:38 -0800184 if (kGL_GrGLStandard == standard) {
185 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
186 }
187 else {
188 fES2CompatibilitySupport = true;
189 }
190
cdalton0edea2c2015-05-21 08:27:44 -0700191 if (kGL_GrGLStandard == standard) {
192 fMultisampleDisableSupport = true;
193 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700194 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700195 }
196
kkinnunend94708e2015-07-30 22:47:04 -0700197 if (kGL_GrGLStandard == standard) {
198 if (version >= GR_GL_VER(3, 0)) {
199 fBindFragDataLocationSupport = true;
200 }
201 } else {
202 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
203 fBindFragDataLocationSupport = true;
204 }
joshualittc1f56b52015-06-22 12:31:31 -0700205 }
206
halcanary6950de62015-11-07 05:29:00 -0800207#if 0 // Disabled due to https://bug.skia.org/4454
joshualitt7bdd70a2015-10-01 06:28:11 -0700208 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
kkinnunen177519e2015-10-28 06:18:35 -0700209#else
210 fBindUniformLocationSupport = false;
211#endif
joshualitt7bdd70a2015-10-01 06:28:11 -0700212
bsalomon7ea33f52015-11-22 14:51:00 -0800213 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
214 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
215 fExternalTextureSupport = true;
216 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
217 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
218 // At least one driver has been found that has this extension without the "GL_" prefix.
219 fExternalTextureSupport = true;
220 }
221 }
222
bsalomone179a912016-01-20 06:18:10 -0800223 if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 1)) ||
bsalomone5286e02016-01-14 09:24:09 -0800224 ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
bsalomone179a912016-01-20 06:18:10 -0800225 // We also require textureSize() support for rectangle 2D samplers which was added in GLSL
226 // 1.40.
227 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
228 fRectangleTextureSupport = true;
229 }
bsalomone5286e02016-01-14 09:24:09 -0800230 }
231
bsalomoncdee0092016-01-08 13:20:12 -0800232 if (kGL_GrGLStandard == standard) {
233 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
234 fTextureSwizzleSupport = true;
235 }
236 } else {
237 if (version >= GR_GL_VER(3,0)) {
238 fTextureSwizzleSupport = true;
239 }
240 }
241
bsalomon88c7b982015-07-31 11:20:16 -0700242#ifdef SK_BUILD_FOR_WIN
243 // We're assuming that on Windows Chromium we're using ANGLE.
244 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
245 kChromium_GrGLDriver == ctxInfo.driver();
246 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
247 fRGBA8888PixelsOpsAreSlow = isANGLE;
248 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
249 // check DX11 ANGLE.
250 fPartialFBOReadIsSlow = isANGLE;
251#endif
252
cdalton4cd67132015-06-10 19:23:46 -0700253 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700254 * GrShaderCaps fields
255 **************************************************************************/
256
egdaniel0a482332015-10-26 08:59:10 -0700257 // This must be called after fCoreProfile is set on the GrGLCaps
258 this->initGLSL(ctxInfo);
259 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
260
egdaniel05ded892015-10-26 07:38:05 -0700261 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
262
263 // For now these two are equivalent but we could have dst read in shader via some other method.
264 // Before setting this, initGLSL() must have been called.
265 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
266
267 // Enable supported shader-related caps
268 if (kGL_GrGLStandard == standard) {
269 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
270 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
271 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
272 glslCaps->fShaderDerivativeSupport = true;
273 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
274 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
275 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
276 }
277 else {
278 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
279
280 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
281 ctxInfo.hasExtension("GL_OES_standard_derivatives");
282 }
283
egdaniel05ded892015-10-26 07:38:05 -0700284 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700285 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000286 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700287
cdalton63f6c1f2015-11-06 07:09:43 -0800288 // We need dual source blending and the ability to disable multisample in order to support mixed
289 // samples in every corner case.
egdanieleed519e2016-01-15 11:36:18 -0800290 if (fMultisampleDisableSupport &&
291 glslCaps->dualSourceBlendingSupport() &&
292 fShaderCaps->pathRenderingSupport()) {
293 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
kkinnunenea409432015-12-10 01:21:59 -0800294 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800295 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
egdanieleed519e2016-01-15 11:36:18 -0800296 if (fUsesMixedSamples && kNVIDIA_GrGLDriver == ctxInfo.driver()) {
cdalton63f6c1f2015-11-06 07:09:43 -0800297 fDiscardRenderTargetSupport = false;
298 fInvalidateFBType = kNone_InvalidateFBType;
299 }
300 }
301
egdanieleed519e2016-01-15 11:36:18 -0800302 // fUsesMixedSamples must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700303 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700304 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700305 this->initStencilFormats(ctxInfo);
306
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000307 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000308 // we could also look for GL_ATI_separate_stencil extension or
309 // GL_EXT_stencil_two_side but they use different function signatures
310 // than GL2.0+ (and than each other).
311 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
312 // supported on GL 1.4 and higher or by extension
313 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
314 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
315 } else {
316 // ES 2 has two sided stencil and stencil wrap
317 fTwoSidedStencilSupport = true;
318 fStencilWrapOpsSupport = true;
319 }
320
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000321 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000322 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
323 // extension includes glMapBuffer.
324 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
325 fMapBufferFlags |= kSubset_MapFlag;
326 fMapBufferType = kMapBufferRange_MapBufferType;
327 } else {
328 fMapBufferType = kMapBuffer_MapBufferType;
329 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000330 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000331 // Unextended GLES2 doesn't have any buffer mapping.
332 fMapBufferFlags = kNone_MapBufferType;
333 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
334 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
335 fMapBufferType = kChromium_MapBufferType;
336 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
337 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
338 fMapBufferType = kMapBufferRange_MapBufferType;
339 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
340 fMapBufferFlags = kCanMap_MapFlag;
341 fMapBufferType = kMapBuffer_MapBufferType;
342 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000343 }
344
jvanverthd7a2c1f2015-12-07 07:36:44 -0800345 if (kGL_GrGLStandard == standard) {
346 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
347 fTransferBufferType = kPBO_TransferBufferType;
348 }
349 } else {
350 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
351 fTransferBufferType = kPBO_TransferBufferType;
352 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
353 fTransferBufferType = kChromium_TransferBufferType;
354 }
355 }
356
joshualitte5b74c62015-06-01 14:17:47 -0700357 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
358 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
359 if (fGeometryBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700360 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
361 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
362 // a small subset.
363#if 0
cdalton1acea862015-06-02 13:05:52 -0700364 fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700365#else
366 fGeometryBufferMapThreshold = SK_MaxS32;
367#endif
joshualitte5b74c62015-06-01 14:17:47 -0700368 }
369
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000370 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000371 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
372 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
373 fNPOTTextureTileSupport = true;
374 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000375 } else {
376 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000377 // ES3 has no limitations.
378 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
379 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000380 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
381 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
382 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
383 // to alllow arbitrary wrap modes, however.
384 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000385 }
386
bsalomone72bd022015-10-26 07:33:03 -0700387 // Using MIPs on this GPU seems to be a source of trouble.
388 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
389 fMipMapSupport = false;
390 }
391
bsalomon@google.combcce8922013-03-25 15:38:39 +0000392 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
393 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
394 // Our render targets are always created with textures as the color
395 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000396 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000397
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000398 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
399
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000400 // Disable scratch texture reuse on Mali and Adreno devices
401 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
402 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000403
robertphillips1b8e1b52015-06-24 06:54:10 -0700404#if 0
405 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
406 kQualcomm_GrGLVendor != ctxInfo.vendor();
407#endif
408
egdaniel05ded892015-10-26 07:38:05 -0700409 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000410 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
egdanieleed519e2016-01-15 11:36:18 -0800411 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxColorSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000412 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
egdanieleed519e2016-01-15 11:36:18 -0800413 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxColorSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000414 }
egdanieleed519e2016-01-15 11:36:18 -0800415 fMaxStencilSampleCount = fMaxColorSampleCount;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000416
bsalomon63b21962014-11-05 07:05:34 -0800417 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800418 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800419 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800420 fUseDrawInsteadOfClear = true;
421 }
422
joshualitt83bc2292015-06-18 14:18:02 -0700423 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
424 fUseDrawInsteadOfPartialRenderTargetWrite = true;
425 }
426
robertphillips63926682015-08-20 09:39:02 -0700427#ifdef SK_BUILD_FOR_WIN
428 // On ANGLE deferring flushes can lead to GPU starvation
429 fPreferVRAMUseOverFlushes = !isANGLE;
430#endif
431
bsalomon7dea7b72015-08-19 08:26:51 -0700432 if (kChromium_GrGLDriver == ctxInfo.driver()) {
433 fMustClearUploadedBufferData = true;
434 }
435
bsalomond08ea5f2015-02-20 06:58:13 -0800436 if (kGL_GrGLStandard == standard) {
437 // ARB allows mixed size FBO attachments, EXT does not.
438 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
439 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
440 fOversizedStencilSupport = true;
441 } else {
442 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
443 }
444 } else {
445 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
446 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
447 }
448
joshualitt58001552015-06-26 12:46:36 -0700449 if (kGL_GrGLStandard == standard) {
450 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
451 // instanced arrays, but we could make this more granular if we wanted
452 fSupportsInstancedDraws =
453 version >= GR_GL_VER(3, 2) ||
454 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
455 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
456 } else {
457 fSupportsInstancedDraws =
458 version >= GR_GL_VER(3, 0) ||
459 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
460 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
461 }
462
jvanverthcba99b82015-06-24 06:59:57 -0700463 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800464
465 if (contextOptions.fUseShaderSwizzling) {
466 fTextureSwizzleSupport = false;
467 }
468
469 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
470 // already been detected.
471 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700472
473 this->applyOptionsOverrides(contextOptions);
474 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000475}
476
egdaniel472d44e2015-10-22 08:20:00 -0700477const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
478 bool isCoreProfile) {
479 switch (generation) {
480 case k110_GrGLSLGeneration:
481 if (kGLES_GrGLStandard == standard) {
482 // ES2s shader language is based on version 1.20 but is version
483 // 1.00 of the ES language.
484 return "#version 100\n";
485 } else {
486 SkASSERT(kGL_GrGLStandard == standard);
487 return "#version 110\n";
488 }
489 case k130_GrGLSLGeneration:
490 SkASSERT(kGL_GrGLStandard == standard);
491 return "#version 130\n";
492 case k140_GrGLSLGeneration:
493 SkASSERT(kGL_GrGLStandard == standard);
494 return "#version 140\n";
495 case k150_GrGLSLGeneration:
496 SkASSERT(kGL_GrGLStandard == standard);
497 if (isCoreProfile) {
498 return "#version 150\n";
499 } else {
500 return "#version 150 compatibility\n";
501 }
502 case k330_GrGLSLGeneration:
503 if (kGLES_GrGLStandard == standard) {
504 return "#version 300 es\n";
505 } else {
506 SkASSERT(kGL_GrGLStandard == standard);
507 if (isCoreProfile) {
508 return "#version 330\n";
509 } else {
510 return "#version 330 compatibility\n";
511 }
512 }
513 case k310es_GrGLSLGeneration:
514 SkASSERT(kGLES_GrGLStandard == standard);
515 return "#version 310 es\n";
516 }
517 return "<no version>";
518}
519
egdaniel05ded892015-10-26 07:38:05 -0700520void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700521 GrGLStandard standard = ctxInfo.standard();
522 GrGLVersion version = ctxInfo.version();
523
524 /**************************************************************************
525 * Caps specific to GrGLSLCaps
526 **************************************************************************/
527
528 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
529 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
530
531 if (kGLES_GrGLStandard == standard) {
532 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
533 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
534 glslCaps->fFBFetchSupport = true;
535 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
536 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
537 }
538 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
539 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
540 glslCaps->fFBFetchNeedsCustomOutput = false;
541 glslCaps->fFBFetchSupport = true;
542 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
543 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
544 }
545 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
546 // The arm extension also requires an additional flag which we will set onResetContext
547 glslCaps->fFBFetchNeedsCustomOutput = false;
548 glslCaps->fFBFetchSupport = true;
549 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
550 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
551 }
552 glslCaps->fUsesPrecisionModifiers = true;
553 }
554
555 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
556
557 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
558 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
559
560 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
561 // function that may require a gradient calculation inside a conditional block may return
562 // undefined results". This appears to be an issue with the 'any' call since even the simple
563 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
564 // from our GrTextureDomain processor.
565 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
566
egdaniel472d44e2015-10-22 08:20:00 -0700567 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
568 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800569
570 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
571 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
572 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800573
574 // Frag Coords Convention support is not part of ES
575 // Known issue on at least some Intel platforms:
576 // http://code.google.com/p/skia/issues/detail?id=946
577 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
578 kGLES_GrGLStandard != standard &&
579 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
580 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
581 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
582 }
583
584 if (kGLES_GrGLStandard == standard) {
585 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
586 }
587
bsalomon7ea33f52015-11-22 14:51:00 -0800588 if (fExternalTextureSupport) {
589 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
590 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
591 } else {
592 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
593 }
594 }
595
egdaniel8dcdedc2015-11-11 06:27:20 -0800596 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
597 // the abs first in a separate expression.
598 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
599 glslCaps->fCanUseMinAndAbsTogether = false;
600 }
601
bsalomon7ea33f52015-11-22 14:51:00 -0800602 // 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 -0800603 // thus must us -1.0 * %s.x to work correctly
604 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
605 glslCaps->fMustForceNegatedAtanParamToFloat = true;
606 }
egdaniel472d44e2015-10-22 08:20:00 -0700607}
608
kkinnunencfe62e32015-07-01 02:58:50 -0700609bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700610 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
611
612 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700613 return false;
614 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700615
kkinnunencfe62e32015-07-01 02:58:50 -0700616 if (kGL_GrGLStandard == ctxInfo.standard()) {
617 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
618 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
619 return false;
620 }
621 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700622 if (!hasChromiumPathRendering &&
623 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700624 return false;
625 }
626 }
627 // We only support v1.3+ of GL_NV_path_rendering which allows us to
628 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
629 // additions are detected by checking the existence of the function.
630 // We also use *Then* functions that not all drivers might have. Check
631 // them for consistency.
halcanary96fcdcc2015-08-27 07:41:13 -0700632 if (nullptr == gli->fFunctions.fStencilThenCoverFillPath ||
633 nullptr == gli->fFunctions.fStencilThenCoverStrokePath ||
634 nullptr == gli->fFunctions.fStencilThenCoverFillPathInstanced ||
635 nullptr == gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
636 nullptr == gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700637 return false;
638 }
639 return true;
640}
piotaixre4b23142014-10-02 10:57:53 -0700641bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf,
bsalomon7928ef62016-01-05 10:26:39 -0800642 GrPixelConfig readConfig,
643 GrPixelConfig currFBOConfig) const {
644 SkASSERT(this->isConfigRenderable(currFBOConfig, false));
645
bsalomon76148af2016-01-12 11:13:47 -0800646 GrGLenum readFormat;
647 GrGLenum readType;
648 if (!this->getReadPixelsFormat(currFBOConfig, readConfig, &readFormat, &readType)) {
649 return false;
650 }
651
bsalomon7928ef62016-01-05 10:26:39 -0800652 if (kGL_GrGLStandard == intf->fStandard) {
bsalomon23e56662016-01-14 07:19:47 -0800653 // All of our renderable configs can be converted to each other by glReadPixels in OpenGL.
bsalomon7928ef62016-01-05 10:26:39 -0800654 return true;
piotaixre4b23142014-10-02 10:57:53 -0700655 }
bsalomon7928ef62016-01-05 10:26:39 -0800656
bsalomon76148af2016-01-12 11:13:47 -0800657 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800658
659 if (kNormalizedFixedPoint_FormatType == fConfigTable[currFBOConfig].fFormatType) {
660 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
661 return true;
662 }
663 } else {
664 SkASSERT(kFloat_FormatType == fConfigTable[currFBOConfig].fFormatType);
665 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
666 return true;
667 }
668 }
669
670 if (0 == fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat) {
671 ReadPixelsFormat* rpFormat =
672 const_cast<ReadPixelsFormat*>(&fConfigTable[currFBOConfig].fSecondReadPixelsFormat);
673 GrGLint format = 0, type = 0;
674 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
675 GR_GL_GetIntegerv(intf, GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
676 rpFormat->fFormat = format;
677 rpFormat->fType = type;
678 }
679
680 return fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
681 fConfigTable[currFBOConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700682}
683
robertphillips@google.com6177e692013-02-28 20:16:25 +0000684void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000685
686 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000687 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000688 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
689 // ES3 driver bugs on at least one device with a tiled GPU (N10).
690 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
691 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
692 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
693 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800694 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700695 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000696 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000697 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
698 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
699 // chrome's extension is equivalent to the EXT msaa
700 // and fbo_blit extensions.
701 fMSFBOType = kDesktop_EXT_MSFBOType;
702 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
703 fMSFBOType = kES_Apple_MSFBOType;
704 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000705 } else {
egdanieleed519e2016-01-15 11:36:18 -0800706 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700707 fMSFBOType = kMixedSamples_MSFBOType;
708 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000709 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000710 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000711 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
712 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000713 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000714 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000715 }
716}
717
cdalton1dd05422015-06-12 09:01:18 -0700718void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
719 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
720
721 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
722 // for now until its own blacklists can be updated.
723 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
724 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700725 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700726 return;
727 }
728
729 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
730 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
731 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
732 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
733 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
734 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
735 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
736 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
737 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
738 return;
739 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
740 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
741 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
742 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
743 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
744 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
745 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
746 // slow on a particular platform.
747 } else {
748 return; // No advanced blend support.
749 }
750
751 SkASSERT(this->advancedBlendEquationSupport());
752
753 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
754 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
755 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
756 (1 << kColorBurn_GrBlendEquation);
757 }
joel.liang9764c402015-07-09 19:46:18 -0700758 if (kARM_GrGLVendor == ctxInfo.vendor()) {
759 // Blacklist color-burn on ARM until the fix is released.
760 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
761 }
cdalton1dd05422015-06-12 09:01:18 -0700762}
763
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000764namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700765const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000766}
767
768void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
769
770 // Build up list of legal stencil formats (though perhaps not supported on
771 // the particular gpu/driver) from most preferred to least.
772
773 // these consts are in order of most preferred to least preferred
774 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
775
776 static const StencilFormat
777 // internal Format stencil bits total bits packed?
778 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
779 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
780 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
781 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000782 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000783 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
784
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000785 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000786 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000787 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000788 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
789 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
790
791 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
792 // require FBO support we can expect these are legal formats and don't
793 // check. These also all support the unsized GL_STENCIL_INDEX.
794 fStencilFormats.push_back() = gS8;
795 fStencilFormats.push_back() = gS16;
796 if (supportsPackedDS) {
797 fStencilFormats.push_back() = gD24S8;
798 }
799 fStencilFormats.push_back() = gS4;
800 if (supportsPackedDS) {
801 fStencilFormats.push_back() = gDS;
802 }
803 } else {
804 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
805 // for other formats.
806 // ES doesn't support using the unsized format.
807
808 fStencilFormats.push_back() = gS8;
809 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000810 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
811 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000812 fStencilFormats.push_back() = gD24S8;
813 }
814 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
815 fStencilFormats.push_back() = gS4;
816 }
817 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000818}
819
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000820SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000821
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000822 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000823
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000824 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000825 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000826 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000827 i,
828 fStencilFormats[i].fStencilBits,
829 fStencilFormats[i].fTotalBits);
830 }
831
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000832 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000833 "None",
834 "ARB",
835 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000836 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000837 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000838 "IMG MS To Texture",
839 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700840 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000841 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000842 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
843 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
844 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000845 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
846 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
847 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
848 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700849 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000850 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000851
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000852 static const char* kInvalidateFBTypeStr[] = {
853 "None",
854 "Discard",
855 "Invalidate",
856 };
857 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
858 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
859 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
860 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000861
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000862 static const char* kMapBufferTypeStr[] = {
863 "None",
864 "MapBuffer",
865 "MapBufferRange",
866 "Chromium",
867 };
868 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
869 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
870 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
871 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
872 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
873
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000874 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000875 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000876 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000877 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000878 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
879 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000880 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000881 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
882 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
883 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
884 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000885
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000886 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
887 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
888 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
889 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000890 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700891 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
892 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800893 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000894 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000895 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700896 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700897 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
898 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700899 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800900 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -0800901 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800902 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800903
904 r.append("Configs\n-------\n");
905 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
906 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -0800907 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
908 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -0800909 i,
910 fConfigTable[i].fFlags,
911 fConfigTable[i].fFormats.fBaseInternalFormat,
912 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -0800913 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
914 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -0800915 fConfigTable[i].fFormats.fExternalType,
916 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -0800917 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -0800918 }
919
jvanverthe9c0fc62015-04-29 11:18:05 -0700920 return r;
921}
922
jvanverthe9c0fc62015-04-29 11:18:05 -0700923static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
924 switch (p) {
925 case kLow_GrSLPrecision:
926 return GR_GL_LOW_FLOAT;
927 case kMedium_GrSLPrecision:
928 return GR_GL_MEDIUM_FLOAT;
929 case kHigh_GrSLPrecision:
930 return GR_GL_HIGH_FLOAT;
931 }
932 SkFAIL("Unknown precision.");
933 return -1;
934}
935
936static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
937 switch (type) {
938 case kVertex_GrShaderType:
939 return GR_GL_VERTEX_SHADER;
940 case kGeometry_GrShaderType:
941 return GR_GL_GEOMETRY_SHADER;
942 case kFragment_GrShaderType:
943 return GR_GL_FRAGMENT_SHADER;
944 }
945 SkFAIL("Unknown shader type.");
946 return -1;
947}
948
jvanverthcba99b82015-06-24 06:59:57 -0700949void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
950 const GrGLInterface* intf,
951 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700952 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
953 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
954 for (int s = 0; s < kGrShaderTypeCount; ++s) {
955 if (kGeometry_GrShaderType != s) {
956 GrShaderType shaderType = static_cast<GrShaderType>(s);
957 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -0700958 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -0700959 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700960 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
961 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
962 GrGLenum glPrecision = precision_to_gl_float_type(precision);
963 GrGLint range[2];
964 GrGLint bits;
965 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
966 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -0700967 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
968 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
969 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -0700970 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -0700971 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700972 }
jvanverthcba99b82015-06-24 06:59:57 -0700973 else if (!glslCaps->fShaderPrecisionVaries) {
974 glslCaps->fShaderPrecisionVaries =
975 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -0700976 }
977 }
978 }
979 }
980 }
981 }
982 else {
983 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -0700984 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700985 for (int s = 0; s < kGrShaderTypeCount; ++s) {
986 if (kGeometry_GrShaderType != s) {
987 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700988 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
989 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
990 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -0700991 }
992 }
993 }
994 }
995 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
996 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
997 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
998 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -0700999 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001000 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001001 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1002 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001003 }
1004 }
1005}
1006
bsalomon41e4384e2016-01-08 09:12:44 -08001007bool GrGLCaps::bgraIsInternalFormat() const {
1008 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1009}
1010
bsalomon76148af2016-01-12 11:13:47 -08001011bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1012 GrGLenum* internalFormat, GrGLenum* externalFormat,
1013 GrGLenum* externalType) const {
1014 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1015 externalFormat, externalType)) {
1016 return false;
1017 }
1018 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1019 return true;
1020}
1021
1022bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1023 GrGLenum* internalFormat) const {
1024 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1025 return false;
1026 }
1027 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1028 return true;
1029}
1030
1031bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1032 GrGLenum* externalFormat, GrGLenum* externalType) const {
1033 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1034 externalFormat, externalType)) {
1035 return false;
1036 }
1037 return true;
1038}
1039
1040bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1041 if (GrPixelConfigIsCompressed(config)) {
1042 return false;
1043 }
1044 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1045 return true;
1046}
1047
1048bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1049 ExternalFormatUsage usage, GrGLenum* externalFormat,
1050 GrGLenum* externalType) const {
1051 SkASSERT(externalFormat && externalType);
1052 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1053 return false;
1054 }
1055
1056 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1057 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1058
1059 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1060 // made to work in many cases using glPixelStore and what not but is not needed currently.
1061 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1062 return false;
1063 }
1064
1065 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1066 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1067
1068 return true;
1069}
1070
bsalomoncdee0092016-01-08 13:20:12 -08001071void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1072 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001073 /*
1074 Comments on renderability of configs on various GL versions.
1075 OpenGL < 3.0:
1076 no built in support for render targets.
1077 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1078 format RGB, RGBA and NV float formats we don't use.
1079 This is the following:
1080 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1081 RGB10_A2, RGBA12,RGBA16
1082 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1083 since they aren't required by later standards and the driver can simply return
1084 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1085 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1086 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1087 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1088 This adds a lot of additional renderable sized formats, including ALPHA8.
1089 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1090 16F, 32I, 32UI, and 32F variants).
1091 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1092
1093 For both the above extensions we limit ourselves to those that are also required by
1094 OpenGL 3.0.
1095
1096 OpenGL 3.0:
1097 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1098 but are not required to be supported as renderable textures/renderbuffer.
1099 Required renderable color formats:
1100 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1101 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1102 RGB10_A2.
1103 - R11F_G11F_B10F.
1104 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1105 and RG8UI.
1106 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1107 - ALPHA8
1108
1109 OpenGL 3.1, 3.2, 3.3
1110 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1111 OpengGL 3.3, 4.0, 4.1
1112 Adds RGB10_A2UI.
1113 OpengGL 4.2
1114 Adds
1115 - RGB5_A1, RGBA4
1116 - RGB565
1117 OpenGL 4.4
1118 Does away with the separate list and adds a column to the sized internal color format
1119 table. However, no new formats become required color renderable.
1120
1121 ES 2.0
1122 color renderable: RGBA4, RGB5_A1, RGB565
1123 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1124 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1125 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1126 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1127 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1128 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1129
1130 ES 3.0
1131 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1132 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1133 RGB5_A1.
1134 - RGB8 and RGB565.
1135 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1136 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1137 ES 3.1
1138 Adds RGB10_A2, RGB10_A2UI,
1139 ES 3.2
1140 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1141 */
1142 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1143 if (kNone_MSFBOType != fMSFBOType) {
1144 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1145 }
1146
1147 GrGLStandard standard = ctxInfo.standard();
1148 GrGLVersion version = ctxInfo.version();
1149
bsalomon30447372015-12-21 09:03:05 -08001150 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1151 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001152 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001153 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001154 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001155 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001156
1157 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1158 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001159 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1160 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001161 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001162 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001163 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1164 if (kGL_GrGLStandard == standard) {
1165 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1166 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001167 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001168 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1169 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1170 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1171 }
egdaniel4999df82016-01-07 17:06:04 -08001172 }
bsalomoncdee0092016-01-08 13:20:12 -08001173 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001174
bsalomon76148af2016-01-12 11:13:47 -08001175 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1176 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001177 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001178 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001179 if (kGL_GrGLStandard == standard) {
1180 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1181 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1182 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1183 // Since the internal format is RGBA8, it is also renderable.
1184 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1185 allRenderFlags;
1186 }
1187 } else {
1188 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1189 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1190 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1191 // The APPLE extension doesn't make this renderable.
1192 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1193 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1194 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1195 // Though, that seems to not be the case if the texture storage extension is
1196 // present. The specs don't exactly make that clear.
1197 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1198 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1199 }
1200 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1201 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1202 ConfigInfo::kRenderable_Flag;
1203 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
1204 this->usesMSAARenderBuffers()) {
1205 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1206 ConfigInfo::kRenderableWithMSAA_Flag;
1207 }
1208 }
1209 }
bsalomoncdee0092016-01-08 13:20:12 -08001210 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001211
bsalomon41e4384e2016-01-08 09:12:44 -08001212 // We only enable srgb support if both textures and FBOs support srgb.
1213 bool srgbSupport = false;
1214 if (kGL_GrGLStandard == standard) {
1215 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1216 srgbSupport = true;
1217 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1218 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1219 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1220 srgbSupport = true;
1221 }
1222 }
1223 // All the above srgb extensions support toggling srgb writes
1224 fSRGBWriteControl = srgbSupport;
1225 } else {
1226 // See https://bug.skia.org/4148 for PowerVR issue.
1227 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1228 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1229 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1230 // sRGB writing for destinations.
1231 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1232 }
bsalomon30447372015-12-21 09:03:05 -08001233 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1234 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1235 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1236 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001237 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1238 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001239 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001240 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001241 if (srgbSupport) {
1242 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1243 allRenderFlags;
1244 }
bsalomoncdee0092016-01-08 13:20:12 -08001245 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001246
1247 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1248 if (this->ES2CompatibilitySupport()) {
1249 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1250 } else {
1251 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1252 }
bsalomon76148af2016-01-12 11:13:47 -08001253 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1254 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001255 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001256 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001257 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1258 if (kGL_GrGLStandard == standard) {
1259 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1260 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1261 }
1262 } else {
1263 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1264 }
bsalomoncdee0092016-01-08 13:20:12 -08001265 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001266
1267 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1268 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001269 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1270 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001271 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001272 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001273 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1274 if (kGL_GrGLStandard == standard) {
1275 if (version >= GR_GL_VER(4, 2)) {
1276 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1277 }
1278 } else {
1279 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1280 }
bsalomoncdee0092016-01-08 13:20:12 -08001281 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001282
1283 if (this->textureRedSupport()) {
1284 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1285 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001286 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1287 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001288 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001289 } else {
1290 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1291 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001292 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1293 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001294 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001295 }
1296 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001297 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001298 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1299 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1300 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1301 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1302 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1303 }
1304
1305 // Check for [half] floating point texture support
1306 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1307 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1308 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1309 bool hasFPTextures = false;
1310 bool hasHalfFPTextures = false;
1311 // for now we don't support floating point MSAA on ES
1312 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1313 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1314
1315 if (kGL_GrGLStandard == standard) {
1316 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1317 hasFPTextures = true;
1318 hasHalfFPTextures = true;
1319 }
1320 } else {
1321 if (version >= GR_GL_VER(3, 1)) {
1322 hasFPTextures = true;
1323 hasHalfFPTextures = true;
1324 } else {
1325 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1326 ctxInfo.hasExtension("GL_OES_texture_float")) {
1327 hasFPTextures = true;
1328 }
1329 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1330 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1331 hasHalfFPTextures = true;
1332 }
1333 }
1334 }
bsalomon30447372015-12-21 09:03:05 -08001335
1336 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1337 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001338 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1339 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001340 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001341 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001342 if (hasFPTextures) {
1343 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1344 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1345 // many precision issues and no clients actually want this yet.
1346 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1347 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1348 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1349 }
1350 }
bsalomoncdee0092016-01-08 13:20:12 -08001351 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001352
1353 if (this->textureRedSupport()) {
1354 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1355 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001356 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1357 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001358 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001359 } else {
1360 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1361 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001362 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1363 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001364 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001365 }
1366 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1367 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1368 } else {
1369 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1370 }
bsalomon7928ef62016-01-05 10:26:39 -08001371 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001372 if (hasHalfFPTextures) {
1373 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1374 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1375 // GL_RED internal format.
1376 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1377 (this->textureRedSupport() &&
1378 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1379 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1380 }
1381 }
bsalomon30447372015-12-21 09:03:05 -08001382
1383 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1384 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001385 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1386 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001387 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1388 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1389 } else {
1390 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1391 }
bsalomon7928ef62016-01-05 10:26:39 -08001392 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001393 if (hasHalfFPTextures) {
1394 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1395 // ES requires 3.2 or EXT_color_buffer_half_float.
1396 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1397 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1398 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1399 }
1400 }
bsalomoncdee0092016-01-08 13:20:12 -08001401 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001402
1403 // Compressed texture support
1404
1405 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1406 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1407
1408 // TODO: Fix command buffer bindings and remove this.
1409 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001410
1411 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001412 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001413
1414 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1415 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001416 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001417 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001418 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001419 // Disable this for now, while we investigate https://bug.skia.org/4333
1420 if (false) {
1421 // Check for 8-bit palette..
1422 GrGLint numFormats;
1423 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1424 if (numFormats) {
1425 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1426 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1427 for (int i = 0; i < numFormats; ++i) {
1428 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1429 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1430 break;
1431 }
1432 }
1433 }
1434 }
bsalomoncdee0092016-01-08 13:20:12 -08001435 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001436
bsalomon41e4384e2016-01-08 09:12:44 -08001437 // May change the internal format based on extensions.
1438 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1439 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1440 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1441 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1442 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1443 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1444 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1445 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1446 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1447 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1448 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1449 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1450 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1451 GR_GL_COMPRESSED_RED_RGTC1;
1452 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1453 GR_GL_COMPRESSED_RED_RGTC1;
1454 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1455 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1456 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1457 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1458 GR_GL_COMPRESSED_3DC_X;
1459
bsalomon30447372015-12-21 09:03:05 -08001460 }
bsalomon76148af2016-01-12 11:13:47 -08001461 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001462 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001463 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001464 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001465
1466 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1467 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001468 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001469 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001470 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001471 if (kGL_GrGLStandard == standard) {
1472 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1473 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1474 }
1475 } else {
1476 if (version >= GR_GL_VER(3, 0) ||
1477 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1478 // ETC2 is a superset of ETC1, so we can just check for that, too.
1479 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1480 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1481 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1482 }
1483 }
bsalomoncdee0092016-01-08 13:20:12 -08001484 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001485
1486 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1487 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001488 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001489 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001490 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001491 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1492 // decompressing the textures in the driver, and is generally slower.
1493 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1494 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1495 }
bsalomoncdee0092016-01-08 13:20:12 -08001496 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001497
1498 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1499 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1500 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1501 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001502 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1503 0;
bsalomon30447372015-12-21 09:03:05 -08001504 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001505 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001506 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1507 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1508 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1509 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1510 }
bsalomoncdee0092016-01-08 13:20:12 -08001511 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001512
1513 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1514
1515 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001516 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1517 ctxInfo.version() >= GR_GL_VER(3,0));
1518 // All ES versions (thus far) require sized internal formats for render buffers.
1519 // TODO: Always use sized internal format?
1520 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1521
bsalomon30447372015-12-21 09:03:05 -08001522 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001523 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1524 // param to glTex[Sub]Image.
1525 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1526 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1527 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1528 fConfigTable[i].fFormats.fSizedInternalFormat :
1529 fConfigTable[i].fFormats.fBaseInternalFormat;
1530 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001531 fConfigTable[i].fFormats.fSizedInternalFormat :
1532 fConfigTable[i].fFormats.fBaseInternalFormat;
1533 }
1534 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1535 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1536 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1537 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1538 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001539 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001540 GR_GL_SRGB_ALPHA;
1541 }
1542
1543 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1544 // as a base format.
1545 // GL_EXT_texture_format_BGRA8888:
1546 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1547 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1548 // formats.
1549 // GL_APPLE_texture_format_BGRA8888:
1550 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1551 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1552 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001553 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001554 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1555 }
1556
bsalomoncdee0092016-01-08 13:20:12 -08001557 // If we don't have texture swizzle support then the shader generator must insert the
1558 // swizzle into shader code.
1559 if (!this->textureSwizzleSupport()) {
1560 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1561 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1562 }
1563 }
1564
bsalomon7f9b2e42016-01-12 13:29:26 -08001565 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1566 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1567 // gets written to the single component.
1568 if (this->textureRedSupport()) {
1569 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1570 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1571 if (GrPixelConfigIsAlphaOnly(config) &&
1572 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1573 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1574 }
1575 }
1576 }
1577
bsalomon30447372015-12-21 09:03:05 -08001578#ifdef SK_DEBUG
1579 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001580 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001581 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001582 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1583 fConfigTable[i].fFormats.fBaseInternalFormat);
1584 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001585 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001586 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1587 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1588 fConfigTable[i].fFormats.fExternalFormat[j]);
1589 }
1590 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001591 }
1592#endif
1593}
1594
egdanielb7e7d572015-11-04 04:23:53 -08001595void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}