blob: 132e9b217c9555a9757fad8b498c86dc84ba8e24 [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;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000036 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000037 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000038 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070039 fDirectStateAccessSupport = false;
40 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080041 fES2CompatibilitySupport = false;
cdaltond4727922015-11-10 12:49:06 -080042 fMultisampleDisableSupport = false;
cdalton06604b92016-02-05 10:09:51 -080043 fDrawIndirectSupport = false;
44 fMultiDrawIndirectSupport = false;
45 fBaseInstanceSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000046 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000047 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070048 fBindFragDataLocationSupport = false;
bsalomon7ea33f52015-11-22 14:51:00 -080049 fExternalTextureSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080050 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080051 fTextureSwizzleSupport = false;
bsalomon16921ec2015-07-30 15:34:56 -070052 fSRGBWriteControl = false;
bsalomon88c7b982015-07-31 11:20:16 -070053 fRGBA8888PixelsOpsAreSlow = false;
54 fPartialFBOReadIsSlow = false;
piotaixre4b23142014-10-02 10:57:53 -070055
bsalomon083617b2016-02-12 12:10:14 -080056 fBlitFramebufferSupport = kNone_BlitFramebufferSupport;
57
halcanary385fe4d2015-08-26 13:07:48 -070058 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070059
cdalton4cd67132015-06-10 19:23:46 -070060 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000061}
62
cdalton4cd67132015-06-10 19:23:46 -070063void GrGLCaps::init(const GrContextOptions& contextOptions,
64 const GrGLContextInfo& ctxInfo,
65 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000066 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000067 GrGLVersion version = ctxInfo.version();
68
bsalomon@google.combcce8922013-03-25 15:38:39 +000069 /**************************************************************************
70 * Caps specific to GrGLCaps
71 **************************************************************************/
72
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000073 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000074 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
75 &fMaxFragmentUniformVectors);
76 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000077 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000078 GrGLint max;
79 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
80 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000081 if (version >= GR_GL_VER(3, 2)) {
82 GrGLint profileMask;
83 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
84 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
85 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000086 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000087 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000088 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000089
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000090 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000091 fUnpackRowLengthSupport = true;
92 fUnpackFlipYSupport = false;
93 fPackRowLengthSupport = true;
94 fPackFlipYSupport = false;
95 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000096 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
97 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000098 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000099 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
100 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000101 fPackFlipYSupport =
102 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
103 }
104
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000105 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000106 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
107
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000108 if (kGL_GrGLStandard == standard) {
cdaltonfd4167d2015-04-21 11:45:56 -0700109 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
110 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
111 ctxInfo.hasExtension("GL_NV_texture_barrier");
112 } else {
113 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
114 }
115
cdaltoneb79eea2016-02-26 10:39:34 -0800116 if (kGL_GrGLStandard == standard) {
117 fSampleLocationsSupport = version >= GR_GL_VER(3,2) ||
118 ctxInfo.hasExtension("GL_ARB_texture_multisample");
119 } else {
120 fSampleLocationsSupport = version >= GR_GL_VER(3,1);
121 }
122
hendrikwa0d5ad72014-12-02 07:30:30 -0800123 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
124 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700125 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800126 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000127 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
128 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800129 } else {
130 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
131 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000132 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000133 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000134 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000135 ctxInfo.hasExtension("GL_ARB_imaging");
136
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000137 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
138 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
139 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
140 // limit this decision to specific GPU families rather than basing it on the vendor alone.
141 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700142 (kARM_GrGLVendor == ctxInfo.vendor() ||
143 kImagination_GrGLVendor == ctxInfo.vendor() ||
144 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000145 fUseNonVBOVertexAndIndexDynamicData = true;
146 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000147
egdaniel9250d242015-05-18 13:04:26 -0700148 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
149 // Thus we are blacklisting this extension for now on Adreno4xx devices.
150 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
151 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
152 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
153 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000154 fDiscardRenderTargetSupport = true;
155 fInvalidateFBType = kInvalidate_InvalidateFBType;
156 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
157 fDiscardRenderTargetSupport = true;
158 fInvalidateFBType = kDiscard_InvalidateFBType;
159 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000160
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000161 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
162 fFullClearIsFree = true;
163 }
164
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000165 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000166 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800167 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
168 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000169 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000170 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
171 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000172 }
173
cdalton626e1ff2015-06-12 13:56:46 -0700174 if (kGL_GrGLStandard == standard) {
175 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
176 } else {
177 fDirectStateAccessSupport = false;
178 }
179
180 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
181 fDebugSupport = true;
182 } else {
183 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
184 }
185
jvanverth3f801cb2014-12-16 09:49:38 -0800186 if (kGL_GrGLStandard == standard) {
187 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
188 }
189 else {
190 fES2CompatibilitySupport = true;
191 }
192
cdalton0edea2c2015-05-21 08:27:44 -0700193 if (kGL_GrGLStandard == standard) {
194 fMultisampleDisableSupport = true;
195 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700196 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700197 }
198
kkinnunend94708e2015-07-30 22:47:04 -0700199 if (kGL_GrGLStandard == standard) {
200 if (version >= GR_GL_VER(3, 0)) {
201 fBindFragDataLocationSupport = true;
202 }
203 } else {
204 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
205 fBindFragDataLocationSupport = true;
206 }
joshualittc1f56b52015-06-22 12:31:31 -0700207 }
208
bsalomonb8909d32016-01-28 07:09:52 -0800209#if 0 // Disabled due to https://bug.skia.org/4454
joshualitt7bdd70a2015-10-01 06:28:11 -0700210 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
bsalomonb8909d32016-01-28 07:09:52 -0800211#else
212 fBindUniformLocationSupport = false;
213#endif
joshualitt7bdd70a2015-10-01 06:28:11 -0700214
bsalomon7ea33f52015-11-22 14:51:00 -0800215 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
216 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
217 fExternalTextureSupport = true;
218 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
219 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
220 // At least one driver has been found that has this extension without the "GL_" prefix.
221 fExternalTextureSupport = true;
222 }
223 }
224
kkinnunene06ed252016-02-16 23:15:40 -0800225 if (kGL_GrGLStandard == standard) {
226 if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
227 // We also require textureSize() support for rectangle 2D samplers which was added in
228 // GLSL 1.40.
229 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
230 fRectangleTextureSupport = true;
231 }
bsalomone179a912016-01-20 06:18:10 -0800232 }
kkinnunene06ed252016-02-16 23:15:40 -0800233 } else {
234 // Command buffer exposes this in GL ES context for Chromium reasons,
235 // but it should not be used. Also, at the time of writing command buffer
236 // lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
bsalomone5286e02016-01-14 09:24:09 -0800237 }
238
bsalomoncdee0092016-01-08 13:20:12 -0800239 if (kGL_GrGLStandard == standard) {
240 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
241 fTextureSwizzleSupport = true;
242 }
243 } else {
244 if (version >= GR_GL_VER(3,0)) {
245 fTextureSwizzleSupport = true;
246 }
247 }
248
bsalomon88c7b982015-07-31 11:20:16 -0700249#ifdef SK_BUILD_FOR_WIN
250 // We're assuming that on Windows Chromium we're using ANGLE.
251 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
252 kChromium_GrGLDriver == ctxInfo.driver();
253 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
254 fRGBA8888PixelsOpsAreSlow = isANGLE;
255 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
256 // check DX11 ANGLE.
257 fPartialFBOReadIsSlow = isANGLE;
258#endif
259
cdalton4cd67132015-06-10 19:23:46 -0700260 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700261 * GrShaderCaps fields
262 **************************************************************************/
263
egdaniel0a482332015-10-26 08:59:10 -0700264 // This must be called after fCoreProfile is set on the GrGLCaps
265 this->initGLSL(ctxInfo);
266 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
267
egdaniel05ded892015-10-26 07:38:05 -0700268 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
269
270 // For now these two are equivalent but we could have dst read in shader via some other method.
271 // Before setting this, initGLSL() must have been called.
272 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
273
274 // Enable supported shader-related caps
275 if (kGL_GrGLStandard == standard) {
276 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
277 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
278 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
279 glslCaps->fShaderDerivativeSupport = true;
280 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
281 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
282 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
cdalton793dc262016-02-08 10:11:47 -0800283 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
284 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
egdaniel05ded892015-10-26 07:38:05 -0700285 }
286 else {
287 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
288
289 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
290 ctxInfo.hasExtension("GL_OES_standard_derivatives");
cdalton793dc262016-02-08 10:11:47 -0800291
292 glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
293 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
egdaniel05ded892015-10-26 07:38:05 -0700294 }
295
ethannicholas22793252016-01-30 09:59:10 -0800296 if (ctxInfo.hasExtension("GL_EXT_shader_pixel_local_storage")) {
297 #define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
298 GR_GL_GetIntegerv(gli, GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT,
299 &glslCaps->fPixelLocalStorageSize);
300 glslCaps->fPLSPathRenderingSupport = glslCaps->fFBFetchSupport;
301 }
302 else {
303 glslCaps->fPixelLocalStorageSize = 0;
304 glslCaps->fPLSPathRenderingSupport = false;
305 }
306
egdaniel05ded892015-10-26 07:38:05 -0700307 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700308 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000309 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700310
cdalton63f6c1f2015-11-06 07:09:43 -0800311 // We need dual source blending and the ability to disable multisample in order to support mixed
312 // samples in every corner case.
egdanieleed519e2016-01-15 11:36:18 -0800313 if (fMultisampleDisableSupport &&
314 glslCaps->dualSourceBlendingSupport() &&
315 fShaderCaps->pathRenderingSupport()) {
316 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
kkinnunenea409432015-12-10 01:21:59 -0800317 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800318 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
kkinnunen9f63b442016-01-25 00:31:49 -0800319 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
320 kChromium_GrGLDriver == ctxInfo.driver())) {
cdalton63f6c1f2015-11-06 07:09:43 -0800321 fDiscardRenderTargetSupport = false;
322 fInvalidateFBType = kNone_InvalidateFBType;
323 }
324 }
325
egdanieleed519e2016-01-15 11:36:18 -0800326 // fUsesMixedSamples must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700327 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700328 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700329 this->initStencilFormats(ctxInfo);
330
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000331 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000332 // we could also look for GL_ATI_separate_stencil extension or
333 // GL_EXT_stencil_two_side but they use different function signatures
334 // than GL2.0+ (and than each other).
335 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
336 // supported on GL 1.4 and higher or by extension
337 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
338 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
339 } else {
340 // ES 2 has two sided stencil and stencil wrap
341 fTwoSidedStencilSupport = true;
342 fStencilWrapOpsSupport = true;
343 }
344
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000345 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000346 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
347 // extension includes glMapBuffer.
348 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
349 fMapBufferFlags |= kSubset_MapFlag;
350 fMapBufferType = kMapBufferRange_MapBufferType;
351 } else {
352 fMapBufferType = kMapBuffer_MapBufferType;
353 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000354 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000355 // Unextended GLES2 doesn't have any buffer mapping.
356 fMapBufferFlags = kNone_MapBufferType;
kkinnunen45c2c812016-02-25 02:03:43 -0800357 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000358 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
359 fMapBufferType = kMapBufferRange_MapBufferType;
kkinnunen45c2c812016-02-25 02:03:43 -0800360 } else if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
361 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
362 fMapBufferType = kChromium_MapBufferType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000363 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
364 fMapBufferFlags = kCanMap_MapFlag;
365 fMapBufferType = kMapBuffer_MapBufferType;
366 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000367 }
368
jvanverthd7a2c1f2015-12-07 07:36:44 -0800369 if (kGL_GrGLStandard == standard) {
370 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
371 fTransferBufferType = kPBO_TransferBufferType;
372 }
373 } else {
374 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
375 fTransferBufferType = kPBO_TransferBufferType;
376 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
377 fTransferBufferType = kChromium_TransferBufferType;
378 }
379 }
380
joshualitte5b74c62015-06-01 14:17:47 -0700381 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
382 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
383 if (fGeometryBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700384 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
385 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
386 // a small subset.
387#if 0
cdalton1acea862015-06-02 13:05:52 -0700388 fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700389#else
390 fGeometryBufferMapThreshold = SK_MaxS32;
391#endif
joshualitte5b74c62015-06-01 14:17:47 -0700392 }
393
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000394 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000395 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
396 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
397 fNPOTTextureTileSupport = true;
398 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000399 } else {
400 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000401 // ES3 has no limitations.
402 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
403 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000404 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
405 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
406 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
407 // to alllow arbitrary wrap modes, however.
408 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000409 }
410
bsalomone72bd022015-10-26 07:33:03 -0700411 // Using MIPs on this GPU seems to be a source of trouble.
412 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
413 fMipMapSupport = false;
414 }
415
bsalomon@google.combcce8922013-03-25 15:38:39 +0000416 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
417 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
418 // Our render targets are always created with textures as the color
419 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000420 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000421
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000422 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
423
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000424 // Disable scratch texture reuse on Mali and Adreno devices
425 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
426 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000427
robertphillips1b8e1b52015-06-24 06:54:10 -0700428#if 0
429 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
430 kQualcomm_GrGLVendor != ctxInfo.vendor();
431#endif
432
egdaniel05ded892015-10-26 07:38:05 -0700433 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000434 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800435 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000436 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
cdaltonaf8bc7d2016-02-05 09:35:20 -0800437 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000438 }
cdaltonaf8bc7d2016-02-05 09:35:20 -0800439 // We only have a use for raster multisample if there is coverage modulation from mixed samples.
440 if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) {
441 GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples);
442 // This is to guard against platforms that may not support as many samples for
443 // glRasterSamples as they do for framebuffers.
444 fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples);
445 }
446 fMaxColorSampleCount = fMaxStencilSampleCount;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000447
bsalomon63b21962014-11-05 07:05:34 -0800448 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800449 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800450 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800451 fUseDrawInsteadOfClear = true;
452 }
453
joshualitt83bc2292015-06-18 14:18:02 -0700454 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
455 fUseDrawInsteadOfPartialRenderTargetWrite = true;
456 }
457
bsalomonbabafcc2016-02-16 11:36:47 -0800458 // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
459 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
460 fUseDrawInsteadOfPartialRenderTargetWrite = true;
461 fUseDrawInsteadOfAllRenderTargetWrites = true;
462 }
463
robertphillips63926682015-08-20 09:39:02 -0700464#ifdef SK_BUILD_FOR_WIN
465 // On ANGLE deferring flushes can lead to GPU starvation
466 fPreferVRAMUseOverFlushes = !isANGLE;
467#endif
468
bsalomon7dea7b72015-08-19 08:26:51 -0700469 if (kChromium_GrGLDriver == ctxInfo.driver()) {
470 fMustClearUploadedBufferData = true;
471 }
472
bsalomond08ea5f2015-02-20 06:58:13 -0800473 if (kGL_GrGLStandard == standard) {
474 // ARB allows mixed size FBO attachments, EXT does not.
475 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
476 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
477 fOversizedStencilSupport = true;
478 } else {
479 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
480 }
481 } else {
482 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
483 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
484 }
485
joshualitt58001552015-06-26 12:46:36 -0700486 if (kGL_GrGLStandard == standard) {
487 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
488 // instanced arrays, but we could make this more granular if we wanted
489 fSupportsInstancedDraws =
490 version >= GR_GL_VER(3, 2) ||
491 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
492 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
493 } else {
494 fSupportsInstancedDraws =
495 version >= GR_GL_VER(3, 0) ||
496 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
497 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
498 }
499
cdalton06604b92016-02-05 10:09:51 -0800500 if (kGL_GrGLStandard == standard) {
501 // We don't use ARB_draw_indirect because it does not support a base instance.
502 // We don't use ARB_multi_draw_indirect because it does not support GL_DRAW_INDIRECT_BUFFER.
503 fDrawIndirectSupport =
504 fMultiDrawIndirectSupport = fBaseInstanceSupport = version >= GR_GL_VER(4,3);
505 } else {
506 fDrawIndirectSupport = version >= GR_GL_VER(3,1);
507 fMultiDrawIndirectSupport = ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
508 fBaseInstanceSupport = ctxInfo.hasExtension("GL_EXT_base_instance");
509 }
510
jvanverthcba99b82015-06-24 06:59:57 -0700511 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800512
513 if (contextOptions.fUseShaderSwizzling) {
514 fTextureSwizzleSupport = false;
515 }
516
kkinnunen45c2c812016-02-25 02:03:43 -0800517 // TODO: remove after command buffer supports full ES 3.0.
518 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3, 0) &&
519 kChromium_GrGLDriver == ctxInfo.driver()) {
kkinnunen45c2c812016-02-25 02:03:43 -0800520 fSupportsInstancedDraws = false;
521 fTextureSwizzleSupport = false;
522 SkASSERT(ctxInfo.hasExtension("GL_CHROMIUM_map_sub"));
523 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
524 fMapBufferType = kChromium_MapBufferType;
525 }
526
bsalomoncdee0092016-01-08 13:20:12 -0800527 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
528 // already been detected.
529 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700530
531 this->applyOptionsOverrides(contextOptions);
532 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000533}
534
egdaniel472d44e2015-10-22 08:20:00 -0700535const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
536 bool isCoreProfile) {
537 switch (generation) {
538 case k110_GrGLSLGeneration:
539 if (kGLES_GrGLStandard == standard) {
540 // ES2s shader language is based on version 1.20 but is version
541 // 1.00 of the ES language.
542 return "#version 100\n";
543 } else {
544 SkASSERT(kGL_GrGLStandard == standard);
545 return "#version 110\n";
546 }
547 case k130_GrGLSLGeneration:
548 SkASSERT(kGL_GrGLStandard == standard);
549 return "#version 130\n";
550 case k140_GrGLSLGeneration:
551 SkASSERT(kGL_GrGLStandard == standard);
552 return "#version 140\n";
553 case k150_GrGLSLGeneration:
554 SkASSERT(kGL_GrGLStandard == standard);
555 if (isCoreProfile) {
556 return "#version 150\n";
557 } else {
558 return "#version 150 compatibility\n";
559 }
560 case k330_GrGLSLGeneration:
561 if (kGLES_GrGLStandard == standard) {
562 return "#version 300 es\n";
563 } else {
564 SkASSERT(kGL_GrGLStandard == standard);
565 if (isCoreProfile) {
566 return "#version 330\n";
567 } else {
568 return "#version 330 compatibility\n";
569 }
570 }
cdalton33ad7012016-02-22 07:55:44 -0800571 case k400_GrGLSLGeneration:
572 SkASSERT(kGL_GrGLStandard == standard);
573 if (isCoreProfile) {
574 return "#version 400\n";
575 } else {
576 return "#version 400 compatibility\n";
577 }
egdaniel472d44e2015-10-22 08:20:00 -0700578 case k310es_GrGLSLGeneration:
579 SkASSERT(kGLES_GrGLStandard == standard);
580 return "#version 310 es\n";
cdalton33ad7012016-02-22 07:55:44 -0800581 case k320es_GrGLSLGeneration:
582 SkASSERT(kGLES_GrGLStandard == standard);
583 return "#version 320 es\n";
egdaniel472d44e2015-10-22 08:20:00 -0700584 }
585 return "<no version>";
586}
587
egdaniel05ded892015-10-26 07:38:05 -0700588void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700589 GrGLStandard standard = ctxInfo.standard();
590 GrGLVersion version = ctxInfo.version();
591
592 /**************************************************************************
593 * Caps specific to GrGLSLCaps
594 **************************************************************************/
595
596 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
597 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
egdaniel472d44e2015-10-22 08:20:00 -0700598 if (kGLES_GrGLStandard == standard) {
599 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
600 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
601 glslCaps->fFBFetchSupport = true;
602 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
603 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
604 }
605 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
606 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
607 glslCaps->fFBFetchNeedsCustomOutput = false;
608 glslCaps->fFBFetchSupport = true;
609 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
610 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
611 }
612 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
613 // The arm extension also requires an additional flag which we will set onResetContext
614 glslCaps->fFBFetchNeedsCustomOutput = false;
615 glslCaps->fFBFetchSupport = true;
616 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
617 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
618 }
619 glslCaps->fUsesPrecisionModifiers = true;
620 }
621
622 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
623
cdaltonc08f1962016-02-12 12:14:06 -0800624 if (kGL_GrGLStandard == standard) {
625 glslCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
626 } else {
627 glslCaps->fFlatInterpolationSupport =
628 ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // This is the value for GLSL ES 3.0.
629 }
630
631 if (kGL_GrGLStandard == standard) {
632 glslCaps->fNoPerspectiveInterpolationSupport =
633 ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
634 } else {
635 if (ctxInfo.hasExtension("GL_NV_shader_noperspective_interpolation")) {
636 glslCaps->fNoPerspectiveInterpolationSupport = true;
637 glslCaps->fNoPerspectiveInterpolationExtensionString =
638 "GL_NV_shader_noperspective_interpolation";
639 }
640 }
641
cdalton33ad7012016-02-22 07:55:44 -0800642 if (kGL_GrGLStandard == standard) {
cdalton4a98cdb2016-03-01 12:12:20 -0800643 glslCaps->fMultisampleInterpolationSupport =
644 ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
645 } else {
646 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
647 glslCaps->fMultisampleInterpolationSupport = true;
648 } else if (ctxInfo.hasExtension("GL_OES_shader_multisample_interpolation")) {
649 glslCaps->fMultisampleInterpolationSupport = true;
650 glslCaps->fMultisampleInterpolationExtensionString =
651 "GL_OES_shader_multisample_interpolation";
652 }
653 }
654
655 if (kGL_GrGLStandard == standard) {
cdalton33ad7012016-02-22 07:55:44 -0800656 glslCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration;
657 } else {
658 if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) {
659 glslCaps->fSampleVariablesSupport = true;
660 } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) {
661 glslCaps->fSampleVariablesSupport = true;
662 glslCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables";
663 }
664 }
665
666 if (glslCaps->fSampleVariablesSupport) {
667 glslCaps->fSampleMaskOverrideCoverageSupport =
668 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage");
669 }
670
egdaniel472d44e2015-10-22 08:20:00 -0700671 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
672 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
673
674 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
675 // function that may require a gradient calculation inside a conditional block may return
676 // undefined results". This appears to be an issue with the 'any' call since even the simple
677 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
678 // from our GrTextureDomain processor.
679 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
680
egdaniel472d44e2015-10-22 08:20:00 -0700681 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
682 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800683
684 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
685 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
686 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800687
688 // Frag Coords Convention support is not part of ES
689 // Known issue on at least some Intel platforms:
690 // http://code.google.com/p/skia/issues/detail?id=946
691 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
692 kGLES_GrGLStandard != standard &&
693 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
694 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
695 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
696 }
697
698 if (kGLES_GrGLStandard == standard) {
699 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
700 }
701
bsalomon7ea33f52015-11-22 14:51:00 -0800702 if (fExternalTextureSupport) {
703 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
704 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
705 } else {
706 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
707 }
708 }
709
egdaniel8dcdedc2015-11-11 06:27:20 -0800710 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
711 // the abs first in a separate expression.
712 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
713 glslCaps->fCanUseMinAndAbsTogether = false;
714 }
715
bsalomon7ea33f52015-11-22 14:51:00 -0800716 // 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 -0800717 // thus must us -1.0 * %s.x to work correctly
718 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
719 glslCaps->fMustForceNegatedAtanParamToFloat = true;
720 }
egdaniel472d44e2015-10-22 08:20:00 -0700721}
722
kkinnunencfe62e32015-07-01 02:58:50 -0700723bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700724 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
725
726 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700727 return false;
728 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700729
kkinnunencfe62e32015-07-01 02:58:50 -0700730 if (kGL_GrGLStandard == ctxInfo.standard()) {
731 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
732 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
733 return false;
734 }
735 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700736 if (!hasChromiumPathRendering &&
737 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700738 return false;
739 }
740 }
741 // We only support v1.3+ of GL_NV_path_rendering which allows us to
742 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
743 // additions are detected by checking the existence of the function.
744 // We also use *Then* functions that not all drivers might have. Check
745 // them for consistency.
bsalomon9f2dc272016-02-08 07:22:17 -0800746 if (!gli->fFunctions.fStencilThenCoverFillPath ||
747 !gli->fFunctions.fStencilThenCoverStrokePath ||
748 !gli->fFunctions.fStencilThenCoverFillPathInstanced ||
749 !gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
750 !gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700751 return false;
752 }
753 return true;
754}
bsalomon1aa20292016-01-22 08:16:09 -0800755
756bool GrGLCaps::readPixelsSupported(GrPixelConfig rtConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800757 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800758 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
759 std::function<bool ()> bindRenderTarget) const {
bsalomone9573312016-01-25 14:33:25 -0800760 // If it's not possible to even have a render target of rtConfig then read pixels is
761 // not supported regardless of readConfig.
762 if (!this->isConfigRenderable(rtConfig, false)) {
763 return false;
764 }
bsalomon7928ef62016-01-05 10:26:39 -0800765
bsalomon76148af2016-01-12 11:13:47 -0800766 GrGLenum readFormat;
767 GrGLenum readType;
bsalomon1aa20292016-01-22 08:16:09 -0800768 if (!this->getReadPixelsFormat(rtConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800769 return false;
770 }
771
bsalomon1aa20292016-01-22 08:16:09 -0800772 if (kGL_GrGLStandard == fStandard) {
bsalomone9573312016-01-25 14:33:25 -0800773 // Some OpenGL implementations allow GL_ALPHA as a format to glReadPixels. However,
774 // the manual (https://www.opengl.org/sdk/docs/man/) says only these formats are allowed:
775 // GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, GL_RED, GL_GREEN, GL_BLUE,
776 // GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA. We check for the subset that we would use.
777 if (readFormat != GR_GL_RED && readFormat != GR_GL_RGB && readFormat != GR_GL_RGBA &&
778 readFormat != GR_GL_BGRA) {
779 return false;
780 }
781 // There is also a set of allowed types, but all the types we use are in the set:
782 // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
783 // GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
784 // GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4,
785 // GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
786 // GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,GL_UNSIGNED_INT_10_10_10_2,
787 // GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
788 // GL_UNSIGNED_INT_5_9_9_9_REV, or GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
bsalomon7928ef62016-01-05 10:26:39 -0800789 return true;
piotaixre4b23142014-10-02 10:57:53 -0700790 }
bsalomon7928ef62016-01-05 10:26:39 -0800791
bsalomon76148af2016-01-12 11:13:47 -0800792 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800793
bsalomon1aa20292016-01-22 08:16:09 -0800794 if (kNormalizedFixedPoint_FormatType == fConfigTable[rtConfig].fFormatType) {
bsalomon7928ef62016-01-05 10:26:39 -0800795 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
796 return true;
797 }
798 } else {
bsalomon1aa20292016-01-22 08:16:09 -0800799 SkASSERT(kFloat_FormatType == fConfigTable[rtConfig].fFormatType);
bsalomon7928ef62016-01-05 10:26:39 -0800800 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
801 return true;
802 }
803 }
804
bsalomon1aa20292016-01-22 08:16:09 -0800805 if (0 == fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800806 ReadPixelsFormat* rpFormat =
bsalomon1aa20292016-01-22 08:16:09 -0800807 const_cast<ReadPixelsFormat*>(&fConfigTable[rtConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800808 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800809 if (!bindRenderTarget()) {
810 return false;
811 }
812 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
813 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800814 rpFormat->fFormat = format;
815 rpFormat->fType = type;
816 }
817
bsalomon1aa20292016-01-22 08:16:09 -0800818 return fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
819 fConfigTable[rtConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700820}
821
robertphillips@google.com6177e692013-02-28 20:16:25 +0000822void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000823
824 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000825 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000826 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
827 // ES3 driver bugs on at least one device with a tiled GPU (N10).
828 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
829 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
830 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
831 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800832 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700833 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000834 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000835 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
836 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
837 // chrome's extension is equivalent to the EXT msaa
838 // and fbo_blit extensions.
839 fMSFBOType = kDesktop_EXT_MSFBOType;
840 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
841 fMSFBOType = kES_Apple_MSFBOType;
842 }
bsalomon083617b2016-02-12 12:10:14 -0800843
844 // Above determined the preferred MSAA approach, now decide whether glBlitFramebuffer
845 // is available.
846 if (ctxInfo.version() >= GR_GL_VER(3, 0)) {
847 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
848 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
849 // The CHROMIUM extension uses the ANGLE version of glBlitFramebuffer and includes its
850 // limitations.
851 fBlitFramebufferSupport = kNoScalingNoMirroring_BlitFramebufferSupport;
852 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000853 } else {
egdanieleed519e2016-01-15 11:36:18 -0800854 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700855 fMSFBOType = kMixedSamples_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800856 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
vbuzinovdded6962015-06-12 08:59:45 -0700857 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000858 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000859 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800860 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000861 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
862 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000863 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon083617b2016-02-12 12:10:14 -0800864 fBlitFramebufferSupport = kFull_BlitFramebufferSupport;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000865 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000866 }
867}
868
cdalton1dd05422015-06-12 09:01:18 -0700869void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
870 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
871
872 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
873 // for now until its own blacklists can be updated.
874 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
875 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700876 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700877 return;
878 }
879
880 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
881 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
882 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
883 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
884 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
885 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
886 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
887 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
888 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
889 return;
890 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
891 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
892 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
893 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
894 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
895 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
896 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
897 // slow on a particular platform.
898 } else {
899 return; // No advanced blend support.
900 }
901
902 SkASSERT(this->advancedBlendEquationSupport());
903
904 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
905 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
906 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
907 (1 << kColorBurn_GrBlendEquation);
908 }
joel.liang9764c402015-07-09 19:46:18 -0700909 if (kARM_GrGLVendor == ctxInfo.vendor()) {
910 // Blacklist color-burn on ARM until the fix is released.
911 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
912 }
cdalton1dd05422015-06-12 09:01:18 -0700913}
914
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000915namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700916const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000917}
918
919void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
920
921 // Build up list of legal stencil formats (though perhaps not supported on
922 // the particular gpu/driver) from most preferred to least.
923
924 // these consts are in order of most preferred to least preferred
925 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
926
927 static const StencilFormat
928 // internal Format stencil bits total bits packed?
929 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
930 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
931 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
932 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000933 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000934 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
935
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000936 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000937 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000938 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000939 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
940 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
941
942 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
943 // require FBO support we can expect these are legal formats and don't
944 // check. These also all support the unsized GL_STENCIL_INDEX.
945 fStencilFormats.push_back() = gS8;
946 fStencilFormats.push_back() = gS16;
947 if (supportsPackedDS) {
948 fStencilFormats.push_back() = gD24S8;
949 }
950 fStencilFormats.push_back() = gS4;
951 if (supportsPackedDS) {
952 fStencilFormats.push_back() = gDS;
953 }
954 } else {
955 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
956 // for other formats.
957 // ES doesn't support using the unsized format.
958
959 fStencilFormats.push_back() = gS8;
960 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000961 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
962 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000963 fStencilFormats.push_back() = gD24S8;
964 }
965 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
966 fStencilFormats.push_back() = gS4;
967 }
968 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000969}
970
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000971SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000972
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000973 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000974
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000975 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000976 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000977 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000978 i,
979 fStencilFormats[i].fStencilBits,
980 fStencilFormats[i].fTotalBits);
981 }
982
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000983 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000984 "None",
985 "ARB",
986 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000987 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000988 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000989 "IMG MS To Texture",
990 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700991 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000992 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000993 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
994 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
995 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000996 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
997 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
998 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
999 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -07001000 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +00001001 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001002
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001003 static const char* kInvalidateFBTypeStr[] = {
1004 "None",
1005 "Discard",
1006 "Invalidate",
1007 };
1008 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
1009 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
1010 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
1011 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +00001012
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001013 static const char* kMapBufferTypeStr[] = {
1014 "None",
1015 "MapBuffer",
1016 "MapBufferRange",
1017 "Chromium",
1018 };
1019 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
1020 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
1021 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
1022 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
1023 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
1024
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001025 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001026 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +00001027 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001028 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001029 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
1030 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001031 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001032 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
1033 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
1034 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
1035 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +00001036
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001037 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001038 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
1039 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001040 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -07001041 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
1042 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -08001043 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
cdalton06604b92016-02-05 10:09:51 -08001044 r.appendf("Draw indirect support: %s\n", (fDrawIndirectSupport ? "YES" : "NO"));
1045 r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO"));
1046 r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001047 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +00001048 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -07001049 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -07001050 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
1051 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -07001052 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -08001053 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -08001054 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -08001055 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -08001056
1057 r.append("Configs\n-------\n");
1058 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1059 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -08001060 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
1061 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -08001062 i,
1063 fConfigTable[i].fFlags,
1064 fConfigTable[i].fFormats.fBaseInternalFormat,
1065 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -08001066 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
1067 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -08001068 fConfigTable[i].fFormats.fExternalType,
1069 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -08001070 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -08001071 }
1072
jvanverthe9c0fc62015-04-29 11:18:05 -07001073 return r;
1074}
1075
jvanverthe9c0fc62015-04-29 11:18:05 -07001076static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
1077 switch (p) {
1078 case kLow_GrSLPrecision:
1079 return GR_GL_LOW_FLOAT;
1080 case kMedium_GrSLPrecision:
1081 return GR_GL_MEDIUM_FLOAT;
1082 case kHigh_GrSLPrecision:
1083 return GR_GL_HIGH_FLOAT;
1084 }
1085 SkFAIL("Unknown precision.");
1086 return -1;
1087}
1088
1089static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
1090 switch (type) {
1091 case kVertex_GrShaderType:
1092 return GR_GL_VERTEX_SHADER;
1093 case kGeometry_GrShaderType:
1094 return GR_GL_GEOMETRY_SHADER;
1095 case kFragment_GrShaderType:
1096 return GR_GL_FRAGMENT_SHADER;
1097 }
1098 SkFAIL("Unknown shader type.");
1099 return -1;
1100}
1101
jvanverthcba99b82015-06-24 06:59:57 -07001102void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
1103 const GrGLInterface* intf,
1104 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001105 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
1106 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
1107 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1108 if (kGeometry_GrShaderType != s) {
1109 GrShaderType shaderType = static_cast<GrShaderType>(s);
1110 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -07001111 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -07001112 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001113 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1114 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1115 GrGLenum glPrecision = precision_to_gl_float_type(precision);
1116 GrGLint range[2];
1117 GrGLint bits;
1118 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
1119 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -07001120 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
1121 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
1122 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -07001123 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -07001124 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001125 }
jvanverthcba99b82015-06-24 06:59:57 -07001126 else if (!glslCaps->fShaderPrecisionVaries) {
1127 glslCaps->fShaderPrecisionVaries =
1128 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -07001129 }
1130 }
1131 }
1132 }
1133 }
1134 }
1135 else {
1136 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -07001137 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -07001138 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1139 if (kGeometry_GrShaderType != s) {
1140 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001141 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
1142 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
1143 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001144 }
1145 }
1146 }
1147 }
1148 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1149 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1150 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1151 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -07001152 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001153 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001154 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1155 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001156 }
1157 }
1158}
1159
bsalomon41e4384e2016-01-08 09:12:44 -08001160bool GrGLCaps::bgraIsInternalFormat() const {
1161 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1162}
1163
bsalomon76148af2016-01-12 11:13:47 -08001164bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1165 GrGLenum* internalFormat, GrGLenum* externalFormat,
1166 GrGLenum* externalType) const {
1167 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1168 externalFormat, externalType)) {
1169 return false;
1170 }
1171 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1172 return true;
1173}
1174
1175bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1176 GrGLenum* internalFormat) const {
1177 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1178 return false;
1179 }
1180 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1181 return true;
1182}
1183
1184bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1185 GrGLenum* externalFormat, GrGLenum* externalType) const {
1186 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1187 externalFormat, externalType)) {
1188 return false;
1189 }
1190 return true;
1191}
1192
1193bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1194 if (GrPixelConfigIsCompressed(config)) {
1195 return false;
1196 }
1197 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1198 return true;
1199}
1200
1201bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1202 ExternalFormatUsage usage, GrGLenum* externalFormat,
1203 GrGLenum* externalType) const {
1204 SkASSERT(externalFormat && externalType);
1205 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1206 return false;
1207 }
1208
1209 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1210 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1211
1212 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1213 // made to work in many cases using glPixelStore and what not but is not needed currently.
1214 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1215 return false;
1216 }
1217
1218 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1219 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1220
bsalomone9573312016-01-25 14:33:25 -08001221 // When GL_RED is supported as a texture format, our alpha-only textures are stored using
1222 // GL_RED and we swizzle in order to map all components to 'r'. However, in this case the
1223 // surface is not alpha-only and we want alpha to really mean the alpha component of the
1224 // texture, not the red component.
1225 if (memoryIsAlphaOnly && !surfaceIsAlphaOnly) {
1226 if (this->textureRedSupport()) {
1227 SkASSERT(GR_GL_RED == *externalFormat);
1228 *externalFormat = GR_GL_ALPHA;
1229 }
1230 }
1231
bsalomon76148af2016-01-12 11:13:47 -08001232 return true;
1233}
1234
bsalomoncdee0092016-01-08 13:20:12 -08001235void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1236 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001237 /*
1238 Comments on renderability of configs on various GL versions.
1239 OpenGL < 3.0:
1240 no built in support for render targets.
1241 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1242 format RGB, RGBA and NV float formats we don't use.
1243 This is the following:
1244 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1245 RGB10_A2, RGBA12,RGBA16
1246 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1247 since they aren't required by later standards and the driver can simply return
1248 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1249 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1250 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1251 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1252 This adds a lot of additional renderable sized formats, including ALPHA8.
1253 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1254 16F, 32I, 32UI, and 32F variants).
1255 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1256
1257 For both the above extensions we limit ourselves to those that are also required by
1258 OpenGL 3.0.
1259
1260 OpenGL 3.0:
1261 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1262 but are not required to be supported as renderable textures/renderbuffer.
1263 Required renderable color formats:
1264 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1265 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1266 RGB10_A2.
1267 - R11F_G11F_B10F.
1268 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1269 and RG8UI.
1270 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1271 - ALPHA8
1272
1273 OpenGL 3.1, 3.2, 3.3
1274 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1275 OpengGL 3.3, 4.0, 4.1
1276 Adds RGB10_A2UI.
1277 OpengGL 4.2
1278 Adds
1279 - RGB5_A1, RGBA4
1280 - RGB565
1281 OpenGL 4.4
1282 Does away with the separate list and adds a column to the sized internal color format
1283 table. However, no new formats become required color renderable.
1284
1285 ES 2.0
1286 color renderable: RGBA4, RGB5_A1, RGB565
1287 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1288 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1289 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1290 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1291 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1292 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1293
1294 ES 3.0
1295 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1296 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1297 RGB5_A1.
1298 - RGB8 and RGB565.
1299 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1300 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1301 ES 3.1
1302 Adds RGB10_A2, RGB10_A2UI,
1303 ES 3.2
1304 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1305 */
1306 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1307 if (kNone_MSFBOType != fMSFBOType) {
1308 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1309 }
1310
1311 GrGLStandard standard = ctxInfo.standard();
1312 GrGLVersion version = ctxInfo.version();
1313
cblume790d5132016-02-29 11:13:29 -08001314 bool texStorageSupported = false;
1315 if (kGL_GrGLStandard == standard) {
1316 // The EXT version can apply to either GL or GLES.
1317 texStorageSupported = version >= GR_GL_VER(4,2) ||
1318 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
1319 ctxInfo.hasExtension("GL_EXT_texture_storage");
1320 } else {
1321 // Qualcomm Adreno drivers appear to have issues with texture storage.
1322 texStorageSupported = (version >= GR_GL_VER(3,0) &&
1323 kQualcomm_GrGLVendor != ctxInfo.vendor()) &&
1324 ctxInfo.hasExtension("GL_EXT_texture_storage");
1325 }
1326
1327 // TODO: remove after command buffer supports full ES 3.0
1328 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0) &&
1329 kChromium_GrGLDriver == ctxInfo.driver()) {
1330 texStorageSupported = false;
1331 }
1332
bsalomon30447372015-12-21 09:03:05 -08001333 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1334 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001335 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001336 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001337 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001338 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001339
1340 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1341 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001342 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1343 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001344 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001345 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001346 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1347 if (kGL_GrGLStandard == standard) {
1348 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1349 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001350 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001351 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1352 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1353 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1354 }
egdaniel4999df82016-01-07 17:06:04 -08001355 }
cblume790d5132016-02-29 11:13:29 -08001356 if (texStorageSupported) {
1357 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1358 }
bsalomoncdee0092016-01-08 13:20:12 -08001359 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001360
bsalomon76148af2016-01-12 11:13:47 -08001361 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1362 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001363 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001364 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001365 if (kGL_GrGLStandard == standard) {
1366 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1367 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1368 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1369 // Since the internal format is RGBA8, it is also renderable.
1370 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1371 allRenderFlags;
1372 }
1373 } else {
1374 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1375 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1376 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1377 // The APPLE extension doesn't make this renderable.
1378 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1379 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1380 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1381 // Though, that seems to not be the case if the texture storage extension is
1382 // present. The specs don't exactly make that clear.
1383 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1384 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1385 }
1386 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1387 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1388 ConfigInfo::kRenderable_Flag;
1389 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001390 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001391 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1392 ConfigInfo::kRenderableWithMSAA_Flag;
1393 }
1394 }
1395 }
cblume790d5132016-02-29 11:13:29 -08001396 if (texStorageSupported) {
1397 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1398 }
bsalomoncdee0092016-01-08 13:20:12 -08001399 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001400
bsalomon41e4384e2016-01-08 09:12:44 -08001401 // We only enable srgb support if both textures and FBOs support srgb.
1402 bool srgbSupport = false;
1403 if (kGL_GrGLStandard == standard) {
1404 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1405 srgbSupport = true;
1406 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1407 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1408 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1409 srgbSupport = true;
1410 }
1411 }
1412 // All the above srgb extensions support toggling srgb writes
1413 fSRGBWriteControl = srgbSupport;
1414 } else {
1415 // See https://bug.skia.org/4148 for PowerVR issue.
1416 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1417 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1418 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1419 // sRGB writing for destinations.
1420 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1421 }
bsalomon30447372015-12-21 09:03:05 -08001422 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1423 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1424 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1425 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001426 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1427 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001428 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001429 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001430 if (srgbSupport) {
1431 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1432 allRenderFlags;
1433 }
cblume790d5132016-02-29 11:13:29 -08001434 if (texStorageSupported) {
1435 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1436 }
bsalomoncdee0092016-01-08 13:20:12 -08001437 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001438
1439 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1440 if (this->ES2CompatibilitySupport()) {
1441 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1442 } else {
1443 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1444 }
bsalomon76148af2016-01-12 11:13:47 -08001445 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1446 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001447 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001448 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001449 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1450 if (kGL_GrGLStandard == standard) {
1451 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1452 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1453 }
1454 } else {
1455 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1456 }
cblume790d5132016-02-29 11:13:29 -08001457 // 565 is not a sized internal format on desktop GL. So on desktop with
1458 // 565 we always use an unsized internal format to let the system pick
1459 // the best sized format to convert the 565 data to. Since TexStorage
1460 // only allows sized internal formats we disallow it.
1461 //
1462 // TODO: As of 4.2, regular GL supports 565. This logic is due for an
1463 // update.
1464 if (texStorageSupported && kGL_GrGLStandard != standard) {
1465 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1466 }
bsalomoncdee0092016-01-08 13:20:12 -08001467 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001468
1469 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1470 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001471 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1472 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001473 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001474 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001475 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1476 if (kGL_GrGLStandard == standard) {
1477 if (version >= GR_GL_VER(4, 2)) {
1478 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1479 }
1480 } else {
1481 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1482 }
cblume790d5132016-02-29 11:13:29 -08001483 if (texStorageSupported) {
1484 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1485 }
bsalomoncdee0092016-01-08 13:20:12 -08001486 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001487
1488 if (this->textureRedSupport()) {
1489 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1490 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001491 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1492 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001493 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001494 } else {
1495 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1496 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001497 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1498 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001499 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001500 }
1501 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001502 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001503 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1504 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1505 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1506 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1507 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1508 }
cblume790d5132016-02-29 11:13:29 -08001509 if (texStorageSupported) {
1510 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1511 }
bsalomon41e4384e2016-01-08 09:12:44 -08001512
1513 // Check for [half] floating point texture support
1514 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1515 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1516 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1517 bool hasFPTextures = false;
1518 bool hasHalfFPTextures = false;
1519 // for now we don't support floating point MSAA on ES
1520 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1521 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1522
1523 if (kGL_GrGLStandard == standard) {
1524 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1525 hasFPTextures = true;
1526 hasHalfFPTextures = true;
1527 }
1528 } else {
1529 if (version >= GR_GL_VER(3, 1)) {
1530 hasFPTextures = true;
1531 hasHalfFPTextures = true;
1532 } else {
1533 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1534 ctxInfo.hasExtension("GL_OES_texture_float")) {
1535 hasFPTextures = true;
1536 }
1537 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1538 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1539 hasHalfFPTextures = true;
1540 }
1541 }
1542 }
bsalomon30447372015-12-21 09:03:05 -08001543
1544 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1545 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001546 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1547 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001548 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001549 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001550 if (hasFPTextures) {
1551 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1552 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1553 // many precision issues and no clients actually want this yet.
1554 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1555 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1556 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1557 }
1558 }
cblume790d5132016-02-29 11:13:29 -08001559 if (texStorageSupported) {
1560 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1561 }
bsalomoncdee0092016-01-08 13:20:12 -08001562 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001563
1564 if (this->textureRedSupport()) {
1565 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1566 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001567 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1568 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001569 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001570 } else {
1571 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1572 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001573 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1574 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001575 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001576 }
1577 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1578 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1579 } else {
1580 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1581 }
bsalomon7928ef62016-01-05 10:26:39 -08001582 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001583 if (hasHalfFPTextures) {
1584 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1585 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1586 // GL_RED internal format.
1587 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1588 (this->textureRedSupport() &&
1589 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1590 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1591 }
1592 }
cblume790d5132016-02-29 11:13:29 -08001593 if (texStorageSupported) {
1594 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1595 }
bsalomon30447372015-12-21 09:03:05 -08001596
1597 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1598 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001599 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1600 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001601 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1602 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1603 } else {
1604 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1605 }
bsalomon7928ef62016-01-05 10:26:39 -08001606 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001607 if (hasHalfFPTextures) {
1608 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1609 // ES requires 3.2 or EXT_color_buffer_half_float.
1610 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1611 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1612 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1613 }
1614 }
cblume790d5132016-02-29 11:13:29 -08001615 if (texStorageSupported) {
1616 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
1617 }
bsalomoncdee0092016-01-08 13:20:12 -08001618 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001619
1620 // Compressed texture support
1621
1622 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1623 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1624
1625 // TODO: Fix command buffer bindings and remove this.
1626 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001627
1628 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001629 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001630
1631 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1632 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001633 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001634 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001635 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001636 // Disable this for now, while we investigate https://bug.skia.org/4333
1637 if (false) {
1638 // Check for 8-bit palette..
1639 GrGLint numFormats;
1640 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1641 if (numFormats) {
1642 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1643 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1644 for (int i = 0; i < numFormats; ++i) {
1645 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1646 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1647 break;
1648 }
1649 }
1650 }
1651 }
bsalomoncdee0092016-01-08 13:20:12 -08001652 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001653
bsalomon41e4384e2016-01-08 09:12:44 -08001654 // May change the internal format based on extensions.
1655 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1656 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1657 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1658 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1659 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1660 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1661 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1662 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1663 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1664 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1665 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1666 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1667 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1668 GR_GL_COMPRESSED_RED_RGTC1;
1669 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1670 GR_GL_COMPRESSED_RED_RGTC1;
1671 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1672 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1673 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1674 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1675 GR_GL_COMPRESSED_3DC_X;
1676
bsalomon30447372015-12-21 09:03:05 -08001677 }
bsalomon76148af2016-01-12 11:13:47 -08001678 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001679 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001680 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001681 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001682
1683 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1684 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001685 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001686 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001687 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001688 if (kGL_GrGLStandard == standard) {
1689 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1690 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1691 }
1692 } else {
1693 if (version >= GR_GL_VER(3, 0) ||
1694 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1695 // ETC2 is a superset of ETC1, so we can just check for that, too.
1696 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1697 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1698 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1699 }
1700 }
bsalomoncdee0092016-01-08 13:20:12 -08001701 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001702
1703 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1704 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001705 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001706 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001707 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001708 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1709 // decompressing the textures in the driver, and is generally slower.
1710 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1711 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1712 }
bsalomoncdee0092016-01-08 13:20:12 -08001713 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001714
1715 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1716 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1717 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1718 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001719 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1720 0;
bsalomon30447372015-12-21 09:03:05 -08001721 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001722 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001723 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1724 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1725 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1726 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1727 }
bsalomoncdee0092016-01-08 13:20:12 -08001728 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001729
1730 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1731
1732 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001733 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1734 ctxInfo.version() >= GR_GL_VER(3,0));
1735 // All ES versions (thus far) require sized internal formats for render buffers.
1736 // TODO: Always use sized internal format?
1737 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1738
bsalomon30447372015-12-21 09:03:05 -08001739 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001740 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1741 // param to glTex[Sub]Image.
1742 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1743 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1744 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1745 fConfigTable[i].fFormats.fSizedInternalFormat :
1746 fConfigTable[i].fFormats.fBaseInternalFormat;
1747 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001748 fConfigTable[i].fFormats.fSizedInternalFormat :
1749 fConfigTable[i].fFormats.fBaseInternalFormat;
1750 }
1751 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1752 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1753 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1754 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1755 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001756 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001757 GR_GL_SRGB_ALPHA;
1758 }
1759
1760 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1761 // as a base format.
1762 // GL_EXT_texture_format_BGRA8888:
1763 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1764 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1765 // formats.
1766 // GL_APPLE_texture_format_BGRA8888:
1767 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1768 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1769 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001770 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001771 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1772 }
1773
bsalomoncdee0092016-01-08 13:20:12 -08001774 // If we don't have texture swizzle support then the shader generator must insert the
1775 // swizzle into shader code.
1776 if (!this->textureSwizzleSupport()) {
1777 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1778 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1779 }
1780 }
1781
bsalomon7f9b2e42016-01-12 13:29:26 -08001782 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1783 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1784 // gets written to the single component.
1785 if (this->textureRedSupport()) {
1786 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1787 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1788 if (GrPixelConfigIsAlphaOnly(config) &&
1789 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1790 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1791 }
1792 }
1793 }
1794
bsalomon30447372015-12-21 09:03:05 -08001795#ifdef SK_DEBUG
1796 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001797 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001798 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001799 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1800 fConfigTable[i].fFormats.fBaseInternalFormat);
1801 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001802 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001803 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1804 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1805 fConfigTable[i].fFormats.fExternalFormat[j]);
1806 }
1807 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001808 }
1809#endif
1810}
1811
egdanielb7e7d572015-11-04 04:23:53 -08001812void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}