blob: 350c3e570a8a457cb013b8c09955f3eaa2f5d1fa [file] [log] [blame]
bsalomon@google.comf7fa8062012-02-14 14:09:57 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9#include "GrGLCaps.h"
joshualittb4384b92014-10-21 12:53:15 -070010
egdanielb7e7d572015-11-04 04:23:53 -080011#include "GrContextOptions.h"
robertphillips@google.com6177e692013-02-28 20:16:25 +000012#include "GrGLContext.h"
bsalomon1aa20292016-01-22 08:16:09 -080013#include "GrGLRenderTarget.h"
jvanverthcba99b82015-06-24 06:59:57 -070014#include "glsl/GrGLSLCaps.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000015#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000016#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000017
bsalomon682c2692015-05-22 14:01:46 -070018GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
19 const GrGLContextInfo& ctxInfo,
20 const GrGLInterface* glInterface) : INHERITED(contextOptions) {
bsalomon1aa20292016-01-22 08:16:09 -080021 fStandard = ctxInfo.standard();
22
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000023 fStencilFormats.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000024 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000025 fInvalidateFBType = kNone_InvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000026 fMapBufferType = kNone_MapBufferType;
jvanverthd7a2c1f2015-12-07 07:36:44 -080027 fTransferBufferType = kNone_TransferBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000028 fMaxFragmentUniformVectors = 0;
bsalomon@google.com60da4172012-06-01 19:25:00 +000029 fMaxVertexAttributes = 0;
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000030 fMaxFragmentTextureUnits = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000031 fUnpackRowLengthSupport = false;
32 fUnpackFlipYSupport = false;
33 fPackRowLengthSupport = false;
34 fPackFlipYSupport = false;
35 fTextureUsageSupport = false;
36 fTexStorageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000037 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000038 fImagingSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000039 fVertexArrayObjectSupport = false;
cdalton626e1ff2015-06-12 13:56:46 -070040 fDirectStateAccessSupport = false;
41 fDebugSupport = false;
jvanverth3f801cb2014-12-16 09:49:38 -080042 fES2CompatibilitySupport = false;
cdaltond4727922015-11-10 12:49:06 -080043 fMultisampleDisableSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000044 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000045 fIsCoreProfile = false;
joshualittc1f56b52015-06-22 12:31:31 -070046 fBindFragDataLocationSupport = false;
bsalomon7ea33f52015-11-22 14:51:00 -080047 fExternalTextureSupport = false;
bsalomone5286e02016-01-14 09:24:09 -080048 fRectangleTextureSupport = false;
bsalomoncdee0092016-01-08 13:20:12 -080049 fTextureSwizzleSupport = false;
bsalomon16921ec2015-07-30 15:34:56 -070050 fSRGBWriteControl = false;
bsalomon88c7b982015-07-31 11:20:16 -070051 fRGBA8888PixelsOpsAreSlow = false;
52 fPartialFBOReadIsSlow = false;
piotaixre4b23142014-10-02 10:57:53 -070053
halcanary385fe4d2015-08-26 13:07:48 -070054 fShaderCaps.reset(new GrGLSLCaps(contextOptions));
bsalomon4ee6bd82015-05-27 13:23:23 -070055
cdalton4cd67132015-06-10 19:23:46 -070056 this->init(contextOptions, ctxInfo, glInterface);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000057}
58
cdalton4cd67132015-06-10 19:23:46 -070059void GrGLCaps::init(const GrContextOptions& contextOptions,
60 const GrGLContextInfo& ctxInfo,
61 const GrGLInterface* gli) {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000062 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000063 GrGLVersion version = ctxInfo.version();
64
bsalomon@google.combcce8922013-03-25 15:38:39 +000065 /**************************************************************************
66 * Caps specific to GrGLCaps
67 **************************************************************************/
68
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000069 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000070 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
71 &fMaxFragmentUniformVectors);
72 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000073 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000074 GrGLint max;
75 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
76 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000077 if (version >= GR_GL_VER(3, 2)) {
78 GrGLint profileMask;
79 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
80 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
81 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000082 }
bsalomon@google.com60da4172012-06-01 19:25:00 +000083 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000084 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000085
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +000086 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000087 fUnpackRowLengthSupport = true;
88 fUnpackFlipYSupport = false;
89 fPackRowLengthSupport = true;
90 fPackFlipYSupport = false;
91 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000092 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
93 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000094 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +000095 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
96 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000097 fPackFlipYSupport =
98 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
99 }
100
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000101 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000102 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
103
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000104 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000105 // The EXT version can apply to either GL or GLES.
106 fTexStorageSupport = version >= GR_GL_VER(4,2) ||
107 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
108 ctxInfo.hasExtension("GL_EXT_texture_storage");
109 } else {
110 // Qualcomm Adreno drivers appear to have issues with texture storage.
111 fTexStorageSupport = (version >= GR_GL_VER(3,0) &&
112 kQualcomm_GrGLVendor != ctxInfo.vendor()) ||
113 ctxInfo.hasExtension("GL_EXT_texture_storage");
114 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000115
cdaltonfd4167d2015-04-21 11:45:56 -0700116 if (kGL_GrGLStandard == standard) {
117 fTextureBarrierSupport = version >= GR_GL_VER(4,5) ||
118 ctxInfo.hasExtension("GL_ARB_texture_barrier") ||
119 ctxInfo.hasExtension("GL_NV_texture_barrier");
120 } else {
121 fTextureBarrierSupport = ctxInfo.hasExtension("GL_NV_texture_barrier");
122 }
123
hendrikwa0d5ad72014-12-02 07:30:30 -0800124 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED
125 // and GL_RG on FBO textures.
cdalton1acea862015-06-02 13:05:52 -0700126 if (kMesa_GrGLDriver != ctxInfo.driver()) {
hendrikwa0d5ad72014-12-02 07:30:30 -0800127 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000128 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
129 ctxInfo.hasExtension("GL_ARB_texture_rg");
hendrikwa0d5ad72014-12-02 07:30:30 -0800130 } else {
131 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
132 ctxInfo.hasExtension("GL_EXT_texture_rg");
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000133 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000134 }
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000135 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000136 ctxInfo.hasExtension("GL_ARB_imaging");
137
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000138 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
139 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
140 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
141 // limit this decision to specific GPU families rather than basing it on the vendor alone.
142 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700143 (kARM_GrGLVendor == ctxInfo.vendor() ||
144 kImagination_GrGLVendor == ctxInfo.vendor() ||
145 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000146 fUseNonVBOVertexAndIndexDynamicData = true;
147 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000148
egdaniel9250d242015-05-18 13:04:26 -0700149 // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand.
150 // Thus we are blacklisting this extension for now on Adreno4xx devices.
151 if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
152 ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
153 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
154 ctxInfo.hasExtension("GL_ARB_invalidate_subdata"))) {
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000155 fDiscardRenderTargetSupport = true;
156 fInvalidateFBType = kInvalidate_InvalidateFBType;
157 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
158 fDiscardRenderTargetSupport = true;
159 fInvalidateFBType = kDiscard_InvalidateFBType;
160 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000161
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000162 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
163 fFullClearIsFree = true;
164 }
165
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000166 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000167 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
tomhudson612e9262014-11-24 11:22:36 -0800168 ctxInfo.hasExtension("GL_ARB_vertex_array_object") ||
169 ctxInfo.hasExtension("GL_APPLE_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000170 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000171 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
172 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000173 }
174
cdalton626e1ff2015-06-12 13:56:46 -0700175 if (kGL_GrGLStandard == standard) {
176 fDirectStateAccessSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access");
177 } else {
178 fDirectStateAccessSupport = false;
179 }
180
181 if (kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) {
182 fDebugSupport = true;
183 } else {
184 fDebugSupport = ctxInfo.hasExtension("GL_KHR_debug");
185 }
186
jvanverth3f801cb2014-12-16 09:49:38 -0800187 if (kGL_GrGLStandard == standard) {
188 fES2CompatibilitySupport = ctxInfo.hasExtension("GL_ARB_ES2_compatibility");
189 }
190 else {
191 fES2CompatibilitySupport = true;
192 }
193
cdalton0edea2c2015-05-21 08:27:44 -0700194 if (kGL_GrGLStandard == standard) {
195 fMultisampleDisableSupport = true;
196 } else {
kkinnunenbf49e462015-07-30 22:43:52 -0700197 fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
cdalton0edea2c2015-05-21 08:27:44 -0700198 }
199
kkinnunend94708e2015-07-30 22:47:04 -0700200 if (kGL_GrGLStandard == standard) {
201 if (version >= GR_GL_VER(3, 0)) {
202 fBindFragDataLocationSupport = true;
203 }
204 } else {
205 if (version >= GR_GL_VER(3, 0) && ctxInfo.hasExtension("GL_EXT_blend_func_extended")) {
206 fBindFragDataLocationSupport = true;
207 }
joshualittc1f56b52015-06-22 12:31:31 -0700208 }
209
halcanary6950de62015-11-07 05:29:00 -0800210#if 0 // Disabled due to https://bug.skia.org/4454
joshualitt7bdd70a2015-10-01 06:28:11 -0700211 fBindUniformLocationSupport = ctxInfo.hasExtension("GL_CHROMIUM_bind_uniform_location");
kkinnunen177519e2015-10-28 06:18:35 -0700212#else
213 fBindUniformLocationSupport = false;
214#endif
joshualitt7bdd70a2015-10-01 06:28:11 -0700215
bsalomon7ea33f52015-11-22 14:51:00 -0800216 if (ctxInfo.hasExtension("GL_OES_EGL_image_external")) {
217 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
218 fExternalTextureSupport = true;
219 } else if (ctxInfo.hasExtension("GL_OES_EGL_image_external_essl3") ||
220 ctxInfo.hasExtension("OES_EGL_image_external_essl3")) {
221 // At least one driver has been found that has this extension without the "GL_" prefix.
222 fExternalTextureSupport = true;
223 }
224 }
225
bsalomone179a912016-01-20 06:18:10 -0800226 if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 1)) ||
bsalomone5286e02016-01-14 09:24:09 -0800227 ctxInfo.hasExtension("GL_ARB_texture_rectangle")) {
bsalomone179a912016-01-20 06:18:10 -0800228 // We also require textureSize() support for rectangle 2D samplers which was added in GLSL
229 // 1.40.
230 if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
231 fRectangleTextureSupport = true;
232 }
bsalomone5286e02016-01-14 09:24:09 -0800233 }
234
bsalomoncdee0092016-01-08 13:20:12 -0800235 if (kGL_GrGLStandard == standard) {
236 if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
237 fTextureSwizzleSupport = true;
238 }
239 } else {
240 if (version >= GR_GL_VER(3,0)) {
241 fTextureSwizzleSupport = true;
242 }
243 }
244
bsalomon88c7b982015-07-31 11:20:16 -0700245#ifdef SK_BUILD_FOR_WIN
246 // We're assuming that on Windows Chromium we're using ANGLE.
247 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() ||
248 kChromium_GrGLDriver == ctxInfo.driver();
249 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
250 fRGBA8888PixelsOpsAreSlow = isANGLE;
251 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is still true and
252 // check DX11 ANGLE.
253 fPartialFBOReadIsSlow = isANGLE;
254#endif
255
cdalton4cd67132015-06-10 19:23:46 -0700256 /**************************************************************************
egdaniel05ded892015-10-26 07:38:05 -0700257 * GrShaderCaps fields
258 **************************************************************************/
259
egdaniel0a482332015-10-26 08:59:10 -0700260 // This must be called after fCoreProfile is set on the GrGLCaps
261 this->initGLSL(ctxInfo);
262 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
263
egdaniel05ded892015-10-26 07:38:05 -0700264 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
265
266 // For now these two are equivalent but we could have dst read in shader via some other method.
267 // Before setting this, initGLSL() must have been called.
268 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
269
270 // Enable supported shader-related caps
271 if (kGL_GrGLStandard == standard) {
272 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
273 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
274 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
275 glslCaps->fShaderDerivativeSupport = true;
276 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
277 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
278 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
279 }
280 else {
281 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
282
283 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
284 ctxInfo.hasExtension("GL_OES_standard_derivatives");
285 }
286
egdaniel05ded892015-10-26 07:38:05 -0700287 /**************************************************************************
bsalomon4b91f762015-05-19 09:29:46 -0700288 * GrCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000289 **************************************************************************/
cdalton4cd67132015-06-10 19:23:46 -0700290
cdalton63f6c1f2015-11-06 07:09:43 -0800291 // We need dual source blending and the ability to disable multisample in order to support mixed
292 // samples in every corner case.
egdanieleed519e2016-01-15 11:36:18 -0800293 if (fMultisampleDisableSupport &&
294 glslCaps->dualSourceBlendingSupport() &&
295 fShaderCaps->pathRenderingSupport()) {
296 fUsesMixedSamples = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") ||
kkinnunenea409432015-12-10 01:21:59 -0800297 ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_mixed_samples");
cdalton63f6c1f2015-11-06 07:09:43 -0800298 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed samples.
kkinnunen9f63b442016-01-25 00:31:49 -0800299 if (fUsesMixedSamples && (kNVIDIA_GrGLDriver == ctxInfo.driver() ||
300 kChromium_GrGLDriver == ctxInfo.driver())) {
cdalton63f6c1f2015-11-06 07:09:43 -0800301 fDiscardRenderTargetSupport = false;
302 fInvalidateFBType = kNone_InvalidateFBType;
303 }
304 }
305
egdanieleed519e2016-01-15 11:36:18 -0800306 // fUsesMixedSamples must be set before calling initFSAASupport.
cdalton4cd67132015-06-10 19:23:46 -0700307 this->initFSAASupport(ctxInfo, gli);
cdalton1dd05422015-06-12 09:01:18 -0700308 this->initBlendEqationSupport(ctxInfo);
cdalton4cd67132015-06-10 19:23:46 -0700309 this->initStencilFormats(ctxInfo);
310
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000311 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000312 // we could also look for GL_ATI_separate_stencil extension or
313 // GL_EXT_stencil_two_side but they use different function signatures
314 // than GL2.0+ (and than each other).
315 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
316 // supported on GL 1.4 and higher or by extension
317 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
318 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
319 } else {
320 // ES 2 has two sided stencil and stencil wrap
321 fTwoSidedStencilSupport = true;
322 fStencilWrapOpsSupport = true;
323 }
324
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000325 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000326 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
327 // extension includes glMapBuffer.
328 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
329 fMapBufferFlags |= kSubset_MapFlag;
330 fMapBufferType = kMapBufferRange_MapBufferType;
331 } else {
332 fMapBufferType = kMapBuffer_MapBufferType;
333 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000334 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000335 // Unextended GLES2 doesn't have any buffer mapping.
336 fMapBufferFlags = kNone_MapBufferType;
337 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
338 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
339 fMapBufferType = kChromium_MapBufferType;
340 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
341 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
342 fMapBufferType = kMapBufferRange_MapBufferType;
343 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
344 fMapBufferFlags = kCanMap_MapFlag;
345 fMapBufferType = kMapBuffer_MapBufferType;
346 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000347 }
348
jvanverthd7a2c1f2015-12-07 07:36:44 -0800349 if (kGL_GrGLStandard == standard) {
350 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
351 fTransferBufferType = kPBO_TransferBufferType;
352 }
353 } else {
354 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
355 fTransferBufferType = kPBO_TransferBufferType;
356 } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
357 fTransferBufferType = kChromium_TransferBufferType;
358 }
359 }
360
joshualitte5b74c62015-06-01 14:17:47 -0700361 // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
362 // threshold to the maximum unless the client gives us a hint that map memory is cheap.
363 if (fGeometryBufferMapThreshold < 0) {
bsalomonbc233752015-06-26 11:38:25 -0700364 // We think mapping on Chromium will be cheaper once we know ahead of time how much space
365 // we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
366 // a small subset.
367#if 0
cdalton1acea862015-06-02 13:05:52 -0700368 fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
bsalomonbc233752015-06-26 11:38:25 -0700369#else
370 fGeometryBufferMapThreshold = SK_MaxS32;
371#endif
joshualitte5b74c62015-06-01 14:17:47 -0700372 }
373
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000374 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000375 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
376 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
377 fNPOTTextureTileSupport = true;
378 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000379 } else {
380 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000381 // ES3 has no limitations.
382 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
383 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000384 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
385 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
386 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
387 // to alllow arbitrary wrap modes, however.
388 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000389 }
390
bsalomone72bd022015-10-26 07:33:03 -0700391 // Using MIPs on this GPU seems to be a source of trouble.
392 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer()) {
393 fMipMapSupport = false;
394 }
395
bsalomon@google.combcce8922013-03-25 15:38:39 +0000396 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
397 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
398 // Our render targets are always created with textures as the color
399 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000400 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000401
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000402 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
403
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000404 // Disable scratch texture reuse on Mali and Adreno devices
405 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
406 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000407
robertphillips1b8e1b52015-06-24 06:54:10 -0700408#if 0
409 fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
410 kQualcomm_GrGLVendor != ctxInfo.vendor();
411#endif
412
egdaniel05ded892015-10-26 07:38:05 -0700413 // initFSAASupport() must have been called before this point
bsalomon@google.com347c3822013-05-01 20:10:01 +0000414 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
egdanieleed519e2016-01-15 11:36:18 -0800415 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxColorSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000416 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
egdanieleed519e2016-01-15 11:36:18 -0800417 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxColorSampleCount);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000418 }
egdanieleed519e2016-01-15 11:36:18 -0800419 fMaxStencilSampleCount = fMaxColorSampleCount;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000420
bsalomon63b21962014-11-05 07:05:34 -0800421 if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() ||
bsalomone702d972015-01-29 10:07:32 -0800422 kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() ||
bsalomona8fcea02015-02-13 09:00:39 -0800423 kAdreno3xx_GrGLRenderer == ctxInfo.renderer()) {
bsalomon63b21962014-11-05 07:05:34 -0800424 fUseDrawInsteadOfClear = true;
425 }
426
joshualitt83bc2292015-06-18 14:18:02 -0700427 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
428 fUseDrawInsteadOfPartialRenderTargetWrite = true;
429 }
430
robertphillips63926682015-08-20 09:39:02 -0700431#ifdef SK_BUILD_FOR_WIN
432 // On ANGLE deferring flushes can lead to GPU starvation
433 fPreferVRAMUseOverFlushes = !isANGLE;
434#endif
435
bsalomon7dea7b72015-08-19 08:26:51 -0700436 if (kChromium_GrGLDriver == ctxInfo.driver()) {
437 fMustClearUploadedBufferData = true;
438 }
439
bsalomond08ea5f2015-02-20 06:58:13 -0800440 if (kGL_GrGLStandard == standard) {
441 // ARB allows mixed size FBO attachments, EXT does not.
442 if (ctxInfo.version() >= GR_GL_VER(3, 0) ||
443 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
444 fOversizedStencilSupport = true;
445 } else {
446 SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object"));
447 }
448 } else {
449 // ES 3.0 supports mixed size FBO attachments, 2.0 does not.
450 fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0);
451 }
452
joshualitt58001552015-06-26 12:46:36 -0700453 if (kGL_GrGLStandard == standard) {
454 // 3.1 has draw_instanced but not instanced_arrays, for the time being we only care about
455 // instanced arrays, but we could make this more granular if we wanted
456 fSupportsInstancedDraws =
457 version >= GR_GL_VER(3, 2) ||
458 (ctxInfo.hasExtension("GL_ARB_draw_instanced") &&
459 ctxInfo.hasExtension("GL_ARB_instanced_arrays"));
460 } else {
461 fSupportsInstancedDraws =
462 version >= GR_GL_VER(3, 0) ||
463 (ctxInfo.hasExtension("GL_EXT_draw_instanced") &&
464 ctxInfo.hasExtension("GL_EXT_instanced_arrays"));
465 }
466
jvanverthcba99b82015-06-24 06:59:57 -0700467 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
bsalomoncdee0092016-01-08 13:20:12 -0800468
469 if (contextOptions.fUseShaderSwizzling) {
470 fTextureSwizzleSupport = false;
471 }
472
473 // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
474 // already been detected.
475 this->initConfigTable(ctxInfo, gli, glslCaps);
cdalton4cd67132015-06-10 19:23:46 -0700476
477 this->applyOptionsOverrides(contextOptions);
478 glslCaps->applyOptionsOverrides(contextOptions);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000479}
480
egdaniel472d44e2015-10-22 08:20:00 -0700481const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration generation,
482 bool isCoreProfile) {
483 switch (generation) {
484 case k110_GrGLSLGeneration:
485 if (kGLES_GrGLStandard == standard) {
486 // ES2s shader language is based on version 1.20 but is version
487 // 1.00 of the ES language.
488 return "#version 100\n";
489 } else {
490 SkASSERT(kGL_GrGLStandard == standard);
491 return "#version 110\n";
492 }
493 case k130_GrGLSLGeneration:
494 SkASSERT(kGL_GrGLStandard == standard);
495 return "#version 130\n";
496 case k140_GrGLSLGeneration:
497 SkASSERT(kGL_GrGLStandard == standard);
498 return "#version 140\n";
499 case k150_GrGLSLGeneration:
500 SkASSERT(kGL_GrGLStandard == standard);
501 if (isCoreProfile) {
502 return "#version 150\n";
503 } else {
504 return "#version 150 compatibility\n";
505 }
506 case k330_GrGLSLGeneration:
507 if (kGLES_GrGLStandard == standard) {
508 return "#version 300 es\n";
509 } else {
510 SkASSERT(kGL_GrGLStandard == standard);
511 if (isCoreProfile) {
512 return "#version 330\n";
513 } else {
514 return "#version 330 compatibility\n";
515 }
516 }
517 case k310es_GrGLSLGeneration:
518 SkASSERT(kGLES_GrGLStandard == standard);
519 return "#version 310 es\n";
520 }
521 return "<no version>";
522}
523
egdaniel05ded892015-10-26 07:38:05 -0700524void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
egdaniel472d44e2015-10-22 08:20:00 -0700525 GrGLStandard standard = ctxInfo.standard();
526 GrGLVersion version = ctxInfo.version();
527
528 /**************************************************************************
529 * Caps specific to GrGLSLCaps
530 **************************************************************************/
531
532 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
533 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
ethannicholas5366a092016-01-22 09:45:47 -0800534
egdaniel472d44e2015-10-22 08:20:00 -0700535 if (kGLES_GrGLStandard == standard) {
536 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
537 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
538 glslCaps->fFBFetchSupport = true;
539 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
540 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
541 }
542 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
543 // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
544 glslCaps->fFBFetchNeedsCustomOutput = false;
545 glslCaps->fFBFetchSupport = true;
546 glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
547 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
548 }
549 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
550 // The arm extension also requires an additional flag which we will set onResetContext
551 glslCaps->fFBFetchNeedsCustomOutput = false;
552 glslCaps->fFBFetchSupport = true;
553 glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
554 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
555 }
556 glslCaps->fUsesPrecisionModifiers = true;
557 }
558
559 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture");
560
561 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
562 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
563
564 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation error "Calls to any
565 // function that may require a gradient calculation inside a conditional block may return
566 // undefined results". This appears to be an issue with the 'any' call since even the simple
567 // "result=black; if (any()) result=white;" code fails to compile. This issue comes into play
568 // from our GrTextureDomain processor.
569 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.vendor();
570
egdaniel472d44e2015-10-22 08:20:00 -0700571 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCaps->fGLSLGeneration,
572 fIsCoreProfile);
egdaniel574a4c12015-11-02 06:22:44 -0800573
574 if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) {
575 glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
576 }
egdaniel8dcdedc2015-11-11 06:27:20 -0800577
578 // Frag Coords Convention support is not part of ES
579 // Known issue on at least some Intel platforms:
580 // http://code.google.com/p/skia/issues/detail?id=946
581 if (kIntel_GrGLVendor != ctxInfo.vendor() &&
582 kGLES_GrGLStandard != standard &&
583 (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
584 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) {
585 glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
586 }
587
588 if (kGLES_GrGLStandard == standard) {
589 glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended";
590 }
591
bsalomon7ea33f52015-11-22 14:51:00 -0800592 if (fExternalTextureSupport) {
593 if (ctxInfo.glslGeneration() == k110_GrGLSLGeneration) {
594 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external";
595 } else {
596 glslCaps->fExternalTextureExtensionString = "GL_OES_EGL_image_external_essl3";
597 }
598 }
599
egdaniel8dcdedc2015-11-11 06:27:20 -0800600 // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do
601 // the abs first in a separate expression.
602 if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
603 glslCaps->fCanUseMinAndAbsTogether = false;
604 }
605
bsalomon7ea33f52015-11-22 14:51:00 -0800606 // 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 -0800607 // thus must us -1.0 * %s.x to work correctly
608 if (kIntel_GrGLVendor == ctxInfo.vendor()) {
609 glslCaps->fMustForceNegatedAtanParamToFloat = true;
610 }
egdaniel472d44e2015-10-22 08:20:00 -0700611}
612
kkinnunencfe62e32015-07-01 02:58:50 -0700613bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
kkinnunen6bb6d402015-07-14 10:59:23 -0700614 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering");
615
616 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700617 return false;
618 }
kkinnunen6bb6d402015-07-14 10:59:23 -0700619
kkinnunencfe62e32015-07-01 02:58:50 -0700620 if (kGL_GrGLStandard == ctxInfo.standard()) {
621 if (ctxInfo.version() < GR_GL_VER(4, 3) &&
622 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
623 return false;
624 }
625 } else {
kkinnunen6bb6d402015-07-14 10:59:23 -0700626 if (!hasChromiumPathRendering &&
627 ctxInfo.version() < GR_GL_VER(3, 1)) {
kkinnunencfe62e32015-07-01 02:58:50 -0700628 return false;
629 }
630 }
631 // We only support v1.3+ of GL_NV_path_rendering which allows us to
632 // set individual fragment inputs with ProgramPathFragmentInputGen. The API
633 // additions are detected by checking the existence of the function.
634 // We also use *Then* functions that not all drivers might have. Check
635 // them for consistency.
halcanary96fcdcc2015-08-27 07:41:13 -0700636 if (nullptr == gli->fFunctions.fStencilThenCoverFillPath ||
637 nullptr == gli->fFunctions.fStencilThenCoverStrokePath ||
638 nullptr == gli->fFunctions.fStencilThenCoverFillPathInstanced ||
639 nullptr == gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
640 nullptr == gli->fFunctions.fProgramPathFragmentInputGen) {
kkinnunencfe62e32015-07-01 02:58:50 -0700641 return false;
642 }
643 return true;
644}
bsalomon1aa20292016-01-22 08:16:09 -0800645
646bool GrGLCaps::readPixelsSupported(GrPixelConfig rtConfig,
bsalomon7928ef62016-01-05 10:26:39 -0800647 GrPixelConfig readConfig,
bsalomon1aa20292016-01-22 08:16:09 -0800648 std::function<void (GrGLenum, GrGLint*)> getIntegerv,
649 std::function<bool ()> bindRenderTarget) const {
650 SkASSERT(this->isConfigRenderable(rtConfig, false));
bsalomon7928ef62016-01-05 10:26:39 -0800651
bsalomon76148af2016-01-12 11:13:47 -0800652 GrGLenum readFormat;
653 GrGLenum readType;
bsalomon1aa20292016-01-22 08:16:09 -0800654 if (!this->getReadPixelsFormat(rtConfig, readConfig, &readFormat, &readType)) {
bsalomon76148af2016-01-12 11:13:47 -0800655 return false;
656 }
657
bsalomon1aa20292016-01-22 08:16:09 -0800658 if (kGL_GrGLStandard == fStandard) {
bsalomon23e56662016-01-14 07:19:47 -0800659 // All of our renderable configs can be converted to each other by glReadPixels in OpenGL.
bsalomon7928ef62016-01-05 10:26:39 -0800660 return true;
piotaixre4b23142014-10-02 10:57:53 -0700661 }
bsalomon7928ef62016-01-05 10:26:39 -0800662
bsalomon76148af2016-01-12 11:13:47 -0800663 // See Section 16.1.2 in the ES 3.2 specification.
bsalomon7928ef62016-01-05 10:26:39 -0800664
bsalomon1aa20292016-01-22 08:16:09 -0800665 if (kNormalizedFixedPoint_FormatType == fConfigTable[rtConfig].fFormatType) {
bsalomon7928ef62016-01-05 10:26:39 -0800666 if (GR_GL_RGBA == readFormat && GR_GL_UNSIGNED_BYTE == readType) {
667 return true;
668 }
669 } else {
bsalomon1aa20292016-01-22 08:16:09 -0800670 SkASSERT(kFloat_FormatType == fConfigTable[rtConfig].fFormatType);
bsalomon7928ef62016-01-05 10:26:39 -0800671 if (GR_GL_RGBA == readFormat && GR_GL_FLOAT == readType) {
672 return true;
673 }
674 }
675
bsalomon1aa20292016-01-22 08:16:09 -0800676 if (0 == fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat) {
bsalomon7928ef62016-01-05 10:26:39 -0800677 ReadPixelsFormat* rpFormat =
bsalomon1aa20292016-01-22 08:16:09 -0800678 const_cast<ReadPixelsFormat*>(&fConfigTable[rtConfig].fSecondReadPixelsFormat);
bsalomon7928ef62016-01-05 10:26:39 -0800679 GrGLint format = 0, type = 0;
bsalomon1aa20292016-01-22 08:16:09 -0800680 if (!bindRenderTarget()) {
681 return false;
682 }
683 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format);
684 getIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
bsalomon7928ef62016-01-05 10:26:39 -0800685 rpFormat->fFormat = format;
686 rpFormat->fType = type;
687 }
688
bsalomon1aa20292016-01-22 08:16:09 -0800689 return fConfigTable[rtConfig].fSecondReadPixelsFormat.fFormat == readFormat &&
690 fConfigTable[rtConfig].fSecondReadPixelsFormat.fType == readType;
piotaixre4b23142014-10-02 10:57:53 -0700691}
692
robertphillips@google.com6177e692013-02-28 20:16:25 +0000693void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000694
695 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000696 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000697 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
698 // ES3 driver bugs on at least one device with a tiled GPU (N10).
699 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
700 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
701 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
702 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
egdanieleed519e2016-01-15 11:36:18 -0800703 } else if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700704 fMSFBOType = kMixedSamples_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000705 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000706 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
707 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
708 // chrome's extension is equivalent to the EXT msaa
709 // and fbo_blit extensions.
710 fMSFBOType = kDesktop_EXT_MSFBOType;
711 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
712 fMSFBOType = kES_Apple_MSFBOType;
713 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000714 } else {
egdanieleed519e2016-01-15 11:36:18 -0800715 if (fUsesMixedSamples) {
vbuzinovdded6962015-06-12 08:59:45 -0700716 fMSFBOType = kMixedSamples_MSFBOType;
717 } else if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000718 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000719 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000720 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
721 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000722 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000723 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000724 }
725}
726
cdalton1dd05422015-06-12 09:01:18 -0700727void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) {
728 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
729
730 // Disabling advanced blend on various platforms with major known issues. We also block Chrome
731 // for now until its own blacklists can be updated.
732 if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() ||
733 kIntel_GrGLDriver == ctxInfo.driver() ||
joel.liang9764c402015-07-09 19:46:18 -0700734 kChromium_GrGLDriver == ctxInfo.driver()) {
cdalton1dd05422015-06-12 09:01:18 -0700735 return;
736 }
737
738 if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
739 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
740 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
741 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
742 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
743 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
744 } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() &&
745 ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) {
746 // Non-coherent advanced blend has an issue on NVIDIA pre 337.00.
747 return;
748 } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
749 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
750 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
751 } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
752 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
753 glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
754 // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is
755 // slow on a particular platform.
756 } else {
757 return; // No advanced blend support.
758 }
759
760 SkASSERT(this->advancedBlendEquationSupport());
761
762 if (kNVIDIA_GrGLDriver == ctxInfo.driver()) {
763 // Blacklist color-dodge and color-burn on NVIDIA until the fix is released.
764 fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) |
765 (1 << kColorBurn_GrBlendEquation);
766 }
joel.liang9764c402015-07-09 19:46:18 -0700767 if (kARM_GrGLVendor == ctxInfo.vendor()) {
768 // Blacklist color-burn on ARM until the fix is released.
769 fAdvBlendEqBlacklist |= (1 << kColorBurn_GrBlendEquation);
770 }
cdalton1dd05422015-06-12 09:01:18 -0700771}
772
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000773namespace {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700774const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000775}
776
777void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
778
779 // Build up list of legal stencil formats (though perhaps not supported on
780 // the particular gpu/driver) from most preferred to least.
781
782 // these consts are in order of most preferred to least preferred
783 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
784
785 static const StencilFormat
786 // internal Format stencil bits total bits packed?
787 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
788 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
789 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
790 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000791 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000792 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
793
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000794 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000795 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000796 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000797 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
798 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
799
800 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
801 // require FBO support we can expect these are legal formats and don't
802 // check. These also all support the unsized GL_STENCIL_INDEX.
803 fStencilFormats.push_back() = gS8;
804 fStencilFormats.push_back() = gS16;
805 if (supportsPackedDS) {
806 fStencilFormats.push_back() = gD24S8;
807 }
808 fStencilFormats.push_back() = gS4;
809 if (supportsPackedDS) {
810 fStencilFormats.push_back() = gDS;
811 }
812 } else {
813 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
814 // for other formats.
815 // ES doesn't support using the unsized format.
816
817 fStencilFormats.push_back() = gS8;
818 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000819 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
820 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000821 fStencilFormats.push_back() = gD24S8;
822 }
823 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
824 fStencilFormats.push_back() = gS4;
825 }
826 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000827}
828
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000829SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000830
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000831 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000832
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000833 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000834 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000835 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000836 i,
837 fStencilFormats[i].fStencilBits,
838 fStencilFormats[i].fTotalBits);
839 }
840
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000841 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000842 "None",
843 "ARB",
844 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000845 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000846 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000847 "IMG MS To Texture",
848 "EXT MS To Texture",
vbuzinovdded6962015-06-12 08:59:45 -0700849 "MixedSamples",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000850 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000851 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
852 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
853 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000854 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
855 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
856 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
857 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
vbuzinovdded6962015-06-12 08:59:45 -0700858 GR_STATIC_ASSERT(7 == kMixedSamples_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000859 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000860
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000861 static const char* kInvalidateFBTypeStr[] = {
862 "None",
863 "Discard",
864 "Invalidate",
865 };
866 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
867 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
868 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
869 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000870
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000871 static const char* kMapBufferTypeStr[] = {
872 "None",
873 "MapBuffer",
874 "MapBufferRange",
875 "Chromium",
876 };
877 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
878 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
879 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
880 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
881 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
882
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000883 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000884 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000885 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000886 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000887 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
888 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000889 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000890 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
891 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
892 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
893 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000894
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000895 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
896 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
897 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
898 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000899 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
cdalton626e1ff2015-06-12 13:56:46 -0700900 r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
901 r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
cdaltond4727922015-11-10 12:49:06 -0800902 r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000903 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000904 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
bsalomon16921ec2015-07-30 15:34:56 -0700905 r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
robertphillips63926682015-08-20 09:39:02 -0700906 r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
907 r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
joshualitt7bdd70a2015-10-01 06:28:11 -0700908 r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800909 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
bsalomone5286e02016-01-14 09:24:09 -0800910 r.appendf("Rectangle texture support: %s\n", (fRectangleTextureSupport? "YES" : "NO"));
bsalomoncdee0092016-01-08 13:20:12 -0800911 r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO"));
bsalomon41e4384e2016-01-08 09:12:44 -0800912
913 r.append("Configs\n-------\n");
914 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
915 r.appendf(" cfg: %d flags: 0x%04x, b_internal: 0x%08x s_internal: 0x%08x, e_format: "
bsalomon76148af2016-01-12 11:13:47 -0800916 "0x%08x, e_format_teximage: 0x%08x, e_type: 0x%08x, i_for_teximage: 0x%08x, "
917 "i_for_renderbuffer: 0x%08x\n",
bsalomon41e4384e2016-01-08 09:12:44 -0800918 i,
919 fConfigTable[i].fFlags,
920 fConfigTable[i].fFormats.fBaseInternalFormat,
921 fConfigTable[i].fFormats.fSizedInternalFormat,
bsalomon76148af2016-01-12 11:13:47 -0800922 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage],
923 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage],
bsalomon41e4384e2016-01-08 09:12:44 -0800924 fConfigTable[i].fFormats.fExternalType,
925 fConfigTable[i].fFormats.fInternalFormatTexImage,
bsalomon76148af2016-01-12 11:13:47 -0800926 fConfigTable[i].fFormats.fInternalFormatRenderbuffer);
bsalomon41e4384e2016-01-08 09:12:44 -0800927 }
928
jvanverthe9c0fc62015-04-29 11:18:05 -0700929 return r;
930}
931
jvanverthe9c0fc62015-04-29 11:18:05 -0700932static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
933 switch (p) {
934 case kLow_GrSLPrecision:
935 return GR_GL_LOW_FLOAT;
936 case kMedium_GrSLPrecision:
937 return GR_GL_MEDIUM_FLOAT;
938 case kHigh_GrSLPrecision:
939 return GR_GL_HIGH_FLOAT;
940 }
941 SkFAIL("Unknown precision.");
942 return -1;
943}
944
945static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
946 switch (type) {
947 case kVertex_GrShaderType:
948 return GR_GL_VERTEX_SHADER;
949 case kGeometry_GrShaderType:
950 return GR_GL_GEOMETRY_SHADER;
951 case kFragment_GrShaderType:
952 return GR_GL_FRAGMENT_SHADER;
953 }
954 SkFAIL("Unknown shader type.");
955 return -1;
956}
957
jvanverthcba99b82015-06-24 06:59:57 -0700958void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
959 const GrGLInterface* intf,
960 GrGLSLCaps* glslCaps) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700961 if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4, 1) ||
962 ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
963 for (int s = 0; s < kGrShaderTypeCount; ++s) {
964 if (kGeometry_GrShaderType != s) {
965 GrShaderType shaderType = static_cast<GrShaderType>(s);
966 GrGLenum glShader = shader_type_to_gl_shader(shaderType);
halcanary96fcdcc2015-08-27 07:41:13 -0700967 GrShaderCaps::PrecisionInfo* first = nullptr;
jvanverthcba99b82015-06-24 06:59:57 -0700968 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700969 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
970 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
971 GrGLenum glPrecision = precision_to_gl_float_type(precision);
972 GrGLint range[2];
973 GrGLint bits;
974 GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits);
975 if (bits) {
jvanverthcba99b82015-06-24 06:59:57 -0700976 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = range[0];
977 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = range[1];
978 glslCaps->fFloatPrecisions[s][p].fBits = bits;
jvanverthe9c0fc62015-04-29 11:18:05 -0700979 if (!first) {
jvanverthcba99b82015-06-24 06:59:57 -0700980 first = &glslCaps->fFloatPrecisions[s][p];
jvanverthe9c0fc62015-04-29 11:18:05 -0700981 }
jvanverthcba99b82015-06-24 06:59:57 -0700982 else if (!glslCaps->fShaderPrecisionVaries) {
983 glslCaps->fShaderPrecisionVaries =
984 (*first != glslCaps->fFloatPrecisions[s][p]);
jvanverthe9c0fc62015-04-29 11:18:05 -0700985 }
986 }
987 }
988 }
989 }
990 }
991 else {
992 // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float.
jvanverthcba99b82015-06-24 06:59:57 -0700993 glslCaps->fShaderPrecisionVaries = false;
jvanverthe9c0fc62015-04-29 11:18:05 -0700994 for (int s = 0; s < kGrShaderTypeCount; ++s) {
995 if (kGeometry_GrShaderType != s) {
996 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -0700997 glslCaps->fFloatPrecisions[s][p].fLogRangeLow = 127;
998 glslCaps->fFloatPrecisions[s][p].fLogRangeHigh = 127;
999 glslCaps->fFloatPrecisions[s][p].fBits = 23;
jvanverthe9c0fc62015-04-29 11:18:05 -07001000 }
1001 }
1002 }
1003 }
1004 // GetShaderPrecisionFormat doesn't accept GL_GEOMETRY_SHADER as a shader type. Assume they're
1005 // the same as the vertex shader. Only fragment shaders were ever allowed to omit support for
1006 // highp. GS was added after GetShaderPrecisionFormat was added to the list of features that
1007 // are recommended against.
jvanverthcba99b82015-06-24 06:59:57 -07001008 if (glslCaps->fGeometryShaderSupport) {
jvanverthe9c0fc62015-04-29 11:18:05 -07001009 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
jvanverthcba99b82015-06-24 06:59:57 -07001010 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] =
1011 glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
jvanverthe9c0fc62015-04-29 11:18:05 -07001012 }
1013 }
1014}
1015
bsalomon41e4384e2016-01-08 09:12:44 -08001016bool GrGLCaps::bgraIsInternalFormat() const {
1017 return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA;
1018}
1019
bsalomon76148af2016-01-12 11:13:47 -08001020bool GrGLCaps::getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1021 GrGLenum* internalFormat, GrGLenum* externalFormat,
1022 GrGLenum* externalType) const {
1023 if (!this->getExternalFormat(surfaceConfig, externalConfig, kTexImage_ExternalFormatUsage,
1024 externalFormat, externalType)) {
1025 return false;
1026 }
1027 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1028 return true;
1029}
1030
1031bool GrGLCaps::getCompressedTexImageFormats(GrPixelConfig surfaceConfig,
1032 GrGLenum* internalFormat) const {
1033 if (!GrPixelConfigIsCompressed(surfaceConfig)) {
1034 return false;
1035 }
1036 *internalFormat = fConfigTable[surfaceConfig].fFormats.fInternalFormatTexImage;
1037 return true;
1038}
1039
1040bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
1041 GrGLenum* externalFormat, GrGLenum* externalType) const {
1042 if (!this->getExternalFormat(surfaceConfig, externalConfig, kOther_ExternalFormatUsage,
1043 externalFormat, externalType)) {
1044 return false;
1045 }
1046 return true;
1047}
1048
1049bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
1050 if (GrPixelConfigIsCompressed(config)) {
1051 return false;
1052 }
1053 *internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
1054 return true;
1055}
1056
1057bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
1058 ExternalFormatUsage usage, GrGLenum* externalFormat,
1059 GrGLenum* externalType) const {
1060 SkASSERT(externalFormat && externalType);
1061 if (GrPixelConfigIsCompressed(memoryConfig) || GrPixelConfigIsCompressed(memoryConfig)) {
1062 return false;
1063 }
1064
1065 bool surfaceIsAlphaOnly = GrPixelConfigIsAlphaOnly(surfaceConfig);
1066 bool memoryIsAlphaOnly = GrPixelConfigIsAlphaOnly(memoryConfig);
1067
1068 // We don't currently support moving RGBA data into and out of ALPHA surfaces. It could be
1069 // made to work in many cases using glPixelStore and what not but is not needed currently.
1070 if (surfaceIsAlphaOnly && !memoryIsAlphaOnly) {
1071 return false;
1072 }
1073
1074 *externalFormat = fConfigTable[memoryConfig].fFormats.fExternalFormat[usage];
1075 *externalType = fConfigTable[memoryConfig].fFormats.fExternalType;
1076
1077 return true;
1078}
1079
bsalomoncdee0092016-01-08 13:20:12 -08001080void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli,
1081 GrGLSLCaps* glslCaps) {
bsalomon41e4384e2016-01-08 09:12:44 -08001082 /*
1083 Comments on renderability of configs on various GL versions.
1084 OpenGL < 3.0:
1085 no built in support for render targets.
1086 GL_EXT_framebuffer_object adds possible support for any sized format with base internal
1087 format RGB, RGBA and NV float formats we don't use.
1088 This is the following:
1089 R3_G3_B2, RGB4, RGB5, RGB8, RGB10, RGB12, RGB16, RGBA2, RGBA4, RGB5_A1, RGBA8
1090 RGB10_A2, RGBA12,RGBA16
1091 Though, it is hard to believe the more obscure formats such as RGBA12 would work
1092 since they aren't required by later standards and the driver can simply return
1093 FRAMEBUFFER_UNSUPPORTED for anything it doesn't allow.
1094 GL_ARB_framebuffer_object adds everything added by the EXT extension and additionally
1095 any sized internal format with a base internal format of ALPHA, LUMINANCE,
1096 LUMINANCE_ALPHA, INTENSITY, RED, and RG.
1097 This adds a lot of additional renderable sized formats, including ALPHA8.
1098 The GL_ARB_texture_rg brings in the RED and RG formats (8, 8I, 8UI, 16, 16I, 16UI,
1099 16F, 32I, 32UI, and 32F variants).
1100 Again, the driver has an escape hatch via FRAMEBUFFER_UNSUPPORTED.
1101
1102 For both the above extensions we limit ourselves to those that are also required by
1103 OpenGL 3.0.
1104
1105 OpenGL 3.0:
1106 Any format with base internal format ALPHA, RED, RG, RGB or RGBA is "color-renderable"
1107 but are not required to be supported as renderable textures/renderbuffer.
1108 Required renderable color formats:
1109 - RGBA32F, RGBA32I, RGBA32UI, RGBA16, RGBA16F, RGBA16I,
1110 RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, and
1111 RGB10_A2.
1112 - R11F_G11F_B10F.
1113 - RG32F, RG32I, RG32UI, RG16, RG16F, RG16I, RG16UI, RG8, RG8I,
1114 and RG8UI.
1115 - R32F, R32I, R32UI, R16F, R16I, R16UI, R16, R8, R8I, and R8UI.
1116 - ALPHA8
1117
1118 OpenGL 3.1, 3.2, 3.3
1119 Same as 3.0 except ALPHA8 requires GL_ARB_compatibility/compatibility profile.
1120 OpengGL 3.3, 4.0, 4.1
1121 Adds RGB10_A2UI.
1122 OpengGL 4.2
1123 Adds
1124 - RGB5_A1, RGBA4
1125 - RGB565
1126 OpenGL 4.4
1127 Does away with the separate list and adds a column to the sized internal color format
1128 table. However, no new formats become required color renderable.
1129
1130 ES 2.0
1131 color renderable: RGBA4, RGB5_A1, RGB565
1132 GL_EXT_texture_rg adds support for R8, RG5 as a color render target
1133 GL_OES_rgb8_rgba8 adds support for RGB8 and RGBA8
1134 GL_ARM_rgba8 adds support for RGBA8 (but not RGB8)
1135 GL_EXT_texture_format_BGRA8888 does not add renderbuffer support
1136 GL_CHROMIUM_renderbuffer_format_BGRA8888 adds BGRA8 as color-renderable
1137 GL_APPLE_texture_format_BGRA8888 does not add renderbuffer support
1138
1139 ES 3.0
1140 - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
1141 RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
1142 RGB5_A1.
1143 - RGB8 and RGB565.
1144 - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
1145 - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI
1146 ES 3.1
1147 Adds RGB10_A2, RGB10_A2UI,
1148 ES 3.2
1149 Adds R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F, R11F_G11F_B10F.
1150 */
1151 uint32_t allRenderFlags = ConfigInfo::kRenderable_Flag;
1152 if (kNone_MSFBOType != fMSFBOType) {
1153 allRenderFlags |= ConfigInfo::kRenderableWithMSAA_Flag;
1154 }
1155
1156 GrGLStandard standard = ctxInfo.standard();
1157 GrGLVersion version = ctxInfo.version();
1158
bsalomon30447372015-12-21 09:03:05 -08001159 fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0;
1160 fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0;
bsalomon76148af2016-01-12 11:13:47 -08001161 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001162 fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001163 fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001164 fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001165
1166 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1167 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001168 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1169 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001170 fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001171 fConfigTable[kRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001172 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1173 if (kGL_GrGLStandard == standard) {
1174 // We require some form of FBO support and all GLs with FBO support can render to RGBA8
1175 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
egdaniel4999df82016-01-07 17:06:04 -08001176 } else {
bsalomon41e4384e2016-01-08 09:12:44 -08001177 if (version >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
1178 ctxInfo.hasExtension("GL_ARM_rgba8")) {
1179 fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags;
1180 }
egdaniel4999df82016-01-07 17:06:04 -08001181 }
bsalomoncdee0092016-01-08 13:20:12 -08001182 fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001183
bsalomon76148af2016-01-12 11:13:47 -08001184 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1185 GR_GL_BGRA;
bsalomon30447372015-12-21 09:03:05 -08001186 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001187 fConfigTable[kBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001188 if (kGL_GrGLStandard == standard) {
1189 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1190 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1191 if (version >= GR_GL_VER(1, 2) || ctxInfo.hasExtension("GL_EXT_bgra")) {
1192 // Since the internal format is RGBA8, it is also renderable.
1193 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1194 allRenderFlags;
1195 }
1196 } else {
1197 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
1198 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
1199 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
1200 // The APPLE extension doesn't make this renderable.
1201 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1202 if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
1203 // On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
1204 // Though, that seems to not be the case if the texture storage extension is
1205 // present. The specs don't exactly make that clear.
1206 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1207 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
1208 }
1209 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
1210 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1211 ConfigInfo::kRenderable_Flag;
1212 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888") &&
kkinnunen9f63b442016-01-25 00:31:49 -08001213 (this->usesMSAARenderBuffers() || this->fMSFBOType == kMixedSamples_MSFBOType)) {
bsalomon41e4384e2016-01-08 09:12:44 -08001214 fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |=
1215 ConfigInfo::kRenderableWithMSAA_Flag;
1216 }
1217 }
1218 }
bsalomoncdee0092016-01-08 13:20:12 -08001219 fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001220
bsalomon41e4384e2016-01-08 09:12:44 -08001221 // We only enable srgb support if both textures and FBOs support srgb.
1222 bool srgbSupport = false;
1223 if (kGL_GrGLStandard == standard) {
1224 if (ctxInfo.version() >= GR_GL_VER(3,0)) {
1225 srgbSupport = true;
1226 } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
1227 if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
1228 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
1229 srgbSupport = true;
1230 }
1231 }
1232 // All the above srgb extensions support toggling srgb writes
1233 fSRGBWriteControl = srgbSupport;
1234 } else {
1235 // See https://bug.skia.org/4148 for PowerVR issue.
1236 srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
1237 (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
1238 // ES through 3.1 requires EXT_srgb_write_control to support toggling
1239 // sRGB writing for destinations.
1240 fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
1241 }
bsalomon30447372015-12-21 09:03:05 -08001242 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
1243 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
1244 // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
1245 // external format is GL_RGBA. See below for note about ES2.0 and glTex[Sub]Image.
bsalomon76148af2016-01-12 11:13:47 -08001246 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1247 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001248 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001249 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001250 if (srgbSupport) {
1251 fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
1252 allRenderFlags;
1253 }
bsalomoncdee0092016-01-08 13:20:12 -08001254 fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001255
1256 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
1257 if (this->ES2CompatibilitySupport()) {
1258 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
1259 } else {
1260 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB5;
1261 }
bsalomon76148af2016-01-12 11:13:47 -08001262 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1263 GR_GL_RGB;
bsalomon30447372015-12-21 09:03:05 -08001264 fConfigTable[kRGB_565_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_5_6_5;
bsalomon7928ef62016-01-05 10:26:39 -08001265 fConfigTable[kRGB_565_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001266 fConfigTable[kRGB_565_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1267 if (kGL_GrGLStandard == standard) {
1268 if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ES2_compatibility")) {
1269 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1270 }
1271 } else {
1272 fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags;
1273 }
bsalomoncdee0092016-01-08 13:20:12 -08001274 fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001275
1276 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1277 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4;
bsalomon76148af2016-01-12 11:13:47 -08001278 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1279 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001280 fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
bsalomon7928ef62016-01-05 10:26:39 -08001281 fConfigTable[kRGBA_4444_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001282 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1283 if (kGL_GrGLStandard == standard) {
1284 if (version >= GR_GL_VER(4, 2)) {
1285 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1286 }
1287 } else {
1288 fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags;
1289 }
bsalomoncdee0092016-01-08 13:20:12 -08001290 fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001291
1292 if (this->textureRedSupport()) {
1293 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1294 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
bsalomon76148af2016-01-12 11:13:47 -08001295 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1296 GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001297 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001298 } else {
1299 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1300 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8;
bsalomon76148af2016-01-12 11:13:47 -08001301 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1302 GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001303 fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001304 }
1305 fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
bsalomon7928ef62016-01-05 10:26:39 -08001306 fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001307 fConfigTable[kAlpha_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1308 if (this->textureRedSupport() || kDesktop_ARB_MSFBOType == this->msFBOType()) {
1309 // desktop ARB extension/3.0+ supports ALPHA8 as renderable.
1310 // Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
1311 fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
1312 }
1313
1314 // Check for [half] floating point texture support
1315 // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
1316 // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
1317 // [half] floating point textures became part of the standard in ES3.1 / OGL 3.0.
1318 bool hasFPTextures = false;
1319 bool hasHalfFPTextures = false;
1320 // for now we don't support floating point MSAA on ES
1321 uint32_t fpRenderFlags = (kGL_GrGLStandard == standard) ?
1322 allRenderFlags : (uint32_t)ConfigInfo::kRenderable_Flag;
1323
1324 if (kGL_GrGLStandard == standard) {
1325 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_texture_float")) {
1326 hasFPTextures = true;
1327 hasHalfFPTextures = true;
1328 }
1329 } else {
1330 if (version >= GR_GL_VER(3, 1)) {
1331 hasFPTextures = true;
1332 hasHalfFPTextures = true;
1333 } else {
1334 if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
1335 ctxInfo.hasExtension("GL_OES_texture_float")) {
1336 hasFPTextures = true;
1337 }
1338 if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
1339 ctxInfo.hasExtension("GL_OES_texture_half_float")) {
1340 hasHalfFPTextures = true;
1341 }
1342 }
1343 }
bsalomon30447372015-12-21 09:03:05 -08001344
1345 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1346 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA32F;
bsalomon76148af2016-01-12 11:13:47 -08001347 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1348 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001349 fConfigTable[kRGBA_float_GrPixelConfig].fFormats.fExternalType = GR_GL_FLOAT;
bsalomon7928ef62016-01-05 10:26:39 -08001350 fConfigTable[kRGBA_float_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001351 if (hasFPTextures) {
1352 fConfigTable[kRGBA_float_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1353 // For now we only enable rendering to float on desktop, because on ES we'd have to solve
1354 // many precision issues and no clients actually want this yet.
1355 if (kGL_GrGLStandard == standard /* || version >= GR_GL_VER(3,2) ||
1356 ctxInfo.hasExtension("GL_EXT_color_buffer_float")*/) {
1357 fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags;
1358 }
1359 }
bsalomoncdee0092016-01-08 13:20:12 -08001360 fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001361
1362 if (this->textureRedSupport()) {
1363 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
1364 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F;
bsalomon76148af2016-01-12 11:13:47 -08001365 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1366 = GR_GL_RED;
bsalomoncdee0092016-01-08 13:20:12 -08001367 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001368 } else {
1369 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA;
1370 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F;
bsalomon76148af2016-01-12 11:13:47 -08001371 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage]
1372 = GR_GL_ALPHA;
bsalomoncdee0092016-01-08 13:20:12 -08001373 fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA();
bsalomon30447372015-12-21 09:03:05 -08001374 }
1375 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1376 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1377 } else {
1378 fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1379 }
bsalomon7928ef62016-01-05 10:26:39 -08001380 fConfigTable[kAlpha_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001381 if (hasHalfFPTextures) {
1382 fConfigTable[kAlpha_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1383 // ES requires either 3.2 or the combination of EXT_color_buffer_half_float and support for
1384 // GL_RED internal format.
1385 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1386 (this->textureRedSupport() &&
1387 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float"))) {
1388 fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= fpRenderFlags;
1389 }
1390 }
bsalomon30447372015-12-21 09:03:05 -08001391
1392 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
1393 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA16F;
bsalomon76148af2016-01-12 11:13:47 -08001394 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1395 GR_GL_RGBA;
bsalomon30447372015-12-21 09:03:05 -08001396 if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) {
1397 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT;
1398 } else {
1399 fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT_OES;
1400 }
bsalomon7928ef62016-01-05 10:26:39 -08001401 fConfigTable[kRGBA_half_GrPixelConfig].fFormatType = kFloat_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001402 if (hasHalfFPTextures) {
1403 fConfigTable[kRGBA_half_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1404 // ES requires 3.2 or EXT_color_buffer_half_float.
1405 if (kGL_GrGLStandard == standard || version >= GR_GL_VER(3,2) ||
1406 ctxInfo.hasExtension("GL_EXT_color_buffer_half_float")) {
1407 fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags;
1408 }
1409 }
bsalomoncdee0092016-01-08 13:20:12 -08001410 fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon41e4384e2016-01-08 09:12:44 -08001411
1412 // Compressed texture support
1413
1414 // glCompressedTexImage2D is available on all OpenGL ES devices. It is available on standard
1415 // OpenGL after version 1.3. We'll assume at least that level of OpenGL support.
1416
1417 // TODO: Fix command buffer bindings and remove this.
1418 fCompressedTexSubImageSupport = SkToBool(gli->fFunctions.fCompressedTexSubImage2D);
bsalomon30447372015-12-21 09:03:05 -08001419
1420 // No sized/unsized internal format distinction for compressed formats, no external format.
bsalomon41e4384e2016-01-08 09:12:44 -08001421 // Below we set the external formats and types to 0.
bsalomon30447372015-12-21 09:03:05 -08001422
1423 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_PALETTE8_RGBA8;
1424 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_PALETTE8_RGBA8;
bsalomon76148af2016-01-12 11:13:47 -08001425 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001426 fConfigTable[kIndex_8_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001427 fConfigTable[kIndex_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001428 // Disable this for now, while we investigate https://bug.skia.org/4333
1429 if (false) {
1430 // Check for 8-bit palette..
1431 GrGLint numFormats;
1432 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
1433 if (numFormats) {
1434 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
1435 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
1436 for (int i = 0; i < numFormats; ++i) {
1437 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
1438 fConfigTable[kIndex_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1439 break;
1440 }
1441 }
1442 }
1443 }
bsalomoncdee0092016-01-08 13:20:12 -08001444 fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001445
bsalomon41e4384e2016-01-08 09:12:44 -08001446 // May change the internal format based on extensions.
1447 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1448 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1449 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1450 GR_GL_COMPRESSED_LUMINANCE_LATC1;
1451 if (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
1452 ctxInfo.hasExtension("GL_NV_texture_compression_latc")) {
1453 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1454 } else if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(3, 0)) ||
1455 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
1456 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc")) {
1457 // RGTC is identical and available on OpenGL 3.0+ as well as with extensions
1458 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1459 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat =
1460 GR_GL_COMPRESSED_RED_RGTC1;
1461 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1462 GR_GL_COMPRESSED_RED_RGTC1;
1463 } else if (ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture")) {
1464 fConfigTable[kLATC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1465 fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_3DC_X;
1466 fConfigTable[kLATC_GrPixelConfig].fFormats.fSizedInternalFormat =
1467 GR_GL_COMPRESSED_3DC_X;
1468
bsalomon30447372015-12-21 09:03:05 -08001469 }
bsalomon76148af2016-01-12 11:13:47 -08001470 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001471 fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001472 fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomoncdee0092016-01-08 13:20:12 -08001473 fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001474
1475 fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
1476 fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
bsalomon76148af2016-01-12 11:13:47 -08001477 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001478 fConfigTable[kETC1_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001479 fConfigTable[kETC1_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001480 if (kGL_GrGLStandard == standard) {
1481 if (version >= GR_GL_VER(4, 3) || ctxInfo.hasExtension("GL_ARB_ES3_compatibility")) {
1482 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1483 }
1484 } else {
1485 if (version >= GR_GL_VER(3, 0) ||
1486 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
1487 // ETC2 is a superset of ETC1, so we can just check for that, too.
1488 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
1489 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))) {
1490 fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1491 }
1492 }
bsalomoncdee0092016-01-08 13:20:12 -08001493 fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001494
1495 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC;
1496 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC;
bsalomon76148af2016-01-12 11:13:47 -08001497 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0;
bsalomon30447372015-12-21 09:03:05 -08001498 fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001499 fConfigTable[kR11_EAC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001500 // Check for R11_EAC. We don't support R11_EAC on desktop, as most cards default to
1501 // decompressing the textures in the driver, and is generally slower.
1502 if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) {
1503 fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1504 }
bsalomoncdee0092016-01-08 13:20:12 -08001505 fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR();
bsalomon30447372015-12-21 09:03:05 -08001506
1507 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat =
1508 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
1509 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fSizedInternalFormat =
1510 GR_GL_COMPRESSED_RGBA_ASTC_12x12;
bsalomon76148af2016-01-12 11:13:47 -08001511 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
1512 0;
bsalomon30447372015-12-21 09:03:05 -08001513 fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fExternalType = 0;
bsalomon7928ef62016-01-05 10:26:39 -08001514 fConfigTable[kASTC_12x12_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
bsalomon41e4384e2016-01-08 09:12:44 -08001515 if (ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
1516 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
1517 ctxInfo.hasExtension("GL_OES_texture_compression_astc")) {
1518 fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
1519 }
bsalomoncdee0092016-01-08 13:20:12 -08001520 fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
bsalomon30447372015-12-21 09:03:05 -08001521
1522 // Bulk populate the texture internal/external formats here and then deal with exceptions below.
1523
1524 // ES 2.0 requires that the internal/external formats match.
bsalomon76148af2016-01-12 11:13:47 -08001525 bool useSizedTexFormats = (kGL_GrGLStandard == ctxInfo.standard() ||
1526 ctxInfo.version() >= GR_GL_VER(3,0));
1527 // All ES versions (thus far) require sized internal formats for render buffers.
1528 // TODO: Always use sized internal format?
1529 bool useSizedRbFormats = kGLES_GrGLStandard == ctxInfo.standard();
1530
bsalomon30447372015-12-21 09:03:05 -08001531 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001532 // Almost always we want to pass fExternalFormat[kOther_ExternalFormatUsage] as the <format>
1533 // param to glTex[Sub]Image.
1534 fConfigTable[i].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
1535 fConfigTable[i].fFormats.fExternalFormat[kOther_ExternalFormatUsage];
1536 fConfigTable[i].fFormats.fInternalFormatTexImage = useSizedTexFormats ?
1537 fConfigTable[i].fFormats.fSizedInternalFormat :
1538 fConfigTable[i].fFormats.fBaseInternalFormat;
1539 fConfigTable[i].fFormats.fInternalFormatRenderbuffer = useSizedRbFormats ?
bsalomon30447372015-12-21 09:03:05 -08001540 fConfigTable[i].fFormats.fSizedInternalFormat :
1541 fConfigTable[i].fFormats.fBaseInternalFormat;
1542 }
1543 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
1544 // param to Tex(Sub)Image. ES 2.0 requires the <internalFormat> and <format> params to match.
1545 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the <format> param.
1546 // On OpenGL and ES 3.0+ GL_SRGB_ALPHA does not work for the <format> param to glTexImage.
1547 if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
bsalomon76148af2016-01-12 11:13:47 -08001548 fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
bsalomon30447372015-12-21 09:03:05 -08001549 GR_GL_SRGB_ALPHA;
1550 }
1551
1552 // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
1553 // as a base format.
1554 // GL_EXT_texture_format_BGRA8888:
1555 // This extension GL_BGRA as an unsized internal format. However, it is written against ES
1556 // 2.0 and therefore doesn't define a value for GL_BGRA8 as ES 2.0 uses unsized internal
1557 // formats.
1558 // GL_APPLE_texture_format_BGRA8888:
1559 // ES 2.0: the extension makes BGRA an external format but not an internal format.
1560 // ES 3.0: the extension explicitly states GL_BGRA8 is not a valid internal format for
1561 // glTexImage (just for glTexStorage).
bsalomon76148af2016-01-12 11:13:47 -08001562 if (useSizedTexFormats && this->bgraIsInternalFormat()) {
bsalomon30447372015-12-21 09:03:05 -08001563 fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA;
1564 }
1565
bsalomoncdee0092016-01-08 13:20:12 -08001566 // If we don't have texture swizzle support then the shader generator must insert the
1567 // swizzle into shader code.
1568 if (!this->textureSwizzleSupport()) {
1569 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1570 glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle;
1571 }
1572 }
1573
bsalomon7f9b2e42016-01-12 13:29:26 -08001574 // Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
1575 // implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
1576 // gets written to the single component.
1577 if (this->textureRedSupport()) {
1578 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
1579 GrPixelConfig config = static_cast<GrPixelConfig>(i);
1580 if (GrPixelConfigIsAlphaOnly(config) &&
1581 fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
1582 glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
1583 }
1584 }
1585 }
1586
bsalomon30447372015-12-21 09:03:05 -08001587#ifdef SK_DEBUG
1588 // Make sure we initialized everything.
bsalomon76148af2016-01-12 11:13:47 -08001589 ConfigInfo defaultEntry;
bsalomon30447372015-12-21 09:03:05 -08001590 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
bsalomon76148af2016-01-12 11:13:47 -08001591 SkASSERT(defaultEntry.fFormats.fBaseInternalFormat !=
1592 fConfigTable[i].fFormats.fBaseInternalFormat);
1593 SkASSERT(defaultEntry.fFormats.fSizedInternalFormat !=
bsalomon30447372015-12-21 09:03:05 -08001594 fConfigTable[i].fFormats.fSizedInternalFormat);
bsalomon76148af2016-01-12 11:13:47 -08001595 for (int j = 0; j < kExternalFormatUsageCnt; ++j) {
1596 SkASSERT(defaultEntry.fFormats.fExternalFormat[j] !=
1597 fConfigTable[i].fFormats.fExternalFormat[j]);
1598 }
1599 SkASSERT(defaultEntry.fFormats.fExternalType != fConfigTable[i].fFormats.fExternalType);
bsalomon30447372015-12-21 09:03:05 -08001600 }
1601#endif
1602}
1603
egdanielb7e7d572015-11-04 04:23:53 -08001604void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}