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

#ifndef GrGpu_DEFINED
#define GrGpu_DEFINED

#include "include/core/SkPath.h"
#include "include/core/SkSpan.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrTypes.h"
#include "include/private/SkTArray.h"
#include "src/core/SkTInternalLList.h"
#include "src/gpu/GrAttachment.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrOpsRenderPass.h"
#include "src/gpu/GrPixmap.h"
#include "src/gpu/GrSwizzle.h"
#include "src/gpu/GrXferProcessor.h"

class GrAttachment;
class GrBackendRenderTarget;
class GrBackendSemaphore;
struct GrContextOptions;
class GrDirectContext;
class GrGpuBuffer;
class GrGLContext;
class GrPath;
class GrPathRenderer;
class GrPathRendererChain;
class GrPipeline;
class GrGeometryProcessor;
class GrRenderTarget;
class GrRingBuffer;
class GrSemaphore;
class GrStagingBufferManager;
class GrStencilSettings;
class GrSurface;
class GrTexture;
class GrThreadSafePipelineBuilder;
class SkJSONWriter;

namespace SkSL {
    class Compiler;
}

class GrGpu : public SkRefCnt {
public:
    GrGpu(GrDirectContext* direct);
    ~GrGpu() override;

    GrDirectContext* getContext() { return fContext; }
    const GrDirectContext* getContext() const { return fContext; }

    /**
     * Gets the capabilities of the draw target.
     */
    const GrCaps* caps() const { return fCaps.get(); }
    sk_sp<const GrCaps> refCaps() const { return fCaps; }

    virtual GrStagingBufferManager* stagingBufferManager() { return nullptr; }

    virtual GrRingBuffer* uniformsRingBuffer() { return nullptr; }

    SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); }

    enum class DisconnectType {
        // No cleanup should be attempted, immediately cease making backend API calls
        kAbandon,
        // Free allocated resources (not known by GrResourceCache) before returning and
        // ensure no backend backend 3D API calls will be made after disconnect() returns.
        kCleanup,
    };

    // Called by context when the underlying backend context is already or will be destroyed
    // before GrDirectContext.
    virtual void disconnect(DisconnectType);

    virtual GrThreadSafePipelineBuilder* pipelineBuilder() = 0;
    virtual sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() = 0;

    // Called by GrDirectContext::isContextLost. Returns true if the backend Gpu object has gotten
    // into an unrecoverable, lost state.
    virtual bool isDeviceLost() const { return false; }

    /**
     * The GrGpu object normally assumes that no outsider is setting state
     * within the underlying 3D API's context/device/whatever. This call informs
     * the GrGpu that the state was modified and it shouldn't make assumptions
     * about the state.
     */
    void markContextDirty(uint32_t state = kAll_GrBackendState) { fResetBits |= state; }

    /**
     * Creates a texture object. If renderable is kYes then the returned texture can
     * be used as a render target by calling GrTexture::asRenderTarget(). Not all
     * pixel configs can be used as render targets. Support for configs as textures
     * or render targets can be checked using GrCaps.
     *
     * @param dimensions     dimensions of the texture to be created.
     * @param format         the format for the texture (not currently used).
     * @param renderable     should the resulting texture be renderable
     * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is
     *                       kYes. If renderable is kNo then this must be 1.
     * @param budgeted       does this texture count against the resource cache budget?
     * @param isProtected    should the texture be created as protected.
     * @param texels         array of mipmap levels containing texel data to load.
     *                       If level i has pixels then it is assumed that its dimensions are
     *                       max(1, floor(dimensions.fWidth / 2)) by
     *                       max(1, floor(dimensions.fHeight / 2)).
     *                       If texels[i].fPixels == nullptr for all i <= mipLevelCount or
     *                       mipLevelCount is 0 then the texture's contents are uninitialized.
     *                       If a level has non-null pixels, its row bytes must be a multiple of the
     *                       config's bytes-per-pixel. The row bytes must be tight to the
     *                       level width if !caps->writePixelsRowBytesSupport().
     *                       If mipLevelCount > 1 and texels[i].fPixels != nullptr for any i > 0
     *                       then all levels must have non-null pixels. All levels must have
     *                       non-null pixels if GrCaps::createTextureMustSpecifyAllLevels() is true.
     * @param textureColorType The color type interpretation of the texture for the purpose of
     *                       of uploading texel data.
     * @param srcColorType   The color type of data in texels[].
     * @param texelLevelCount the number of levels in 'texels'. May be 0, 1, or
     *                       floor(max((log2(dimensions.fWidth), log2(dimensions.fHeight)))). It
     *                       must be the latter if GrCaps::createTextureMustSpecifyAllLevels() is
     *                       true.
     * @return  The texture object if successful, otherwise nullptr.
     */
    sk_sp<GrTexture> createTexture(SkISize dimensions,
                                   const GrBackendFormat& format,
                                   GrTextureType textureType,
                                   GrRenderable renderable,
                                   int renderTargetSampleCnt,
                                   SkBudgeted budgeted,
                                   GrProtected isProtected,
                                   GrColorType textureColorType,
                                   GrColorType srcColorType,
                                   const GrMipLevel texels[],
                                   int texelLevelCount);

    /**
     * Simplified createTexture() interface for when there is no initial texel data to upload.
     */
    sk_sp<GrTexture> createTexture(SkISize dimensions,
                                   const GrBackendFormat& format,
                                   GrTextureType textureType,
                                   GrRenderable renderable,
                                   int renderTargetSampleCnt,
                                   GrMipmapped mipMapped,
                                   SkBudgeted budgeted,
                                   GrProtected isProtected);

    sk_sp<GrTexture> createCompressedTexture(SkISize dimensions,
                                             const GrBackendFormat& format,
                                             SkBudgeted budgeted,
                                             GrMipmapped mipMapped,
                                             GrProtected isProtected,
                                             const void* data, size_t dataSize);

    /**
     * Implements GrResourceProvider::wrapBackendTexture
     */
    sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&,
                                        GrWrapOwnership,
                                        GrWrapCacheable,
                                        GrIOType);

    sk_sp<GrTexture> wrapCompressedBackendTexture(const GrBackendTexture&,
                                                  GrWrapOwnership,
                                                  GrWrapCacheable);

    /**
     * Implements GrResourceProvider::wrapRenderableBackendTexture
     */
    sk_sp<GrTexture> wrapRenderableBackendTexture(const GrBackendTexture&,
                                                  int sampleCnt,
                                                  GrWrapOwnership,
                                                  GrWrapCacheable);

    /**
     * Implements GrResourceProvider::wrapBackendRenderTarget
     */
    sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTarget&);

    /**
     * Implements GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget
     */
    sk_sp<GrRenderTarget> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
                                                              const GrVkDrawableInfo&);

    /**
     * Creates a buffer in GPU memory. For a client-side buffer use GrBuffer::CreateCPUBacked.
     *
     * @param size            size of buffer to create.
     * @param intendedType    hint to the graphics subsystem about what the buffer will be used for.
     * @param accessPattern   hint to the graphics subsystem about how the data will be accessed.
     * @param data            optional data with which to initialize the buffer.
     *
     * @return the buffer if successful, otherwise nullptr.
     */
    sk_sp<GrGpuBuffer> createBuffer(size_t size, GrGpuBufferType intendedType,
                                    GrAccessPattern accessPattern, const void* data = nullptr);

    /**
     * Resolves MSAA. The resolveRect must already be in the native destination space.
     */
    void resolveRenderTarget(GrRenderTarget*, const SkIRect& resolveRect);

    /**
     * Uses the base of the texture to recompute the contents of the other levels.
     */
    bool regenerateMipMapLevels(GrTexture*);

    /**
     * If the backend API has stateful texture bindings, this resets them back to defaults.
     */
    void resetTextureBindings();

    /**
     * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
     *
     * @param surface           the surface to read from
     * @param rect              the rectangle of pixels to read
     * @param surfaceColorType  the color type for this use of the surface.
     * @param dstColorType      the color type of the destination buffer.
     * @param buffer            memory to read the rectangle into.
     * @param rowBytes          the number of bytes between consecutive rows. Must be a multiple of
     *                          dstColorType's bytes-per-pixel. Must be tight to width if
     *                          !caps->readPixelsRowBytesSupport().
     *
     * @return true if the read succeeded, false if not. The read can fail
     *              because of the surface doesn't support reading, the color type
     *              is not allowed for the format of the surface or if the rectangle
     *              read is not contained in the surface.
     */
    bool readPixels(GrSurface* surface,
                    SkIRect rect,
                    GrColorType surfaceColorType,
                    GrColorType dstColorType,
                    void* buffer,
                    size_t rowBytes);

    /**
     * Updates the pixels in a rectangle of a surface.  No sRGB/linear conversions are performed.
     *
     * @param surface            the surface to write to.
     * @param rect               the rectangle of pixels to overwrite
     * @param surfaceColorType   the color type for this use of the surface.
     * @param srcColorType       the color type of the source buffer.
     * @param texels             array of mipmap levels containing texture data. Row bytes must be a
     *                           multiple of srcColorType's bytes-per-pixel. Must be tight to level
     *                           width if !caps->writePixelsRowBytesSupport().
     * @param mipLevelCount      number of levels in 'texels'
     * @param prepForTexSampling After doing write pixels should the surface be prepared for texture
     *                           sampling. This is currently only used by Vulkan for inline uploads
     *                           to set that layout back to sampled after doing the upload. Inline
     *                           uploads currently can happen between draws in a single op so it is
     *                           not trivial to break up the OpsTask into two tasks when we see
     *                           an inline upload. However, once we are able to support doing that
     *                           we can remove this parameter.
     *
     * @return true if the write succeeded, false if not. The read can fail
     *              because of the surface doesn't support writing (e.g. read only),
     *              the color type is not allowed for the format of the surface or
     *              if the rectangle written is not contained in the surface.
     */
    bool writePixels(GrSurface* surface,
                     SkIRect rect,
                     GrColorType surfaceColorType,
                     GrColorType srcColorType,
                     const GrMipLevel texels[],
                     int mipLevelCount,
                     bool prepForTexSampling = false);

    /**
     * Helper for the case of a single level.
     */
    bool writePixels(GrSurface* surface,
                     SkIRect rect,
                     GrColorType surfaceColorType,
                     GrColorType srcColorType,
                     const void* buffer,
                     size_t rowBytes,
                     bool prepForTexSampling = false) {
        GrMipLevel mipLevel = {buffer, rowBytes, nullptr};
        return this->writePixels(surface,
                                 rect,
                                 surfaceColorType,
                                 srcColorType,
                                 &mipLevel,
                                 1,
                                 prepForTexSampling);
    }

    /**
     * Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped,
     * the base level is written to.
     *
     * @param texture          the texture to write to.
     * @param rect             the rectangle of pixels in the texture to overwrite
     * @param textureColorType the color type for this use of the surface.
     * @param bufferColorType  the color type of the transfer buffer's pixel data
     * @param transferBuffer   GrBuffer to read pixels from (type must be "kXferCpuToGpu")
     * @param offset           offset from the start of the buffer
     * @param rowBytes         number of bytes between consecutive rows in the buffer. Must be a
     *                         multiple of bufferColorType's bytes-per-pixel. Must be tight to
     *                         rect.width() if !caps->writePixelsRowBytesSupport().
     */
    bool transferPixelsTo(GrTexture* texture,
                          SkIRect rect,
                          GrColorType textureColorType,
                          GrColorType bufferColorType,
                          sk_sp<GrGpuBuffer> transferBuffer,
                          size_t offset,
                          size_t rowBytes);

    /**
     * Reads the pixels from a rectangle of a surface into a buffer. Use
     * GrCaps::SupportedRead::fOffsetAlignmentForTransferBuffer to determine the requirements for
     * the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read.
     *
     * If successful the row bytes in the buffer is always:
     *   GrColorTypeBytesPerPixel(bufferColorType) * rect.width()
     *
     * Asserts that the caller has passed a properly aligned offset and that the buffer is
     * large enough to hold the result
     *
     * @param surface          the surface to read from.
     * @param rect             the rectangle of pixels to read
     * @param surfaceColorType the color type for this use of the surface.
     * @param bufferColorType  the color type of the transfer buffer's pixel data
     * @param transferBuffer   GrBuffer to write pixels to (type must be "kXferGpuToCpu")
     * @param offset           offset from the start of the buffer
     */
    bool transferPixelsFrom(GrSurface* surface,
                            SkIRect rect,
                            GrColorType surfaceColorType,
                            GrColorType bufferColorType,
                            sk_sp<GrGpuBuffer> transferBuffer,
                            size_t offset);

    // Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
    // take place at higher levels and this function implement faster copy paths. The rect
    // and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the
    // src/dst bounds and non-empty. They must also be in their exact device space coords, including
    // already being transformed for origin if need be. If canDiscardOutsideDstRect is set to true
    // then we don't need to preserve any data on the dst surface outside of the copy.
    bool copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
                     const SkIPoint& dstPoint);

    // Returns a GrOpsRenderPass which OpsTasks send draw commands to instead of directly
    // to the Gpu object. The 'bounds' rect is the content rect of the renderTarget.
    // If a 'stencil' is provided it will be the one bound to 'renderTarget'. If one is not
    // provided but 'renderTarget' has a stencil buffer then that is a signal that the
    // render target's stencil buffer should be ignored.
    GrOpsRenderPass* getOpsRenderPass(GrRenderTarget* renderTarget,
                                      bool useMSAASurface,
                                      GrAttachment* stencil,
                                      GrSurfaceOrigin,
                                      const SkIRect& bounds,
                                      const GrOpsRenderPass::LoadAndStoreInfo&,
                                      const GrOpsRenderPass::StencilLoadAndStoreInfo&,
                                      const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
                                      GrXferBarrierFlags renderPassXferBarriers);

    // Called by GrDrawingManager when flushing.
    // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also
    // insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the
    // inserted semaphores.
    void executeFlushInfo(SkSpan<GrSurfaceProxy*>,
                          SkSurface::BackendSurfaceAccess access,
                          const GrFlushInfo&,
                          const GrBackendSurfaceMutableState* newState);

    bool submitToGpu(bool syncCpu);

    virtual void submit(GrOpsRenderPass*) = 0;

    virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0;
    virtual bool waitFence(GrFence) = 0;
    virtual void deleteFence(GrFence) const = 0;

    virtual std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(
            bool isOwned = true) = 0;
    virtual std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
                                                              GrSemaphoreWrapType,
                                                              GrWrapOwnership) = 0;
    virtual void insertSemaphore(GrSemaphore* semaphore) = 0;
    virtual void waitSemaphore(GrSemaphore* semaphore) = 0;

    virtual void addFinishedProc(GrGpuFinishedProc finishedProc,
                                 GrGpuFinishedContext finishedContext) = 0;
    virtual void checkFinishProcs() = 0;
    virtual void finishOutstandingGpuWork() = 0;

    virtual void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) {}

    /**
     * Checks if we detected an OOM from the underlying 3D API and if so returns true and resets
     * the internal OOM state to false. Otherwise, returns false.
     */
    bool checkAndResetOOMed();

    /**
     *  Put this texture in a safe and known state for use across multiple contexts. Depending on
     *  the backend, this may return a GrSemaphore. If so, other contexts should wait on that
     *  semaphore before using this texture.
     */
    virtual std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) = 0;

    /**
     * Frees any backend specific objects that are not currently in use by the GPU. This is called
     * when the client is trying to free up as much GPU memory as possible. We will not release
     * resources connected to programs/pipelines since the cost to recreate those is significantly
     * higher that other resources.
     */
    virtual void releaseUnlockedBackendObjects() {}

    ///////////////////////////////////////////////////////////////////////////
    // Debugging and Stats

    class Stats {
    public:
#if GR_GPU_STATS
        Stats() = default;

        void reset() { *this = {}; }

        int textureCreates() const { return fTextureCreates; }
        void incTextureCreates() { fTextureCreates++; }

        int textureUploads() const { return fTextureUploads; }
        void incTextureUploads() { fTextureUploads++; }

        int transfersToTexture() const { return fTransfersToTexture; }
        void incTransfersToTexture() { fTransfersToTexture++; }

        int transfersFromSurface() const { return fTransfersFromSurface; }
        void incTransfersFromSurface() { fTransfersFromSurface++; }

        int stencilAttachmentCreates() const { return fStencilAttachmentCreates; }
        void incStencilAttachmentCreates() { fStencilAttachmentCreates++; }

        int msaaAttachmentCreates() const { return fMSAAAttachmentCreates; }
        void incMSAAAttachmentCreates() { fMSAAAttachmentCreates++; }

        int numDraws() const { return fNumDraws; }
        void incNumDraws() { fNumDraws++; }

        int numFailedDraws() const { return fNumFailedDraws; }
        void incNumFailedDraws() { ++fNumFailedDraws; }

        int numSubmitToGpus() const { return fNumSubmitToGpus; }
        void incNumSubmitToGpus() { ++fNumSubmitToGpus; }

        int numScratchTexturesReused() const { return fNumScratchTexturesReused; }
        void incNumScratchTexturesReused() { ++fNumScratchTexturesReused; }

        int numScratchMSAAAttachmentsReused() const { return fNumScratchMSAAAttachmentsReused; }
        void incNumScratchMSAAAttachmentsReused() { ++fNumScratchMSAAAttachmentsReused; }

        int renderPasses() const { return fRenderPasses; }
        void incRenderPasses() { fRenderPasses++; }

        int numReorderedDAGsOverBudget() const { return fNumReorderedDAGsOverBudget; }
        void incNumReorderedDAGsOverBudget() { fNumReorderedDAGsOverBudget++; }

#if GR_TEST_UTILS
        void dump(SkString*);
        void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values);
