
/*
 * 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 "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/gpu/GrDriverBugWorkarounds.h"
#include "include/private/GrTypesPriv.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/gpu/GrBlend.h"
#include "src/gpu/GrSamplerState.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrSurfaceProxy.h"

class GrBackendFormat;
class GrBackendRenderTarget;
class GrBackendTexture;
struct GrContextOptions;
class GrProcessorKeyBuilder;
class GrProgramDesc;
class GrProgramInfo;
class GrRenderTargetProxy;
class GrSurface;
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(); }
    sk_sp<const GrShaderCaps> refShaderCaps() const { return fShaderCaps; }

    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; }

    bool gpuTracingSupport() const { return fGpuTracingSupport; }
    bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
    bool textureBarrierSupport() const { return fTextureBarrierSupport; }
    bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
    bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
    bool drawInstancedSupport() const { return fDrawInstancedSupport; }
    // Is there hardware support for indirect draws? (Ganesh always supports indirect draws as long
    // as it can polyfill them with instanced calls, but this cap tells us if they are supported
    // natively.)
    bool nativeDrawIndirectSupport() const { return fNativeDrawIndirectSupport; }
    bool useClientSideIndirectBuffers() const {
#ifdef SK_DEBUG
        if (!fNativeDrawIndirectSupport || fNativeDrawIndexedIndirectIsBroken) {
            // We might implement indirect draws with a polyfill, so the commands need to reside in
            // CPU memory.
            SkASSERT(fUseClientSideIndirectBuffers);
        }
#endif
        return fUseClientSideIndirectBuffers;
    }
    bool conservativeRasterSupport() const { return fConservativeRasterSupport; }
    bool wireframeSupport() const { return fWireframeSupport; }
    // This flag indicates that we never have to resolve MSAA. In practice, it means that we have
    // an MSAA-render-to-texture extension: Any render target we create internally will use the
    // extension, and any wrapped render target is the client's responsibility.
    bool msaaResolvesAutomatically() const { return fMSAAResolvesAutomatically; }
    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; }

    // Should we discard stencil values after a render pass? (Tilers get better performance if we
    // always load stencil buffers with a "clear" op, and then discard the content when finished.)
    bool discardStencilValuesAfterRenderPass() const {
        // b/160958008
        return false;
#if 0
        // This method is actually just a duplicate of preferFullscreenClears(), with a descriptive
        // name for the sake of readability.
        return this->preferFullscreenClears();
#endif
    }

    // D3D does not allow the refs or masks to differ on a two-sided stencil draw.
    bool twoSidedStencilRefsAndMasksMustMatch() const {
        return fTwoSidedStencilRefsAndMasksMustMatch;
    }

    bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }

    bool avoidStencilBuffers() const { return fAvoidStencilBuffers; }

    bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; }

    // http://skbug.com/9739
    bool requiresManualFBBarrierAfterTessellatedStencilDraw() const {
        return fRequiresManualFBBarrierAfterTessellatedStencilDraw;
    }

    // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
    bool nativeDrawIndexedIndirectIsBroken() const { return fNativeDrawIndexedIndirectIsBroken; }

    /**
     * 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 isAdvancedBlendEquationDisabled(GrBlendEquation equation) const {
        SkASSERT(GrBlendEquationIsAdvanced(equation));
        SkASSERT(this->advancedBlendEquationSupport());
        return SkToBool(fAdvBlendEqDisableFlags & (1 << equation));
    }

    // On some GPUs it is a performance win to disable blending instead of doing src-over with a src
    // alpha equal to 1. To disable blending we collapse src-over to src and the backends will
    // handle the disabling of blending.
    bool shouldCollapseSrcOverToSrcWhenAble() const {
        return fShouldCollapseSrcOverToSrcWhenAble;
    }

    // When abandoning the GrDirectContext do we need to sync the GPU before we start abandoning
    // resources.
    bool mustSyncGpuDuringAbandon() const {
        return fMustSyncGpuDuringAbandon;
    }

    // Shortcut for shaderCaps()->reducedShaderMode().
    bool reducedShaderMode() const { return this->shaderCaps()->reducedShaderMode(); }

    /**
     * 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.
        kAsyncRead_MapFlag  = 0x4,   //<! Are maps for reading asynchronous WRT GrOpsRenderPass
                                     //   submitted to GrGpu.
    };

    // This returns the general mapping support for the GPU. However, even if this returns a flag
    // that says buffers can be mapped, it does NOT mean that every buffer will be mappable. Thus
    // calls of map should still check to see if a valid pointer was returned from the map call and
    // handle fallbacks appropriately. If this does return kNone_MapFlags then all calls to map() on
    // any buffer will fail.
    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; }

    int maxWindowRectangles() const { return fMaxWindowRectangles; }

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

    uint32_t maxPushConstantsSize() const { return fMaxPushConstantsSize; }

    virtual bool isFormatSRGB(const GrBackendFormat&) const = 0;

    bool isFormatCompressed(const GrBackendFormat& format) const;

    // Can a texture be made with the GrBackendFormat, and then be bound and sampled in a shader.
    virtual bool isFormatTexturable(const GrBackendFormat&) const = 0;

    // Returns whether a texture of the given format can be copied to a texture of the same format.
    virtual bool isFormatCopyable(const GrBackendFormat&) const = 0;

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

    // Returns the number of samples to use when performing draws to the given config with internal
    // MSAA. If 0, Ganesh should not attempt to use internal multisampling.
    int internalMultisampleCount(const GrBackendFormat& format) const {
        return std::min(fInternalMultisampleCount, this->maxRenderTargetSampleCount(format));
    }

    virtual bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
                                               int sampleCount = 1) const = 0;

    virtual bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const = 0;

    // Find a sample count greater than or equal to the requested count which is supported for a
    // render target of the given format 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, const GrBackendFormat&) const = 0;

    /**
     * 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;

    /**
     * Indicates whether surface supports GrGpu::readPixels, must be copied, or cannot be read.
     */
    enum class SurfaceReadPixelsSupport {
        /** GrGpu::readPixels is supported by the surface. */
        kSupported,
        /**
         * GrGpu::readPixels is not supported by this surface but this surface can be drawn
         * or copied to a Ganesh-created GrTextureType::kTexture2D and then that surface will be
         * readable.
         */
        kCopyToTexture2D,
        /**
         * Not supported
         */
        kUnsupported,
    };
    /**
     * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). We may
     * either be able to read directly from the surface, read from a copy of the surface, or not
     * read at all.
     */
    virtual SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const = 0;

    struct SupportedWrite {
        GrColorType fColorType;
        // If the write is occurring using GrGpu::transferPixelsTo then this provides the
        // minimum alignment of the offset into the transfer buffer.
        size_t fOffsetAlignmentForTransferBuffer;
    };

    /**
     * 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 SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
                                                         const GrBackendFormat& surfaceFormat,
                                                         GrColorType srcColorType) const = 0;

    struct SupportedRead {
        GrColorType fColorType;
        // If the read is occurring using GrGpu::transferPixelsFrom then this provides the
        // minimum alignment of the offset into the transfer buffer.
        size_t fOffsetAlignmentForTransferBuffer;
    };

    /**
     * Given a src surface's color type and its backend format as well as a color type the caller
     * would like read into, this provides a legal color type that the caller may pass to
     * GrGpu::readPixels(). The returned color type may differ from the passed dstColorType, in
     * which case the caller must convert the read pixel data (see GrConvertPixels). When converting
     * to dstColorType the swizzle in the returned struct should be applied. The caller must check
     * the returned color type for kUnknown.
     */
    SupportedRead supportedReadPixelsColorType(GrColorType srcColorType,
                                               const GrBackendFormat& srcFormat,
                                               GrColorType dstColorType) const;

    /**
     * Do GrGpu::writePixels() and GrGpu::transferPixelsTo() support a src buffer where the row
     * bytes is not equal to bpp * w?
     */
    bool writePixelsRowBytesSupport() const { return fWritePixelsRowBytesSupport; }
    /**
     * Does GrGpu::readPixels() support a dst buffer where the row bytes is not equal to bpp * w?
     */
    bool readPixelsRowBytesSupport() const { return fReadPixelsRowBytesSupport; }

    bool transferFromSurfaceToBufferSupport() const { return fTransferFromSurfaceToBufferSupport; }
    bool transferFromBufferToTextureSupport() const { return fTransferFromBufferToTextureSupport; }

    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; }

    /** Supports using GrFence. */
    bool fenceSyncSupport() const { return fFenceSyncSupport; }

    /** Supports using GrSemaphore. */
    bool semaphoreSupport() const { return fSemaphoreSupport; }

    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; }

    bool avoidLargeIndexBufferDraws() const { return fAvoidLargeIndexBufferDraws; }

    /// 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; }

    // Should we disable the clip mask atlas due to a faulty driver?
    bool driverDisableMSAAClipAtlas() const { return fDriverDisableMSAAClipAtlas; }

    // Should we disable GrTessellationPathRenderer due to a faulty driver?
    bool disableTessellationPathRenderer() const { return fDisableTessellationPathRenderer; }

    // Returns how to sample the dst values for the passed in GrRenderTargetProxy.
    GrDstSampleType getDstSampleTypeForProxy(const GrRenderTargetProxy*) const;

    /**
     * This is used to try to ensure a successful copy a dst in order to perform shader-based
     * blending.
     *
     * fRectsMustMatch will be set to true if the copy operation must ensure that the src and dest
     * rects are identical.
     *
     * fMustCopyWholeSrc will be set to true if copy rect must equal src's bounds.
     *
     * Caller will detect cases when copy cannot succeed and try copy-as-draw as a fallback.
     */
    struct DstCopyRestrictions {
        GrSurfaceProxy::RectsMustMatch fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kNo;
        bool fMustCopyWholeSrc = false;
    };
    virtual DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src,
                                                       GrColorType ct) const {
        return {};
    }

    bool validateSurfaceParams(const SkISize&, const GrBackendFormat&, GrRenderable renderable,
                               int renderTargetSampleCnt, GrMipmapped) const;

    bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat& format) const;

    /** These are used when creating a new texture internally. */
    GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const;

    virtual GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const = 0;

    /**
     * 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; }

    /**
     * Returns the GrSwizzle to use when sampling or reading back from a texture with the passed in
     * GrBackendFormat and GrColorType.
     */
    GrSwizzle getReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const;

    /**
     * Returns the GrSwizzle to use when writing colors to a surface with the passed in
     * GrBackendFormat and GrColorType.
     */
    virtual GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const = 0;

    virtual uint64_t computeFormatKey(const GrBackendFormat&) const = 0;

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

    /**
     * Adds fields to the key to represent the sampler that will be created for the passed
     * in parameters. Currently this extra keying is only needed when building a vulkan pipeline
     * with immutable samplers.
     */
    virtual void addExtraSamplerKey(GrProcessorKeyBuilder*,
                                    GrSamplerState,
                                    const GrBackendFormat&) const {}

    enum class ProgramDescOverrideFlags {
        kNone = 0,
        // If using discardable msaa surfaces in vulkan, when we break up a render pass for an
        // inline upload, we must do a load msaa subpass for the second render pass. However, if the
        // original render pass did not have this load subpass (e.g. clear or discard load op), then
        // all the GrProgramInfos for draws that end up in the second render pass will have been
        // recorded thinking they will be in a render pass with only 1 subpass. Thus we add an
        // override flag to the makeDesc call to force the actually VkPipeline that gets created to
        // be created using a render pass with 2 subpasses. We do miss on the pre-compile with this
        // approach, but inline uploads are very rare and already slow.
        kVulkanHasResolveLoadSubpass = 0x1,
    };
    GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(ProgramDescOverrideFlags);


    virtual GrProgramDesc makeDesc(
            GrRenderTarget*, const GrProgramInfo&,
            ProgramDescOverrideFlags overrideFlags = ProgramDescOverrideFlags::kNone) const = 0;

    // This method specifies, for each backend, the extra properties of a RT when Ganesh creates one
    // internally. For example, for Vulkan, Ganesh always creates RTs that can be used as input
    // attachments.
    virtual GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const {
        return GrInternalSurfaceFlags::kNone;
    }

    bool supportsDynamicMSAA(const GrRenderTargetProxy*) const;

    // skbug.com/11935. Task reordering is disabled for some GPUs on GL due to driver bugs.
    bool avoidReorderingRenderTasks() const {
        return fAvoidReorderingRenderTasks;
    }

