blob: 2fe38479deb4cabdd83561b93edc3a8dd91f8d56 [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"
robertphillips@google.com6177e692013-02-28 20:16:25 +000010#include "GrGLContext.h"
bsalomon@google.comc9668ec2012-04-11 18:16:41 +000011#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000012#include "SkTSort.h"
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000013
14GrGLCaps::GrGLCaps() {
15 this->reset();
16}
17
18void GrGLCaps::reset() {
bsalomon@google.combcce8922013-03-25 15:38:39 +000019 INHERITED::reset();
20
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000021 fVerifiedColorConfigs.reset();
22 fStencilFormats.reset();
23 fStencilVerifiedColorConfigs.reset();
24 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000025 fInvalidateFBType = kNone_InvalidateFBType;
krajcevski3217c4a2014-06-09 09:10:04 -070026 fLATCAlias = kLATC_LATCAlias;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000027 fMapBufferType = kNone_MapBufferType;
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;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000031 fMaxFixedFunctionTextureCoords = 0;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000032 fRGBA8RenderbufferSupport = false;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000033 fBGRAIsInternalFormat = false;
34 fTextureSwizzleSupport = false;
35 fUnpackRowLengthSupport = false;
36 fUnpackFlipYSupport = false;
37 fPackRowLengthSupport = false;
38 fPackFlipYSupport = false;
39 fTextureUsageSupport = false;
40 fTexStorageSupport = false;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000041 fTextureRedSupport = false;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000042 fImagingSupport = false;
robertphillips@google.com1d89c932012-06-27 19:31:41 +000043 fTwoFormatLimit = false;
bsalomon@google.com706f6682012-10-23 14:53:55 +000044 fFragCoordsConventionSupport = false;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000045 fVertexArrayObjectSupport = false;
bsalomon@google.com96966a52013-02-21 16:34:21 +000046 fUseNonVBOVertexAndIndexDynamicData = false;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000047 fIsCoreProfile = false;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +000048 fFullClearIsFree = false;
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000049 fDropsTileOnZeroDivide = false;
joshualitt58162332014-08-01 06:44:53 -070050 fFBFetchSupport = false;
51 fFBFetchColorName = NULL;
52 fFBFetchExtensionString = NULL;
piotaixre4b23142014-10-02 10:57:53 -070053
54 fReadPixelsSupportedCache.reset();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000055}
56
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000057GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000058 *this = caps;
59}
60
commit-bot@chromium.orgbeb8b3a2014-04-15 15:37:51 +000061GrGLCaps& GrGLCaps::operator= (const GrGLCaps& caps) {
bsalomon@google.combcce8922013-03-25 15:38:39 +000062 INHERITED::operator=(caps);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000063 fVerifiedColorConfigs = caps.fVerifiedColorConfigs;
64 fStencilFormats = caps.fStencilFormats;
65 fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
krajcevski3217c4a2014-06-09 09:10:04 -070066 fLATCAlias = caps.fLATCAlias;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000067 fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
bsalomon@google.com60da4172012-06-01 19:25:00 +000068 fMaxVertexAttributes = caps.fMaxVertexAttributes;
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +000069 fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +000070 fMaxFixedFunctionTextureCoords = caps.fMaxFixedFunctionTextureCoords;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000071 fMSFBOType = caps.fMSFBOType;
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +000072 fInvalidateFBType = caps.fInvalidateFBType;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000073 fMapBufferType = caps.fMapBufferType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000074 fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000075 fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
76 fTextureSwizzleSupport = caps.fTextureSwizzleSupport;
77 fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport;
78 fUnpackFlipYSupport = caps.fUnpackFlipYSupport;
79 fPackRowLengthSupport = caps.fPackRowLengthSupport;
80 fPackFlipYSupport = caps.fPackFlipYSupport;
81 fTextureUsageSupport = caps.fTextureUsageSupport;
82 fTexStorageSupport = caps.fTexStorageSupport;
robertphillips@google.com443e5a52012-04-30 20:01:21 +000083 fTextureRedSupport = caps.fTextureRedSupport;
bsalomon@google.come76b7cc2012-06-18 12:47:06 +000084 fImagingSupport = caps.fImagingSupport;
robertphillips@google.com1d89c932012-06-27 19:31:41 +000085 fTwoFormatLimit = caps.fTwoFormatLimit;
bsalomon@google.com706f6682012-10-23 14:53:55 +000086 fFragCoordsConventionSupport = caps.fFragCoordsConventionSupport;
bsalomon@google.com07631cf2013-03-05 14:14:58 +000087 fVertexArrayObjectSupport = caps.fVertexArrayObjectSupport;
bsalomon@google.com96966a52013-02-21 16:34:21 +000088 fUseNonVBOVertexAndIndexDynamicData = caps.fUseNonVBOVertexAndIndexDynamicData;
bsalomon@google.com2b1b8c02013-02-28 22:06:02 +000089 fIsCoreProfile = caps.fIsCoreProfile;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +000090 fFullClearIsFree = caps.fFullClearIsFree;
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000091 fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
joshualitt58162332014-08-01 06:44:53 -070092 fFBFetchSupport = caps.fFBFetchSupport;
93 fFBFetchColorName = caps.fFBFetchColorName;
94 fFBFetchExtensionString = caps.fFBFetchExtensionString;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +000095
96 return *this;
97}
98
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +000099bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000100
101 this->reset();
102 if (!ctxInfo.isInitialized()) {
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000103 return false;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000104 }
105
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000106 GrGLStandard standard = ctxInfo.standard();
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000107 GrGLVersion version = ctxInfo.version();
108
bsalomon@google.combcce8922013-03-25 15:38:39 +0000109 /**************************************************************************
110 * Caps specific to GrGLCaps
111 **************************************************************************/
112
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000113 if (kGLES_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000114 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
115 &fMaxFragmentUniformVectors);
116 } else {
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000117 SkASSERT(kGL_GrGLStandard == standard);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000118 GrGLint max;
119 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
120 fMaxFragmentUniformVectors = max / 4;
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +0000121 if (version >= GR_GL_VER(3, 2)) {
122 GrGLint profileMask;
123 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
124 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
125 }
126 if (!fIsCoreProfile) {
127 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_COORDS, &fMaxFixedFunctionTextureCoords);
128 // Sanity check
129 SkASSERT(fMaxFixedFunctionTextureCoords > 0 && fMaxFixedFunctionTextureCoords < 128);
130 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000131 }
bsalomon@google.com60da4172012-06-01 19:25:00 +0000132 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes);
commit-bot@chromium.orga15f7e52013-06-05 23:29:25 +0000133 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000134
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000135 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000136 fRGBA8RenderbufferSupport = true;
137 } else {
commit-bot@chromium.orgc5dffe42013-08-20 15:25:21 +0000138 fRGBA8RenderbufferSupport = version >= GR_GL_VER(3,0) ||
139 ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000140 ctxInfo.hasExtension("GL_ARM_rgba8");
141 }
142
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000143 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000144 fTextureSwizzleSupport = version >= GR_GL_VER(3,3) ||
145 ctxInfo.hasExtension("GL_ARB_texture_swizzle");
146 } else {
commit-bot@chromium.org6364b5e2013-08-20 20:22:52 +0000147 fTextureSwizzleSupport = version >= GR_GL_VER(3,0);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000148 }
149
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000150 if (kGL_GrGLStandard == standard) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000151 fUnpackRowLengthSupport = true;
152 fUnpackFlipYSupport = false;
153 fPackRowLengthSupport = true;
154 fPackFlipYSupport = false;
155 } else {
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000156 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) ||
157 ctxInfo.hasExtension("GL_EXT_unpack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000158 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
commit-bot@chromium.orgdc3134c2013-08-16 16:12:23 +0000159 fPackRowLengthSupport = version >= GR_GL_VER(3,0) ||
160 ctxInfo.hasExtension("GL_NV_pack_subimage");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000161 fPackFlipYSupport =
162 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
163 }
164
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000165 fTextureUsageSupport = (kGLES_GrGLStandard == standard) &&
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000166 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
167
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000168 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000169 // The EXT version can apply to either GL or GLES.
170 fTexStorageSupport = version >= GR_GL_VER(4,2) ||
171 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
172 ctxInfo.hasExtension("GL_EXT_texture_storage");
173 } else {
174 // Qualcomm Adreno drivers appear to have issues with texture storage.
175 fTexStorageSupport = (version >= GR_GL_VER(3,0) &&
176 kQualcomm_GrGLVendor != ctxInfo.vendor()) ||
177 ctxInfo.hasExtension("GL_EXT_texture_storage");
178 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000179
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000180 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support it if
181 // it doesn't have ARB_texture_rg extension.
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000182 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org459104c2013-06-14 14:42:56 +0000183 if (ctxInfo.isMesa()) {
184 fTextureRedSupport = ctxInfo.hasExtension("GL_ARB_texture_rg");
185 } else {
186 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
187 ctxInfo.hasExtension("GL_ARB_texture_rg");
188 }
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000189 } else {
commit-bot@chromium.orgc5dffe42013-08-20 15:25:21 +0000190 fTextureRedSupport = version >= GR_GL_VER(3,0) ||
191 ctxInfo.hasExtension("GL_EXT_texture_rg");
robertphillips@google.com443e5a52012-04-30 20:01:21 +0000192 }
193
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000194 fImagingSupport = kGL_GrGLStandard == standard &&
bsalomon@google.come76b7cc2012-06-18 12:47:06 +0000195 ctxInfo.hasExtension("GL_ARB_imaging");
196
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000197 // ES 2 only guarantees RGBA/uchar + one other format/type combo for
198 // ReadPixels. The other format has to checked at run-time since it
199 // can change based on which render target is bound
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000200 fTwoFormatLimit = kGLES_GrGLStandard == standard;
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000201
bsalomon@google.com706f6682012-10-23 14:53:55 +0000202 // Known issue on at least some Intel platforms:
203 // http://code.google.com/p/skia/issues/detail?id=946
204 if (kIntel_GrGLVendor != ctxInfo.vendor()) {
205 fFragCoordsConventionSupport = ctxInfo.glslGeneration() >= k150_GrGLSLGeneration ||
206 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions");
207 }
208
bsalomon@google.com3012ded2013-02-22 16:44:04 +0000209 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with
210 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex
211 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
212 // limit this decision to specific GPU families rather than basing it on the vendor alone.
213 if (!GR_GL_MUST_USE_VBO &&
bsalomoned82c4e2014-09-02 07:54:47 -0700214 (kARM_GrGLVendor == ctxInfo.vendor() ||
215 kImagination_GrGLVendor == ctxInfo.vendor() ||
216 kQualcomm_GrGLVendor == ctxInfo.vendor())) {
bsalomon@google.com96966a52013-02-21 16:34:21 +0000217 fUseNonVBOVertexAndIndexDynamicData = true;
218 }
skia.committer@gmail.com631cdcb2013-03-01 12:12:55 +0000219
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000220 if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
skia.committer@gmail.coma9157722014-04-03 03:04:26 +0000221 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) ||
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000222 ctxInfo.hasExtension("GL_ARB_invalidate_subdata")) {
223 fDiscardRenderTargetSupport = true;
224 fInvalidateFBType = kInvalidate_InvalidateFBType;
225 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
226 fDiscardRenderTargetSupport = true;
227 fInvalidateFBType = kDiscard_InvalidateFBType;
228 }
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000229
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000230 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
231 fFullClearIsFree = true;
232 }
233
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000234 if (kGL_GrGLStandard == standard) {
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000235 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
236 ctxInfo.hasExtension("GL_ARB_vertex_array_object");
237 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000238 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) ||
239 ctxInfo.hasExtension("GL_OES_vertex_array_object");
bsalomon@google.com07631cf2013-03-05 14:14:58 +0000240 }
241
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000242 if (kGLES_GrGLStandard == standard) {
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000243 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
joshualitt58162332014-08-01 06:44:53 -0700244 fFBFetchSupport = true;
245 fFBFetchColorName = "gl_LastFragData[0]";
246 fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000247 } else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
joshualitt58162332014-08-01 06:44:53 -0700248 fFBFetchSupport = true;
249 fFBFetchColorName = "gl_LastFragData[0]";
250 fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
251 } else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
252 // The arm extension also requires an additional flag which we will set onResetContext
253 // This is all temporary.
254 fFBFetchSupport = true;
255 fFBFetchColorName = "gl_LastFragColorARM";
256 fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000257 }
258 }
259
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000260 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
261 fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
262
robertphillips@google.com6177e692013-02-28 20:16:25 +0000263 this->initFSAASupport(ctxInfo, gli);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000264 this->initStencilFormats(ctxInfo);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000265
266 /**************************************************************************
bsalomon@google.comc26d94f2013-03-25 18:19:00 +0000267 * GrDrawTargetCaps fields
bsalomon@google.combcce8922013-03-25 15:38:39 +0000268 **************************************************************************/
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000269 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000270 // we could also look for GL_ATI_separate_stencil extension or
271 // GL_EXT_stencil_two_side but they use different function signatures
272 // than GL2.0+ (and than each other).
273 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0));
274 // supported on GL 1.4 and higher or by extension
275 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) ||
276 ctxInfo.hasExtension("GL_EXT_stencil_wrap");
277 } else {
278 // ES 2 has two sided stencil and stencil wrap
279 fTwoSidedStencilSupport = true;
280 fStencilWrapOpsSupport = true;
281 }
282
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000283 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000284 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO
285 // extension includes glMapBuffer.
286 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) {
287 fMapBufferFlags |= kSubset_MapFlag;
288 fMapBufferType = kMapBufferRange_MapBufferType;
289 } else {
290 fMapBufferType = kMapBuffer_MapBufferType;
291 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000292 } else {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000293 // Unextended GLES2 doesn't have any buffer mapping.
294 fMapBufferFlags = kNone_MapBufferType;
295 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) {
296 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
297 fMapBufferType = kChromium_MapBufferType;
298 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) {
299 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
300 fMapBufferType = kMapBufferRange_MapBufferType;
301 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) {
302 fMapBufferFlags = kCanMap_MapFlag;
303 fMapBufferType = kMapBuffer_MapBufferType;
304 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000305 }
306
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000307 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000308 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) ||
309 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two"));
310 fNPOTTextureTileSupport = true;
311 fMipMapSupport = true;
bsalomon@google.combcce8922013-03-25 15:38:39 +0000312 } else {
313 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
commit-bot@chromium.org22dd6b92013-08-16 18:13:48 +0000314 // ES3 has no limitations.
315 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) ||
316 ctxInfo.hasExtension("GL_OES_texture_npot");
commit-bot@chromium.org47442312013-12-19 16:18:01 +0000317 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP
318 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently,
319 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to
320 // to alllow arbitrary wrap modes, however.
321 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot");
bsalomon@google.combcce8922013-03-25 15:38:39 +0000322 }
323
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000324 fHWAALineSupport = (kGL_GrGLStandard == standard);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000325
326 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize);
327 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize);
328 // Our render targets are always created with textures as the color
329 // attachment, hence this min:
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000330 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
bsalomon@google.combcce8922013-03-25 15:38:39 +0000331
kkinnunen32b9a3b2014-07-02 22:56:35 -0700332 fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
333
334 if (fPathRenderingSupport) {
335 if (kGL_GrGLStandard == standard) {
336 // We need one of the two possible texturing methods: using fixed function pipeline
337 // (PathTexGen, texcoords, ...) or using the newer NVPR API additions that support
338 // setting individual fragment inputs with ProgramPathFragmentInputGen. The API
339 // additions are detected by checking the existence of the function. Eventually we may
340 // choose to remove the fixed function codepath.
341 // Set fMaxFixedFunctionTextureCoords = 0 here if you want to force
342 // ProgramPathFragmentInputGen usage on desktop.
343 fPathRenderingSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access") &&
344 (fMaxFixedFunctionTextureCoords > 0 ||
345 ((ctxInfo.version() >= GR_GL_VER(4,3) ||
346 ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
bsalomon49f085d2014-09-05 13:34:00 -0700347 gli->fFunctions.fProgramPathFragmentInputGen));
kkinnunen32b9a3b2014-07-02 22:56:35 -0700348 } else {
kkinnunenec56e452014-08-25 22:21:16 -0700349 fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1);
kkinnunen32b9a3b2014-07-02 22:56:35 -0700350 }
351 }
bsalomon@google.combcce8922013-03-25 15:38:39 +0000352
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000353 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
354
joshualitt58162332014-08-01 06:44:53 -0700355 // For now these two are equivalent but we could have dst read in shader via some other method
356 fDstReadInShaderSupport = fFBFetchSupport;
robertphillips@google.com8995b7b2013-11-01 15:03:34 +0000357
358 // Disable scratch texture reuse on Mali and Adreno devices
359 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
360 kQualcomm_GrGLVendor != ctxInfo.vendor();
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +0000361
bsalomon@google.combcce8922013-03-25 15:38:39 +0000362 // Enable supported shader-related caps
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000363 if (kGL_GrGLStandard == standard) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000364 fDualSourceBlendingSupport = ctxInfo.version() >= GR_GL_VER(3,3) ||
365 ctxInfo.hasExtension("GL_ARB_blend_func_extended");
366 fShaderDerivativeSupport = true;
367 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
368 fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3,2) &&
369 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
370 } else {
371 fShaderDerivativeSupport = ctxInfo.hasExtension("GL_OES_standard_derivatives");
372 }
373
bsalomon@google.com347c3822013-05-01 20:10:01 +0000374 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000375 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount);
376 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
377 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
378 }
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000379
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000380 this->initConfigTexturableTable(ctxInfo, gli);
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000381 this->initConfigRenderableTable(ctxInfo);
commit-bot@chromium.orgf4e67e32014-04-30 01:26:04 +0000382
383 return true;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000384}
385
386void GrGLCaps::initConfigRenderableTable(const GrGLContextInfo& ctxInfo) {
387
388 // OpenGL < 3.0
389 // no support for render targets unless the GL_ARB_framebuffer_object
390 // extension is supported (in which case we get ALPHA, RED, RG, RGB,
391 // RGBA (ALPHA8, RGBA4, RGBA8) for OpenGL > 1.1). Note that we
392 // probably don't get R8 in this case.
393
394 // OpenGL 3.0
395 // base color renderable: ALPHA, RED, RG, RGB, and RGBA
396 // sized derivatives: ALPHA8, R8, RGBA4, RGBA8
397
398 // >= OpenGL 3.1
399 // base color renderable: RED, RG, RGB, and RGBA
400 // sized derivatives: R8, RGBA4, RGBA8
401 // if the GL_ARB_compatibility extension is supported then we get back
402 // support for GL_ALPHA and ALPHA8
403
404 // GL_EXT_bgra adds BGRA render targets to any version
405
406 // ES 2.0
407 // color renderable: RGBA4, RGB5_A1, RGB565
408 // GL_EXT_texture_rg adds support for R8 as a color render target
409 // GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8
410 // GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888 added BGRA support
411
412 // ES 3.0
413 // Same as ES 2.0 except R8 and RGBA8 are supported without extensions (the functions called
414 // below already account for this).
415
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000416 GrGLStandard standard = ctxInfo.standard();
417
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000418 enum {
419 kNo_MSAA = 0,
420 kYes_MSAA = 1,
421 };
422
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000423 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000424 // Post 3.0 we will get R8
425 // Prior to 3.0 we will get ALPHA8 (with GL_ARB_framebuffer_object)
426 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
427 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000428 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kNo_MSAA] = true;
429 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kYes_MSAA] = true;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000430 }
431 } else {
432 // On ES we can only hope for R8
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000433 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kNo_MSAA] = fTextureRedSupport;
434 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kYes_MSAA] = fTextureRedSupport;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000435 }
436
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000437 if (kGL_GrGLStandard != standard) {
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000438 // only available in ES
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000439 fConfigRenderSupport[kRGB_565_GrPixelConfig][kNo_MSAA] = true;
440 fConfigRenderSupport[kRGB_565_GrPixelConfig][kYes_MSAA] = true;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000441 }
442
443 // we no longer support 444 as a render target
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000444 fConfigRenderSupport[kRGBA_4444_GrPixelConfig][kNo_MSAA] = false;
445 fConfigRenderSupport[kRGBA_4444_GrPixelConfig][kYes_MSAA] = false;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000446
447 if (this->fRGBA8RenderbufferSupport) {
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000448 fConfigRenderSupport[kRGBA_8888_GrPixelConfig][kNo_MSAA] = true;
commit-bot@chromium.orgda3d69c2013-10-28 15:09:13 +0000449 fConfigRenderSupport[kRGBA_8888_GrPixelConfig][kYes_MSAA] = true;
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000450 }
451
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000452 if (this->isConfigTexturable(kBGRA_8888_GrPixelConfig)) {
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000453 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kNo_MSAA] = true;
454 // The GL_EXT_texture_format_BGRA8888 extension does not add BGRA to the list of
455 // configs that are color-renderable and can be passed to glRenderBufferStorageMultisample.
commit-bot@chromium.org4256d242013-10-17 16:29:41 +0000456 // Chromium may have an extension to allow BGRA renderbuffers to work on desktop platforms.
commit-bot@chromium.org90313cc2014-01-17 15:05:38 +0000457 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888")) {
commit-bot@chromium.org4256d242013-10-17 16:29:41 +0000458 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kYes_MSAA] = true;
459 } else {
460 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kYes_MSAA] =
461 !fBGRAIsInternalFormat || !this->usesMSAARenderBuffers();
462 }
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000463 }
464
joshualittee5da552014-07-16 13:32:56 -0700465 if (this->isConfigTexturable(kRGBA_float_GrPixelConfig)) {
466 fConfigRenderSupport[kRGBA_float_GrPixelConfig][kNo_MSAA] = true;
467 }
468
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000469 // If we don't support MSAA then undo any places above where we set a config as renderable with
470 // msaa.
471 if (kNone_MSFBOType == fMSFBOType) {
472 for (int i = 0; i < kGrPixelConfigCnt; ++i) {
473 fConfigRenderSupport[i][kYes_MSAA] = false;
474 }
commit-bot@chromium.org73880512013-10-14 15:33:45 +0000475 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000476}
477
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000478void GrGLCaps::initConfigTexturableTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000479 GrGLStandard standard = ctxInfo.standard();
480 GrGLVersion version = ctxInfo.version();
481
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000482 // Base texture support
483 fConfigTextureSupport[kAlpha_8_GrPixelConfig] = true;
484 fConfigTextureSupport[kRGB_565_GrPixelConfig] = true;
485 fConfigTextureSupport[kRGBA_4444_GrPixelConfig] = true;
486 fConfigTextureSupport[kRGBA_8888_GrPixelConfig] = true;
487
488 // Check for 8-bit palette..
489 GrGLint numFormats;
490 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
491 if (numFormats) {
492 SkAutoSTMalloc<10, GrGLint> formats(numFormats);
493 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
494 for (int i = 0; i < numFormats; ++i) {
495 if (GR_GL_PALETTE8_RGBA8 == formats[i]) {
496 fConfigTextureSupport[kIndex_8_GrPixelConfig] = true;
497 break;
498 }
499 }
500 }
501
502 // Check for BGRA
503 if (kGL_GrGLStandard == standard) {
504 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] =
505 version >= GR_GL_VER(1,2) || ctxInfo.hasExtension("GL_EXT_bgra");
506 } else {
507 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
508 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] = true;
509 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
510 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] = true;
511 fBGRAIsInternalFormat = true;
512 }
513 SkASSERT(fConfigTextureSupport[kBGRA_8888_GrPixelConfig] ||
514 kSkia8888_GrPixelConfig != kBGRA_8888_GrPixelConfig);
515 }
516
517 // Compressed texture support
518
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000519 // glCompressedTexImage2D is available on all OpenGL ES devices...
520 // however, it is only available on standard OpenGL after version 1.3
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000521 bool hasCompressTex2D = (kGL_GrGLStandard != standard || version >= GR_GL_VER(1, 3));
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000522
krajcevski786978162014-07-30 11:25:44 -0700523 fCompressedTexSubImageSupport =
bsalomon49f085d2014-09-05 13:34:00 -0700524 hasCompressTex2D && (gli->fFunctions.fCompressedTexSubImage2D);
krajcevski786978162014-07-30 11:25:44 -0700525
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000526 // Check for ETC1
527 bool hasETC1 = false;
528
529 // First check version for support
530 if (kGL_GrGLStandard == standard) {
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000531 hasETC1 = hasCompressTex2D &&
joshualittee5da552014-07-16 13:32:56 -0700532 (version >= GR_GL_VER(4, 3) ||
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000533 ctxInfo.hasExtension("GL_ARB_ES3_compatibility"));
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000534 } else {
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000535 hasETC1 = hasCompressTex2D &&
536 (version >= GR_GL_VER(3, 0) ||
537 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") ||
538 // ETC2 is a superset of ETC1, so we can just check for that, too.
539 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") &&
540 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture")));
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000541 }
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000542 fConfigTextureSupport[kETC1_GrPixelConfig] = hasETC1;
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000543
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +0000544 // Check for LATC under its various forms
545 LATCAlias alias = kLATC_LATCAlias;
546 bool hasLATC = hasCompressTex2D &&
547 (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") ||
548 ctxInfo.hasExtension("GL_NV_texture_compression_latc"));
549
550 // Check for RGTC
551 if (!hasLATC) {
552 // If we're using OpenGL 3.0 or later, then we have RGTC, an identical compression format.
553 if (kGL_GrGLStandard == standard) {
554 hasLATC = version >= GR_GL_VER(3, 0);
555 }
556
557 if (!hasLATC) {
558 hasLATC =
559 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") ||
560 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc");
561 }
562
563 if (hasLATC) {
564 alias = kRGTC_LATCAlias;
565 }
566 }
567
568 // Check for 3DC
569 if (!hasLATC) {
570 hasLATC = ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture");
571 if (hasLATC) {
572 alias = k3DC_LATCAlias;
573 }
574 }
575
576 fConfigTextureSupport[kLATC_GrPixelConfig] = hasLATC;
577 fLATCAlias = alias;
krajcevski238b4562014-06-30 09:09:22 -0700578
krajcevskib3abe902014-07-30 13:08:11 -0700579 // Check for R11_EAC ... We don't support R11_EAC on desktop, as most
580 // cards default to decompressing the textures in the driver, and is
581 // generally slower.
582 if (kGL_GrGLStandard != standard) {
krajcevski238b4562014-06-30 09:09:22 -0700583 fConfigTextureSupport[kR11_EAC_GrPixelConfig] = version >= GR_GL_VER(3, 0);
584 }
joshualittee5da552014-07-16 13:32:56 -0700585
krajcevski7ef21622014-07-16 15:21:13 -0700586 // Check for ASTC
piotaixre4b23142014-10-02 10:57:53 -0700587 fConfigTextureSupport[kASTC_12x12_GrPixelConfig] =
krajcevski7ef21622014-07-16 15:21:13 -0700588 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
589 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
590 ctxInfo.hasExtension("GL_OES_texture_compression_astc");
591
joshualittee5da552014-07-16 13:32:56 -0700592 // Check for floating point texture support
593 // NOTE: We disallow floating point textures on ES devices if linear
594 // filtering modes are not supported. This is for simplicity, but a more
595 // granular approach is possible. Coincidentally, floating point textures became part of
596 // the standard in ES3.1 / OGL 3.1, hence the shorthand
597 bool hasFPTextures = version >= GR_GL_VER(3, 1);
598 if (!hasFPTextures) {
599 hasFPTextures = ctxInfo.hasExtension("GL_ARB_texture_float") ||
600 (ctxInfo.hasExtension("OES_texture_float_linear") &&
601 ctxInfo.hasExtension("GL_OES_texture_float"));
602 }
603 fConfigTextureSupport[kRGBA_float_GrPixelConfig] = hasFPTextures;
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +0000604}
605
piotaixre4b23142014-10-02 10:57:53 -0700606bool GrGLCaps::doReadPixelsSupported(const GrGLInterface* intf,
607 GrGLenum format,
608 GrGLenum type) const {
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000609 if (GR_GL_RGBA == format && GR_GL_UNSIGNED_BYTE == type) {
610 // ES 2 guarantees this format is supported
robertphillips@google.comeca2dfb2012-06-27 20:13:49 +0000611 return true;
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000612 }
613
614 if (!fTwoFormatLimit) {
615 // not limited by ES 2's constraints
616 return true;
617 }
618
bsalomon@google.com548a4332012-07-11 19:45:22 +0000619 GrGLint otherFormat = GR_GL_RGBA;
620 GrGLint otherType = GR_GL_UNSIGNED_BYTE;
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000621
622 // The other supported format/type combo supported for ReadPixels
623 // can change based on which render target is bound
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000624 GR_GL_GetIntegerv(intf,
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000625 GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT,
626 &otherFormat);
627
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000628 GR_GL_GetIntegerv(intf,
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000629 GR_GL_IMPLEMENTATION_COLOR_READ_TYPE,
630 &otherType);
631
bsalomon@google.com548a4332012-07-11 19:45:22 +0000632 return (GrGLenum)otherFormat == format && (GrGLenum)otherType == type;
robertphillips@google.com1d89c932012-06-27 19:31:41 +0000633}
634
piotaixre4b23142014-10-02 10:57:53 -0700635bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf,
636 GrGLenum format,
637 GrGLenum type,
638 GrGLenum currFboFormat) const {
639
640 ReadPixelsSupportedFormats::Key key = {format, type, currFboFormat};
641
642 ReadPixelsSupportedFormats* cachedValue = fReadPixelsSupportedCache.find(key);
643
644 if (NULL == cachedValue) {
645 bool value = doReadPixelsSupported(intf, format, type);
646 ReadPixelsSupportedFormats newValue(key, value);
647 fReadPixelsSupportedCache.add(newValue);
648
649 return newValue.value();
650 }
651
652 return cachedValue->value();
653}
654
robertphillips@google.com6177e692013-02-28 20:16:25 +0000655void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000656
657 fMSFBOType = kNone_MSFBOType;
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000658 if (kGL_GrGLStandard != ctxInfo.standard()) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000659 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed
660 // ES3 driver bugs on at least one device with a tiled GPU (N10).
661 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
662 fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
663 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
664 fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
commit-bot@chromium.org92b78842014-01-16 20:49:46 +0000665 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000666 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType;
667 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
668 // chrome's extension is equivalent to the EXT msaa
669 // and fbo_blit extensions.
670 fMSFBOType = kDesktop_EXT_MSFBOType;
671 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
672 fMSFBOType = kES_Apple_MSFBOType;
673 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000674 } else {
675 if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
676 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000677 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000678 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
679 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
bsalomon@google.com347c3822013-05-01 20:10:01 +0000680 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000681 }
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000682 }
683}
684
685namespace {
686const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
687}
688
689void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
690
691 // Build up list of legal stencil formats (though perhaps not supported on
692 // the particular gpu/driver) from most preferred to least.
693
694 // these consts are in order of most preferred to least preferred
695 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
696
697 static const StencilFormat
698 // internal Format stencil bits total bits packed?
699 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
700 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
701 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
702 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000703 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000704 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
705
commit-bot@chromium.org9e90aed2014-01-16 16:35:09 +0000706 if (kGL_GrGLStandard == ctxInfo.standard()) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000707 bool supportsPackedDS =
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000708 ctxInfo.version() >= GR_GL_VER(3,0) ||
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000709 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
710 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
711
712 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
713 // require FBO support we can expect these are legal formats and don't
714 // check. These also all support the unsized GL_STENCIL_INDEX.
715 fStencilFormats.push_back() = gS8;
716 fStencilFormats.push_back() = gS16;
717 if (supportsPackedDS) {
718 fStencilFormats.push_back() = gD24S8;
719 }
720 fStencilFormats.push_back() = gS4;
721 if (supportsPackedDS) {
722 fStencilFormats.push_back() = gDS;
723 }
724 } else {
725 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
726 // for other formats.
727 // ES doesn't support using the unsized format.
728
729 fStencilFormats.push_back() = gS8;
730 //fStencilFormats.push_back() = gS16;
commit-bot@chromium.org04c500f2013-09-06 15:28:01 +0000731 if (ctxInfo.version() >= GR_GL_VER(3,0) ||
732 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000733 fStencilFormats.push_back() = gD24S8;
734 }
735 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
736 fStencilFormats.push_back() = gS4;
737 }
738 }
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000739 SkASSERT(0 == fStencilVerifiedColorConfigs.count());
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000740 fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count());
741}
742
743void GrGLCaps::markColorConfigAndStencilFormatAsVerified(
744 GrPixelConfig config,
745 const GrGLStencilBuffer::Format& format) {
746#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
747 return;
748#endif
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000749 SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt);
750 SkASSERT(fStencilFormats.count() == fStencilVerifiedColorConfigs.count());
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000751 int count = fStencilFormats.count();
752 // we expect a really small number of possible formats so linear search
753 // should be OK
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000754 SkASSERT(count < 16);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000755 for (int i = 0; i < count; ++i) {
756 if (format.fInternalFormat ==
757 fStencilFormats[i].fInternalFormat) {
758 fStencilVerifiedColorConfigs[i].markVerified(config);
759 return;
760 }
761 }
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000762 SkFAIL("Why are we seeing a stencil format that "
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000763 "GrGLCaps doesn't know about.");
764}
765
766bool GrGLCaps::isColorConfigAndStencilFormatVerified(
767 GrPixelConfig config,
768 const GrGLStencilBuffer::Format& format) const {
769#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
770 return false;
771#endif
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000772 SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000773 int count = fStencilFormats.count();
774 // we expect a really small number of possible formats so linear search
775 // should be OK
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000776 SkASSERT(count < 16);
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000777 for (int i = 0; i < count; ++i) {
778 if (format.fInternalFormat ==
779 fStencilFormats[i].fInternalFormat) {
780 return fStencilVerifiedColorConfigs[i].isVerified(config);
781 }
782 }
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000783 SkFAIL("Why are we seeing a stencil format that "
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000784 "GLCaps doesn't know about.");
785 return false;
786}
787
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000788SkString GrGLCaps::dump() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000789
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000790 SkString r = INHERITED::dump();
bsalomon@google.combcce8922013-03-25 15:38:39 +0000791
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000792 r.appendf("--- GL-Specific ---\n");
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000793 for (int i = 0; i < fStencilFormats.count(); ++i) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000794 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000795 i,
796 fStencilFormats[i].fStencilBits,
797 fStencilFormats[i].fTotalBits);
798 }
799
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000800 static const char* kMSFBOExtStr[] = {
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000801 "None",
802 "ARB",
803 "EXT",
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000804 "ES 3.0",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000805 "Apple",
bsalomon@google.com347c3822013-05-01 20:10:01 +0000806 "IMG MS To Texture",
807 "EXT MS To Texture",
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000808 };
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000809 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
810 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
811 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000812 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType);
813 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType);
814 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType);
815 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000816 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000817
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000818 static const char* kInvalidateFBTypeStr[] = {
819 "None",
820 "Discard",
821 "Invalidate",
822 };
823 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
824 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
825 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
826 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000827
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000828 static const char* kMapBufferTypeStr[] = {
829 "None",
830 "MapBuffer",
831 "MapBufferRange",
832 "Chromium",
833 };
834 GR_STATIC_ASSERT(0 == kNone_MapBufferType);
835 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType);
836 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType);
837 GR_STATIC_ASSERT(3 == kChromium_MapBufferType);
838 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1);
839
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000840 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000841 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
joshualitt58162332014-08-01 06:44:53 -0700842 r.appendf("FB Fetch Support: %s\n", (fFBFetchSupport ? "YES" : "NO"));
commit-bot@chromium.org52ffbf62014-04-02 16:19:33 +0000843 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000844 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000845 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
846 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
commit-bot@chromium.org0a6fe712014-04-23 19:26:26 +0000847 if (!fIsCoreProfile) {
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000848 r.appendf("Max Fixed Function Texture Coords: %d\n", fMaxFixedFunctionTextureCoords);
commit-bot@chromium.org3628ad92013-08-30 19:43:47 +0000849 }
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000850 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
851 r.appendf("Support RGBA8 Render Buffer: %s\n", (fRGBA8RenderbufferSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000852 r.appendf("BGRA is an internal format: %s\n", (fBGRAIsInternalFormat ? "YES": "NO"));
853 r.appendf("Support texture swizzle: %s\n", (fTextureSwizzleSupport ? "YES": "NO"));
854 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
855 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
856 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
857 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO"));
bsalomon@google.combcce8922013-03-25 15:38:39 +0000858
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000859 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO"));
860 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO"));
861 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO"));
862 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO"));
863 r.appendf("Two Format Limit: %s\n", (fTwoFormatLimit ? "YES": "NO"));
864 r.appendf("Fragment coord conventions support: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000865 (fFragCoordsConventionSupport ? "YES": "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000866 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
867 r.appendf("Use non-VBO for dynamic data: %s\n",
bsalomon@google.combcce8922013-03-25 15:38:39 +0000868 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000869 r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO"));
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000870 r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO"));
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +0000871 return r;
bsalomon@google.comf7fa8062012-02-14 14:09:57 +0000872}