Home | History | Annotate | Download | only in gl
      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 
     22 class GrGLContextInfo;
     23 class GrGLSLCaps;
     24 class 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  */
     31 class GrGLCaps : public GrCaps {
     32 public:
     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 
    353 private:
    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