
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef GrCaps_DEFINED
#define GrCaps_DEFINED

#include "../private/GrTypesPriv.h"
#include "GrBlend.h"
#include "GrDriverBugWorkarounds.h"
#include "GrShaderCaps.h"
#include "SkImageInfo.h"
#include "SkRefCnt.h"
#include "SkString.h"

class GrBackendFormat;
class GrBackendRenderTarget;
class GrBackendTexture;
struct GrContextOptions;
class GrRenderTargetProxy;
class GrSurface;
class GrSurfaceProxy;
class SkJSONWriter;

/**
 * Represents the capabilities of a GrContext.
 */
class GrCaps : public SkRefCnt {
public:
    GrCaps(const GrContextOptions&);

    void dumpJSON(SkJSONWriter*) const;

    const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); }

    bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
    /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
        only for POT textures) */
    bool mipMapSupport() const { return fMipMapSupport; }

    /**
     * Skia convention is that a device only has sRGB support if it supports sRGB formats for both
     * textures and framebuffers.
     */
    bool srgbSupport() const { return fSRGBSupport; }
    /**
     * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers?
     */
    bool srgbWriteControl() const { return fSRGBWriteControl; }
    bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
    bool gpuTracingSupport() const { return fGpuTracingSupport; }
    bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
    bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
    bool textureBarrierSupport() const { return fTextureBarrierSupport; }
    bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
    bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
    bool instanceAttribSupport() const { return fInstanceAttribSupport; }
    bool usesMixedSamples() const { return fUsesMixedSamples; }
    bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; }

    // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some
    // systems. This cap is only set if primitive restart will improve performance.
    bool usePrimitiveRestart() const { return fUsePrimitiveRestart; }

    bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }

    // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to
    // initialize each tile with a constant value rather than loading each pixel from memory.
    bool preferFullscreenClears() const { return fPreferFullscreenClears; }

    bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }

    bool preferTrianglesOverSampleMask() const { return fPreferTrianglesOverSampleMask; }

    bool avoidStencilBuffers() const { return fAvoidStencilBuffers; }

    bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; }

    /**
     * Indicates the capabilities of the fixed function blend unit.
     */
    enum BlendEquationSupport {
        kBasic_BlendEquationSupport,             //<! Support to select the operator that
                                                 //   combines src and dst terms.
        kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
                                                 //   SVG/PDF blend modes. Requires blend barriers.
        kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
                                                 //   require blend barriers, and permits overlap.

        kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
    };

    BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }

    bool advancedBlendEquationSupport() const {
        return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
    }

    bool advancedCoherentBlendEquationSupport() const {
        return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
    }

    bool isAdvancedBlendEquationBlacklisted(GrBlendEquation equation) const {
        SkASSERT(GrBlendEquationIsAdvanced(equation));
        SkASSERT(this->advancedBlendEquationSupport());
        return SkToBool(fAdvBlendEqBlacklist & (1 << equation));
    }

    /**
     * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
     * textures allows partial mappings or full mappings.
     */
    enum MapFlags {
        kNone_MapFlags   = 0x0,       //<! Cannot map the resource.

        kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
                                      //   the other flags to have meaning.
        kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
    };

    uint32_t mapBufferFlags() const { return fMapBufferFlags; }

    // Scratch textures not being reused means that those scratch textures
    // that we upload to (i.e., don't have a render target) will not be
    // recycled in the texture cache. This is to prevent ghosting by drivers
    // (in particular for deferred architectures).
    bool reuseScratchTextures() const { return fReuseScratchTextures; }
    bool reuseScratchBuffers() const { return fReuseScratchBuffers; }

    /// maximum number of attribute values per vertex
    int maxVertexAttributes() const { return fMaxVertexAttributes; }

    int maxRenderTargetSize() const { return fMaxRenderTargetSize; }

    /** This is the largest render target size that can be used without incurring extra perfomance
        cost. It is usually the max RT size, unless larger render targets are known to be slower. */
    int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; }

    int maxTextureSize() const { return fMaxTextureSize; }

    /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
        It is usually the max texture size, unless we're overriding it for testing. */
    int maxTileSize() const {
        SkASSERT(fMaxTileSize <= fMaxTextureSize);
        return fMaxTileSize;
    }

    int maxWindowRectangles() const { return fMaxWindowRectangles; }

    // Returns whether mixed samples is supported for the given backend render target.
    bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const {
        return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt);
    }

    // A tuned, platform-specific value for the maximum number of analytic fragment processors we
    // should use to implement a clip, before falling back on a mask.
    int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; }

    virtual bool isConfigTexturable(GrPixelConfig) const = 0;

    // Returns whether a texture of the given config can be copied to a texture of the same config.
    virtual bool isConfigCopyable(GrPixelConfig) const = 0;

    // Returns the maximum supported sample count for a config. 0 means the config is not renderable
    // 1 means the config is renderable but doesn't support MSAA.
    virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0;

    bool isConfigRenderable(GrPixelConfig config) const {
        return this->maxRenderTargetSampleCount(config) > 0;
    }

    // TODO: Remove this after Flutter updated to no longer use it.
    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
        return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0);
    }

    // Find a sample count greater than or equal to the requested count which is supported for a
    // color buffer of the given config or 0 if no such sample count is supported. If the requested
    // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
    // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
    virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0;
    // TODO: Remove. Legacy name used by Chrome.
    int getSampleCount(int requestedCount, GrPixelConfig config) const {
        return this->getRenderTargetSampleCount(requestedCount, config);
    }

    /**
     * Backends may have restrictions on what types of surfaces support GrGpu::writePixels().
     * If this returns false then the caller should implement a fallback where a temporary texture
     * is created, pixels are written to it, and then that is copied or drawn into the the surface.
     */
    bool surfaceSupportsWritePixels(const GrSurface*) const;

    /**
     * Backends may have restrictions on what types of surfaces support GrGpu::readPixels().
     * If this returns false then the caller should implement a fallback where a temporary texture
     * is created, the surface is drawn or copied into the temporary, and pixels are read from the
     * temporary.
     */
    virtual bool surfaceSupportsReadPixels(const GrSurface*) const = 0;

    /**
     * Given a dst pixel config and a src color type what color type must the caller coax the
     * the data into in order to use GrGpu::writePixels().
     */
    virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config,
                                                      GrColorType /*srcColorType*/) const {
        return GrPixelConfigToColorType(config);
    }

    /**
     * Given a src pixel config and a dst color type what color type must the caller read to using
     * GrGpu::readPixels() and then coax into dstColorType.
     */
    virtual GrColorType supportedReadPixelsColorType(GrPixelConfig config,
                                                     GrColorType /*dstColorType*/) const {
        return GrPixelConfigToColorType(config);
    }

    /** Are transfer buffers (to textures and from surfaces) supported? */
    bool transferBufferSupport() const { return fTransferBufferSupport; }

    /**
     * Gets the requirements to use GrGpu::transferPixelsFrom for a given GrColorType. To check
     * whether a pixels as GrColorType can be read for a given surface see
     * supportedReadPixelsColorType() and surfaceSupportsReadPixels().
     *
     * @param bufferColorType The color type of the pixel data that will be stored in the transfer
     *                        buffer.
     * @param width  The number of color values per row that will be stored in the buffer.
     * @param rowBytes The number of bytes per row that will be used in the transfer buffer.
     * @param alignment The required alignment of the offset into the transfer buffer passed
     *                         to GrGpu::transferPixelsFrom.
     * @return true if transferPixelFrom is supported, false otherwise. If false then rowBytes and
     * alignment are not updated.
     */
    bool transferFromBufferRequirements(GrColorType bufferColorType, int width, size_t* rowBytes,
                                        size_t* offsetAlignment) const;

    bool suppressPrints() const { return fSuppressPrints; }

    size_t bufferMapThreshold() const {
        SkASSERT(fBufferMapThreshold >= 0);
        return fBufferMapThreshold;
    }

    /** True in environments that will issue errors if memory uploaded to buffers
        is not initialized (even if not read by draw calls). */
    bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }

    /** For some environments, there is a performance or safety concern to not
        initializing textures. For example, with WebGL and Firefox, there is a large
        performance hit to not doing it.
     */
    bool shouldInitializeTextures() const { return fShouldInitializeTextures; }


    /** Returns true if the given backend supports importing AHardwareBuffers via the
     * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API
     * level >= 26.
     * */
    bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; }

    bool wireframeMode() const { return fWireframeMode; }

    bool fenceSyncSupport() const { return fFenceSyncSupport; }
    bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
    /**
     * Returns whether or not we will be able to do a copy given the passed in params
     */
    bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
                        const SkIRect& srcRect, const SkIPoint& dstPoint) const;

    bool dynamicStateArrayGeometryProcessorTextureSupport() const {
        return fDynamicStateArrayGeometryProcessorTextureSupport;
    }

    // Not all backends support clearing with a scissor test (e.g. Metal), this will always
    // return true if performColorClearsAsDraws() returns true.
    bool performPartialClearsAsDraws() const {
        return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws;
    }

    // Many drivers have issues with color clears.
    bool performColorClearsAsDraws() const { return fPerformColorClearsAsDraws; }

    /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
    /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
    /// op instead of using glClear seems to resolve the issue.
    bool performStencilClearsAsDraws() const { return fPerformStencilClearsAsDraws; }

    // Can we use coverage counting shortcuts to render paths? Coverage counting can cause artifacts
    // along shared edges if care isn't taken to ensure both contours wind in the same direction.
    bool allowCoverageCounting() const { return fAllowCoverageCounting; }

    // Should we disable the CCPR code due to a faulty driver?
    bool driverBlacklistCCPR() const { return fDriverBlacklistCCPR; }

    /**
     * This is can be called before allocating a texture to be a dst for copySurface. This is only
     * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It
     * will populate config and flags fields of the desc such that copySurface can efficiently
     * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation
     * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if
     * copy rect must equal src's bounds.
     */
    virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                                    GrSurfaceOrigin* origin, bool* rectsMustMatch,
                                    bool* disallowSubrect) const = 0;

    bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const;

    /**
     * If the GrBackendRenderTarget can be used with the supplied SkColorType the return will be
     * the config that matches the backend format and requested SkColorType. Otherwise, kUnknown is
     * returned.
     */
    virtual GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&,
                                                      SkColorType) const = 0;

    // TODO: replace validateBackendRenderTarget with calls to getConfigFromBackendFormat?
    // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too
    // Returns kUnknown if a valid config could not be determined.
    virtual GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat& format,
                                                     SkColorType ct) const = 0;

    /**
     * Special method only for YUVA images. Returns a config that matches the backend format or
     * kUnknown if a config could not be determined.
     */
    virtual GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat& format) const = 0;

    /** These are used when creating a new texture internally. */
    virtual GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
                                                            GrSRGBEncoded srgbEncoded) const = 0;
    GrBackendFormat getBackendFormatFromColorType(SkColorType ct) const;

    /**
     * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and
     * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support.
     */
    bool clampToBorderSupport() const { return fClampToBorderSupport; }

    const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }

