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

#ifndef GrMeshDrawTarget_DEFINED
#define GrMeshDrawTarget_DEFINED

#include "src/base/SkArenaAlloc.h"
#include "src/gpu/ganesh/GrDrawIndirectCommand.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"

class GrAtlasManager;
class GrThreadSafeCache;

namespace skgpu {
    namespace v1 { class SmallPathAtlasMgr; }

    struct IndexWriter;
    struct VertexWriter;
} // namespace skgpu

namespace sktext::gpu {
class StrikeCache;
}

/*
 * Abstract interface that supports creating vertices, indices, and meshes, as well as
 * invoking GPU draw operations.
 */
class GrMeshDrawTarget {
public:
    virtual ~GrMeshDrawTarget() {}

    /** Adds a draw of a mesh. 'primProcProxies' must have
     * GrGeometryProcessor::numTextureSamplers() entries. Can be null if no samplers.
     */
    virtual void recordDraw(const GrGeometryProcessor*,
                            const GrSimpleMesh[],
                            int meshCnt,
                            const GrSurfaceProxy* const primProcProxies[],
                            GrPrimitiveType) = 0;

    /**
     * Helper for drawing GrSimpleMesh(es) with zero primProc textures.
     */
    void recordDraw(const GrGeometryProcessor* gp,
                    const GrSimpleMesh meshes[],
                    int meshCnt,
                    GrPrimitiveType primitiveType) {
        this->recordDraw(gp, meshes, meshCnt, nullptr, primitiveType);
    }

    /**
     * Makes space for vertex data. The returned pointer is the location where vertex data
     * should be written. On return the buffer that will hold the data as well as an offset into
     * the buffer (in 'vertexSize' units) where the data will be placed.
     */
    virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
                                  int* startVertex) = 0;

    /**
     * Makes space for index data. The returned pointer is the location where index data
     * should be written. On return the buffer that will hold the data as well as an offset into
     * the buffer (in uint16_t units) where the data will be placed.
     */
    virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;

    /**
     * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
     * vertices in the returned pointer, which may exceed 'minVertexCount'.
     * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
     * buffer is allocated on behalf of this request.
     */
    virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
                                         int fallbackVertexCount, sk_sp<const GrBuffer>*,
                                         int* startVertex, int* actualVertexCount) = 0;

    /**
     * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
     * indices in the returned pointer, which may exceed 'minIndexCount'.
     * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
     * buffer is allocated on behalf of this request.
     */
    virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
                                            sk_sp<const GrBuffer>*, int* startIndex,
                                            int* actualIndexCount) = 0;

    /**
     * Makes space for elements in a draw-indirect buffer. Upon success, the returned pointer is a
     * CPU mapping where the data should be written.
     */
    virtual GrDrawIndirectWriter makeDrawIndirectSpace(int drawCount, sk_sp<const GrBuffer>* buffer,
                                                       size_t* offsetInBytes) = 0;

    /**
     * Makes space for elements in a draw-indexed-indirect buffer. Upon success, the returned
     * pointer is a CPU mapping where the data should be written.
     */
    virtual GrDrawIndexedIndirectWriter makeDrawIndexedIndirectSpace(int drawCount,
                                                                     sk_sp<const GrBuffer>*,
                                                                     size_t* offsetInBytes) = 0;

    /** Helpers for ops that only need to use the VertexWriter to fill the data directly. */
    skgpu::VertexWriter makeVertexWriter(size_t vertexSize, int vertexCount,
                                         sk_sp<const GrBuffer>*, int* startVertex);
    skgpu::IndexWriter makeIndexWriter(int indexCount, sk_sp<const GrBuffer>*, int* startIndex);
    skgpu::VertexWriter makeVertexWriterAtLeast(size_t vertexSize, int minVertexCount,
                                                int fallbackVertexCount, sk_sp<const GrBuffer>*,
                                                int* startVertex, int* actualVertexCount);
    skgpu::IndexWriter makeIndexWriterAtLeast(int minIndexCount, int fallbackIndexCount,
                                              sk_sp<const GrBuffer>*, int* startIndex,
                                              int* actualIndexCount);

    /** Helpers for ops which over-allocate and then return excess data to the pool. */
    virtual void putBackIndices(int indices) = 0;
    virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
    virtual void putBackIndirectDraws(int count) = 0;
    virtual void putBackIndexedIndirectDraws(int count) = 0;

    GrSimpleMesh* allocMesh() { return this->allocator()->make<GrSimpleMesh>(); }
    GrSimpleMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrSimpleMesh>(n); }
    const GrSurfaceProxy** allocPrimProcProxyPtrs(int n) {
        return this->allocator()->makeArray<const GrSurfaceProxy*>(n);
    }

    virtual GrRenderTargetProxy* rtProxy() const = 0;
    virtual const GrSurfaceProxyView& writeView() const = 0;

    virtual const GrAppliedClip* appliedClip() const = 0;
    virtual GrAppliedClip detachAppliedClip() = 0;

    virtual const GrDstProxyView& dstProxyView() const = 0;
    virtual bool usesMSAASurface() const = 0;

    virtual GrXferBarrierFlags renderPassBarriers() const = 0;

    virtual GrLoadOp colorLoadOp() const = 0;

    virtual GrThreadSafeCache* threadSafeCache() const = 0;
    virtual GrResourceProvider* resourceProvider() const = 0;
    uint32_t contextUniqueID() const;

    virtual sktext::gpu::StrikeCache* strikeCache() const = 0;
    virtual GrAtlasManager* atlasManager() const = 0;
#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
    virtual skgpu::v1::SmallPathAtlasMgr* smallPathAtlasManager() const = 0;
#endif

    // This should be called during onPrepare of a GrOp. The caller should add any proxies to the
    // array it will use that it did not access during a call to visitProxies. This is usually the
    // case for atlases.
    virtual SkTArray<GrSurfaceProxy*, true>* sampledProxyArray() = 0;

    virtual const GrCaps& caps() const = 0;

    virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;

    virtual SkArenaAlloc* allocator() = 0;
};

#endif
