1
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10 #include "GrGLCaps.h"
11 #include "GrGLContextInfo.h"
12
GrGLCaps()13 GrGLCaps::GrGLCaps() {
14 this->reset();
15 }
16
reset()17 void GrGLCaps::reset() {
18 fVerifiedColorConfigs.reset();
19 fStencilFormats.reset();
20 fStencilVerifiedColorConfigs.reset();
21 fMSFBOType = kNone_MSFBOType;
22 fMaxFragmentUniformVectors = 0;
23 fRGBA8RenderbufferSupport = false;
24 fBGRAFormatSupport = false;
25 fBGRAIsInternalFormat = false;
26 fTextureSwizzleSupport = false;
27 fUnpackRowLengthSupport = false;
28 fUnpackFlipYSupport = false;
29 fPackRowLengthSupport = false;
30 fPackFlipYSupport = false;
31 fTextureUsageSupport = false;
32 fTexStorageSupport = false;
33 }
34
GrGLCaps(const GrGLCaps & caps)35 GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
36 *this = caps;
37 }
38
operator =(const GrGLCaps & caps)39 GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
40 fVerifiedColorConfigs = caps.fVerifiedColorConfigs;
41 fStencilFormats = caps.fStencilFormats;
42 fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
43 fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
44 fMSFBOType = caps.fMSFBOType;
45 fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
46 fBGRAFormatSupport = caps.fBGRAFormatSupport;
47 fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
48 fTextureSwizzleSupport = caps.fTextureSwizzleSupport;
49 fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport;
50 fUnpackFlipYSupport = caps.fUnpackFlipYSupport;
51 fPackRowLengthSupport = caps.fPackRowLengthSupport;
52 fPackFlipYSupport = caps.fPackFlipYSupport;
53 fTextureUsageSupport = caps.fTextureUsageSupport;
54 fTexStorageSupport = caps.fTexStorageSupport;
55
56 return *this;
57 }
58
init(const GrGLContextInfo & ctxInfo)59 void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
60
61 this->reset();
62 if (!ctxInfo.isInitialized()) {
63 return;
64 }
65
66 const GrGLInterface* gli = ctxInfo.interface();
67 GrGLBinding binding = ctxInfo.binding();
68 GrGLVersion version = ctxInfo.version();
69
70 if (kES2_GrGLBinding == binding) {
71 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
72 &fMaxFragmentUniformVectors);
73 } else {
74 GrAssert(kDesktop_GrGLBinding == binding);
75 GrGLint max;
76 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
77 fMaxFragmentUniformVectors = max / 4;
78 }
79
80 if (kDesktop_GrGLBinding == binding) {
81 fRGBA8RenderbufferSupport = true;
82 } else {
83 fRGBA8RenderbufferSupport = ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
84 ctxInfo.hasExtension("GL_ARM_rgba8");
85 }
86
87 if (kDesktop_GrGLBinding == binding) {
88 fBGRAFormatSupport = version >= GR_GL_VER(1,2) ||
89 ctxInfo.hasExtension("GL_EXT_bgra");
90 } else {
91 bool hasBGRAExt = false;
92 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
93 fBGRAFormatSupport = true;
94 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
95 fBGRAFormatSupport = true;
96 fBGRAIsInternalFormat = true;
97 }
98 GrAssert(fBGRAFormatSupport ||
99 kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig);
100 }
101
102 if (kDesktop_GrGLBinding == binding) {
103 fTextureSwizzleSupport = version >= GR_GL_VER(3,3) ||
104 ctxInfo.hasExtension("GL_ARB_texture_swizzle");
105 } else {
106 fTextureSwizzleSupport = false;
107 }
108
109 if (kDesktop_GrGLBinding == binding) {
110 fUnpackRowLengthSupport = true;
111 fUnpackFlipYSupport = false;
112 fPackRowLengthSupport = true;
113 fPackFlipYSupport = false;
114 } else {
115 fUnpackRowLengthSupport =ctxInfo.hasExtension("GL_EXT_unpack_subimage");
116 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
117 // no extension for pack row length
118 fPackRowLengthSupport = false;
119 fPackFlipYSupport =
120 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
121 }
122
123 fTextureUsageSupport = (kES2_GrGLBinding == binding) &&
124 ctxInfo.hasExtension("GL_ANGLE_texture_usage");
125
126 // Tex storage is in desktop 4.2 and can be an extension to desktop or ES.
127 fTexStorageSupport = (kDesktop_GrGLBinding == binding &&
128 version >= GR_GL_VER(4,2)) ||
129 ctxInfo.hasExtension("GL_ARB_texture_storage") ||
130 ctxInfo.hasExtension("GL_EXT_texture_storage");
131
132 this->initFSAASupport(ctxInfo);
133 this->initStencilFormats(ctxInfo);
134 }
135
initFSAASupport(const GrGLContextInfo & ctxInfo)136 void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) {
137
138 fMSFBOType = kNone_MSFBOType;
139 if (kDesktop_GrGLBinding != ctxInfo.binding()) {
140 if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
141 // chrome's extension is equivalent to the EXT msaa
142 // and fbo_blit extensions.
143 fMSFBOType = kDesktopEXT_MSFBOType;
144 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
145 fMSFBOType = kAppleES_MSFBOType;
146 }
147 } else {
148 if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
149 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
150 fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType;
151 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
152 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
153 fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
154 }
155 }
156 }
157
158 namespace {
159 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
160 }
161
initStencilFormats(const GrGLContextInfo & ctxInfo)162 void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
163
164 // Build up list of legal stencil formats (though perhaps not supported on
165 // the particular gpu/driver) from most preferred to least.
166
167 // these consts are in order of most preferred to least preferred
168 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
169
170 static const StencilFormat
171 // internal Format stencil bits total bits packed?
172 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false},
173 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false},
174 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true },
175 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false},
176 gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false},
177 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true };
178
179 if (kDesktop_GrGLBinding == ctxInfo.binding()) {
180 bool supportsPackedDS =
181 ctxInfo.version() >= GR_GL_VER(3,0) ||
182 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
183 ctxInfo.hasExtension("GL_ARB_framebuffer_object");
184
185 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
186 // require FBO support we can expect these are legal formats and don't
187 // check. These also all support the unsized GL_STENCIL_INDEX.
188 fStencilFormats.push_back() = gS8;
189 fStencilFormats.push_back() = gS16;
190 if (supportsPackedDS) {
191 fStencilFormats.push_back() = gD24S8;
192 }
193 fStencilFormats.push_back() = gS4;
194 if (supportsPackedDS) {
195 fStencilFormats.push_back() = gDS;
196 }
197 } else {
198 // ES2 has STENCIL_INDEX8 without extensions but requires extensions
199 // for other formats.
200 // ES doesn't support using the unsized format.
201
202 fStencilFormats.push_back() = gS8;
203 //fStencilFormats.push_back() = gS16;
204 if (ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
205 fStencilFormats.push_back() = gD24S8;
206 }
207 if (ctxInfo.hasExtension("GL_OES_stencil4")) {
208 fStencilFormats.push_back() = gS4;
209 }
210 }
211 GrAssert(0 == fStencilVerifiedColorConfigs.count());
212 fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count());
213 }
214
markColorConfigAndStencilFormatAsVerified(GrPixelConfig config,const GrGLStencilBuffer::Format & format)215 void GrGLCaps::markColorConfigAndStencilFormatAsVerified(
216 GrPixelConfig config,
217 const GrGLStencilBuffer::Format& format) {
218 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
219 return;
220 #endif
221 GrAssert((unsigned)config < kGrPixelConfigCount);
222 GrAssert(fStencilFormats.count() == fStencilVerifiedColorConfigs.count());
223 int count = fStencilFormats.count();
224 // we expect a really small number of possible formats so linear search
225 // should be OK
226 GrAssert(count < 16);
227 for (int i = 0; i < count; ++i) {
228 if (format.fInternalFormat ==
229 fStencilFormats[i].fInternalFormat) {
230 fStencilVerifiedColorConfigs[i].markVerified(config);
231 return;
232 }
233 }
234 GrCrash("Why are we seeing a stencil format that "
235 "GrGLCaps doesn't know about.");
236 }
237
isColorConfigAndStencilFormatVerified(GrPixelConfig config,const GrGLStencilBuffer::Format & format) const238 bool GrGLCaps::isColorConfigAndStencilFormatVerified(
239 GrPixelConfig config,
240 const GrGLStencilBuffer::Format& format) const {
241 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
242 return false;
243 #endif
244 GrAssert((unsigned)config < kGrPixelConfigCount);
245 int count = fStencilFormats.count();
246 // we expect a really small number of possible formats so linear search
247 // should be OK
248 GrAssert(count < 16);
249 for (int i = 0; i < count; ++i) {
250 if (format.fInternalFormat ==
251 fStencilFormats[i].fInternalFormat) {
252 return fStencilVerifiedColorConfigs[i].isVerified(config);
253 }
254 }
255 GrCrash("Why are we seeing a stencil format that "
256 "GLCaps doesn't know about.");
257 return false;
258 }
259
print() const260 void GrGLCaps::print() const {
261 for (int i = 0; i < fStencilFormats.count(); ++i) {
262 GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
263 i,
264 fStencilFormats[i].fStencilBits,
265 fStencilFormats[i].fTotalBits);
266 }
267
268 GR_STATIC_ASSERT(0 == kNone_MSFBOType);
269 GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
270 GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
271 GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
272 static const char* gMSFBOExtStr[] = {
273 "None",
274 "ARB",
275 "EXT",
276 "Apple",
277 };
278 GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
279 GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
280 GrPrintf("Support RGBA8 Render Buffer: %s\n",
281 (fRGBA8RenderbufferSupport ? "YES": "NO"));
282 GrPrintf("BGRA is an internal format: %s\n",
283 (fBGRAIsInternalFormat ? "YES": "NO"));
284 GrPrintf("Support texture swizzle: %s\n",
285 (fTextureSwizzleSupport ? "YES": "NO"));
286 GrPrintf("Unpack Row length support: %s\n",
287 (fUnpackRowLengthSupport ? "YES": "NO"));
288 GrPrintf("Unpack Flip Y support: %s\n",
289 (fUnpackFlipYSupport ? "YES": "NO"));
290 GrPrintf("Pack Row length support: %s\n",
291 (fPackRowLengthSupport ? "YES": "NO"));
292 GrPrintf("Pack Flip Y support: %s\n",
293 (fPackFlipYSupport ? "YES": "NO"));
294 }
295
296