protected:
    /** Subclasses must call this at the end of their constructors in order to apply caps
        overrides requested by the client. Note that overrides will only reduce the caps never
        expand them. */
    void applyOptionsOverrides(const GrContextOptions& options);

    sk_sp<GrShaderCaps> fShaderCaps;

    bool fNPOTTextureTileSupport                     : 1;
    bool fMipMapSupport                              : 1;
    bool fSRGBSupport                                : 1;
    bool fSRGBWriteControl                           : 1;
    bool fDiscardRenderTargetSupport                 : 1;
    bool fReuseScratchTextures                       : 1;
    bool fReuseScratchBuffers                        : 1;
    bool fGpuTracingSupport                          : 1;
    bool fCompressedTexSubImageSupport               : 1;
    bool fOversizedStencilSupport                    : 1;
    bool fTextureBarrierSupport                      : 1;
    bool fSampleLocationsSupport                     : 1;
    bool fMultisampleDisableSupport                  : 1;
    bool fInstanceAttribSupport                      : 1;
    bool fUsesMixedSamples                           : 1;
    bool fUsePrimitiveRestart                        : 1;
    bool fPreferClientSideDynamicBuffers             : 1;
    bool fPreferFullscreenClears                     : 1;
    bool fMustClearUploadedBufferData                : 1;
    bool fShouldInitializeTextures                   : 1;
    bool fSupportsAHardwareBufferImages              : 1;
    bool fHalfFloatVertexAttributeSupport            : 1;
    bool fClampToBorderSupport                       : 1;
    bool fPerformPartialClearsAsDraws                : 1;
    bool fPerformColorClearsAsDraws                  : 1;
    bool fPerformStencilClearsAsDraws                : 1;
    bool fAllowCoverageCounting                      : 1;
    bool fTransferBufferSupport                      : 1;

    // Driver workaround
    bool fDriverBlacklistCCPR                        : 1;
    bool fAvoidStencilBuffers                        : 1;
    bool fAvoidWritePixelsFastPath                   : 1;

    // ANGLE performance workaround
    bool fPreferVRAMUseOverFlushes                   : 1;

    // On some platforms it's better to make more triangles than to use the sample mask (MSAA only).
    bool fPreferTrianglesOverSampleMask              : 1;

    // TODO: this may need to be an enum to support different fence types
    bool fFenceSyncSupport                           : 1;

    // Requires fence sync support in GL.
    bool fCrossContextTextureSupport                 : 1;

    // Not (yet) implemented in VK backend.
    bool fDynamicStateArrayGeometryProcessorTextureSupport : 1;

    BlendEquationSupport fBlendEquationSupport;
    uint32_t fAdvBlendEqBlacklist;
    GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);

    uint32_t fMapBufferFlags;
    int fBufferMapThreshold;

    int fMaxRenderTargetSize;
    int fMaxPreferredRenderTargetSize;
    int fMaxVertexAttributes;
    int fMaxTextureSize;
    int fMaxTileSize;
    int fMaxWindowRectangles;
    int fMaxClipAnalyticFPs;

    GrDriverBugWorkarounds fDriverBugWorkarounds;

private:
    virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
    virtual void onDumpJSON(SkJSONWriter*) const {}
    virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0;
    virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
                                  const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
    virtual bool onTransferFromBufferRequirements(GrColorType bufferColorType, int width,
                                                  size_t* rowBytes, size_t* offsetAlignment) const;

    // Backends should implement this if they have any extra requirements for use of window
    // rectangles for a specific GrBackendRenderTarget outside of basic support.
    virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const {
        return true;
    }

    bool fSuppressPrints : 1;
    bool fWireframeMode  : 1;

    typedef SkRefCnt INHERITED;
};

#endif
