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 <functional>
13
14#include "GrCaps.h"
15#include "GrGLStencilAttachment.h"
16#include "GrSwizzle.h"
17#include "SkChecksum.h"
18#include "SkTHash.h"
19#include "SkTArray.h"
20#include "../private/GrGLSL.h"
21
22class GrGLContextInfo;
23class GrGLRenderTarget;
24
25/**
26 * Stores some capabilities of a GL context. Most are determined by the GL
27 * version and the extensions string. It also tracks formats that have passed
28 * the FBO completeness test.
29 */
30class GrGLCaps : public GrCaps {
31public:
32    typedef GrGLStencilAttachment::Format StencilFormat;
33
34    /**
35     * The type of MSAA for FBOs supported. Different extensions have different
36     * semantics of how / when a resolve is performed.
37     */
38    enum MSFBOType {
39        /**
40         * no support for MSAA FBOs
41         */
42        kNone_MSFBOType = 0,
43        /**
44         * OpenGL < 3.0 with GL_EXT_framebuffer_object. Doesn't allow rendering to ALPHA.
45         */
46        kEXT_MSFBOType,
47        /**
48         * OpenGL 3.0+, OpenGL ES 3.0+, and GL_ARB_framebuffer_object.
49         */
50        kStandard_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         * GL_NV_framebuffer_mixed_samples.
69         */
70        kMixedSamples_MSFBOType,
71
72        kLast_MSFBOType = kMixedSamples_MSFBOType
73    };
74
75    enum BlitFramebufferFlags {
76        kNoSupport_BlitFramebufferFlag                    = 1 << 0,
77        kNoScalingOrMirroring_BlitFramebufferFlag         = 1 << 1,
78        kResolveMustBeFull_BlitFrambufferFlag             = 1 << 2,
79        kNoMSAADst_BlitFramebufferFlag                    = 1 << 3,
80        kNoFormatConversion_BlitFramebufferFlag           = 1 << 4,
81        kNoFormatConversionForMSAASrc_BlitFramebufferFlag = 1 << 5,
82        kRectsMustMatchForMSAASrc_BlitFramebufferFlag     = 1 << 6,
83    };
84
85    enum InvalidateFBType {
86        kNone_InvalidateFBType,
87        kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
88        kInvalidate_InvalidateFBType,    //<! glInvalidateFramebuffer()
89
90        kLast_InvalidateFBType = kInvalidate_InvalidateFBType
91    };
92
93    enum MapBufferType {
94        kNone_MapBufferType,
95        kMapBuffer_MapBufferType,         // glMapBuffer()
96        kMapBufferRange_MapBufferType,    // glMapBufferRange()
97        kChromium_MapBufferType,          // GL_CHROMIUM_map_sub
98
99        kLast_MapBufferType = kChromium_MapBufferType,
100    };
101
102    enum TransferBufferType {
103        kNone_TransferBufferType,
104        kPBO_TransferBufferType,          // ARB_pixel_buffer_object
105        kChromium_TransferBufferType,     // CHROMIUM_pixel_transfer_buffer_object
106
107        kLast_TransferBufferType = kChromium_TransferBufferType,
108    };
109
110    /**
111     * Initializes the GrGLCaps to the set of features supported in the current
112     * OpenGL context accessible via ctxInfo.
113     */
114    GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
115             const GrGLInterface* glInterface);
116
117    bool isConfigTexturable(GrPixelConfig config) const override {
118        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
119    }
120
121    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
122        if (withMSAA) {
123            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
124        } else {
125            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
126        }
127    }
128    bool canConfigBeImageStorage(GrPixelConfig config) const override {
129        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseAsImageStorage_Flag);
130    }
131    bool canConfigBeFBOColorAttachment(GrPixelConfig config) const {
132        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kFBOColorAttachment_Flag);
133    }
134
135    bool isConfigTexSupportEnabled(GrPixelConfig config) const {
136        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag);
137    }
138
139    bool canUseConfigWithTexelBuffer(GrPixelConfig config) const {
140        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseWithTexelBuffer_Flag);
141    }
142
143    /** Returns the mapping between GrPixelConfig components and GL internal format components. */
144    const GrSwizzle& configSwizzle(GrPixelConfig config) const {
145        return fConfigTable[config].fSwizzle;
146    }
147
148    GrGLenum configSizedInternalFormat(GrPixelConfig config) const {
149        return fConfigTable[config].fFormats.fSizedInternalFormat;
150    }
151
152    bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
153                            GrGLenum* internalFormat, GrGLenum* externalFormat,
154                            GrGLenum* externalType) const;
155
156    bool getCompressedTexImageFormats(GrPixelConfig surfaceConfig, GrGLenum* internalFormat) const;
157
158    bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
159                             GrGLenum* externalFormat, GrGLenum* externalType) const;
160
161    bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
162
163    /** The format to use read/write a texture as an image in a shader */
164    GrGLenum getImageFormat(GrPixelConfig config) const {
165        return fConfigTable[config].fFormats.fSizedInternalFormat;
166    }
167
168    /**
169    * Gets an array of legal stencil formats. These formats are not guaranteed
170    * to be supported by the driver but are legal GLenum names given the GL
171    * version and extensions supported.
172    */
173    const SkTArray<StencilFormat, true>& stencilFormats() const {
174        return fStencilFormats;
175    }
176
177    /**
178     * Has a stencil format index been found for the config (or we've found that no format works).
179     */
180    bool hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config) const {
181        return fConfigTable[config].fStencilFormatIndex != ConfigInfo::kUnknown_StencilIndex;
182    }
183
184    /**
185     * Gets the stencil format index for the config. This assumes
186     * hasStencilFormatBeenDeterminedForConfig has already been checked. Returns a value < 0 if
187     * no stencil format is supported with the config. Otherwise, returned index refers to the array
188     * returned by stencilFormats().
189     */
190    int getStencilFormatIndexForConfig(GrPixelConfig config) const {
191        SkASSERT(this->hasStencilFormatBeenDeterminedForConfig(config));
192        return fConfigTable[config].fStencilFormatIndex;
193    }
194
195    /**
196     * If index is >= 0 this records an index into stencilFormats() as the best stencil format for
197     * the config. If < 0 it records that the config has no supported stencil format index.
198     */
199    void setStencilFormatIndexForConfig(GrPixelConfig config, int index) {
200        SkASSERT(!this->hasStencilFormatBeenDeterminedForConfig(config));
201        if (index < 0) {
202            fConfigTable[config].fStencilFormatIndex = ConfigInfo::kUnsupported_StencilFormatIndex;
203        } else {
204            fConfigTable[config].fStencilFormatIndex = index;
205        }
206    }
207
208    /**
209     * Call to note that a color config has been verified as a valid color
210     * attachment. This may save future calls to glCheckFramebufferStatus
211     * using isConfigVerifiedColorAttachment().
212     */
213    void markConfigAsValidColorAttachment(GrPixelConfig config) {
214        fConfigTable[config].fFlags |= ConfigInfo::kVerifiedColorAttachment_Flag;
215    }
216
217    /**
218     * Call to check whether a config has been verified as a valid color
219     * attachment.
220     */
221    bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
222        return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kVerifiedColorAttachment_Flag);
223    }
224
225    /**
226     * Reports the type of MSAA FBO support.
227     */
228    MSFBOType msFBOType() const { return fMSFBOType; }
229
230    /**
231     * Does the preferred MSAA FBO extension have MSAA renderbuffers?
232     */
233    bool usesMSAARenderBuffers() const {
234        return kNone_MSFBOType != fMSFBOType &&
235               kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
236               kES_EXT_MsToTexture_MSFBOType != fMSFBOType &&
237               kMixedSamples_MSFBOType != fMSFBOType;
238    }
239
240    /**
241     * What functionality is supported by glBlitFramebuffer.
242     */
243    uint32_t blitFramebufferSupportFlags() const { return fBlitFramebufferFlags; }
244
245    /**
246     * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
247     * then implicitly resolved when read.
248     */
249    bool usesImplicitMSAAResolve() const {
250        return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
251               kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
252    }
253
254    InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
255
256    /// What type of buffer mapping is supported?
257    MapBufferType mapBufferType() const { return fMapBufferType; }
258
259    /// What type of transfer buffer is supported?
260    TransferBufferType transferBufferType() const { return fTransferBufferType; }
261
262    /// The maximum number of fragment uniform vectors (GLES has min. 16).
263    int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
264
265    /**
266     * Depending on the ES extensions present the BGRA external format may
267     * correspond to either a BGRA or RGBA internalFormat. On desktop GL it is
268     * RGBA.
269     */
270    bool bgraIsInternalFormat() const;
271
272    /// Is there support for GL_UNPACK_ROW_LENGTH
273    bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
274
275    /// Is there support for GL_UNPACK_FLIP_Y
276    bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
277
278    /// Is there support for GL_PACK_ROW_LENGTH
279    bool packRowLengthSupport() const { return fPackRowLengthSupport; }
280
281    /// Is there support for GL_PACK_REVERSE_ROW_ORDER
282    bool packFlipYSupport() const { return fPackFlipYSupport; }
283
284    /// Is there support for texture parameter GL_TEXTURE_USAGE
285    bool textureUsageSupport() const { return fTextureUsageSupport; }
286
287    /// Is there support for GL_RED and GL_R8
288    bool textureRedSupport() const { return fTextureRedSupport; }
289
290    /// Is GL_ARB_IMAGING supported
291    bool imagingSupport() const { return fImagingSupport; }
292
293    /// Is there support for Vertex Array Objects?
294    bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
295
296    /// Is there support for GL_EXT_direct_state_access?
297    bool directStateAccessSupport() const { return fDirectStateAccessSupport; }
298
299    /// Is there support for GL_KHR_debug?
300    bool debugSupport() const { return fDebugSupport; }
301
302    /// Is there support for ES2 compatability?
303    bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
304
305    /// Is there support for glDraw*Instanced?
306    bool drawInstancedSupport() const { return fDrawInstancedSupport; }
307
308    /// Is there support for glDraw*Indirect? Note that the baseInstance fields of indirect draw
309    /// commands cannot be used unless we have base instance support.
310    bool drawIndirectSupport() const { return fDrawIndirectSupport; }
311
312    /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect
313    /// draw commands cannot be used unless we have base instance support.
314    bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
315
316    /// Is there support for glDrawRangeElements?
317    bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
318
319    /// Are the baseInstance fields supported in indirect draw commands?
320    bool baseInstanceSupport() const { return fBaseInstanceSupport; }
321
322    /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
323    bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
324
325    /// Does ReadPixels support reading readConfig pixels from a FBO that is surfaceConfig?
326    bool readPixelsSupported(GrPixelConfig surfaceConfig,
327                             GrPixelConfig readConfig,
328                             std::function<void (GrGLenum, GrGLint*)> getIntegerv,
329                             std::function<bool ()> bindRenderTarget,
330                             std::function<void ()> unbindRenderTarget) const;
331
332    bool isCoreProfile() const { return fIsCoreProfile; }
333
334    bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; }
335
336    bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; }
337
338    /// Are textures with GL_TEXTURE_RECTANGLE type supported.
339    bool rectangleTextureSupport() const { return fRectangleTextureSupport; }
340
341    /// GL_ARB_texture_swizzle
342    bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
343
344    bool mipMapLevelAndLodControlSupport() const { return fMipMapLevelAndLodControlSupport; }
345
346    bool doManualMipmapping() const { return fDoManualMipmapping; }
347
348    bool srgbDecodeDisableSupport() const { return fSRGBDecodeDisableSupport; }
349    bool srgbDecodeDisableAffectsMipmaps() const { return fSRGBDecodeDisableAffectsMipmaps; }
350
351    /**
352     * Returns a string containing the caps info.
353     */
354    SkString dump() const override;
355
356    bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; }
357    bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; }
358    bool rgbaToBgraReadbackConversionsAreSlow() const {
359        return fRGBAToBGRAReadbackConversionsAreSlow;
360    }
361
362    bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override;
363
364private:
365    enum ExternalFormatUsage {
366        kTexImage_ExternalFormatUsage,
367        kOther_ExternalFormatUsage,
368
369        kLast_ExternalFormatUsage = kOther_ExternalFormatUsage
370    };
371    static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1;
372    bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
373                           ExternalFormatUsage usage, GrGLenum* externalFormat,
374                           GrGLenum* externalType) const;
375
376    void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
377    void initGLSL(const GrGLContextInfo&);
378    bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*);
379
380    void onApplyOptionsOverrides(const GrContextOptions& options) override;
381
382    void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
383    void initBlendEqationSupport(const GrGLContextInfo&);
384    void initStencilFormats(const GrGLContextInfo&);
385    // This must be called after initFSAASupport().
386    void initConfigTable(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*,
387                         GrShaderCaps*);
388
389    void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*, GrShaderCaps*);
390
391    GrGLStandard fStandard;
392
393    SkTArray<StencilFormat, true> fStencilFormats;
394
395    int fMaxFragmentUniformVectors;
396
397    MSFBOType           fMSFBOType;
398    InvalidateFBType    fInvalidateFBType;
399    MapBufferType       fMapBufferType;
400    TransferBufferType  fTransferBufferType;
401
402    bool fUnpackRowLengthSupport : 1;
403    bool fUnpackFlipYSupport : 1;
404    bool fPackRowLengthSupport : 1;
405    bool fPackFlipYSupport : 1;
406    bool fTextureUsageSupport : 1;
407    bool fTextureRedSupport : 1;
408    bool fImagingSupport  : 1;
409    bool fVertexArrayObjectSupport : 1;
410    bool fDirectStateAccessSupport : 1;
411    bool fDebugSupport : 1;
412    bool fES2CompatibilitySupport : 1;
413    bool fDrawInstancedSupport : 1;
414    bool fDrawIndirectSupport : 1;
415    bool fDrawRangeElementsSupport : 1;
416    bool fMultiDrawIndirectSupport : 1;
417    bool fBaseInstanceSupport : 1;
418    bool fUseNonVBOVertexAndIndexDynamicData : 1;
419    bool fIsCoreProfile : 1;
420    bool fBindFragDataLocationSupport : 1;
421    bool fRGBA8888PixelsOpsAreSlow : 1;
422    bool fPartialFBOReadIsSlow : 1;
423    bool fBindUniformLocationSupport : 1;
424    bool fRectangleTextureSupport : 1;
425    bool fTextureSwizzleSupport : 1;
426    bool fMipMapLevelAndLodControlSupport : 1;
427    bool fRGBAToBGRAReadbackConversionsAreSlow : 1;
428    bool fDoManualMipmapping : 1;
429    bool fSRGBDecodeDisableSupport : 1;
430    bool fSRGBDecodeDisableAffectsMipmaps : 1;
431
432    uint32_t fBlitFramebufferFlags;
433
434    /** Number type of the components (with out considering number of bits.) */
435    enum FormatType {
436        kNormalizedFixedPoint_FormatType,
437        kFloat_FormatType,
438        kInteger_FormatType,
439    };
440
441    struct ReadPixelsFormat {
442        ReadPixelsFormat() : fFormat(0), fType(0) {}
443        GrGLenum fFormat;
444        GrGLenum fType;
445    };
446
447    struct ConfigFormats {
448        ConfigFormats() {
449            // Inits to known bad GL enum values.
450            memset(this, 0xAB, sizeof(ConfigFormats));
451        }
452        GrGLenum fBaseInternalFormat;
453        GrGLenum fSizedInternalFormat;
454
455        /** The external format and type are to be used when uploading/downloading data using this
456            config where both the CPU data and GrSurface are the same config. To get the external
457            format and type when converting between configs while copying to/from memory use
458            getExternalFormat().
459            The kTexImage external format is usually the same as kOther except for kSRGBA on some
460            GL contexts. */
461        GrGLenum fExternalFormat[kExternalFormatUsageCnt];
462        GrGLenum fExternalType;
463
464        // Either the base or sized internal format depending on the GL and config.
465        GrGLenum fInternalFormatTexImage;
466        GrGLenum fInternalFormatRenderbuffer;
467    };
468
469    struct ConfigInfo {
470        ConfigInfo() : fStencilFormatIndex(kUnknown_StencilIndex), fFlags(0) {}
471
472        ConfigFormats fFormats;
473
474        FormatType fFormatType;
475
476        // On ES contexts there are restrictions on type type/format that may be used for
477        // ReadPixels. One is implicitly specified by the current FBO's format. The other is
478        // queryable. This stores the queried option (lazily).
479        ReadPixelsFormat fSecondReadPixelsFormat;
480
481        enum {
482            // This indicates that a stencil format has not yet been determined for the config.
483            kUnknown_StencilIndex = -1,
484            // This indicates that there is no supported stencil format for the config.
485            kUnsupported_StencilFormatIndex = -2
486        };
487
488        // Index fStencilFormats.
489        int      fStencilFormatIndex;
490
491        enum {
492            kVerifiedColorAttachment_Flag = 0x1,
493            kTextureable_Flag             = 0x2,
494            kRenderable_Flag              = 0x4,
495            kRenderableWithMSAA_Flag      = 0x8,
496            /** kFBOColorAttachment means that even if the config cannot be a GrRenderTarget, we can
497                still attach it to a FBO for blitting or reading pixels. */
498            kFBOColorAttachment_Flag      = 0x10,
499            kCanUseTexStorage_Flag        = 0x20,
500            kCanUseWithTexelBuffer_Flag   = 0x40,
501            kCanUseAsImageStorage_Flag    = 0x80,
502        };
503        uint32_t fFlags;
504
505        GrSwizzle fSwizzle;
506    };
507
508    ConfigInfo fConfigTable[kGrPixelConfigCnt];
509
510    typedef GrCaps INHERITED;
511};
512
513#endif
514