gfx/skia/trunk/src/gpu/GrBufferAllocPool.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrBufferAllocPool.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,347 @@
     1.4 +/*
     1.5 + * Copyright 2010 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef GrBufferAllocPool_DEFINED
    1.12 +#define GrBufferAllocPool_DEFINED
    1.13 +
    1.14 +#include "SkTArray.h"
    1.15 +#include "SkTDArray.h"
    1.16 +#include "SkTypes.h"
    1.17 +
    1.18 +class GrGeometryBuffer;
    1.19 +class GrGpu;
    1.20 +
    1.21 +/**
    1.22 + * A pool of geometry buffers tied to a GrGpu.
    1.23 + *
    1.24 + * The pool allows a client to make space for geometry and then put back excess
    1.25 + * space if it over allocated. When a client is ready to draw from the pool
    1.26 + * it calls unlock on the pool ensure buffers are ready for drawing. The pool
    1.27 + * can be reset after drawing is completed to recycle space.
    1.28 + *
    1.29 + * At creation time a minimum per-buffer size can be specified. Additionally,
    1.30 + * a number of buffers to preallocate can be specified. These will
    1.31 + * be allocated at the min size and kept around until the pool is destroyed.
    1.32 + */
    1.33 +class GrBufferAllocPool : public SkNoncopyable {
    1.34 +public:
    1.35 +    /**
    1.36 +     * Ensures all buffers are unlocked and have all data written to them.
    1.37 +     * Call before drawing using buffers from the pool.
    1.38 +     */
    1.39 +    void unlock();
    1.40 +
    1.41 +    /**
    1.42 +     *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
    1.43 +     */
    1.44 +    void reset();
    1.45 +
    1.46 +    /**
    1.47 +     * Gets the number of preallocated buffers that are yet to be used.
    1.48 +     */
    1.49 +    int preallocatedBuffersRemaining() const;
    1.50 +
    1.51 +    /**
    1.52 +     * gets the number of preallocated buffers
    1.53 +     */
    1.54 +    int preallocatedBufferCount() const;
    1.55 +
    1.56 +    /**
    1.57 +     * Frees data from makeSpaces in LIFO order.
    1.58 +     */
    1.59 +    void putBack(size_t bytes);
    1.60 +
    1.61 +    /**
    1.62 +     * Gets the GrGpu that this pool is associated with.
    1.63 +     */
    1.64 +    GrGpu* getGpu() { return fGpu; }
    1.65 +
    1.66 +protected:
    1.67 +    /**
    1.68 +     * Used to determine what type of buffers to create. We could make the
    1.69 +     * createBuffer a virtual except that we want to use it in the cons for
    1.70 +     * pre-allocated buffers.
    1.71 +     */
    1.72 +    enum BufferType {
    1.73 +        kVertex_BufferType,
    1.74 +        kIndex_BufferType,
    1.75 +    };
    1.76 +
    1.77 +    /**
    1.78 +     * Constructor
    1.79 +     *
    1.80 +     * @param gpu                   The GrGpu used to create the buffers.
    1.81 +     * @param bufferType            The type of buffers to create.
    1.82 +     * @param frequentResetHint     A hint that indicates that the pool
    1.83 +     *                              should expect frequent unlock() calls
    1.84 +     *                              (as opposed to many makeSpace / acquires
    1.85 +     *                              between resets).
    1.86 +     * @param bufferSize            The minimum size of created buffers.
    1.87 +     *                              This value will be clamped to some
    1.88 +     *                              reasonable minimum.
    1.89 +     * @param preallocBufferCnt     The pool will allocate this number of
    1.90 +     *                              buffers at bufferSize and keep them until it
    1.91 +     *                              is destroyed.
    1.92 +     */
    1.93 +     GrBufferAllocPool(GrGpu* gpu,
    1.94 +                       BufferType bufferType,
    1.95 +                       bool frequentResetHint,
    1.96 +                       size_t   bufferSize = 0,
    1.97 +                       int preallocBufferCnt = 0);
    1.98 +
    1.99 +    virtual ~GrBufferAllocPool();
   1.100 +
   1.101 +    /**
   1.102 +     * Gets the size of the preallocated buffers.
   1.103 +     *
   1.104 +     * @return the size of preallocated buffers.
   1.105 +     */
   1.106 +    size_t preallocatedBufferSize() const {
   1.107 +        return fPreallocBuffers.count() ? fMinBlockSize : 0;
   1.108 +    }
   1.109 +
   1.110 +    /**
   1.111 +     * Returns a block of memory to hold data. A buffer designated to hold the
   1.112 +     * data is given to the caller. The buffer may or may not be locked. The
   1.113 +     * returned ptr remains valid until any of the following:
   1.114 +     *      *makeSpace is called again.
   1.115 +     *      *unlock is called.
   1.116 +     *      *reset is called.
   1.117 +     *      *this object is destroyed.
   1.118 +     *
   1.119 +     * Once unlock on the pool is called the data is guaranteed to be in the
   1.120 +     * buffer at the offset indicated by offset. Until that time it may be
   1.121 +     * in temporary storage and/or the buffer may be locked.
   1.122 +     *
   1.123 +     * @param size         the amount of data to make space for
   1.124 +     * @param alignment    alignment constraint from start of buffer
   1.125 +     * @param buffer       returns the buffer that will hold the data.
   1.126 +     * @param offset       returns the offset into buffer of the data.
   1.127 +     * @return pointer to where the client should write the data.
   1.128 +     */
   1.129 +    void* makeSpace(size_t size,
   1.130 +                    size_t alignment,
   1.131 +                    const GrGeometryBuffer** buffer,
   1.132 +                    size_t* offset);
   1.133 +
   1.134 +    /**
   1.135 +     * Gets the number of items of a size that can be added to the current
   1.136 +     * buffer without spilling to another buffer. If the pool has been reset, or
   1.137 +     * the previous makeSpace completely exhausted a buffer then the returned
   1.138 +     * size will be the size of the next available preallocated buffer, or zero
   1.139 +     * if no preallocated buffer remains available. It is assumed that items
   1.140 +     * should be itemSize-aligned from the start of a buffer.
   1.141 +     *
   1.142 +     * @return the number of items that would fit in the current buffer.
   1.143 +     */
   1.144 +    int currentBufferItems(size_t itemSize) const;
   1.145 +
   1.146 +    GrGeometryBuffer* createBuffer(size_t size);
   1.147 +
   1.148 +private:
   1.149 +
   1.150 +    // The GrGpu must be able to clear the ref of pools it creates as members
   1.151 +    friend class GrGpu;
   1.152 +    void releaseGpuRef();
   1.153 +
   1.154 +    struct BufferBlock {
   1.155 +        size_t              fBytesFree;
   1.156 +        GrGeometryBuffer*   fBuffer;
   1.157 +    };
   1.158 +
   1.159 +    bool createBlock(size_t requestSize);
   1.160 +    void destroyBlock();
   1.161 +    void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
   1.162 +#ifdef SK_DEBUG
   1.163 +    void validate(bool unusedBlockAllowed = false) const;
   1.164 +#endif
   1.165 +
   1.166 +    size_t                          fBytesInUse;
   1.167 +
   1.168 +    GrGpu*                          fGpu;
   1.169 +    bool                            fGpuIsReffed;
   1.170 +    bool                            fFrequentResetHint;
   1.171 +    SkTDArray<GrGeometryBuffer*>    fPreallocBuffers;
   1.172 +    size_t                          fMinBlockSize;
   1.173 +    BufferType                      fBufferType;
   1.174 +
   1.175 +    SkTArray<BufferBlock>           fBlocks;
   1.176 +    int                             fPreallocBuffersInUse;
   1.177 +    // We attempt to cycle through the preallocated buffers rather than
   1.178 +    // always starting from the first.
   1.179 +    int                             fPreallocBufferStartIdx;
   1.180 +    SkAutoMalloc                    fCpuData;
   1.181 +    void*                           fBufferPtr;
   1.182 +};
   1.183 +
   1.184 +class GrVertexBuffer;
   1.185 +
   1.186 +/**
   1.187 + * A GrBufferAllocPool of vertex buffers
   1.188 + */
   1.189 +class GrVertexBufferAllocPool : public GrBufferAllocPool {
   1.190 +public:
   1.191 +    /**
   1.192 +     * Constructor
   1.193 +     *
   1.194 +     * @param gpu                   The GrGpu used to create the vertex buffers.
   1.195 +     * @param frequentResetHint     A hint that indicates that the pool
   1.196 +     *                              should expect frequent unlock() calls
   1.197 +     *                              (as opposed to many makeSpace / acquires
   1.198 +     *                              between resets).
   1.199 +     * @param bufferSize            The minimum size of created VBs This value
   1.200 +     *                              will be clamped to some reasonable minimum.
   1.201 +     * @param preallocBufferCnt     The pool will allocate this number of VBs at
   1.202 +     *                              bufferSize and keep them until it is
   1.203 +     *                              destroyed.
   1.204 +     */
   1.205 +    GrVertexBufferAllocPool(GrGpu* gpu,
   1.206 +                            bool frequentResetHint,
   1.207 +                            size_t bufferSize = 0,
   1.208 +                            int preallocBufferCnt = 0);
   1.209 +
   1.210 +    /**
   1.211 +     * Returns a block of memory to hold vertices. A buffer designated to hold
   1.212 +     * the vertices given to the caller. The buffer may or may not be locked.
   1.213 +     * The returned ptr remains valid until any of the following:
   1.214 +     *      *makeSpace is called again.
   1.215 +     *      *unlock is called.
   1.216 +     *      *reset is called.
   1.217 +     *      *this object is destroyed.
   1.218 +     *
   1.219 +     * Once unlock on the pool is called the vertices are guaranteed to be in
   1.220 +     * the buffer at the offset indicated by startVertex. Until that time they
   1.221 +     * may be in temporary storage and/or the buffer may be locked.
   1.222 +     *
   1.223 +     * @param vertexSize   specifies size of a vertex to allocate space for
   1.224 +     * @param vertexCount  number of vertices to allocate space for
   1.225 +     * @param buffer       returns the vertex buffer that will hold the
   1.226 +     *                     vertices.
   1.227 +     * @param startVertex  returns the offset into buffer of the first vertex.
   1.228 +     *                     In units of the size of a vertex from layout param.
   1.229 +     * @return pointer to first vertex.
   1.230 +     */
   1.231 +    void* makeSpace(size_t vertexSize,
   1.232 +                    int vertexCount,
   1.233 +                    const GrVertexBuffer** buffer,
   1.234 +                    int* startVertex);
   1.235 +
   1.236 +    /**
   1.237 +     * Shortcut to make space and then write verts into the made space.
   1.238 +     */
   1.239 +    bool appendVertices(size_t vertexSize,
   1.240 +                        int vertexCount,
   1.241 +                        const void* vertices,
   1.242 +                        const GrVertexBuffer** buffer,
   1.243 +                        int* startVertex);
   1.244 +
   1.245 +    /**
   1.246 +     * Gets the number of vertices that can be added to the current VB without
   1.247 +     * spilling to another VB. If the pool has been reset, or the previous
   1.248 +     * makeSpace completely exhausted a VB then the returned number of vertices
   1.249 +     * would fit in the next available preallocated buffer. If any makeSpace
   1.250 +     * would force a new VB to be created the return value will be zero.
   1.251 +     *
   1.252 +     * @param   the size of a vertex to compute space for.
   1.253 +     * @return the number of vertices that would fit in the current buffer.
   1.254 +     */
   1.255 +    int currentBufferVertices(size_t vertexSize) const;
   1.256 +
   1.257 +    /**
   1.258 +     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
   1.259 +     * Zero if no preallocated buffers.
   1.260 +     *
   1.261 +     * @param   the size of a vertex to compute space for.
   1.262 +     *
   1.263 +     * @return number of vertices that fit in one of the preallocated vertex
   1.264 +     *         buffers.
   1.265 +     */
   1.266 +    int preallocatedBufferVertices(size_t vertexSize) const;
   1.267 +
   1.268 +private:
   1.269 +    typedef GrBufferAllocPool INHERITED;
   1.270 +};
   1.271 +
   1.272 +class GrIndexBuffer;
   1.273 +
   1.274 +/**
   1.275 + * A GrBufferAllocPool of index buffers
   1.276 + */
   1.277 +class GrIndexBufferAllocPool : public GrBufferAllocPool {
   1.278 +public:
   1.279 +    /**
   1.280 +     * Constructor
   1.281 +     *
   1.282 +     * @param gpu                   The GrGpu used to create the index buffers.
   1.283 +     * @param frequentResetHint     A hint that indicates that the pool
   1.284 +     *                              should expect frequent unlock() calls
   1.285 +     *                              (as opposed to many makeSpace / acquires
   1.286 +     *                              between resets).
   1.287 +     * @param bufferSize            The minimum size of created IBs This value
   1.288 +     *                              will be clamped to some reasonable minimum.
   1.289 +     * @param preallocBufferCnt     The pool will allocate this number of VBs at
   1.290 +     *                              bufferSize and keep them until it is
   1.291 +     *                              destroyed.
   1.292 +     */
   1.293 +    GrIndexBufferAllocPool(GrGpu* gpu,
   1.294 +                           bool frequentResetHint,
   1.295 +                           size_t bufferSize = 0,
   1.296 +                           int preallocBufferCnt = 0);
   1.297 +
   1.298 +    /**
   1.299 +     * Returns a block of memory to hold indices. A buffer designated to hold
   1.300 +     * the indices is given to the caller. The buffer may or may not be locked.
   1.301 +     * The returned ptr remains valid until any of the following:
   1.302 +     *      *makeSpace is called again.
   1.303 +     *      *unlock is called.
   1.304 +     *      *reset is called.
   1.305 +     *      *this object is destroyed.
   1.306 +     *
   1.307 +     * Once unlock on the pool is called the indices are guaranteed to be in the
   1.308 +     * buffer at the offset indicated by startIndex. Until that time they may be
   1.309 +     * in temporary storage and/or the buffer may be locked.
   1.310 +     *
   1.311 +     * @param indexCount   number of indices to allocate space for
   1.312 +     * @param buffer       returns the index buffer that will hold the indices.
   1.313 +     * @param startIndex   returns the offset into buffer of the first index.
   1.314 +     * @return pointer to first index.
   1.315 +     */
   1.316 +    void* makeSpace(int indexCount,
   1.317 +                    const GrIndexBuffer** buffer,
   1.318 +                    int* startIndex);
   1.319 +
   1.320 +    /**
   1.321 +     * Shortcut to make space and then write indices into the made space.
   1.322 +     */
   1.323 +    bool appendIndices(int indexCount,
   1.324 +                       const void* indices,
   1.325 +                       const GrIndexBuffer** buffer,
   1.326 +                       int* startIndex);
   1.327 +
   1.328 +    /**
   1.329 +     * Gets the number of indices that can be added to the current IB without
   1.330 +     * spilling to another IB. If the pool has been reset, or the previous
   1.331 +     * makeSpace completely exhausted a IB then the returned number of indices
   1.332 +     * would fit in the next available preallocated buffer. If any makeSpace
   1.333 +     * would force a new IB to be created the return value will be zero.
   1.334 +     */
   1.335 +    int currentBufferIndices() const;
   1.336 +
   1.337 +    /**
   1.338 +     * Gets the number of indices that can fit in a preallocated index buffer.
   1.339 +     * Zero if no preallocated buffers.
   1.340 +     *
   1.341 +     * @return number of indices that fit in one of the preallocated index
   1.342 +     *         buffers.
   1.343 +     */
   1.344 +    int preallocatedBufferIndices() const;
   1.345 +
   1.346 +private:
   1.347 +    typedef GrBufferAllocPool INHERITED;
   1.348 +};
   1.349 +
   1.350 +#endif

mercurial