1/*
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#ifndef GrGLCaps_DEFINED
10#define GrGLCaps_DEFINED
11
12#include "GrDrawTargetCaps.h"
13#include "GrGLStencilBuffer.h"
14#include "SkTArray.h"
15#include "SkTDArray.h"
16
17class GrGLContextInfo;
18
19/**
20 * Stores some capabilities of a GL context. Most are determined by the GL
21 * version and the extensions string. It also tracks formats that have passed
22 * the FBO completeness test.
23 */
24class GrGLCaps : public GrDrawTargetCaps {
25public:
26    SK_DECLARE_INST_COUNT(GrGLCaps)
27
28    typedef GrGLStencilBuffer::Format StencilFormat;
29
30    /**
31     * The type of MSAA for FBOs supported. Different extensions have different
32     * semantics of how / when a resolve is performed.
33     */
34    enum MSFBOType {
35        /**
36         * no support for MSAA FBOs
37         */
38        kNone_MSFBOType = 0,
39        /**
40         * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object).
41         */
42        kDesktop_ARB_MSFBOType,
43        /**
44         * earlier GL_EXT_framebuffer* extensions
45         */
46        kDesktop_EXT_MSFBOType,
47        /**
48         * Similar to kDesktop_ARB but with additional restrictions on glBlitFramebuffer.
49         */
50        kES_3_0_MSFBOType,
51        /**
52         * GL_APPLE_framebuffer_multisample ES extension
53         */
54        kES_Apple_MSFBOType,
55        /**
56         * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
57         * Instead the texture is multisampled when bound to the FBO and then resolved automatically
58         * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
59         * GR_GL_MAX_SAMPLES_IMG).
60         */
61        kES_IMG_MsToTexture_MSFBOType,
62        /**
63         * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
64         * GL_MAX_SAMPLES value.
65         */
66        kES_EXT_MsToTexture_MSFBOType,
67
68        kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType
69    };
70
71    enum FBFetchType {
72        kNone_FBFetchType,
73        /** GL_EXT_shader_framebuffer_fetch */
74        kEXT_FBFetchType,
75        /** GL_NV_shader_framebuffer_fetch */
76        kNV_FBFetchType,
77
78        kLast_FBFetchType = kNV_FBFetchType
79    };
80
81    enum InvalidateFBType {
82        kNone_InvalidateFBType,
83        kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
84        kInvalidate_InvalidateFBType,     //<! glInvalidateFramebuffer()
85
86        kLast_InvalidateFBType = kInvalidate_InvalidateFBType
87    };
88
89    enum MapBufferType {
90        kNone_MapBufferType,
91        kMapBuffer_MapBufferType,         // glMapBuffer()
92        kMapBufferRange_MapBufferType,    // glMapBufferRange()
93        kChromium_MapBufferType,          // GL_CHROMIUM_map_sub
94
95        kLast_MapBufferType = kChromium_MapBufferType,
96    };
97
98    /**
99     * Creates a GrGLCaps that advertises no support for any extensions,
100     * formats, etc. Call init to initialize from a GrGLContextInfo.
101     */
102    GrGLCaps();
103
104    GrGLCaps(const GrGLCaps& caps);
105
106    GrGLCaps& operator = (const GrGLCaps& caps);
107
108    /**
109     * Resets the caps such that nothing is supported.
110     */
111    virtual void reset() SK_OVERRIDE;
112
113    /**
114     * Initializes the GrGLCaps to the set of features supported in the current
115     * OpenGL context accessible via ctxInfo.
116     */
117    bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* interface);
118
119    /**
120     * Call to note that a color config has been verified as a valid color
121     * attachment. This may save future calls to glCheckFramebufferStatus
122     * using isConfigVerifiedColorAttachment().
123     */
124    void markConfigAsValidColorAttachment(GrPixelConfig config) {
125        fVerifiedColorConfigs.markVerified(config);
126    }
127
128    /**
129     * Call to check whether a config has been verified as a valid color
130     * attachment.
131     */
132    bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
133        return fVerifiedColorConfigs.isVerified(config);
134    }
135
136    /**
137     * Call to note that a color config / stencil format pair passed
138     * FBO status check. We may skip calling glCheckFramebufferStatus for
139     * this combination in the future using
140     * isColorConfigAndStencilFormatVerified().
141     */
142    void markColorConfigAndStencilFormatAsVerified(
143                    GrPixelConfig config,
144                    const GrGLStencilBuffer::Format& format);
145
146    /**
147     * Call to check whether color config / stencil format pair has already
148     * passed FBO status check.
149     */
150    bool isColorConfigAndStencilFormatVerified(
151                    GrPixelConfig config,
152                    const GrGLStencilBuffer::Format& format) const;
153
154    /**
155     * Reports the type of MSAA FBO support.
156     */
157    MSFBOType msFBOType() const { return fMSFBOType; }
158
159    /**
160     * Does the supported MSAA FBO extension have MSAA renderbuffers?
161     */
162    bool usesMSAARenderBuffers() const {
163        return kNone_MSFBOType != fMSFBOType &&
164               kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
165               kES_EXT_MsToTexture_MSFBOType != fMSFBOType;
166    }
167
168    /**
169     * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
170     * then implicitly resolved when read.
171     */
172    bool usesImplicitMSAAResolve() const {
173        return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
174               kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
175    }
176
177    FBFetchType fbFetchType() const { return fFBFetchType; }
178
179    InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
180
181    /// What type of buffer mapping is supported?
182    MapBufferType mapBufferType() const { return fMapBufferType; }
183
184    /**
185     * Gets an array of legal stencil formats. These formats are not guaranteed
186     * to be supported by the driver but are legal GLenum names given the GL
187     * version and extensions supported.
188     */
189    const SkTArray<StencilFormat, true>& stencilFormats() const {
190        return fStencilFormats;
191    }
192
193    /// The maximum number of fragment uniform vectors (GLES has min. 16).
194    int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
195
196    /// maximum number of attribute values per vertex
197    int maxVertexAttributes() const { return fMaxVertexAttributes; }
198
199    /// maximum number of texture units accessible in the fragment shader.
200    int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; }
201
202    /// maximum number of fixed-function texture coords, or zero if no fixed-function.
203    int maxFixedFunctionTextureCoords() const { return fMaxFixedFunctionTextureCoords; }
204
205    /// ES requires an extension to support RGBA8 in RenderBufferStorage
206    bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; }
207
208    /**
209     * Depending on the ES extensions present the BGRA external format may
210     * correspond either a BGRA or RGBA internalFormat. On desktop GL it is
211     * RGBA.
212     */
213    bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; }
214
215    /// GL_ARB_texture_swizzle support
216    bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
217
218    /// Is there support for GL_UNPACK_ROW_LENGTH
219    bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
220
221    /// Is there support for GL_UNPACK_FLIP_Y
222    bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
223
224    /// Is there support for GL_PACK_ROW_LENGTH
225    bool packRowLengthSupport() const { return fPackRowLengthSupport; }
226
227    /// Is there support for GL_PACK_REVERSE_ROW_ORDER
228    bool packFlipYSupport() const { return fPackFlipYSupport; }
229
230    /// Is there support for texture parameter GL_TEXTURE_USAGE
231    bool textureUsageSupport() const { return fTextureUsageSupport; }
232
233    /// Is there support for glTexStorage
234    bool texStorageSupport() const { return fTexStorageSupport; }
235
236    /// Is there support for GL_RED and GL_R8
237    bool textureRedSupport() const { return fTextureRedSupport; }
238
239    /// Is GL_ARB_IMAGING supported
240    bool imagingSupport() const { return fImagingSupport; }
241
242    /// Is GL_ARB_fragment_coord_conventions supported?
243    bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; }
244
245    /// Is there support for Vertex Array Objects?
246    bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
247
248    /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
249    bool useNonVBOVertexAndIndexDynamicData() const {
250        return fUseNonVBOVertexAndIndexDynamicData;
251    }
252
253    /// Does ReadPixels support the provided format/type combo?
254    bool readPixelsSupported(const GrGLInterface* intf,
255                             GrGLenum format,
256                             GrGLenum type) const;
257
258    bool isCoreProfile() const { return fIsCoreProfile; }
259
260
261    bool fullClearIsFree() const { return fFullClearIsFree; }
262
263    bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
264
265    /**
266     * Returns a string containing the caps info.
267     */
268    virtual SkString dump() const SK_OVERRIDE;
269
270    /**
271     * LATC can appear under one of three possible names. In order to know
272     * which GL internal format to use, we need to keep track of which name
273     * we found LATC under. The default is LATC.
274     */
275    enum LATCAlias {
276        kLATC_LATCAlias,
277        kRGTC_LATCAlias,
278        k3DC_LATCAlias
279    };
280
281    LATCAlias latcAlias() const { return fLATCAlias; }
282
283private:
284    /**
285     * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
286     * performing glCheckFrameBufferStatus for the same config.
287     */
288    struct VerifiedColorConfigs {
289        VerifiedColorConfigs() {
290            this->reset();
291        }
292
293        void reset() {
294            for (int i = 0; i < kNumUints; ++i) {
295                fVerifiedColorConfigs[i] = 0;
296            }
297        }
298
299        static const int kNumUints = (kGrPixelConfigCnt  + 31) / 32;
300        uint32_t fVerifiedColorConfigs[kNumUints];
301
302        void markVerified(GrPixelConfig config) {
303#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
304                return;
305#endif
306            int u32Idx = config / 32;
307            int bitIdx = config % 32;
308            fVerifiedColorConfigs[u32Idx] |= 1 << bitIdx;
309        }
310
311        bool isVerified(GrPixelConfig config) const {
312#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
313            return false;
314#endif
315            int u32Idx = config / 32;
316            int bitIdx = config % 32;
317            return SkToBool(fVerifiedColorConfigs[u32Idx] & (1 << bitIdx));
318        }
319    };
320
321    void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
322    void initStencilFormats(const GrGLContextInfo&);
323    // This must be called after initFSAASupport().
324    void initConfigRenderableTable(const GrGLContextInfo&);
325    void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*);
326
327    // tracks configs that have been verified to pass the FBO completeness when
328    // used as a color attachment
329    VerifiedColorConfigs fVerifiedColorConfigs;
330
331    SkTArray<StencilFormat, true> fStencilFormats;
332    // tracks configs that have been verified to pass the FBO completeness when
333    // used as a color attachment when a particular stencil format is used
334    // as a stencil attachment.
335    SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs;
336
337    int fMaxFragmentUniformVectors;
338    int fMaxVertexAttributes;
339    int fMaxFragmentTextureUnits;
340    int fMaxFixedFunctionTextureCoords;
341
342    MSFBOType           fMSFBOType;
343    FBFetchType         fFBFetchType;
344    InvalidateFBType    fInvalidateFBType;
345    MapBufferType       fMapBufferType;
346    LATCAlias           fLATCAlias;
347
348    bool fRGBA8RenderbufferSupport : 1;
349    bool fBGRAIsInternalFormat : 1;
350    bool fTextureSwizzleSupport : 1;
351    bool fUnpackRowLengthSupport : 1;
352    bool fUnpackFlipYSupport : 1;
353    bool fPackRowLengthSupport : 1;
354    bool fPackFlipYSupport : 1;
355    bool fTextureUsageSupport : 1;
356    bool fTexStorageSupport : 1;
357    bool fTextureRedSupport : 1;
358    bool fImagingSupport  : 1;
359    bool fTwoFormatLimit : 1;
360    bool fFragCoordsConventionSupport : 1;
361    bool fVertexArrayObjectSupport : 1;
362    bool fUseNonVBOVertexAndIndexDynamicData : 1;
363    bool fIsCoreProfile : 1;
364    bool fFullClearIsFree : 1;
365    bool fDropsTileOnZeroDivide : 1;
366
367    typedef GrDrawTargetCaps INHERITED;
368};
369
370#endif
371