/*
 * 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 "SkTArray.h"
#include "SkTDArray.h"
#include "SkTypes.h"

class GrGeometryBuffer;
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:
    /**
     * 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();

    /**
     * Gets the number of preallocated buffers that are yet to be used.
     */
    int preallocatedBuffersRemaining() const;

    /**
     * gets the number of preallocated buffers
     */
    int preallocatedBufferCount() const;

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

    /**
     * Gets the GrGpu that this pool is associated with.
     */
    GrGpu* getGpu() { return fGpu; }

protected:
    /**
     * Used to determine what type of buffers to create. We could make the
     * createBuffer a virtual except that we want to use it in the cons for
     * pre-allocated buffers.
     */
    enum BufferType {
        kVertex_BufferType,
        kIndex_BufferType,
    };

    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the buffers.
     * @param bufferType            The type of buffers to create.
     * @param frequentResetHint     A hint that indicates that the pool
     *                              should expect frequent unmap() calls
     *                              (as opposed to many makeSpace / acquires
     *                              between resets).
     * @param bufferSize            The minimum size of created buffers.
     *                              This value will be clamped to some
     *                              reasonable minimum.
     * @param preallocBufferCnt     The pool will allocate this number of
     *                              buffers at bufferSize and keep them until it
     *                              is destroyed.
     */
     GrBufferAllocPool(GrGpu* gpu,
                       BufferType bufferType,
                       bool frequentResetHint,
                       size_t   bufferSize = 0,
                       int preallocBufferCnt = 0);

    virtual ~GrBufferAllocPool();

    /**
     * Gets the size of the preallocated buffers.
     *
     * @return the size of preallocated buffers.
     */
    size_t preallocatedBufferSize() const {
        return fPreallocBuffers.count() ? fMinBlockSize : 0;
    }

    /**
     * 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,
                    const GrGeometryBuffer** buffer,
                    size_t* offset);

    /**
     * Gets the number of items of a size that can be added to the current
     * buffer without spilling to another buffer. If the pool has been reset, or
     * the previous makeSpace completely exhausted a buffer then the returned
     * size will be the size of the next available preallocated buffer, or zero
     * if no preallocated buffer remains available. It is assumed that items
     * should be itemSize-aligned from the start of a buffer.
     *
     * @return the number of items that would fit in the current buffer.
     */
    int currentBufferItems(size_t itemSize) const;

    GrGeometryBuffer* createBuffer(size_t size);

private:

    // The GrGpu must be able to clear the ref of pools it creates as members
    friend class GrGpu;
    void releaseGpuRef();

    struct BufferBlock {
        size_t              fBytesFree;
        GrGeometryBuffer*   fBuffer;
    };

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

    size_t                          fBytesInUse;

    GrGpu*                          fGpu;
    bool                            fGpuIsReffed;
    bool                            fFrequentResetHint;
    SkTDArray<GrGeometryBuffer*>    fPreallocBuffers;
    size_t                          fMinBlockSize;
    BufferType                      fBufferType;

    SkTArray<BufferBlock>           fBlocks;
    int                             fPreallocBuffersInUse;
    // We attempt to cycle through the preallocated buffers rather than
    // always starting from the first.
    int                             fPreallocBufferStartIdx;
    SkAutoMalloc                    fCpuData;
    void*                           fBufferPtr;
};

class GrVertexBuffer;

/**
 * A GrBufferAllocPool of vertex buffers
 */
class GrVertexBufferAllocPool : public GrBufferAllocPool {
public:
    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the vertex buffers.
     * @param frequentResetHint     A hint that indicates that the pool
     *                              should expect frequent unmap() calls
     *                              (as opposed to many makeSpace / acquires
     *                              between resets).
     * @param bufferSize            The minimum size of created VBs This value
     *                              will be clamped to some reasonable minimum.
     * @param preallocBufferCnt     The pool will allocate this number of VBs at
     *                              bufferSize and keep them until it is
     *                              destroyed.
     */
    GrVertexBufferAllocPool(GrGpu* gpu,
                            bool frequentResetHint,
                            size_t bufferSize = 0,
                            int preallocBufferCnt = 0);

    /**
     * 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,
                    const GrVertexBuffer** buffer,
                    int* startVertex);

    /**
     * Shortcut to make space and then write verts into the made space.
     */
    bool appendVertices(size_t vertexSize,
                        int vertexCount,
                        const void* vertices,
                        const GrVertexBuffer** buffer,
                        int* startVertex);

    /**
     * Gets the number of vertices that can be added to the current VB without
     * spilling to another VB. If the pool has been reset, or the previous
     * makeSpace completely exhausted a VB then the returned number of vertices
     * would fit in the next available preallocated buffer. If any makeSpace
     * would force a new VB to be created the return value will be zero.
     *
     * @param   the size of a vertex to compute space for.
     * @return the number of vertices that would fit in the current buffer.
     */
    int currentBufferVertices(size_t vertexSize) const;

    /**
     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
     * Zero if no preallocated buffers.
     *
     * @param   the size of a vertex to compute space for.
     *
     * @return number of vertices that fit in one of the preallocated vertex
     *         buffers.
     */
    int preallocatedBufferVertices(size_t vertexSize) const;

private:
    typedef GrBufferAllocPool INHERITED;
};

class GrIndexBuffer;

/**
 * A GrBufferAllocPool of index buffers
 */
class GrIndexBufferAllocPool : public GrBufferAllocPool {
public:
    /**
     * Constructor
     *
     * @param gpu                   The GrGpu used to create the index buffers.
     * @param frequentResetHint     A hint that indicates that the pool
     *                              should expect frequent unmap() calls
     *                              (as opposed to many makeSpace / acquires
     *                              between resets).
     * @param bufferSize            The minimum size of created IBs This value
     *                              will be clamped to some reasonable minimum.
     * @param preallocBufferCnt     The pool will allocate this number of VBs at
     *                              bufferSize and keep them until it is
     *                              destroyed.
     */
    GrIndexBufferAllocPool(GrGpu* gpu,
                           bool frequentResetHint,
                           size_t bufferSize = 0,
                           int preallocBufferCnt = 0);

    /**
     * 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,
                    const GrIndexBuffer** buffer,
                    int* startIndex);

    /**
     * Shortcut to make space and then write indices into the made space.
     */
    bool appendIndices(int indexCount,
                       const void* indices,
                       const GrIndexBuffer** buffer,
                       int* startIndex);

    /**
     * Gets the number of indices that can be added to the current IB without
     * spilling to another IB. If the pool has been reset, or the previous
     * makeSpace completely exhausted a IB then the returned number of indices
     * would fit in the next available preallocated buffer. If any makeSpace
     * would force a new IB to be created the return value will be zero.
     */
    int currentBufferIndices() const;

    /**
     * Gets the number of indices that can fit in a preallocated index buffer.
     * Zero if no preallocated buffers.
     *
     * @return number of indices that fit in one of the preallocated index
     *         buffers.
     */
    int preallocatedBufferIndices() const;

private:
    typedef GrBufferAllocPool INHERITED;
};

#endif