#endif
    private:
        int fTextureCreates = 0;
        int fTextureUploads = 0;
        int fTransfersToTexture = 0;
        int fTransfersFromSurface = 0;
        int fStencilAttachmentCreates = 0;
        int fMSAAAttachmentCreates = 0;
        int fNumDraws = 0;
        int fNumFailedDraws = 0;
        int fNumSubmitToGpus = 0;
        int fNumScratchTexturesReused = 0;
        int fNumScratchMSAAAttachmentsReused = 0;
        int fRenderPasses = 0;
        int fNumReorderedDAGsOverBudget = 0;

#else  // !GR_GPU_STATS

#if GR_TEST_UTILS
        void dump(SkString*) {}
        void dumpKeyValuePairs(SkTArray<SkString>*, SkTArray<double>*) {}
#endif
        void incTextureCreates() {}
        void incTextureUploads() {}
        void incTransfersToTexture() {}
        void incTransfersFromSurface() {}
        void incStencilAttachmentCreates() {}
        void incMSAAAttachmentCreates() {}
        void incNumDraws() {}
        void incNumFailedDraws() {}
        void incNumSubmitToGpus() {}
        void incNumScratchTexturesReused() {}
        void incNumScratchMSAAAttachmentsReused() {}
        void incRenderPasses() {}
        void incNumReorderedDAGsOverBudget() {}
