aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/include/GrVertexBufferAllocPool.h
blob: 6a781aa3447e8b6d8557beebd22760d82ef1f8a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
    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 GrVertexBufferAllocPool_DEFINED
#define GrVertexBufferAllocPool_DEFINED

#include "GrNoncopyable.h"
#include "GrTDArray.h"
#include "GrTArray.h"

class GrVertexBuffer;
class GrGpu;

/**
 * A pool of vertices in vertex buffers tied to a GrGpu.
 *
 * The pool has an alloc() function that returns a pointer into a locked
 * vertex buffer. A client can release() if it has over-allocated.
 *
 * At creation time a minimum VB size can be specified. Additionally,
 * a number of vertex buffers to preallocate can be specified. These will
 * be allocated at the min size and kept until the pool is destroyed.
 */
class GrVertexBufferAllocPool : GrNoncopyable {
public:
    /**
     * Constructor
     *
     * @param gpu               The GrGpu used to create the vertex buffers.
     * @param bufferSize        The size of created VBs (unless an alloc request
     *                          exceeds this size in which case a larger VB is
     *                          created). This value is 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,
                             size_t   bufferSize = 0,
                             int preallocBufferCnt = 0);
    ~GrVertexBufferAllocPool();

    /**
     * Ensures all VBs are unlocked. Call before using to draw.
     */
    void unlock();

    /**
     *  Frees all vertex data that has been allocated with alloc().
     */
    void reset();

    /**
     * Returns a block of memory bytes size big. The vertex buffer
     * containing the memory is returned in buffer.
     *
     * @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 using layout param.
     * @return pointer to first vertex.
     */
    void* alloc(GrVertexLayout layout,
                uint32_t vertexCount,
                GrVertexBuffer** buffer,
                uint32_t* startVertex);

    /**
     * Gets the number of vertices that can be allocated without changing VBs.
     * This means either the last VB returned by alloc() if the last alloc did
     * not exhaust it. If that VB was exhausted by the last alloc or alloc hasn't
     * been called since reset() then it will be the number of vertices that
     * would fit in an available preallocated VB. If no preallocated VB
     * is available then it returns 0 since the next alloc would force a new
     * VB to be created.
     */
    int currentBufferVertices(GrVertexLayout layout) const;

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

    /**
     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
     * Zero if no preallocated buffers.
     */
    int preallocatedBufferVertices(GrVertexLayout layout) const;

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


    /**
     * Releases the most recently allocated bytes back to the pool.
     */
    void release(size_t bytes);

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


private:
    struct BufferBlock {
        size_t              fBytesFree;
        GrVertexBuffer*     fVertexBuffer;
    };

    bool createBlock(size_t size);
    void destroyBlock();

    GrTArray<BufferBlock>       fBlocks;
    GrTDArray<GrVertexBuffer*>  fPreallocBuffers;
    int                         fPreallocBuffersInUse;
    int                         fFirstPreallocBuffer;

    size_t              fMinBlockSize;
    GrGpu*              fGpu;
    void*               fBufferPtr;
};

#endif