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 "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 
     22 class GrGLContextInfo;
     23 class 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  */
     30 class GrGLCaps : public GrCaps {
     31 public:
     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 
    364 private:
    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