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