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

#ifndef GrBufferAllocPool_DEFINED
#define GrBufferAllocPool_DEFINED

#include "include/core/SkTypes.h"
#include "include/private/GrTypesPriv.h"
#include "include/private/SkNoncopyable.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTDArray.h"
#include "src/gpu/GrCpuBuffer.h"
#include "src/gpu/GrDrawIndirectCommand.h"
#include "src/gpu/GrNonAtomicRef.h"

class GrGpu;

/**
 * A pool of geometry buffers tied to a GrGpu.
 *
 * The pool allows a client to make space for geometry and then put back excess
 * space if it over allocated. When a client is ready to draw from the pool
 * it calls unmap on the pool ensure buffers are ready for drawing. The pool
 * can be reset after drawing is completed to recycle space.
 *
 * At creation time a minimum per-buffer size can be specified. Additionally,
 * a number of buffers to preallocate can be specified. These will
 * be allocated at the min size and kept around until the pool is destroyed.
 */
class GrBufferAllocPool : SkNoncopyable {
public:
    inline static constexpr size_t kDefaultBufferSize = 1 << 15;

    /**
     * A cache object that can be shared by multiple GrBufferAllocPool instances. It caches
     * cpu buffer allocations to avoid reallocating them.
     */
    class CpuBufferCache : public GrNonAtomicRef<CpuBufferCache> {
    public:
        static sk_sp<CpuBufferCache> Make(int maxBuffersToCache);

        sk_sp<GrCpuBuffer> makeBuffer(size_t size, bool mustBeInitialized);
        void releaseAll();

    private:
        CpuBufferCache(int maxBuffersToCache);

        struct Buffer {
            sk_sp<GrCpuBuffer> fBuffer;
            bool fCleared = false;
        };
        std::unique_ptr<Buffer[]> fBuffers;
        int fMaxBuffersToCache = 0;
    };

    /**
     * Ensures all buffers are unmapped and have all data written to them.
     * Call before drawing using buffers from the pool.
     */
    void unmap();

    /**
     *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
     */
    void reset();

    /**
     * Frees data from makeSpaces in LIFO order.
     */
    void putBack(size_t bytes);

protected:
    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the buffers.
     * @param bufferType            The type of buffers to create.
     * @param cpuBufferCache        If non-null a cache for client side array buffers
     *                              or staging buffers used before data is uploaded to
     *                              GPU buffer objects.
     */
    GrBufferAllocPool(GrGpu* gpu, GrGpuBufferType bufferType, sk_sp<CpuBufferCache> cpuBufferCache);

    virtual ~GrBufferAllocPool();

    /**
     * Returns a block of memory to hold data. A buffer designated to hold the
     * data is given to the caller. The buffer may or may not be locked. The
     * returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the data is guaranteed to be in the
     * buffer at the offset indicated by offset. Until that time it may be
     * in temporary storage and/or the buffer may be locked.
     *
     * @param size         the amount of data to make space for
     * @param alignment    alignment constraint from start of buffer
     * @param buffer       returns the buffer that will hold the data.
     * @param offset       returns the offset into buffer of the data.
     * @return pointer to where the client should write the data.
     */
    void* makeSpace(size_t size, size_t alignment, sk_sp<const GrBuffer>* buffer, size_t* offset);

    /**
     * Returns a block of memory to hold data. A buffer designated to hold the
     * data is given to the caller. The buffer may or may not be locked. The
     * returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the data is guaranteed to be in the
     * buffer at the offset indicated by offset. Until that time it may be
     * in temporary storage and/or the buffer may be locked.
     *
     * The caller requests a minimum number of bytes, but the block may be (much)
     * larger. Assuming that a new block must be allocated, it will be fallbackSize bytes.
     * The actual block size is returned in actualSize.
     *
     * @param minSize        the minimum amount of data to make space for
     * @param fallbackSize   the amount of data to make space for if a new block is needed
     * @param alignment      alignment constraint from start of buffer
     * @param buffer         returns the buffer that will hold the data.
     * @param offset         returns the offset into buffer of the data.
     * @param actualSize     returns the capacity of the block
     * @return pointer to where the client should write the data.
     */
    void* makeSpaceAtLeast(size_t minSize,
                           size_t fallbackSize,
                           size_t alignment,
                           sk_sp<const GrBuffer>* buffer,
                           size_t* offset,
                           size_t* actualSize);

    sk_sp<GrBuffer> getBuffer(size_t size);

private:
    struct BufferBlock {
        size_t fBytesFree;
        sk_sp<GrBuffer> fBuffer;
    };

    bool createBlock(size_t requestSize);
    void destroyBlock();
    void deleteBlocks();
    void flushCpuData(const BufferBlock& block, size_t flushSize);
    void resetCpuData(size_t newSize);
#ifdef SK_DEBUG
    void validate(bool unusedBlockAllowed = false) const;
#endif
    size_t fBytesInUse = 0;

    SkTArray<BufferBlock> fBlocks;
    sk_sp<CpuBufferCache> fCpuBufferCache;
    sk_sp<GrCpuBuffer> fCpuStagingBuffer;
    GrGpu* fGpu;
    GrGpuBufferType fBufferType;
    void* fBufferPtr = nullptr;
};

/**
 * A GrBufferAllocPool of vertex buffers
 */
