/*
    Copyright 2010 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */


#ifndef GrBufferAllocPool_DEFINED
#define GrBufferAllocPool_DEFINED

#include "GrNoncopyable.h"
#include "GrTDArray.h"
#include "GrTArray.h"
#include "GrMemory.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 unlock 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 : GrNoncopyable {

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

    /**
     *  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 unlock() 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.
     *      *unlock is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unlock 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(GrGeometryBuffer* buffer, size_t flushSize);
#if GR_DEBUG
    void validate() const;
#endif

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

    GrTArray<BufferBlock>           fBlocks;
    int                             fPreallocBuffersInUse;
    int                             fFirstPreallocBuffer;
    GrAutoMalloc                    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 unlock() 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.
     *      *unlock is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unlock 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 layout       specifies type of vertices 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(GrVertexLayout layout,
                    int vertexCount,
                    const GrVertexBuffer** buffer,
                    int* startVertex);

    /**
     * Shortcut to make space and then write verts into the made space.
     */
    bool appendVertices(GrVertexLayout layout,
                        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 format of vertices to compute space for.
     * @return the number of vertices that would fit in the current buffer.
     */
    int currentBufferVertices(GrVertexLayout layout) const;

    /**
     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
     * Zero if no preallocated buffers.
     *
     * @param   the format of vertices to compute space for.
     *
     * @return number of vertices that fit in one of the preallocated vertex
     *         buffers.
     */
    int preallocatedBufferVertices(GrVertexLayout layout) 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 unlock() 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.
     *      *unlock is called.
     *      *reset is called.
     *      *this object is destroyed.
     *
     * Once unlock 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