#endif
    };

    Stats* stats() { return &fStats; }
    void dumpJSON(SkJSONWriter*) const;


    /**
     * Creates a texture directly in the backend API without wrapping it in a GrTexture.
     * Must be matched with a call to deleteBackendTexture().
     *
     * If data is null the texture is uninitialized.
     *
     * If data represents a color then all texture levels are cleared to that color.
     *
     * If data represents pixmaps then it must have a either one pixmap or, if mipmapping
     * is specified, a complete MIP hierarchy of pixmaps. Additionally, if provided, the mip
     * levels must be sized correctly according to the MIP sizes implied by dimensions. They
     * must all have the same color type and that color type must be compatible with the
     * texture format.
     */
    GrBackendTexture createBackendTexture(SkISize dimensions,
                                          const GrBackendFormat&,
                                          GrRenderable,
                                          GrMipmapped,
                                          GrProtected);

    bool clearBackendTexture(const GrBackendTexture&,
                             sk_sp<GrRefCntedCallback> finishedCallback,
                             std::array<float, 4> color);

    /**
     * Same as the createBackendTexture case except compressed backend textures can
     * never be renderable.
     */
    GrBackendTexture createCompressedBackendTexture(SkISize dimensions,
                                                    const GrBackendFormat&,
                                                    GrMipmapped,
                                                    GrProtected);

    bool updateCompressedBackendTexture(const GrBackendTexture&,
                                        sk_sp<GrRefCntedCallback> finishedCallback,
                                        const void* data,
                                        size_t length);

    virtual bool setBackendTextureState(const GrBackendTexture&,
                                        const GrBackendSurfaceMutableState&,
                                        GrBackendSurfaceMutableState* previousState,
                                        sk_sp<GrRefCntedCallback> finishedCallback) {
        return false;
    }

    virtual bool setBackendRenderTargetState(const GrBackendRenderTarget&,
                                             const GrBackendSurfaceMutableState&,
                                             GrBackendSurfaceMutableState* previousState,
                                             sk_sp<GrRefCntedCallback> finishedCallback) {
        return false;
    }

    /**
     * Frees a texture created by createBackendTexture(). If ownership of the backend
     * texture has been transferred to a context using adopt semantics this should not be called.
     */
    virtual void deleteBackendTexture(const GrBackendTexture&) = 0;

    /**
     * In this case we have a program descriptor and a program info but no render target.
     */
    virtual bool compile(const GrProgramDesc&, const GrProgramInfo&) = 0;

    virtual bool precompileShader(const SkData& key, const SkData& data) { return false; }

