blob: 79bb22efac0455cfad4158887f48eba86aae5fcf [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"
bsalomon1aa20292016-01-22 08:16:09 -080013#include "GrGLRenderTarget.h"
jvanverthcba99b82015-06-24 06:59:57 -070014#include "glsl/GrGLSLCaps.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"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000017
bsalomon682c2692015-05-22 14:01:46 -070018GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
19 const GrGLContextInfo& ctxInfo,
20 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080021 fStandard = ctxInfo.standard();
22
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000023 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000024 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000025 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000026 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080027 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000028 fMaxFragmentUniformVectors = 0;
bsalomon@google.com60da4172012-06-01 19:25:00 +000029 fMaxVertexAttributes = 0;
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000030 fMaxFragmentTextureUnits = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000031 fUnpackRowLengthSupport = false;
32 fUnpackFlipYSupport = false;
33 fPackRowLengthSupport = false;
34 fPackFlipYSupport = false;
35 fTextureUsageSupport = false;
36 fTexStorageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000037 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000038 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000039 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070040 fDirectStateAccessSupport = false;
41 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080042 fES2CompatibilitySupport = false;
cdaltond4727922015-11-10 12:49:06 -080043 fMultisampleDisableSupport = false;
cdalton06604b92016-02-05 10:09:51 -080044 fDrawIndirectSupport = false;
45 fMultiDrawIndirectSupport = false;
46 fBaseInstanceSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000047 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000048 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070049 fBindFragDataLocationSupport = false;
bsalomon7ea33f52015-11-22 14:51:00 -080050 fExternalTextureSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080051 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080052 fTextureSwizzleSupport = false;
bsalomon16921ec2015-07-30 15:34:56 -070053 fSRGBWriteControl = false;
bsalomon88c7b982015-07-31 11:20:16 -070054 fRGBA8888PixelsOpsAreSlow = false;
55 fPartialFBOReadIsSlow = false;
piotaixre4b23142014-10-02 10:57:53 -070056
bsalomon083617b2016-02-12 12:10:14 -080057 fBlitFramebufferSupport = kNone_BlitFramebufferSupport;
58
halcanary385fe4d2015-08-26 13:07:48 -070059 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070060
cdalton4cd67132015-06-10 19:23:46 -070061 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000062}
63
cdalton4cd67132015-06-10 19:23:46 -070064void GrGLCaps::init(const GrContextOptions& contextOptions,
65 const GrGLContextInfo& ctxInfo,
66 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000067 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000068 GrGLVersion version = ctxInfo.version();
69
bsalomon@google.combcce8922013-03-25 15:38:39 +000070 /**************************************************************************
71 * Caps specific to GrGLCaps
72 **************************************************************************/
73
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000074 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000075 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
76 &fMaxFragmentUniformVectors);
77 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000078 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000079 GrGLint max;
80 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
81 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000082 if (version >= GR_GL_VER(3, 2)) {
83 GrGLint profileMask;
84 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
85 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
86 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000087 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000088 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000089 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
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) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000110 // The EXT version can apply to either GL or GLES.
111 fTexStorageSupport = version >= GR_GL_VER(4,2) ||
112 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
113 ctxInfo.hasExtension("GL_EXT_texture_storage");
114 } else {
115 // Qualcomm Adreno drivers appear to have issues with texture storage.
116 fTexStorageSupport = (version >= GR_GL_VER(3,0) &&
117 kQualcomm_GrGLVendor != ctxInfo.vendor()) ||
118 ctxInfo.hasExtension("GL_EXT_texture_storage");
119 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000120
cdaltonfd4167d2015-04-21 11:45:56 -0700121 if (kGL_GrGLStandard == standard) {
122 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
123 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
124 ctxInfo.hasExtension("GL_NV_texture_barrier");
125 } else {
126 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
127 }
128
hendrikwa0d5ad72014-12-02 07:30:30 -0800129 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
130 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700131 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800132 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000133 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
134 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800135 } else {
136 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
137 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000138 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000139 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000140 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000141 ctxInfo.hasExtension("GL_ARB_imaging");
142
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000143 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
144 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
145 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
146 // limit this decision to specific GPU families rather than basing it on the vendor alone.
147 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700148 (kARM_GrGLVendor == ctxInfo.vendor() ||
149 kImagination_GrGLVendor == ctxInfo.vendor() ||
150 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000151 fUseNonVBOVertexAndIndexDynamicData = true;
152 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000153
egdaniel9250d242015-05-18 13:04:26 -0700154 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
155 // Thus we are blacklisting this extension for now on Adreno4xx devices.
156 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
157 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
158 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
159 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000160 fDiscardRenderTargetSupport = true;
161 fInvalidateFBType = kInvalidate_InvalidateFBType;
162 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
163 fDiscardRenderTargetSupport = true;
164 fInvalidateFBType = kDiscard_InvalidateFBType;
165 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000166
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000167 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
168 fFullClearIsFree = true;
169 }
170
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000171 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000172 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800173 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
174 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000175 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000176 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
177 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000178 }
179
cdalton626e1ff2015-06-12 13:56:46 -0700180 if (kGL_GrGLStandard == standard) {
181 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
182 } else {
183 fDirectStateAccessSupport = false;
184 }
185
186 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
187 fDebugSupport = true;
188 } else {
189 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
190 }
191
jvanverth3f801cb2014-12-16 09:49:38 -0800192 if (kGL_GrGLStandard == standard) {
193 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
194 }
195 else {
196 fES2CompatibilitySupport = true;
197 }
198
cdalton0edea2c2015-05-21 08:27:44 -0700199 if (kGL_GrGLStandard == standard) {
200 fMultisampleDisableSupport = true;
201 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700202 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700203 }
204
kkinnunend94708e2015-07-30 22:47:04 -0700205 if (kGL_GrGLStandard == standard) {
206 if (version >= GR_GL_VER(3, 0)) {
207 fBindFragDataLocationSupport = true;
208 }
209 } else {
210 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
211 fBindFragDataLocationSupport = true;
212 }
joshualittc1f56b52015-06-22 12:31:31 -0700213 }
214
bsalomonb8909d32016-01-28 07:09:52 -0800215#if 0 // Disabled due to https://bug.skia.org/4454
joshualitt7bdd70a2015-10-01 06:28:11 -0700216 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
bsalomonb8909d32016-01-28 07:09:52 -0800217#else
218 fBindUniformLocationSupport = false;
219#endif
joshualitt7bdd70a2015-10-01 06:28:11 -0700220
bsalomon7ea33f52015-11-22 14:51:00 -0800221 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
222 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
223 fExternalTextureSupport = true;
224 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
225 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
226 // At least one driver has been found that has this extension without the "GL_" prefix.
227 fExternalTextureSupport = true;
228 }
229 }
230
bsalomone179a912016-01-20 06:18:10 -0800231 if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 1)) ||
bsalomone5286e02016-01-14 09:24:09 -0800232 ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
bsalomone179a912016-01-20 06:18:10 -0800233 // We also require textureSize() support for rectangle 2D samplers which was added in GLSL
234 // 1.40.
235 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
236 fRectangleTextureSupport = true;
237 }
bsalomone5286e02016-01-14 09:24:09 -0800238 }
239
bsalomoncdee0092016-01-08 13:20:12 -0800240 if (kGL_GrGLStandard == standard) {
241 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
242 fTextureSwizzleSupport = true;
243 }
244 } else {
245 if (version >= GR_GL_VER(3,0)) {
246 fTextureSwizzleSupport = true;
247 }
248 }
249
bsalomon88c7b982015-07-31 11:20:16 -0700250#ifdef SK_BUILD_FOR_WIN
251 // We're assuming that on Windows Chromium we're using ANGLE.
252 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
253 kChromium_GrGLDriver == ctxInfo.driver();
254 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
255 fRGBA8888PixelsOpsAreSlow = isANGLE;
256 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
257 // check DX11 ANGLE.
258 fPartialFBOReadIsSlow = isANGLE;
259#endif
260
cdalton4cd67132015-06-10 19:23:46 -0700261 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700262 * GrShaderCaps fields
263 **************************************************************************/
264
egdaniel0a482332015-10-26 08:59:10 -0700265 // This must be called after fCoreProfile is set on the GrGLCaps
266 this->initGLSL(ctxInfo);
267 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
268
egdaniel05ded892015-10-26 07:38:05 -0700269 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
270
271 // For now these two are equivalent but we could have dst read in shader via some other method.
272 // Before setting this, initGLSL() must have been called.
273 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
274
275 // Enable supported shader-related caps
276 if (kGL_GrGLStandard == standard) {
277 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
278 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
279 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
280 glslCaps->fShaderDerivativeSupport = true;
281 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
282 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
283 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
cdalton793dc262016-02-08 10:11:47 -0800284 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
285 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700286 }
287 else {
288 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
289
290 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
291 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800292
293 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
294 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700295 }
296
ethannicholas22793252016-01-30 09:59:10 -0800297 if (ctxInfo.hasExtension("GL_EXT_shader_pixel_local_storage")) {
298 #define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
299 GR_GL_GetIntegerv(gli, GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT,
300 &glslCaps->fPixelLocalStorageSize);
301 glslCaps->fPLSPathRenderingSupport = glslCaps->fFBFetchSupport;
302 }
303 else {
304 glslCaps->fPixelLocalStorageSize = 0;
305 glslCaps->fPLSPathRenderingSupport = false;
306 }
307
egdaniel05ded892015-10-26 07:38:05 -0700308 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700309 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000310 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700311
cdalton63f6c1f2015-11-06 07:09:43 -0800312 // We need dual source blending and the ability to disable multisample in order to support mixed
313 // samples in every corner case.
egdanieleed519e2016-01-15 11:36:18 -0800314 if (fMultisampleDisableSupport &&
315 glslCaps->dualSourceBlendingSupport() &&
316 fShaderCaps->pathRenderingSupport()) {
317 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
kkinnunenea409432015-12-10 01:21:59 -0800318 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800319 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
kkinnunen9f63b442016-01-25 00:31:49 -0800320 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
321 kChromium_GrGLDriver == ctxInfo.driver())) {
cdalton63f6c1f2015-11-06 07:09:43 -0800322 fDiscardRenderTargetSupport = false;
323 fInvalidateFBType = kNone_InvalidateFBType;
324 }
325 }
326
egdanieleed519e2016-01-15 11:36:18 -0800327 // fUsesMixedSamples must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700328 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700329 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700330 this->initStencilFormats(ctxInfo);
331
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000332 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000333 // we could also look for GL_ATI_separate_stencil extension or
334 // GL_EXT_stencil_two_side but they use different function signatures
335 // than GL2.0+ (and than each other).
336 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
337 // supported on GL 1.4 and higher or by extension
338 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
339 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
340 } else {
341 // ES 2 has two sided stencil and stencil wrap
342 fTwoSidedStencilSupport = true;
343 fStencilWrapOpsSupport = true;
344 }
345
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000346 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000347 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
348 // extension includes glMapBuffer.
349 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
350 fMapBufferFlags |= kSubset_MapFlag;
351 fMapBufferType = kMapBufferRange_MapBufferType;
352 } else {
353 fMapBufferType = kMapBuffer_MapBufferType;
354 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000355 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000356 // Unextended GLES2 doesn't have any buffer mapping.
357 fMapBufferFlags = kNone_MapBufferType;
358 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
359 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
360 fMapBufferType = kChromium_MapBufferType;
361 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
362 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
363 fMapBufferType = kMapBufferRange_MapBufferType;
364 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
365 fMapBufferFlags = kCanMap_MapFlag;
366 fMapBufferType = kMapBuffer_MapBufferType;
367 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000368 }
369
jvanverthd7a2c1f2015-12-07 07:36:44 -0800370 if (kGL_GrGLStandard == standard) {
371 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
372 fTransferBufferType = kPBO_TransferBufferType;
373 }
374 } else {
375 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
376 fTransferBufferType = kPBO_TransferBufferType;
377 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
378 fTransferBufferType = kChromium_TransferBufferType;
379 }
380 }
381
joshualitte5b74c62015-06-01 14:17:47 -0700382 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
383 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
384 if (fGeometryBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700385 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
386 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
387 // a small subset.
388#if 0
cdalton1acea862015-06-02 13:05:52 -0700389 fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700390#else
391 fGeometryBufferMapThreshold = SK_MaxS32;
392#endif
joshualitte5b74c62015-06-01 14:17:47 -0700393 }
394
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000395 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000396 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
397 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
398 fNPOTTextureTileSupport = true;
399 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000400 } else {
401 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000402 // ES3 has no limitations.
403 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
404 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000405 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
406 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
407 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
408 // to alllow arbitrary wrap modes, however.
409 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000410 }
411
bsalomone72bd022015-10-26 07:33:03 -0700412 // Using MIPs on this GPU seems to be a source of trouble.
413 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
414 fMipMapSupport = false;
415 }
416
bsalomon@google.combcce8922013-03-25 15:38:39 +0000417 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
418 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
419 // Our render targets are always created with textures as the color
420 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000421 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000422
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000423 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
424
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000425 // Disable scratch texture reuse on Mali and Adreno devices
426 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
427 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000428
robertphillips1b8e1b52015-06-24 06:54:10 -0700429#if 0
430 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
431 kQualcomm_GrGLVendor != ctxInfo.vendor();
432#endif
433
egdaniel05ded892015-10-26 07:38:05 -0700434 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000435 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800436 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000437 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800438 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000439 }
cdaltonaf8bc7d2016-02-05 09:35:20 -0800440 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
441 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
442 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
443 // This is to guard against platforms that may not support as many samples for
444 // glRasterSamples as they do for framebuffers.
445 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
446 }
447 fMaxColorSampleCount = fMaxStencilSampleCount;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000448
bsalomon63b21962014-11-05 07:05:34 -0800449 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800450 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800451 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800452 fUseDrawInsteadOfClear = true;
453 }
454
joshualitt83bc2292015-06-18 14:18:02 -0700455 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
456 fUseDrawInsteadOfPartialRenderTargetWrite = true;
457 }
458
robertphillips63926682015-08-20 09:39:02 -0700459#ifdef SK_BUILD_FOR_WIN
460 // On ANGLE deferring flushes can lead to GPU starvation
461 fPreferVRAMUseOverFlushes = !isANGLE;
462#endif
463
bsalomon7dea7b72015-08-19 08:26:51 -0700464 if (kChromium_GrGLDriver == ctxInfo.driver()) {
465 fMustClearUploadedBufferData = true;
466 }
467
bsalomond08ea5f2015-02-20 06:58:13 -0800468 if (kGL_GrGLStandard == standard) {
469 // ARB allows mixed size FBO attachments, EXT does not.
470 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
471 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
472 fOversizedStencilSupport = true;
473 } else {
474 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
475 }
476 } else {
477 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
478 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
479 }
480
joshualitt58001552015-06-26 12:46:36 -0700481 if (kGL_GrGLStandard == standard) {
482 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
483 // instanced arrays, but we could make this more granular if we wanted
484 fSupportsInstancedDraws =
485 version >= GR_GL_VER(3, 2) ||
486 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
487 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
488 } else {
489 fSupportsInstancedDraws =
490 version >= GR_GL_VER(3, 0) ||
491 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
492 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
493 }
494
cdalton06604b92016-02-05 10:09:51 -0800495 if (kGL_GrGLStandard == standard) {
496 // We don't use ARB_draw_indirect because it does not support a base instance.
497 // We don't use ARB_multi_draw_indirect because it does not support GL_DRAW_INDIRECT_BUFFER.
498 fDrawIndirectSupport =
499 fMultiDrawIndirectSupport = fBaseInstanceSupport = version >= GR_GL_VER(4,3);
500 } else {
501 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
502 fMultiDrawIndirectSupport = ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
503 fBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance");
504 }
505
jvanverthcba99b82015-06-24 06:59:57 -0700506 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800507
508 if (contextOptions.fUseShaderSwizzling) {
509 fTextureSwizzleSupport = false;
510 }
511
512 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
513 // already been detected.
514 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700515
516 this->applyOptionsOverrides(contextOptions);
517 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000518}
519
egdaniel472d44e2015-10-22 08:20:00 -0700520const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
521 bool isCoreProfile) {
522 switch (generation) {
523 case k110_GrGLSLGeneration:
524 if (kGLES_GrGLStandard == standard) {
525 // ES2s shader language is based on version 1.20 but is version
526 // 1.00 of the ES language.
527 return "#version 100\n";
528 } else {
529 SkASSERT(kGL_GrGLStandard == standard);
530 return "#version 110\n";
531 }
532 case k130_GrGLSLGeneration:
533 SkASSERT(kGL_GrGLStandard == standard);
534 return "#version 130\n";
535 case k140_GrGLSLGeneration:
536 SkASSERT(kGL_GrGLStandard == standard);
537 return "#version 140\n";
538 case k150_GrGLSLGeneration:
539 SkASSERT(kGL_GrGLStandard == standard);
540 if (isCoreProfile) {
541 return "#version 150\n";
542 } else {
543 return "#version 150 compatibility\n";
544 }
545 case k330_GrGLSLGeneration:
546 if (kGLES_GrGLStandard == standard) {
547 return "#version 300 es\n";
548 } else {
549 SkASSERT(kGL_GrGLStandard == standard);
550 if (isCoreProfile) {
551 return "#version 330\n";
552 } else {
553 return "#version 330 compatibility\n";
554 }
555 }
556 case k310es_GrGLSLGeneration:
557 SkASSERT(kGLES_GrGLStandard == standard);
558 return "#version 310 es\n";
559 }
560 return "<no version>";
561}
562
egdaniel05ded892015-10-26 07:38:05 -0700563void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700564 GrGLStandard standard = ctxInfo.standard();
565 GrGLVersion version = ctxInfo.version();
566
567 /**************************************************************************
568 * Caps specific to GrGLSLCaps
569 **************************************************************************/
570
571 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
572 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700573 if (kGLES_GrGLStandard == standard) {
574 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
575 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
576 glslCaps->fFBFetchSupport = true;
577 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
578 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
579 }
580 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
581 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
582 glslCaps->fFBFetchNeedsCustomOutput = false;
583 glslCaps->fFBFetchSupport = true;
584 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
585 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
586 }
587 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
588 // The arm extension also requires an additional flag which we will set onResetContext
589 glslCaps->fFBFetchNeedsCustomOutput = false;
590 glslCaps->fFBFetchSupport = true;
591 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
592 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
593 }
594 glslCaps->fUsesPrecisionModifiers = true;
595 }
596
597 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
598
599 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
600 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
601
602 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
603 // function that may require a gradient calculation inside a conditional block may return
604 // undefined results". This appears to be an issue with the 'any' call since even the simple
605 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
606 // from our GrTextureDomain processor.
607 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
608
egdaniel472d44e2015-10-22 08:20:00 -0700609 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
610 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800611
612 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
613 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
614 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800615
616 // Frag Coords Convention support is not part of ES
617 // Known issue on at least some Intel platforms:
618 // http://code.google.com/p/skia/issues/detail?id=946
619 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
620 kGLES_GrGLStandard != standard &&
621 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
622 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
623 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
624 }
625
626 if (kGLES_GrGLStandard == standard) {
627 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
628 }
629
bsalomon7ea33f52015-11-22 14:51:00 -0800630 if (fExternalTextureSupport) {
631 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
632 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
633 } else {
634 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
635 }
636 }
637
egdaniel8dcdedc2015-11-11 06:27:20 -0800638 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
639 // the abs first in a separate expression.
640 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
641 glslCaps->fCanUseMinAndAbsTogether = false;
642 }
643
bsalomon7ea33f52015-11-22 14:51:00 -0800644 // 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 -0800645 // thus must us -1.0 * %s.x to work correctly
646 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
647 glslCaps->fMustForceNegatedAtanParamToFloat = true;
648 }
egdaniel472d44e2015-10-22 08:20:00 -0700649}
650
kkinnunencfe62e32015-07-01 02:58:50 -0700651bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700652 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
653
654 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700655 return false;
656 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700657
kkinnunencfe62e32015-07-01 02:58:50 -0700658 if (kGL_GrGLStandard == ctxInfo.standard()) {
659 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
660 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
661 return false;
662 }
663 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700664 if (!hasChromiumPathRendering &&
665 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700666 return false;
667 }
668 }
669 // We only support v1.3+ of GL_NV_path_rendering which allows us to
670 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
671 // additions are detected by checking the existence of the function.
672 // We also use *Then* functions that not all drivers might have. Check
673 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800674 if (!gli->fFunctions.fStencilThenCoverFillPath ||
675 !gli->fFunctions.fStencilThenCoverStrokePath ||
676 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
677 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
678 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700679 return false;
680 }
681 return true;
682}
bsalomon1aa20292016-01-22 08:16:09 -0800683
684bool GrGLCaps::readPixelsSupported(GrPixelConfig rtConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800685 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800686 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
687 std::function<bool ()> bindRenderTarget) const {
bsalomone9573312016-01-25 14:33:25 -0800688 // If it's not possible to even have a render target of rtConfig then read pixels is
689 // not supported regardless of readConfig.
690 if (!this->isConfigRenderable(rtConfig, false)) {
691 return false;
692 }
bsalomon7928ef62016-01-05 10:26:39 -0800693
bsalomon76148af2016-01-12 11:13:47 -0800694 GrGLenum readFormat;
695 GrGLenum readType;
bsalomon1aa20292016-01-22 08:16:09 -0800696 if (!this->getReadPixelsFormat(rtConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800697 return false;
698 }
699
bsalomon1aa20292016-01-22 08:16:09 -0800700 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800701 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
702 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
703 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
704 // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
705 if (readFormat != GR_GL_RED && readFormat != GR_GL_RGB && readFormat != GR_GL_RGBA &&
706 readFormat != GR_GL_BGRA) {
707 return false;
708 }
709 // There is also a set of allowed types, but all the types we use are in the set:
710 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
711 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
712 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
713 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
714 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
715 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
716 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800717 return true;
piotaixre4b23142014-10-02 10:57:53 -0700718 }
bsalomon7928ef62016-01-05 10:26:39 -0800719
bsalomon76148af2016-01-12 11:13:47 -0800720 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800721
bsalomon1aa20292016-01-22 08:16:09 -0800722 if (kNormalizedFixedPoint_FormatType == fConfigTable[rtConfig].fFormatType) {
bsalomon7928ef62016-01-05 10:26:39 -0800723 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
724 return true;
725 }
726 } else {
bsalomon1aa20292016-01-22 08:16:09 -0800727 SkASSERT(kFloat_FormatType == fConfigTable[rtConfig].fFormatType);
bsalomon7928ef62016-01-05 10:26:39 -0800728 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
729 return true;
730 }
731 }
732
bsalomon1aa20292016-01-22 08:16:09 -0800733 if (0 == fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800734 ReadPixelsFormat* rpFormat =
bsalomon1aa20292016-01-22 08:16:09 -0800735 const_cast<ReadPixelsFormat*>(&fConfigTable[rtConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800736 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800737 if (!bindRenderTarget()) {
738 return false;
739 }
740 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
741 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800742 rpFormat->fFormat = format;
743 rpFormat->fType = type;
744 }
745
bsalomon1aa20292016-01-22 08:16:09 -0800746 return fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
747 fConfigTable[rtConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700748}
749
robertphillips@google.com6177e692013-02-28 20:16:25 +0000750void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000751
752 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000753 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000754 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
755 // ES3 driver bugs on at least one device with a tiled GPU (N10).
756 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
757 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
758 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
759 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800760 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700761 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000762 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000763 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
764 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
765 // chrome's extension is equivalent to the EXT msaa
766 // and fbo_blit extensions.
767 fMSFBOType = kDesktop_EXT_MSFBOType;
768 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
769 fMSFBOType = kES_Apple_MSFBOType;
770 }
bsalomon083617b2016-02-12 12:10:14 -0800771
772 // Above determined the preferred MSAA approach, now decide whether glBlitFramebuffer
773 // is available.
774 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
775 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
776 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
777 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
778 // limitations.
779 fBlitFramebufferSupport = kNoScalingNoMirroring_BlitFramebufferSupport;
780 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000781 } else {
egdanieleed519e2016-01-15 11:36:18 -0800782 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700783 fMSFBOType = kMixedSamples_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800784 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
vbuzinovdded6962015-06-12 08:59:45 -0700785 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000786 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000787 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800788 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000789 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
790 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000791 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800792 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000793 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000794 }
795}
796
cdalton1dd05422015-06-12 09:01:18 -0700797void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
798 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
799
800 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
801 // for now until its own blacklists can be updated.
802 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
803 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700804 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700805 return;
806 }
807
808 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
809 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
810 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
811 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
812 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
813 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
814 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
815 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
816 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
817 return;
818 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
819 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
820 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
821 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
822 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
823 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
824 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
825 // slow on a particular platform.
826 } else {
827 return; // No advanced blend support.
828 }
829
830 SkASSERT(this->advancedBlendEquationSupport());
831
832 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
833 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
834 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
835 (1 << kColorBurn_GrBlendEquation);
836 }
joel.liang9764c402015-07-09 19:46:18 -0700837 if (kARM_GrGLVendor == ctxInfo.vendor()) {
838 // Blacklist color-burn on ARM until the fix is released.
839 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
840 }
cdalton1dd05422015-06-12 09:01:18 -0700841}
842
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000843namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700844const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000845}
846
847void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
848
849 // Build up list of legal stencil formats (though perhaps not supported on
850 // the particular gpu/driver) from most preferred to least.
851
852 // these consts are in order of most preferred to least preferred
853 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
854
855 static const StencilFormat
856 // internal Format stencil bits total bits packed?
857 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
858 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
859 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
860 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000861 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000862 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
863
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000864 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000865 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000866 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000867 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
868 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
869
870 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
871 // require FBO support we can expect these are legal formats and don't
872 // check. These also all support the unsized GL_STENCIL_INDEX.
873 fStencilFormats.push_back() = gS8;
874 fStencilFormats.push_back() = gS16;
875 if (supportsPackedDS) {
876 fStencilFormats.push_back() = gD24S8;
877 }
878 fStencilFormats.push_back() = gS4;
879 if (supportsPackedDS) {
880 fStencilFormats.push_back() = gDS;
881 }
882 } else {
883 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
884 // for other formats.
885 // ES doesn't support using the unsized format.
886
887 fStencilFormats.push_back() = gS8;
888 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000889 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
890 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000891 fStencilFormats.push_back() = gD24S8;
892 }
893 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
894 fStencilFormats.push_back() = gS4;
895 }
896 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000897}
898
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000899SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000900
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000901 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000902
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000903 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000904 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000905 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000906 i,
907 fStencilFormats[i].fStencilBits,
908 fStencilFormats[i].fTotalBits);
909 }
910
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000911 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000912 "None",
913 "ARB",
914 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000915 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000916 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000917 "IMG MS To Texture",
918 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700919 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000920 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000921 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
922 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
923 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000924 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
925 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
926 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
927 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700928 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000929 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000930
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000931 static const char* kInvalidateFBTypeStr[] = {
932 "None",
933 "Discard",
934 "Invalidate",
935 };
936 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
937 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
938 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
939 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000940
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000941 static const char* kMapBufferTypeStr[] = {
942 "None",
943 "MapBuffer",
944 "MapBufferRange",
945 "Chromium",
946 };
947 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
948 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
949 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
950 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
951 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
952
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000953 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000954 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000955 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000956 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000957 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
958 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000959 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000960 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
961 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
962 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
963 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000964
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000965 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
966 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
967 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
968 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000969 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700970 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
971 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800972 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
cdalton06604b92016-02-05 10:09:51 -0800973 r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
974 r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
975 r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000976 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000977 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700978 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700979 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
980 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700981 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800982 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -0800983 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800984 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800985
986 r.append("Configs\n-------\n");
987 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
988 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -0800989 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
990 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -0800991 i,
992 fConfigTable[i].fFlags,
993 fConfigTable[i].fFormats.fBaseInternalFormat,
994 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -0800995 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
996 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -0800997 fConfigTable[i].fFormats.fExternalType,
998 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -0800999 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -08001000 }
1001
jvanverthe9c0fc62015-04-29 11:18:05 -07001002 return r;
1003}
1004
jvanverthe9c0fc62015-04-29 11:18:05 -07001005static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1006 switch (p) {
1007 case kLow_GrSLPrecision:
1008 return GR_GL_LOW_FLOAT;
1009 case kMedium_GrSLPrecision:
1010 return GR_GL_MEDIUM_FLOAT;
1011 case kHigh_GrSLPrecision:
1012 return GR_GL_HIGH_FLOAT;
1013 }
1014 SkFAIL("Unknown precision.");
1015 return -1;
1016}
1017
1018static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1019 switch (type) {
1020 case kVertex_GrShaderType:
1021 return GR_GL_VERTEX_SHADER;
1022 case kGeometry_GrShaderType:
1023 return GR_GL_GEOMETRY_SHADER;
1024 case kFragment_GrShaderType:
1025 return GR_GL_FRAGMENT_SHADER;
1026 }
1027 SkFAIL("Unknown shader type.");
1028 return -1;
1029}
1030
jvanverthcba99b82015-06-24 06:59:57 -07001031void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
1032 const GrGLInterface* intf,
1033 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001034 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1035 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1036 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1037 if (kGeometry_GrShaderType != s) {
1038 GrShaderType shaderType = static_cast<GrShaderType>(s);
1039 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001040 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -07001041 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001042 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1043 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1044 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1045 GrGLint range[2];
1046 GrGLint bits;
1047 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1048 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -07001049 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1050 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1051 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001052 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -07001053 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001054 }
jvanverthcba99b82015-06-24 06:59:57 -07001055 else if (!glslCaps->fShaderPrecisionVaries) {
1056 glslCaps->fShaderPrecisionVaries =
1057 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001058 }
1059 }
1060 }
1061 }
1062 }
1063 }
1064 else {
1065 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -07001066 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001067 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1068 if (kGeometry_GrShaderType != s) {
1069 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001070 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1071 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1072 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001073 }
1074 }
1075 }
1076 }
1077 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1078 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1079 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1080 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -07001081 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001082 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001083 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1084 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001085 }
1086 }
1087}
1088
bsalomon41e4384e2016-01-08 09:12:44 -08001089bool GrGLCaps::bgraIsInternalFormat() const {
1090 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1091}
1092
bsalomon76148af2016-01-12 11:13:47 -08001093bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1094 GrGLenum* internalFormat, GrGLenum* externalFormat,
1095 GrGLenum* externalType) const {
1096 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1097 externalFormat, externalType)) {
1098 return false;
1099 }
1100 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1101 return true;
1102}
1103
1104bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1105 GrGLenum* internalFormat) const {
1106 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1107 return false;
1108 }
1109 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1110 return true;
1111}
1112
1113bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1114 GrGLenum* externalFormat, GrGLenum* externalType) const {
1115 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1116 externalFormat, externalType)) {
1117 return false;
1118 }
1119 return true;
1120}
1121
1122bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1123 if (GrPixelConfigIsCompressed(config)) {
1124 return false;
1125 }
1126 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1127 return true;
1128}
1129
1130bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1131 ExternalFormatUsage usage, GrGLenum* externalFormat,
1132 GrGLenum* externalType) const {
1133 SkASSERT(externalFormat && externalType);
1134 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1135 return false;
1136 }
1137
1138 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1139 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1140
1141 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1142 // made to work in many cases using glPixelStore and what not but is not needed currently.
1143 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1144 return false;
1145 }
1146
1147 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1148 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1149
bsalomone9573312016-01-25 14:33:25 -08001150 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1151 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1152 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1153 // texture, not the red component.
1154 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1155 if (this->textureRedSupport()) {
1156 SkASSERT(GR_GL_RED == *externalFormat);
1157 *externalFormat = GR_GL_ALPHA;
1158 }
1159 }
1160
bsalomon76148af2016-01-12 11:13:47 -08001161 return true;
1162}
1163
bsalomoncdee0092016-01-08 13:20:12 -08001164void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1165 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001166 /*
1167 Comments on renderability of configs on various GL versions.
1168 OpenGL < 3.0:
1169 no built in support for render targets.
1170 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1171 format RGB, RGBA and NV float formats we don't use.
1172 This is the following:
1173 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1174 RGB10_A2, RGBA12,RGBA16
1175 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1176 since they aren't required by later standards and the driver can simply return
1177 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1178 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1179 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1180 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1181 This adds a lot of additional renderable sized formats, including ALPHA8.
1182 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1183 16F, 32I, 32UI, and 32F variants).
1184 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1185
1186 For both the above extensions we limit ourselves to those that are also required by
1187 OpenGL 3.0.
1188
1189 OpenGL 3.0:
1190 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1191 but are not required to be supported as renderable textures/renderbuffer.
1192 Required renderable color formats:
1193 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1194 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1195 RGB10_A2.
1196 - R11F_G11F_B10F.
1197 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1198 and RG8UI.
1199 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1200 - ALPHA8
1201
1202 OpenGL 3.1, 3.2, 3.3
1203 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1204 OpengGL 3.3, 4.0, 4.1
1205 Adds RGB10_A2UI.
1206 OpengGL 4.2
1207 Adds
1208 - RGB5_A1, RGBA4
1209 - RGB565
1210 OpenGL 4.4
1211 Does away with the separate list and adds a column to the sized internal color format
1212 table. However, no new formats become required color renderable.
1213
1214 ES 2.0
1215 color renderable: RGBA4, RGB5_A1, RGB565
1216 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1217 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1218 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1219 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1220 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1221 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1222
1223 ES 3.0
1224 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1225 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1226 RGB5_A1.
1227 - RGB8 and RGB565.
1228 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1229 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1230 ES 3.1
1231 Adds RGB10_A2, RGB10_A2UI,
1232 ES 3.2
1233 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1234 */
1235 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1236 if (kNone_MSFBOType != fMSFBOType) {
1237 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1238 }
1239
1240 GrGLStandard standard = ctxInfo.standard();
1241 GrGLVersion version = ctxInfo.version();
1242
bsalomon30447372015-12-21 09:03:05 -08001243 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1244 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001245 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001246 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001247 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001248 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001249
1250 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1251 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001252 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1253 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001254 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001255 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001256 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1257 if (kGL_GrGLStandard == standard) {
1258 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1259 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001260 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001261 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1262 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1263 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1264 }
egdaniel4999df82016-01-07 17:06:04 -08001265 }
bsalomoncdee0092016-01-08 13:20:12 -08001266 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001267
bsalomon76148af2016-01-12 11:13:47 -08001268 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1269 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001270 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001271 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001272 if (kGL_GrGLStandard == standard) {
1273 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1274 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1275 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1276 // Since the internal format is RGBA8, it is also renderable.
1277 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1278 allRenderFlags;
1279 }
1280 } else {
1281 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1282 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1283 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1284 // The APPLE extension doesn't make this renderable.
1285 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1286 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1287 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1288 // Though, that seems to not be the case if the texture storage extension is
1289 // present. The specs don't exactly make that clear.
1290 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1291 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1292 }
1293 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1294 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1295 ConfigInfo::kRenderable_Flag;
1296 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001297 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001298 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1299 ConfigInfo::kRenderableWithMSAA_Flag;
1300 }
1301 }
1302 }
bsalomoncdee0092016-01-08 13:20:12 -08001303 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001304
bsalomon41e4384e2016-01-08 09:12:44 -08001305 // We only enable srgb support if both textures and FBOs support srgb.
1306 bool srgbSupport = false;
1307 if (kGL_GrGLStandard == standard) {
1308 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1309 srgbSupport = true;
1310 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1311 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1312 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1313 srgbSupport = true;
1314 }
1315 }
1316 // All the above srgb extensions support toggling srgb writes
1317 fSRGBWriteControl = srgbSupport;
1318 } else {
1319 // See https://bug.skia.org/4148 for PowerVR issue.
1320 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1321 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1322 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1323 // sRGB writing for destinations.
1324 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1325 }
bsalomon30447372015-12-21 09:03:05 -08001326 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1327 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1328 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1329 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001330 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1331 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001332 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001333 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001334 if (srgbSupport) {
1335 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1336 allRenderFlags;
1337 }
bsalomoncdee0092016-01-08 13:20:12 -08001338 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001339
1340 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1341 if (this->ES2CompatibilitySupport()) {
1342 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1343 } else {
1344 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1345 }
bsalomon76148af2016-01-12 11:13:47 -08001346 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1347 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001348 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001349 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001350 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1351 if (kGL_GrGLStandard == standard) {
1352 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1353 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1354 }
1355 } else {
1356 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1357 }
bsalomoncdee0092016-01-08 13:20:12 -08001358 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001359
1360 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1361 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001362 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1363 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001364 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001365 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001366 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1367 if (kGL_GrGLStandard == standard) {
1368 if (version >= GR_GL_VER(4, 2)) {
1369 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1370 }
1371 } else {
1372 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1373 }
bsalomoncdee0092016-01-08 13:20:12 -08001374 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001375
1376 if (this->textureRedSupport()) {
1377 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1378 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001379 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1380 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001381 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001382 } else {
1383 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1384 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001385 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1386 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001387 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001388 }
1389 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001390 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001391 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1392 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1393 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1394 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1395 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1396 }
1397
1398 // Check for [half] floating point texture support
1399 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1400 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1401 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1402 bool hasFPTextures = false;
1403 bool hasHalfFPTextures = false;
1404 // for now we don't support floating point MSAA on ES
1405 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1406 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1407
1408 if (kGL_GrGLStandard == standard) {
1409 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1410 hasFPTextures = true;
1411 hasHalfFPTextures = true;
1412 }
1413 } else {
1414 if (version >= GR_GL_VER(3, 1)) {
1415 hasFPTextures = true;
1416 hasHalfFPTextures = true;
1417 } else {
1418 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1419 ctxInfo.hasExtension("GL_OES_texture_float")) {
1420 hasFPTextures = true;
1421 }
1422 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1423 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1424 hasHalfFPTextures = true;
1425 }
1426 }
1427 }
bsalomon30447372015-12-21 09:03:05 -08001428
1429 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1430 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001431 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1432 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001433 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001434 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001435 if (hasFPTextures) {
1436 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1437 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1438 // many precision issues and no clients actually want this yet.
1439 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1440 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1441 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1442 }
1443 }
bsalomoncdee0092016-01-08 13:20:12 -08001444 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001445
1446 if (this->textureRedSupport()) {
1447 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1448 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001449 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1450 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001451 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001452 } else {
1453 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1454 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001455 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1456 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001457 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001458 }
1459 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1460 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1461 } else {
1462 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1463 }
bsalomon7928ef62016-01-05 10:26:39 -08001464 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001465 if (hasHalfFPTextures) {
1466 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1467 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1468 // GL_RED internal format.
1469 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1470 (this->textureRedSupport() &&
1471 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1472 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1473 }
1474 }
bsalomon30447372015-12-21 09:03:05 -08001475
1476 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1477 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001478 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1479 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001480 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1481 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1482 } else {
1483 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1484 }
bsalomon7928ef62016-01-05 10:26:39 -08001485 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001486 if (hasHalfFPTextures) {
1487 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1488 // ES requires 3.2 or EXT_color_buffer_half_float.
1489 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1490 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1491 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1492 }
1493 }
bsalomoncdee0092016-01-08 13:20:12 -08001494 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001495
1496 // Compressed texture support
1497
1498 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1499 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1500
1501 // TODO: Fix command buffer bindings and remove this.
1502 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001503
1504 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001505 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001506
1507 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1508 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001509 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001510 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001511 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001512 // Disable this for now, while we investigate https://bug.skia.org/4333
1513 if (false) {
1514 // Check for 8-bit palette..
1515 GrGLint numFormats;
1516 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1517 if (numFormats) {
1518 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1519 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1520 for (int i = 0; i < numFormats; ++i) {
1521 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1522 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1523 break;
1524 }
1525 }
1526 }
1527 }
bsalomoncdee0092016-01-08 13:20:12 -08001528 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001529
bsalomon41e4384e2016-01-08 09:12:44 -08001530 // May change the internal format based on extensions.
1531 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1532 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1533 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1534 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1535 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1536 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1537 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1538 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1539 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1540 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1541 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1542 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1543 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1544 GR_GL_COMPRESSED_RED_RGTC1;
1545 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1546 GR_GL_COMPRESSED_RED_RGTC1;
1547 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1548 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1549 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1550 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1551 GR_GL_COMPRESSED_3DC_X;
1552
bsalomon30447372015-12-21 09:03:05 -08001553 }
bsalomon76148af2016-01-12 11:13:47 -08001554 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001555 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001556 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001557 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001558
1559 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1560 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001561 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001562 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001563 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001564 if (kGL_GrGLStandard == standard) {
1565 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1566 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1567 }
1568 } else {
1569 if (version >= GR_GL_VER(3, 0) ||
1570 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1571 // ETC2 is a superset of ETC1, so we can just check for that, too.
1572 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1573 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1574 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1575 }
1576 }
bsalomoncdee0092016-01-08 13:20:12 -08001577 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001578
1579 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1580 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001581 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001582 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001583 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001584 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1585 // decompressing the textures in the driver, and is generally slower.
1586 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1587 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1588 }
bsalomoncdee0092016-01-08 13:20:12 -08001589 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001590
1591 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1592 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1593 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1594 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001595 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1596 0;
bsalomon30447372015-12-21 09:03:05 -08001597 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001598 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001599 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1600 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1601 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1602 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1603 }
bsalomoncdee0092016-01-08 13:20:12 -08001604 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001605
1606 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1607
1608 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001609 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1610 ctxInfo.version() >= GR_GL_VER(3,0));
1611 // All ES versions (thus far) require sized internal formats for render buffers.
1612 // TODO: Always use sized internal format?
1613 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1614
bsalomon30447372015-12-21 09:03:05 -08001615 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001616 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1617 // param to glTex[Sub]Image.
1618 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1619 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1620 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1621 fConfigTable[i].fFormats.fSizedInternalFormat :
1622 fConfigTable[i].fFormats.fBaseInternalFormat;
1623 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001624 fConfigTable[i].fFormats.fSizedInternalFormat :
1625 fConfigTable[i].fFormats.fBaseInternalFormat;
1626 }
1627 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1628 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1629 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1630 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1631 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001632 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001633 GR_GL_SRGB_ALPHA;
1634 }
1635
1636 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1637 // as a base format.
1638 // GL_EXT_texture_format_BGRA8888:
1639 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1640 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1641 // formats.
1642 // GL_APPLE_texture_format_BGRA8888:
1643 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1644 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1645 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001646 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001647 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1648 }
1649
bsalomoncdee0092016-01-08 13:20:12 -08001650 // If we don't have texture swizzle support then the shader generator must insert the
1651 // swizzle into shader code.
1652 if (!this->textureSwizzleSupport()) {
1653 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1654 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1655 }
1656 }
1657
bsalomon7f9b2e42016-01-12 13:29:26 -08001658 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1659 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1660 // gets written to the single component.
1661 if (this->textureRedSupport()) {
1662 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1663 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1664 if (GrPixelConfigIsAlphaOnly(config) &&
1665 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1666 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1667 }
1668 }
1669 }
1670
bsalomon30447372015-12-21 09:03:05 -08001671#ifdef SK_DEBUG
1672 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001673 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001674 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001675 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1676 fConfigTable[i].fFormats.fBaseInternalFormat);
1677 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001678 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001679 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1680 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1681 fConfigTable[i].fFormats.fExternalFormat[j]);
1682 }
1683 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001684 }
1685#endif
1686}
1687
egdanielb7e7d572015-11-04 04:23:53 -08001688void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}