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 "GrDrawTargetCaps.h"
     13 #include "GrGLStencilAttachment.h"
     14 #include "SkChecksum.h"
     15 #include "SkTHash.h"
     16 #include "SkTArray.h"
     17 
     18 class GrGLContextInfo;
     19 class GrGLSLCaps;
     20 
     21 /**
     22  * Stores some capabilities of a GL context. Most are determined by the GL
     23  * version and the extensions string. It also tracks formats that have passed
     24  * the FBO completeness test.
     25  */
     26 class GrGLCaps : public GrDrawTargetCaps {
     27 public:
     28     SK_DECLARE_INST_COUNT(GrGLCaps)
     29 
     30     typedef GrGLStencilAttachment::Format StencilFormat;
     31 
     32     /**
     33      * The type of MSAA for FBOs supported. Different extensions have different
     34      * semantics of how / when a resolve is performed.
     35      */
     36     enum MSFBOType {
     37         /**
     38          * no support for MSAA FBOs
     39          */
     40         kNone_MSFBOType = 0,
     41         /**
     42          * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object).
     43          */
     44         kDesktop_ARB_MSFBOType,
     45         /**
     46          * earlier GL_EXT_framebuffer* extensions
     47          */
     48         kDesktop_EXT_MSFBOType,
     49         /**
     50          * Similar to kDesktop_ARB but with additional restrictions on glBlitFramebuffer.
     51          */
     52         kES_3_0_MSFBOType,
     53         /**
     54          * GL_APPLE_framebuffer_multisample ES extension
     55          */
     56         kES_Apple_MSFBOType,
     57         /**
     58          * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
     59          * Instead the texture is multisampled when bound to the FBO and then resolved automatically
     60          * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
     61          * GR_GL_MAX_SAMPLES_IMG).
     62          */
     63         kES_IMG_MsToTexture_MSFBOType,
     64         /**
     65          * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
     66          * GL_MAX_SAMPLES value.
     67          */
     68         kES_EXT_MsToTexture_MSFBOType,
     69 
     70         kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType
     71     };
     72 
     73     enum InvalidateFBType {
     74         kNone_InvalidateFBType,
     75         kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
     76         kInvalidate_InvalidateFBType,     //<! glInvalidateFramebuffer()
     77 
     78         kLast_InvalidateFBType = kInvalidate_InvalidateFBType
     79     };
     80 
     81     enum MapBufferType {
     82         kNone_MapBufferType,
     83         kMapBuffer_MapBufferType,         // glMapBuffer()
     84         kMapBufferRange_MapBufferType,    // glMapBufferRange()
     85         kChromium_MapBufferType,          // GL_CHROMIUM_map_sub
     86 
     87         kLast_MapBufferType = kChromium_MapBufferType,
     88     };
     89 
     90     /**
     91      * Creates a GrGLCaps that advertises no support for any extensions,
     92      * formats, etc. Call init to initialize from a GrGLContextInfo.
     93      */
     94     GrGLCaps();
     95 
     96     GrGLCaps(const GrGLCaps& caps);
     97 
     98     GrGLCaps& operator = (const GrGLCaps& caps);
     99 
    100     /**
    101      * Resets the caps such that nothing is supported.
    102      */
    103     void reset() override;
    104 
    105     /**
    106      * Initializes the GrGLCaps to the set of features supported in the current
    107      * OpenGL context accessible via ctxInfo.
    108      */
    109     bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface);
    110 
    111     /**
    112      * Call to note that a color config has been verified as a valid color
    113      * attachment. This may save future calls to glCheckFramebufferStatus
    114      * using isConfigVerifiedColorAttachment().
    115      */
    116     void markConfigAsValidColorAttachment(GrPixelConfig config) {
    117         fVerifiedColorConfigs.markVerified(config);
    118     }
    119 
    120     /**
    121      * Call to check whether a config has been verified as a valid color
    122      * attachment.
    123      */
    124     bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
    125         return fVerifiedColorConfigs.isVerified(config);
    126     }
    127 
    128     /**
    129      * Call to note that a color config / stencil format pair passed
    130      * FBO status check. We may skip calling glCheckFramebufferStatus for
    131      * this combination in the future using
    132      * isColorConfigAndStencilFormatVerified().
    133      */
    134     void markColorConfigAndStencilFormatAsVerified(
    135                     GrPixelConfig config,
    136                     const GrGLStencilAttachment::Format& format);
    137 
    138     /**
    139      * Call to check whether color config / stencil format pair has already
    140      * passed FBO status check.
    141      */
    142     bool isColorConfigAndStencilFormatVerified(
    143                     GrPixelConfig config,
    144                     const GrGLStencilAttachment::Format& format) const;
    145 
    146     /**
    147      * Reports the type of MSAA FBO support.
    148      */
    149     MSFBOType msFBOType() const { return fMSFBOType; }
    150 
    151     /**
    152      * Does the supported MSAA FBO extension have MSAA renderbuffers?
    153      */
    154     bool usesMSAARenderBuffers() const {
    155         return kNone_MSFBOType != fMSFBOType &&
    156                kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
    157                kES_EXT_MsToTexture_MSFBOType != fMSFBOType;
    158     }
    159 
    160     /**
    161      * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
    162      * then implicitly resolved when read.
    163      */
    164     bool usesImplicitMSAAResolve() const {
    165         return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
    166                kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
    167     }
    168 
    169     bool fbMixedSamplesSupport() const { return fFBMixedSamplesSupport; }
    170 
    171     InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
    172 
    173     /// What type of buffer mapping is supported?
    174     MapBufferType mapBufferType() const { return fMapBufferType; }
    175 
    176     /**
    177      * Gets an array of legal stencil formats. These formats are not guaranteed
    178      * to be supported by the driver but are legal GLenum names given the GL
    179      * version and extensions supported.
    180      */
    181     const SkTArray<StencilFormat, true>& stencilFormats() const {
    182         return fStencilFormats;
    183     }
    184 
    185     /// The maximum number of fragment uniform vectors (GLES has min. 16).
    186     int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
    187 
    188     /// maximum number of attribute values per vertex
    189     int maxVertexAttributes() const { return fMaxVertexAttributes; }
    190 
    191     /// maximum number of texture units accessible in the fragment shader.
    192     int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; }
    193 
    194     /// ES requires an extension to support RGBA8 in RenderBufferStorage
    195     bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; }
    196 
    197     /**
    198      * Depending on the ES extensions present the BGRA external format may
    199      * correspond either a BGRA or RGBA internalFormat. On desktop GL it is
    200      * RGBA.
    201      */
    202     bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; }
    203 
    204     /// GL_ARB_texture_swizzle support
    205     bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
    206 
    207     /// Is there support for GL_UNPACK_ROW_LENGTH
    208     bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
    209 
    210     /// Is there support for GL_UNPACK_FLIP_Y
    211     bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
    212 
    213     /// Is there support for GL_PACK_ROW_LENGTH
    214     bool packRowLengthSupport() const { return fPackRowLengthSupport; }
    215 
    216     /// Is there support for GL_PACK_REVERSE_ROW_ORDER
    217     bool packFlipYSupport() const { return fPackFlipYSupport; }
    218 
    219     /// Is there support for texture parameter GL_TEXTURE_USAGE
    220     bool textureUsageSupport() const { return fTextureUsageSupport; }
    221 
    222     /// Is there support for glTexStorage
    223     bool texStorageSupport() const { return fTexStorageSupport; }
    224 
    225     /// Is there support for GL_RED and GL_R8
    226     bool textureRedSupport() const { return fTextureRedSupport; }
    227 
    228     /// Is GL_ARB_IMAGING supported
    229     bool imagingSupport() const { return fImagingSupport; }
    230 
    231     /// Is GL_ARB_fragment_coord_conventions supported?
    232     bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; }
    233 
    234     /// Is there support for Vertex Array Objects?
    235     bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
    236 
    237     /// Is there support for ES2 compatability?
    238     bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
    239 
    240     /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
    241     bool useNonVBOVertexAndIndexDynamicData() const {
    242         return fUseNonVBOVertexAndIndexDynamicData;
    243     }
    244 
    245     /// Does ReadPixels support the provided format/type combo?
    246     bool readPixelsSupported(const GrGLInterface* intf,
    247                              GrGLenum format,
    248                              GrGLenum type,
    249                              GrGLenum currFboFormat) const;
    250 
    251     bool isCoreProfile() const { return fIsCoreProfile; }
    252 
    253 
    254     bool fullClearIsFree() const { return fFullClearIsFree; }
    255 
    256     /**
    257      * Returns a string containing the caps info.
    258      */
    259     SkString dump() const override;
    260 
    261     /**
    262      * LATC can appear under one of three possible names. In order to know
    263      * which GL internal format to use, we need to keep track of which name
    264      * we found LATC under. The default is LATC.
    265      */
    266     enum LATCAlias {
    267         kLATC_LATCAlias,
    268         kRGTC_LATCAlias,
    269         k3DC_LATCAlias
    270     };
    271 
    272     LATCAlias latcAlias() const { return fLATCAlias; }
    273 
    274     GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); }
    275 
    276 private:
    277     /**
    278      * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
    279      * performing glCheckFrameBufferStatus for the same config.
    280      */
    281     struct VerifiedColorConfigs {
    282         VerifiedColorConfigs() {
    283             this->reset();
    284         }
    285 
    286         void reset() {
    287             for (int i = 0; i < kNumUints; ++i) {
    288                 fVerifiedColorConfigs[i] = 0;
    289             }
    290         }
    291 
    292         static const int kNumUints = (kGrPixelConfigCnt  + 31) / 32;
    293         uint32_t fVerifiedColorConfigs[kNumUints];
    294 
    295         void markVerified(GrPixelConfig config) {
    296 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
    297                 return;
    298 #endif
    299             int u32Idx = config / 32;
    300             int bitIdx = config % 32;
    301             fVerifiedColorConfigs[u32Idx] |= 1 << bitIdx;
    302         }
    303 
    304         bool isVerified(GrPixelConfig config) const {
    305 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
    306             return false;
    307 #endif
    308             int u32Idx = config / 32;
    309             int bitIdx = config % 32;
    310             return SkToBool(fVerifiedColorConfigs[u32Idx] & (1 << bitIdx));
    311         }
    312     };
    313 
    314     void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
    315     void initStencilFormats(const GrGLContextInfo&);
    316     // This must be called after initFSAASupport().
    317     void initConfigRenderableTable(const GrGLContextInfo&);
    318     void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*);
    319 
    320     bool doReadPixelsSupported(const GrGLInterface* intf, GrGLenum format, GrGLenum type) const;
    321 
    322     // tracks configs that have been verified to pass the FBO completeness when
    323     // used as a color attachment
    324     VerifiedColorConfigs fVerifiedColorConfigs;
    325 
    326     SkTArray<StencilFormat, true> fStencilFormats;
    327     // tracks configs that have been verified to pass the FBO completeness when
    328     // used as a color attachment when a particular stencil format is used
    329     // as a stencil attachment.
    330     SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs;
    331 
    332     int fMaxFragmentUniformVectors;
    333     int fMaxVertexAttributes;
    334     int fMaxFragmentTextureUnits;
    335 
    336     MSFBOType           fMSFBOType;
    337     InvalidateFBType    fInvalidateFBType;
    338     MapBufferType       fMapBufferType;
    339     LATCAlias           fLATCAlias;
    340 
    341     bool fRGBA8RenderbufferSupport : 1;
    342     bool fBGRAIsInternalFormat : 1;
    343     bool fTextureSwizzleSupport : 1;
    344     bool fUnpackRowLengthSupport : 1;
    345     bool fUnpackFlipYSupport : 1;
    346     bool fPackRowLengthSupport : 1;
    347     bool fPackFlipYSupport : 1;
    348     bool fTextureUsageSupport : 1;
    349     bool fTexStorageSupport : 1;
    350     bool fTextureRedSupport : 1;
    351     bool fImagingSupport  : 1;
    352     bool fTwoFormatLimit : 1;
    353     bool fFragCoordsConventionSupport : 1;
    354     bool fVertexArrayObjectSupport : 1;
    355     bool fES2CompatibilitySupport : 1;
    356     bool fUseNonVBOVertexAndIndexDynamicData : 1;
    357     bool fIsCoreProfile : 1;
    358     bool fFullClearIsFree : 1;
    359     bool fFBMixedSamplesSupport : 1;
    360 
    361     struct ReadPixelsSupportedFormat {
    362         GrGLenum fFormat;
    363         GrGLenum fType;
    364         GrGLenum fFboFormat;
    365 
    366         bool operator==(const ReadPixelsSupportedFormat& rhs) const {
    367             return fFormat    == rhs.fFormat
    368                 && fType      == rhs.fType
    369                 && fFboFormat == rhs.fFboFormat;
    370         }
    371     };
    372     mutable SkTHashMap<ReadPixelsSupportedFormat, bool> fReadPixelsSupportedCache;
    373 
    374     typedef GrDrawTargetCaps INHERITED;
    375 };
    376 
    377 
    378 class GrGLSLCaps : public GrShaderCaps {
    379 public:
    380     SK_DECLARE_INST_COUNT(GrGLSLCaps)
    381 
    382     /**
    383     * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
    384     * special layout qualifiers in the fragment shader.
    385     */
    386     enum AdvBlendEqInteraction {
    387         kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
    388         kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
    389         kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
    390         kSpecificEnables_AdvBlendEqInteraction,  //<! Specific layout qualifiers per equation
    391 
    392         kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
    393     };
    394 
    395     /**
    396      * Creates a GrGLSLCaps that advertises no support for any extensions,
    397      * formats, etc. Call init to initialize from a GrGLContextInfo.
    398      */
    399     GrGLSLCaps();
    400     ~GrGLSLCaps() override {}
    401 
    402     GrGLSLCaps(const GrGLSLCaps& caps);
    403 
    404     GrGLSLCaps& operator = (const GrGLSLCaps& caps);
    405 
    406     /**
    407      * Resets the caps such that nothing is supported.
    408      */
    409     void reset() override;
    410 
    411     /**
    412      * Initializes the GrGLSLCaps to the set of features supported in the current
    413      * OpenGL context accessible via ctxInfo.
    414      */
    415     bool init(const GrGLContextInfo&, const GrGLInterface*, const GrGLCaps&);
    416 
    417     /**
    418      * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
    419      *
    420      * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
    421      */
    422     bool fbFetchSupport() const { return fFBFetchSupport; }
    423 
    424     bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
    425 
    426     const char* fbFetchColorName() const { return fFBFetchColorName; }
    427 
    428     const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
    429 
    430     bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
    431 
    432     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
    433 
    434     bool mustEnableAdvBlendEqs() const {
    435         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
    436     }
    437 
    438     bool mustEnableSpecificAdvBlendEqs() const {
    439         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
    440     }
    441 
    442     /**
    443     * Returns a string containing the caps info.
    444     */
    445     SkString dump() const override;
    446 
    447 private:
    448     // Must be called after fGeometryShaderSupport is initialized.
    449     void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*);
    450 
    451     bool fDropsTileOnZeroDivide : 1;
    452     bool fFBFetchSupport : 1;
    453     bool fFBFetchNeedsCustomOutput : 1;
    454 
    455     const char* fFBFetchColorName;
    456     const char* fFBFetchExtensionString;
    457 
    458     AdvBlendEqInteraction fAdvBlendEqInteraction;
    459 
    460     typedef GrShaderCaps INHERITED;
    461 };
    462 
    463 
    464 #endif
    465