#if GR_TEST_UTILS
    /** Check a handle represents an actual texture in the backend API that has not been freed. */
    virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0;

    /**
     * Creates a GrBackendRenderTarget that can be wrapped using
     * SkSurface::MakeFromBackendRenderTarget. Ideally this is a non-textureable allocation to
     * differentiate from testing with SkSurface::MakeFromBackendTexture. When sampleCnt > 1 this
     * is used to test client wrapped allocations with MSAA where Skia does not allocate a separate
     * buffer for resolving. If the color is non-null the backing store should be cleared to the
     * passed in color.
     */
    virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(
            SkISize dimensions,
            GrColorType,
            int sampleCount = 1,
            GrProtected = GrProtected::kNo) = 0;

    /**
     * Deletes a GrBackendRenderTarget allocated with the above. Synchronization to make this safe
     * is up to the caller.
     */
    virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0;

    // This is only to be used in GL-specific tests.
    virtual const GrGLContext* glContextForTesting() const { return nullptr; }

    // This is only to be used by testing code
    virtual void resetShaderCacheForTesting() const {}

    /**
     * Inserted as a pair around a block of code to do a GPU frame capture.
     * Currently only works with the Metal backend.
     */
    virtual void testingOnly_startCapture() {}
    virtual void testingOnly_endCapture() {}
