Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2013 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #ifndef GrCaps_DEFINED
      9 #define GrCaps_DEFINED
     10 
     11 #include "../private/GrTypesPriv.h"
     12 #include "GrBlend.h"
     13 #include "GrDriverBugWorkarounds.h"
     14 #include "GrShaderCaps.h"
     15 #include "SkImageInfo.h"
     16 #include "SkRefCnt.h"
     17 #include "SkString.h"
     18 
     19 class GrBackendFormat;
     20 class GrBackendRenderTarget;
     21 class GrBackendTexture;
     22 struct GrContextOptions;
     23 class GrRenderTargetProxy;
     24 class GrSurface;
     25 class GrSurfaceProxy;
     26 class SkJSONWriter;
     27 
     28 /**
     29  * Represents the capabilities of a GrContext.
     30  */
     31 class GrCaps : public SkRefCnt {
     32 public:
     33     GrCaps(const GrContextOptions&);
     34 
     35     void dumpJSON(SkJSONWriter*) const;
     36 
     37     const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
     38 
     39     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
     40     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
     41         only for POT textures) */
     42     bool mipMapSupport() const { return fMipMapSupport; }
     43 
     44     /**
     45      * Skia convention is that a device only has sRGB support if it supports sRGB formats for both
     46      * textures and framebuffers.
     47      */
     48     bool srgbSupport() const { return fSRGBSupport; }
     49     /**
     50      * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers?
     51      */
     52     bool srgbWriteControl() const { return fSRGBWriteControl; }
     53     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
     54     bool gpuTracingSupport() const { return fGpuTracingSupport; }
     55     bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
     56     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
     57     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
     58     bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
     59     bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
     60     bool instanceAttribSupport() const { return fInstanceAttribSupport; }
     61     bool usesMixedSamples() const { return fUsesMixedSamples; }
     62     bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; }
     63 
     64     // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some
     65     // systems. This cap is only set if primitive restart will improve performance.
     66     bool usePrimitiveRestart() const { return fUsePrimitiveRestart; }
     67 
     68     bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
     69 
     70     // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to
     71     // initialize each tile with a constant value rather than loading each pixel from memory.
     72     bool preferFullscreenClears() const { return fPreferFullscreenClears; }
     73 
     74     bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
     75 
     76     bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; }
     77 
     78     bool avoidStencilBuffers() const { return fAvoidStencilBuffers; }
     79 
     80     bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; }
     81 
     82     /**
     83      * Indicates the capabilities of the fixed function blend unit.
     84      */
     85     enum BlendEquationSupport {
     86         kBasic_BlendEquationSupport,             //<! Support to select the operator that
     87                                                  //   combines src and dst terms.
     88         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
     89                                                  //   SVG/PDF blend modes. Requires blend barriers.
     90         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
     91                                                  //   require blend barriers, and permits overlap.
     92 
     93         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
     94     };
     95 
     96     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
     97 
     98     bool advancedBlendEquationSupport() const {
     99         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
    100     }
    101 
    102     bool advancedCoherentBlendEquationSupport() const {
    103         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
    104     }
    105 
    106     bool isAdvancedBlendEquationBlacklisted(GrBlendEquation equation) const {
    107         SkASSERT(GrBlendEquationIsAdvanced(equation));
    108         SkASSERT(this->advancedBlendEquationSupport());
    109         return SkToBool(fAdvBlendEqBlacklist & (1 << equation));
    110     }
    111 
    112     /**
    113      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
    114      * textures allows partial mappings or full mappings.
    115      */
    116     enum MapFlags {
    117         kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
    118 
    119         kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
    120                                       //   the other flags to have meaning.
    121         kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
    122     };
    123 
    124     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
    125 
    126     // Scratch textures not being reused means that those scratch textures
    127     // that we upload to (i.e., don't have a render target) will not be
    128     // recycled in the texture cache. This is to prevent ghosting by drivers
    129     // (in particular for deferred architectures).
    130     bool reuseScratchTextures() const { return fReuseScratchTextures; }
    131     bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
    132 
    133     /// maximum number of attribute values per vertex
    134     int maxVertexAttributes() const { return fMaxVertexAttributes; }
    135 
    136     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
    137 
    138     /** This is the largest render target size that can be used without incurring extra perfomance
    139         cost. It is usually the max RT size, unless larger render targets are known to be slower. */
    140     int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; }
    141 
    142     int maxTextureSize() const { return fMaxTextureSize; }
    143 
    144     /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
    145         It is usually the max texture size, unless we're overriding it for testing. */
    146     int maxTileSize() const {
    147         SkASSERT(fMaxTileSize <= fMaxTextureSize);
    148         return fMaxTileSize;
    149     }
    150 
    151     int maxWindowRectangles() const { return fMaxWindowRectangles; }
    152 
    153     // Returns whether mixed samples is supported for the given backend render target.
    154     bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const {
    155         return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt);
    156     }
    157 
    158     // A tuned, platform-specific value for the maximum number of analytic fragment processors we
    159     // should use to implement a clip, before falling back on a mask.
    160     int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; }
    161 
    162     virtual bool isConfigTexturable(GrPixelConfig) const = 0;
    163 
    164     // Returns whether a texture of the given config can be copied to a texture of the same config.
    165     virtual bool isConfigCopyable(GrPixelConfig) const = 0;
    166 
    167     // Returns the maximum supported sample count for a config. 0 means the config is not renderable
    168     // 1 means the config is renderable but doesn't support MSAA.
    169     virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0;
    170 
    171     bool isConfigRenderable(GrPixelConfig config) const {
    172         return this->maxRenderTargetSampleCount(config) > 0;
    173     }
    174 
    175     // TODO: Remove this after Flutter updated to no longer use it.
    176     bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
    177         return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0);
    178     }
    179 
    180     // Find a sample count greater than or equal to the requested count which is supported for a
    181     // color buffer of the given config or 0 if no such sample count is supported. If the requested
    182     // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
    183     // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
    184     virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0;
    185     // TODO: Remove. Legacy name used by Chrome.
    186     int getSampleCount(int requestedCount, GrPixelConfig config) const {
    187         return this->getRenderTargetSampleCount(requestedCount, config);
    188     }
    189 
    190     /**
    191      * Backends may have restrictions on what types of surfaces support GrGpu::writePixels().
    192      * If this returns false then the caller should implement a fallback where a temporary texture
    193      * is created, pixels are written to it, and then that is copied or drawn into the the surface.
    194      */
    195     bool surfaceSupportsWritePixels(const GrSurface*) const;
    196 
    197     /**
    198      * Backends may have restrictions on what types of surfaces support GrGpu::readPixels().
    199      * If this returns false then the caller should implement a fallback where a temporary texture
    200      * is created, the surface is drawn or copied into the temporary, and pixels are read from the
    201      * temporary.
    202      */
    203     virtual bool surfaceSupportsReadPixels(const GrSurface*) const = 0;
    204 
    205     /**
    206      * Given a dst pixel config and a src color type what color type must the caller coax the
    207      * the data into in order to use GrGpu::writePixels().
    208      */
    209     virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config,
    210                                                       GrColorType /*srcColorType*/) const {
    211         return GrPixelConfigToColorType(config);
    212     }
    213 
    214     /**
    215      * Given a src pixel config and a dst color type what color type must the caller read to using
    216      * GrGpu::readPixels() and then coax into dstColorType.
    217      */
    218     virtual GrColorType supportedReadPixelsColorType(GrPixelConfig config,
    219                                                      GrColorType /*dstColorType*/) const {
    220         return GrPixelConfigToColorType(config);
    221     }
    222 
    223     bool suppressPrints() const { return fSuppressPrints; }
    224 
    225     size_t bufferMapThreshold() const {
    226         SkASSERT(fBufferMapThreshold >= 0);
    227         return fBufferMapThreshold;
    228     }
    229 
    230     /** True in environments that will issue errors if memory uploaded to buffers
    231         is not initialized (even if not read by draw calls). */
    232     bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
    233 
    234     /** Returns true if the given backend supports importing AHardwareBuffers via the
    235      * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API
    236      * level >= 26.
    237      * */
    238     bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; }
    239 
    240     bool wireframeMode() const { return fWireframeMode; }
    241 
    242     bool fenceSyncSupport() const { return fFenceSyncSupport; }
    243     bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
    244     /**
    245      * Returns whether or not we will be able to do a copy given the passed in params
    246      */
    247     bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
    248                         const SkIRect& srcRect, const SkIPoint& dstPoint) const;
    249 
    250     bool dynamicStateArrayGeometryProcessorTextureSupport() const {
    251         return fDynamicStateArrayGeometryProcessorTextureSupport;
    252     }
    253 
    254     // Not all backends support clearing with a scissor test (e.g. Metal), this will always
    255     // return true if performColorClearsAsDraws() returns true.
    256     bool performPartialClearsAsDraws() const {
    257         return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws;
    258     }
    259 
    260     // Many drivers have issues with color clears.
    261     bool performColorClearsAsDraws() const {
    262         return fPerformColorClearsAsDraws;
    263     }
    264 
    265     /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
    266     /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
    267     /// op instead of using glClear seems to resolve the issue.
    268     bool performStencilClearsAsDraws() const {
    269         return fPerformStencilClearsAsDraws;
    270     }
    271 
    272     /**
    273      * This is can be called before allocating a texture to be a dst for copySurface. This is only
    274      * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It
    275      * will populate config and flags fields of the desc such that copySurface can efficiently
    276      * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation
    277      * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if
    278      * copy rect must equal src's bounds.
    279      */
    280     virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
    281                                     GrSurfaceOrigin* origin, bool* rectsMustMatch,
    282                                     bool* disallowSubrect) const = 0;
    283 
    284     bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const;
    285 
    286     /**
    287      * If the GrBackendRenderTarget can be used with the supplied SkColorType the return will be
    288      * the config that matches the backend format and requested SkColorType. Otherwise, kUnknown is
    289      * returned.
    290      */
    291     virtual GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&,
    292                                                       SkColorType) const = 0;
    293 
    294     // TODO: replace validateBackendRenderTarget with calls to getConfigFromBackendFormat?
    295     // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too
    296     // Returns kUnknown if a valid config could not be determined.
    297     virtual GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat& format,
    298                                                      SkColorType ct) const = 0;
    299 
    300     /**
    301      * Special method only for YUVA images. Returns a config that matches the backend format or
    302      * kUnknown if a config could not be determined.
    303      */
    304     virtual GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat& format) const = 0;
    305 
    306     /** These are used when creating a new texture internally. */
    307     virtual GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
    308                                                             GrSRGBEncoded srgbEncoded) const = 0;
    309     GrBackendFormat getBackendFormatFromColorType(SkColorType ct) const;
    310 
    311     /**
    312      * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and
    313      * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support.
    314      */
    315     bool clampToBorderSupport() const { return fClampToBorderSupport; }
    316 
    317     const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
    318 
    319 protected:
    320     /** Subclasses must call this at the end of their constructors in order to apply caps
    321         overrides requested by the client. Note that overrides will only reduce the caps never
    322         expand them. */
    323     void applyOptionsOverrides(const GrContextOptions& options);
    324 
    325     sk_sp<GrShaderCaps> fShaderCaps;
    326 
    327     bool fNPOTTextureTileSupport                     : 1;
    328     bool fMipMapSupport                              : 1;
    329     bool fSRGBSupport                                : 1;
    330     bool fSRGBWriteControl                           : 1;
    331     bool fDiscardRenderTargetSupport                 : 1;
    332     bool fReuseScratchTextures                       : 1;
    333     bool fReuseScratchBuffers                        : 1;
    334     bool fGpuTracingSupport                          : 1;
    335     bool fCompressedTexSubImageSupport               : 1;
    336     bool fOversizedStencilSupport                    : 1;
    337     bool fTextureBarrierSupport                      : 1;
    338     bool fSampleLocationsSupport                     : 1;
    339     bool fMultisampleDisableSupport                  : 1;
    340     bool fInstanceAttribSupport                      : 1;
    341     bool fUsesMixedSamples                           : 1;
    342     bool fUsePrimitiveRestart                        : 1;
    343     bool fPreferClientSideDynamicBuffers             : 1;
    344     bool fPreferFullscreenClears                     : 1;
    345     bool fMustClearUploadedBufferData                : 1;
    346     bool fSupportsAHardwareBufferImages              : 1;
    347     bool fHalfFloatVertexAttributeSupport            : 1;
    348     bool fClampToBorderSupport                       : 1;
    349     bool fPerformPartialClearsAsDraws                : 1;
    350     bool fPerformColorClearsAsDraws                  : 1;
    351     bool fPerformStencilClearsAsDraws                : 1;
    352 
    353     // Driver workaround
    354     bool fBlacklistCoverageCounting                  : 1;
    355     bool fAvoidStencilBuffers                        : 1;
    356     bool fAvoidWritePixelsFastPath                   : 1;
    357 
    358     // ANGLE performance workaround
    359     bool fPreferVRAMUseOverFlushes                   : 1;
    360 
    361     // TODO: this may need to be an enum to support different fence types
    362     bool fFenceSyncSupport                           : 1;
    363 
    364     // Requires fence sync support in GL.
    365     bool fCrossContextTextureSupport                 : 1;
    366 
    367     // Not (yet) implemented in VK backend.
    368     bool fDynamicStateArrayGeometryProcessorTextureSupport : 1;
    369 
    370     BlendEquationSupport fBlendEquationSupport;
    371     uint32_t fAdvBlendEqBlacklist;
    372     GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
    373 
    374     uint32_t fMapBufferFlags;
    375     int fBufferMapThreshold;
    376 
    377     int fMaxRenderTargetSize;
    378     int fMaxPreferredRenderTargetSize;
    379     int fMaxVertexAttributes;
    380     int fMaxTextureSize;
    381     int fMaxTileSize;
    382     int fMaxWindowRectangles;
    383     int fMaxClipAnalyticFPs;
    384 
    385     GrDriverBugWorkarounds fDriverBugWorkarounds;
    386 
    387 private:
    388     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
    389     virtual void onDumpJSON(SkJSONWriter*) const {}
    390     virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0;
    391     virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
    392                                   const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
    393 
    394     // Backends should implement this if they have any extra requirements for use of window
    395     // rectangles for a specific GrBackendRenderTarget outside of basic support.
    396     virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const {
    397         return true;
    398     }
    399 
    400     bool fSuppressPrints : 1;
    401     bool fWireframeMode  : 1;
    402 
    403     typedef SkRefCnt INHERITED;
    404 };
    405 
    406 #endif
    407