class GrVertexBufferAllocPool : public GrBufferAllocPool {
public:
    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the vertex buffers.
     * @param cpuBufferCache        If non-null a cache for client side array buffers
     *                              or staging buffers used before data is uploaded to
     *                              GPU buffer objects.
     */
    GrVertexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);

    /**
     * Returns a block of memory to hold vertices. A buffer designated to hold
     * the vertices given to the caller. The buffer may or may not be locked.
     * The returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the vertices are guaranteed to be in
     * the buffer at the offset indicated by startVertex. Until that time they
     * may be in temporary storage and/or the buffer may be locked.
     *
     * @param vertexSize   specifies size of a vertex to allocate space for
     * @param vertexCount  number of vertices to allocate space for
     * @param buffer       returns the vertex buffer that will hold the
     *                     vertices.
     * @param startVertex  returns the offset into buffer of the first vertex.
     *                     In units of the size of a vertex from layout param.
     * @return pointer to first vertex.
     */
    void* makeSpace(size_t vertexSize,
                    int vertexCount,
                    sk_sp<const GrBuffer>* buffer,
                    int* startVertex);

    /**
     * Returns a block of memory to hold vertices. A buffer designated to hold
     * the vertices given to the caller. The buffer may or may not be locked.
     * The returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the vertices are guaranteed to be in
     * the buffer at the offset indicated by startVertex. Until that time they
     * may be in temporary storage and/or the buffer may be locked.
     *
     * The caller requests a minimum number of vertices, but the block may be (much)
     * larger. Assuming that a new block must be allocated, it will be sized to hold
     * fallbackVertexCount vertices. The actual block size (in vertices) is returned in
     * actualVertexCount.
     *
     * @param vertexSize           specifies size of a vertex to allocate space for
     * @param minVertexCount       minimum number of vertices to allocate space for
     * @param fallbackVertexCount  number of vertices to allocate space for if a new block is needed
     * @param buffer               returns the vertex buffer that will hold the vertices.
     * @param startVertex          returns the offset into buffer of the first vertex.
     *                             In units of the size of a vertex from layout param.
     * @param actualVertexCount    returns the capacity of the block (in vertices)
     * @return pointer to first vertex.
     */
    void* makeSpaceAtLeast(size_t vertexSize,
                           int minVertexCount,
                           int fallbackVertexCount,
                           sk_sp<const GrBuffer>* buffer,
                           int* startVertex,
                           int* actualVertexCount);

private:
    using INHERITED = GrBufferAllocPool;
};

/**
 * A GrBufferAllocPool of index buffers
 */
class GrIndexBufferAllocPool : public GrBufferAllocPool {
public:
    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the index buffers.
     * @param cpuBufferCache        If non-null a cache for client side array buffers
     *                              or staging buffers used before data is uploaded to
     *                              GPU buffer objects.
     */
    GrIndexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);

    /**
     * Returns a block of memory to hold indices. A buffer designated to hold
     * the indices is given to the caller. The buffer may or may not be locked.
     * The returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the indices are guaranteed to be in the
     * buffer at the offset indicated by startIndex. Until that time they may be
     * in temporary storage and/or the buffer may be locked.
     *
     * @param indexCount   number of indices to allocate space for
     * @param buffer       returns the index buffer that will hold the indices.
     * @param startIndex   returns the offset into buffer of the first index.
     * @return pointer to first index.
     */
    void* makeSpace(int indexCount, sk_sp<const GrBuffer>* buffer, int* startIndex);

    /**
     * Returns a block of memory to hold indices. A buffer designated to hold
     * the indices is given to the caller. The buffer may or may not be locked.
     * The returned ptr remains valid until any of the following:
     *      *makeSpace is called again.
     *      *unmap is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unmap on the pool is called the indices are guaranteed to be in the
     * buffer at the offset indicated by startIndex. Until that time they may be
     * in temporary storage and/or the buffer may be locked.
     *
     * The caller requests a minimum number of indices, but the block may be (much)
     * larger. Assuming that a new block must be allocated, it will be sized to hold
     * fallbackIndexCount indices. The actual block size (in indices) is returned in
     * actualIndexCount.
     *
     * @param minIndexCount        minimum number of indices to allocate space for
     * @param fallbackIndexCount   number of indices to allocate space for if a new block is needed
     * @param buffer               returns the index buffer that will hold the indices.
     * @param startIndex           returns the offset into buffer of the first index.
     * @param actualIndexCount     returns the capacity of the block (in indices)
     * @return pointer to first index.
     */
    void* makeSpaceAtLeast(int minIndexCount,
                           int fallbackIndexCount,
                           sk_sp<const GrBuffer>* buffer,
                           int* startIndex,
                           int* actualIndexCount);

private:
    using INHERITED = GrBufferAllocPool;
};

class GrDrawIndirectBufferAllocPool : private GrBufferAllocPool {
public:
    GrDrawIndirectBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache)
            : GrBufferAllocPool(gpu, GrGpuBufferType::kDrawIndirect, std::move(cpuBufferCache)) {}

    GrDrawIndirectWriter makeSpace(int drawCount, sk_sp<const GrBuffer>* buffer, size_t* offset) {
        return this->GrBufferAllocPool::makeSpace(drawCount * sizeof(GrDrawIndirectCommand), 4,
                                                  buffer, offset);
    }

    void putBack(int drawCount) {
        this->GrBufferAllocPool::putBack(drawCount * sizeof(GrDrawIndirectCommand));
    }

    GrDrawIndexedIndirectWriter makeIndexedSpace(int drawCount, sk_sp<const GrBuffer>* buffer,
                                                 size_t* offset) {
        return this->GrBufferAllocPool::makeSpace(
                drawCount * sizeof(GrDrawIndexedIndirectCommand), 4, buffer, offset);
    }

    void putBackIndexed(int drawCount) {
        this->GrBufferAllocPool::putBack(drawCount * sizeof(GrDrawIndexedIndirectCommand));
    }

    using GrBufferAllocPool::unmap;
    using GrBufferAllocPool::reset;
};

#endif