#endif

    // width and height may be larger than rt (if underlying API allows it).
    // Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on
    // the GrAttachment.
    virtual sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat,
                                                      SkISize dimensions,
                                                      int numStencilSamples) = 0;

    virtual GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) = 0;

    // Creates an MSAA surface to be used as an MSAA attachment on a framebuffer.
    virtual sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
                                                   const GrBackendFormat& format,
                                                   int numSamples,
                                                   GrProtected isProtected) = 0;

    void handleDirtyContext() {
        if (fResetBits) {
            this->resetContext();
        }
    }

    virtual void storeVkPipelineCacheData() {}

    // http://skbug.com/9739
    virtual void insertManualFramebufferBarrier() {
        SkASSERT(!this->caps()->requiresManualFBBarrierAfterTessellatedStencilDraw());
        SK_ABORT("Manual framebuffer barrier not supported.");
    }

    // Called before certain draws in order to guarantee coherent results from dst reads.
    virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0;

protected:
    static bool CompressedDataIsCorrect(SkISize dimensions,
                                        SkImage::CompressionType,
                                        GrMipmapped,
                                        const void* data,
                                        size_t length);

    // Handles cases where a surface will be updated without a call to flushRenderTarget.
    void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds,
                           uint32_t mipLevels = 1) const;

    void setOOMed() { fOOMed = true; }

    Stats                            fStats;

    // Subclass must call this to initialize caps & compiler in its constructor.
    void initCapsAndCompiler(sk_sp<const GrCaps> caps);

