• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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