#if GR_TEST_UTILS
    struct TestFormatColorTypeCombination {
        GrColorType fColorType;
        GrBackendFormat fFormat;
    };

    virtual std::vector<TestFormatColorTypeCombination> getTestingCombinations() const = 0;
#endif

protected:
    // Subclasses must call this at the end of their init method in order to do final processing on
    // the caps (including overrides requested by the client).
    // NOTE: this method will only reduce the caps, never expand them.
    void finishInitialization(const GrContextOptions& options);

    virtual bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const { return false; }

    sk_sp<GrShaderCaps> fShaderCaps;

    bool fNPOTTextureTileSupport                     : 1;
    bool fMipmapSupport                              : 1;
    bool fReuseScratchTextures                       : 1;
    bool fReuseScratchBuffers                        : 1;
    bool fGpuTracingSupport                          : 1;
    bool fOversizedStencilSupport                    : 1;
    bool fTextureBarrierSupport                      : 1;
    bool fSampleLocationsSupport                     : 1;
    bool fMultisampleDisableSupport                  : 1;
    bool fDrawInstancedSupport                       : 1;
    bool fNativeDrawIndirectSupport                  : 1;
    bool fUseClientSideIndirectBuffers               : 1;
    bool fConservativeRasterSupport                  : 1;
    bool fWireframeSupport                           : 1;
    bool fMSAAResolvesAutomatically                  : 1;
    bool fUsePrimitiveRestart                        : 1;
    bool fPreferClientSideDynamicBuffers             : 1;
    bool fPreferFullscreenClears                     : 1;
    bool fTwoSidedStencilRefsAndMasksMustMatch       : 1;
    bool fMustClearUploadedBufferData                : 1;
    bool fShouldInitializeTextures                   : 1;
    bool fSupportsAHardwareBufferImages              : 1;
    bool fHalfFloatVertexAttributeSupport            : 1;
    bool fClampToBorderSupport                       : 1;
    bool fPerformPartialClearsAsDraws                : 1;
    bool fPerformColorClearsAsDraws                  : 1;
    bool fAvoidLargeIndexBufferDraws                 : 1;
    bool fPerformStencilClearsAsDraws                : 1;
    bool fTransferFromBufferToTextureSupport         : 1;
    bool fTransferFromSurfaceToBufferSupport         : 1;
    bool fWritePixelsRowBytesSupport                 : 1;
    bool fReadPixelsRowBytesSupport                  : 1;
    bool fShouldCollapseSrcOverToSrcWhenAble         : 1;
    bool fMustSyncGpuDuringAbandon                   : 1;

    // Driver workaround
    bool fDriverDisableMSAAClipAtlas                 : 1;
    bool fDisableTessellationPathRenderer            : 1;
    bool fAvoidStencilBuffers                        : 1;
    bool fAvoidWritePixelsFastPath                   : 1;
    bool fRequiresManualFBBarrierAfterTessellatedStencilDraw : 1;
    bool fNativeDrawIndexedIndirectIsBroken          : 1;
    bool fAvoidReorderingRenderTasks                 : 1;

    // ANGLE performance workaround
    bool fPreferVRAMUseOverFlushes                   : 1;

    bool fFenceSyncSupport                           : 1;
    bool fSemaphoreSupport                           : 1;

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

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

    BlendEquationSupport fBlendEquationSupport;
    uint32_t fAdvBlendEqDisableFlags;
    static_assert(kLast_GrBlendEquation < 32);

    uint32_t fMapBufferFlags;
    int fBufferMapThreshold;

    int fMaxRenderTargetSize;
    int fMaxPreferredRenderTargetSize;
    int fMaxVertexAttributes;
    int fMaxTextureSize;
    int fMaxWindowRectangles;
    int fInternalMultisampleCount;
    uint32_t fMaxPushConstantsSize = 0;

    GrDriverBugWorkarounds fDriverBugWorkarounds;

private:
    void applyOptionsOverrides(const GrContextOptions& options);

    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 GrBackendFormat onGetDefaultBackendFormat(GrColorType) const = 0;

    // 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;
    }

    virtual bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const = 0;

    virtual SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType,
                                                         const GrBackendFormat& srcFormat,
                                                         GrColorType dstColorType) const = 0;

    virtual GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const = 0;

    virtual GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const {
        return GrDstSampleType::kAsTextureCopy;
    }

    bool fSuppressPrints : 1;
    bool fWireframeMode  : 1;

    using INHERITED = SkRefCnt;
};

GR_MAKE_BITFIELD_CLASS_OPS(GrCaps::ProgramDescOverrideFlags);

#endif