private:
    virtual GrBackendTexture onCreateBackendTexture(SkISize dimensions,
                                                    const GrBackendFormat&,
                                                    GrRenderable,
                                                    GrMipmapped,
                                                    GrProtected) = 0;

    virtual GrBackendTexture onCreateCompressedBackendTexture(
            SkISize dimensions, const GrBackendFormat&, GrMipmapped, GrProtected) = 0;

    virtual bool onClearBackendTexture(const GrBackendTexture&,
                                       sk_sp<GrRefCntedCallback> finishedCallback,
                                       std::array<float, 4> color) = 0;

    virtual bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
                                                  sk_sp<GrRefCntedCallback> finishedCallback,
                                                  const void* data,
                                                  size_t length) = 0;

    // called when the 3D context state is unknown. Subclass should emit any
    // assumed 3D context state and dirty any state cache.
    virtual void onResetContext(uint32_t resetBits) {}

    // Implementation of resetTextureBindings.
    virtual void onResetTextureBindings() {}

    // overridden by backend-specific derived class to create objects.
    // Texture size, renderablility, format support, sample count will have already been validated
    // in base class before onCreateTexture is called.
    // If the ith bit is set in levelClearMask then the ith MIP level should be cleared.
    virtual sk_sp<GrTexture> onCreateTexture(SkISize dimensions,
                                             const GrBackendFormat&,
                                             GrRenderable,
                                             int renderTargetSampleCnt,
                                             SkBudgeted,
                                             GrProtected,
                                             int mipLevelCoont,
                                             uint32_t levelClearMask) = 0;
    virtual sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
                                                       const GrBackendFormat&,
                                                       SkBudgeted,
                                                       GrMipmapped,
                                                       GrProtected,
                                                       const void* data, size_t dataSize) = 0;
    virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
                                                  GrWrapOwnership,
                                                  GrWrapCacheable,
                                                  GrIOType) = 0;

    virtual sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
                                                            GrWrapOwnership,
                                                            GrWrapCacheable) = 0;

    virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
                                                            int sampleCnt,
                                                            GrWrapOwnership,
                                                            GrWrapCacheable) = 0;
    virtual sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) = 0;
    virtual sk_sp<GrRenderTarget> onWrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
                                                                        const GrVkDrawableInfo&);

    virtual sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType,
                                              GrAccessPattern, const void* data) = 0;

    // overridden by backend-specific derived class to perform the surface read
    virtual bool onReadPixels(GrSurface*,
                              SkIRect,
                              GrColorType surfaceColorType,
                              GrColorType dstColorType,
                              void*,
                              size_t rowBytes) = 0;

    // overridden by backend-specific derived class to perform the surface write
    virtual bool onWritePixels(GrSurface*,
                               SkIRect,
                               GrColorType surfaceColorType,
                               GrColorType srcColorType,
                               const GrMipLevel[],
                               int mipLevelCount,
                               bool prepForTexSampling) = 0;

    // overridden by backend-specific derived class to perform the texture transfer
    virtual bool onTransferPixelsTo(GrTexture*,
                                    SkIRect,
                                    GrColorType textiueColorType,
                                    GrColorType bufferColorType,
                                    sk_sp<GrGpuBuffer> transferBuffer,
                                    size_t offset,
                                    size_t rowBytes) = 0;

    // overridden by backend-specific derived class to perform the surface transfer
    virtual bool onTransferPixelsFrom(GrSurface*,
                                      SkIRect,
                                      GrColorType surfaceColorType,
                                      GrColorType bufferColorType,
                                      sk_sp<GrGpuBuffer> transferBuffer,
                                      size_t offset) = 0;

    // overridden by backend-specific derived class to perform the resolve
    virtual void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) = 0;

    // overridden by backend specific derived class to perform mip map level regeneration.
    virtual bool onRegenerateMipMapLevels(GrTexture*) = 0;

    // overridden by backend specific derived class to perform the copy surface
    virtual bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
                               const SkIPoint& dstPoint) = 0;

    virtual GrOpsRenderPass* onGetOpsRenderPass(
            GrRenderTarget* renderTarget,
            bool useMSAASurface,
            GrAttachment* stencil,
            GrSurfaceOrigin,
            const SkIRect& bounds,
            const GrOpsRenderPass::LoadAndStoreInfo&,
            const GrOpsRenderPass::StencilLoadAndStoreInfo&,
            const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
            GrXferBarrierFlags renderPassXferBarriers) = 0;

    virtual void prepareSurfacesForBackendAccessAndStateUpdates(
            SkSpan<GrSurfaceProxy*> proxies,
            SkSurface::BackendSurfaceAccess access,
            const GrBackendSurfaceMutableState* newState) {}

    virtual bool onSubmitToGpu(bool syncCpu) = 0;

    void reportSubmitHistograms();
    virtual void onReportSubmitHistograms() {}

#ifdef SK_ENABLE_DUMP_GPU
    virtual void onDumpJSON(SkJSONWriter*) const {}
#endif

    sk_sp<GrTexture> createTextureCommon(SkISize,
                                         const GrBackendFormat&,
                                         GrTextureType textureType,
                                         GrRenderable,
                                         int renderTargetSampleCnt,
                                         SkBudgeted,
                                         GrProtected,
                                         int mipLevelCnt,
                                         uint32_t levelClearMask);

    void resetContext() {
        this->onResetContext(fResetBits);
        fResetBits = 0;
    }

    void callSubmittedProcs(bool success);

    sk_sp<const GrCaps>             fCaps;
    // Compiler used for compiling SkSL into backend shader code. We only want to create the
    // compiler once, as there is significant overhead to the first compile.
    std::unique_ptr<SkSL::Compiler> fCompiler;

    uint32_t fResetBits;
    // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu.
    GrDirectContext* fContext;

    struct SubmittedProc {
        SubmittedProc(GrGpuSubmittedProc proc, GrGpuSubmittedContext context)
                : fProc(proc), fContext(context) {}

        GrGpuSubmittedProc fProc;
        GrGpuSubmittedContext fContext;
    };
    SkSTArray<4, SubmittedProc> fSubmittedProcs;

    bool fOOMed = false;

#if SK_HISTOGRAMS_ENABLED
    int fCurrentSubmitRenderPassCount = 0;
#endif

    friend class GrPathRendering;
    using INHERITED = SkRefCnt;
};

#endif
