| epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame^] | 1 |  | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 2 | /* | 
| epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame^] | 3 |  * Copyright 2010 Google Inc. | 
 | 4 |  * | 
 | 5 |  * Use of this source code is governed by a BSD-style license that can be | 
 | 6 |  * found in the LICENSE file. | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 7 |  */ | 
 | 8 |  | 
| epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame^] | 9 |  | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 10 | #include "GrBufferAllocPool.h" | 
 | 11 | #include "GrTypes.h" | 
 | 12 | #include "GrVertexBuffer.h" | 
 | 13 | #include "GrIndexBuffer.h" | 
 | 14 | #include "GrGpu.h" | 
 | 15 |  | 
 | 16 | #if GR_DEBUG | 
 | 17 |     #define VALIDATE validate | 
 | 18 | #else | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 19 |     static void VALIDATE(bool x = false) {} | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 20 | #endif | 
 | 21 |  | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 22 | // page size | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 23 | #define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12) | 
 | 24 |  | 
 | 25 | GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu, | 
 | 26 |                                      BufferType bufferType, | 
 | 27 |                                      bool frequentResetHint, | 
 | 28 |                                      size_t blockSize, | 
 | 29 |                                      int preallocBufferCnt) : | 
 | 30 |         fBlocks(GrMax(8, 2*preallocBufferCnt)) { | 
| bsalomon@google.com | 11f0b51 | 2011-03-29 20:52:23 +0000 | [diff] [blame] | 31 |  | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 32 |     GrAssert(NULL != gpu); | 
 | 33 |     fGpu = gpu; | 
| bsalomon@google.com | 11f0b51 | 2011-03-29 20:52:23 +0000 | [diff] [blame] | 34 |     fGpu->ref(); | 
 | 35 |     fGpuIsReffed = true; | 
 | 36 |  | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 37 |     fBufferType = bufferType; | 
 | 38 |     fFrequentResetHint = frequentResetHint; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 39 |     fBufferPtr = NULL; | 
 | 40 |     fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize); | 
 | 41 |  | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 42 |     fBytesInUse = 0; | 
 | 43 |              | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 44 |     fPreallocBuffersInUse = 0; | 
 | 45 |     fFirstPreallocBuffer = 0; | 
 | 46 |     for (int i = 0; i < preallocBufferCnt; ++i) { | 
 | 47 |         GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize); | 
 | 48 |         if (NULL != buffer) { | 
 | 49 |             *fPreallocBuffers.append() = buffer; | 
 | 50 |             buffer->ref(); | 
 | 51 |         } | 
 | 52 |     } | 
 | 53 | } | 
 | 54 |  | 
 | 55 | GrBufferAllocPool::~GrBufferAllocPool() { | 
 | 56 |     VALIDATE(); | 
 | 57 |     if (fBlocks.count()) { | 
 | 58 |         GrGeometryBuffer* buffer = fBlocks.back().fBuffer; | 
 | 59 |         if (buffer->isLocked()) { | 
 | 60 |             buffer->unlock(); | 
 | 61 |         } | 
 | 62 |     } | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 63 |     while (!fBlocks.empty()) { | 
 | 64 |         destroyBlock(); | 
 | 65 |     } | 
| bsalomon@google.com | 11f0b51 | 2011-03-29 20:52:23 +0000 | [diff] [blame] | 66 |     fPreallocBuffers.unrefAll(); | 
 | 67 |     releaseGpuRef(); | 
 | 68 | } | 
 | 69 |  | 
 | 70 | void GrBufferAllocPool::releaseGpuRef() { | 
 | 71 |     if (fGpuIsReffed) { | 
 | 72 |         fGpu->unref(); | 
 | 73 |         fGpuIsReffed = false; | 
 | 74 |     } | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 75 | } | 
 | 76 |  | 
 | 77 | void GrBufferAllocPool::reset() { | 
 | 78 |     VALIDATE(); | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 79 |     fBytesInUse = 0; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 80 |     if (fBlocks.count()) { | 
 | 81 |         GrGeometryBuffer* buffer = fBlocks.back().fBuffer; | 
 | 82 |         if (buffer->isLocked()) { | 
 | 83 |             buffer->unlock(); | 
 | 84 |         } | 
 | 85 |     } | 
 | 86 |     while (!fBlocks.empty()) { | 
 | 87 |         destroyBlock(); | 
 | 88 |     } | 
 | 89 |     if (fPreallocBuffers.count()) { | 
 | 90 |         // must set this after above loop. | 
 | 91 |         fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) % | 
 | 92 |                                fPreallocBuffers.count(); | 
 | 93 |     } | 
| bsalomon@google.com | 3582bf9 | 2011-06-30 21:32:31 +0000 | [diff] [blame] | 94 |     fCpuData.alloc(fGpu->supportsBufferLocking() ? 0 : fMinBlockSize); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 95 |     GrAssert(0 == fPreallocBuffersInUse); | 
 | 96 |     VALIDATE(); | 
 | 97 | } | 
 | 98 |  | 
 | 99 | void GrBufferAllocPool::unlock() { | 
 | 100 |     VALIDATE(); | 
 | 101 |  | 
 | 102 |     if (NULL != fBufferPtr) { | 
 | 103 |         BufferBlock& block = fBlocks.back(); | 
 | 104 |         if (block.fBuffer->isLocked()) { | 
 | 105 |             block.fBuffer->unlock(); | 
 | 106 |         } else { | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 107 |             size_t flushSize = block.fBuffer->sizeInBytes() - block.fBytesFree; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 108 |             flushCpuData(fBlocks.back().fBuffer, flushSize); | 
 | 109 |         } | 
 | 110 |         fBufferPtr = NULL; | 
 | 111 |     } | 
 | 112 |     VALIDATE(); | 
 | 113 | } | 
 | 114 |  | 
 | 115 | #if GR_DEBUG | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 116 | void GrBufferAllocPool::validate(bool unusedBlockAllowed) const { | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 117 |     if (NULL != fBufferPtr) { | 
 | 118 |         GrAssert(!fBlocks.empty()); | 
 | 119 |         if (fBlocks.back().fBuffer->isLocked()) { | 
 | 120 |             GrGeometryBuffer* buf = fBlocks.back().fBuffer; | 
 | 121 |             GrAssert(buf->lockPtr() == fBufferPtr); | 
 | 122 |         } else { | 
 | 123 |             GrAssert(fCpuData.get() == fBufferPtr); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 124 |         } | 
 | 125 |     } else { | 
 | 126 |         GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked()); | 
 | 127 |     } | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 128 |     size_t bytesInUse = 0; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 129 |     for (int i = 0; i < fBlocks.count() - 1; ++i) { | 
 | 130 |         GrAssert(!fBlocks[i].fBuffer->isLocked()); | 
 | 131 |     } | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 132 |     for (int i = 0; i < fBlocks.count(); ++i) { | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 133 |         size_t bytes = fBlocks[i].fBuffer->sizeInBytes() - fBlocks[i].fBytesFree;  | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 134 |         bytesInUse += bytes; | 
 | 135 |         GrAssert(bytes || unusedBlockAllowed); | 
 | 136 |     } | 
 | 137 |      | 
 | 138 |     GrAssert(bytesInUse == fBytesInUse); | 
 | 139 |     if (unusedBlockAllowed) { | 
 | 140 |         GrAssert((fBytesInUse && !fBlocks.empty()) || | 
 | 141 |                  (!fBytesInUse && (fBlocks.count() < 2))); | 
 | 142 |     } else { | 
 | 143 |         GrAssert((0 == fBytesInUse) == fBlocks.empty()); | 
 | 144 |     } | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 145 | } | 
 | 146 | #endif | 
 | 147 |  | 
 | 148 | void* GrBufferAllocPool::makeSpace(size_t size, | 
 | 149 |                                    size_t alignment, | 
 | 150 |                                    const GrGeometryBuffer** buffer, | 
 | 151 |                                    size_t* offset) { | 
 | 152 |     VALIDATE(); | 
 | 153 |  | 
 | 154 |     GrAssert(NULL != buffer); | 
 | 155 |     GrAssert(NULL != offset); | 
 | 156 |  | 
 | 157 |     if (NULL != fBufferPtr) { | 
 | 158 |         BufferBlock& back = fBlocks.back(); | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 159 |         size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 160 |         size_t pad = GrSizeAlignUpPad(usedBytes, | 
 | 161 |                                       alignment); | 
 | 162 |         if ((size + pad) <= back.fBytesFree) { | 
 | 163 |             usedBytes += pad; | 
 | 164 |             *offset = usedBytes; | 
 | 165 |             *buffer = back.fBuffer; | 
 | 166 |             back.fBytesFree -= size + pad; | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 167 |             fBytesInUse += size; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 168 |             return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes); | 
 | 169 |         } | 
 | 170 |     } | 
 | 171 |  | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 172 |     // We could honor the space request using updateSubData on the current VB | 
 | 173 |     // (if there is room). But we don't currently use draw calls to GL that | 
 | 174 |     // allow the driver to know that previously issued draws won't read from | 
 | 175 |     // the part of the buffer we update. | 
 | 176 |      | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 177 |     if (!createBlock(size)) { | 
 | 178 |         return NULL; | 
 | 179 |     } | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 180 |     GrAssert(NULL != fBufferPtr); | 
 | 181 |  | 
 | 182 |     *offset = 0; | 
 | 183 |     BufferBlock& back = fBlocks.back(); | 
 | 184 |     *buffer = back.fBuffer; | 
 | 185 |     back.fBytesFree -= size; | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 186 |     fBytesInUse += size; | 
 | 187 |     VALIDATE(); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 188 |     return fBufferPtr; | 
 | 189 | } | 
 | 190 |  | 
 | 191 | int GrBufferAllocPool::currentBufferItems(size_t itemSize) const { | 
 | 192 |     VALIDATE(); | 
 | 193 |     if (NULL != fBufferPtr) { | 
 | 194 |         const BufferBlock& back = fBlocks.back(); | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 195 |         size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 196 |         size_t pad = GrSizeAlignUpPad(usedBytes, itemSize); | 
 | 197 |         return (back.fBytesFree - pad) / itemSize; | 
 | 198 |     } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) { | 
 | 199 |         return fMinBlockSize / itemSize; | 
 | 200 |     } | 
 | 201 |     return 0; | 
 | 202 | } | 
 | 203 |  | 
 | 204 | int GrBufferAllocPool::preallocatedBuffersRemaining() const { | 
 | 205 |     return fPreallocBuffers.count() - fPreallocBuffersInUse; | 
 | 206 | } | 
 | 207 |  | 
 | 208 | int GrBufferAllocPool::preallocatedBufferCount() const { | 
 | 209 |     return fPreallocBuffers.count(); | 
 | 210 | } | 
 | 211 |  | 
 | 212 | void GrBufferAllocPool::putBack(size_t bytes) { | 
 | 213 |     VALIDATE(); | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 214 |  | 
 | 215 |     while (bytes) { | 
 | 216 |         // caller shouldnt try to put back more than they've taken | 
 | 217 |         GrAssert(!fBlocks.empty()); | 
 | 218 |         BufferBlock& block = fBlocks.back(); | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 219 |         size_t bytesUsed = block.fBuffer->sizeInBytes() - block.fBytesFree; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 220 |         if (bytes >= bytesUsed) { | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 221 |             bytes -= bytesUsed; | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 222 |             fBytesInUse -= bytesUsed; | 
 | 223 |             destroyBlock(); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 224 |         } else { | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 225 |             block.fBytesFree += bytes; | 
 | 226 |             fBytesInUse -= bytes; | 
 | 227 |             bytes = 0; | 
 | 228 |             break; | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 229 |         } | 
 | 230 |     } | 
 | 231 |     VALIDATE(); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 232 | } | 
 | 233 |  | 
 | 234 | bool GrBufferAllocPool::createBlock(size_t requestSize) { | 
 | 235 |  | 
 | 236 |     size_t size = GrMax(requestSize, fMinBlockSize); | 
 | 237 |     GrAssert(size >= GrBufferAllocPool_MIN_BLOCK_SIZE); | 
 | 238 |  | 
 | 239 |     VALIDATE(); | 
 | 240 |  | 
 | 241 |     BufferBlock& block = fBlocks.push_back(); | 
 | 242 |  | 
 | 243 |     if (size == fMinBlockSize && | 
 | 244 |         fPreallocBuffersInUse < fPreallocBuffers.count()) { | 
 | 245 |  | 
 | 246 |         uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) % | 
 | 247 |                                fPreallocBuffers.count(); | 
 | 248 |         block.fBuffer = fPreallocBuffers[nextBuffer]; | 
 | 249 |         block.fBuffer->ref(); | 
 | 250 |         ++fPreallocBuffersInUse; | 
 | 251 |     } else { | 
 | 252 |         block.fBuffer = this->createBuffer(size); | 
 | 253 |         if (NULL == block.fBuffer) { | 
 | 254 |             fBlocks.pop_back(); | 
 | 255 |             return false; | 
 | 256 |         } | 
 | 257 |     } | 
 | 258 |  | 
 | 259 |     block.fBytesFree = size; | 
 | 260 |     if (NULL != fBufferPtr) { | 
 | 261 |         GrAssert(fBlocks.count() > 1); | 
 | 262 |         BufferBlock& prev = fBlocks.fromBack(1); | 
 | 263 |         if (prev.fBuffer->isLocked()) { | 
 | 264 |             prev.fBuffer->unlock(); | 
 | 265 |         } else { | 
 | 266 |             flushCpuData(prev.fBuffer, | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 267 |                          prev.fBuffer->sizeInBytes() - prev.fBytesFree); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 268 |         } | 
 | 269 |         fBufferPtr = NULL; | 
 | 270 |     } | 
 | 271 |  | 
 | 272 |     GrAssert(NULL == fBufferPtr); | 
 | 273 |  | 
 | 274 |     if (fGpu->supportsBufferLocking() && | 
 | 275 |         size > GR_GEOM_BUFFER_LOCK_THRESHOLD && | 
 | 276 |         (!fFrequentResetHint || requestSize > GR_GEOM_BUFFER_LOCK_THRESHOLD)) { | 
 | 277 |         fBufferPtr = block.fBuffer->lock(); | 
 | 278 |     } | 
 | 279 |  | 
 | 280 |     if (NULL == fBufferPtr) { | 
| bsalomon@google.com | 3582bf9 | 2011-06-30 21:32:31 +0000 | [diff] [blame] | 281 |         fBufferPtr = fCpuData.alloc(size); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 282 |     } | 
 | 283 |  | 
| bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 284 |     VALIDATE(true); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 285 |  | 
 | 286 |     return true; | 
 | 287 | } | 
 | 288 |  | 
 | 289 | void GrBufferAllocPool::destroyBlock() { | 
 | 290 |     GrAssert(!fBlocks.empty()); | 
 | 291 |  | 
 | 292 |     BufferBlock& block = fBlocks.back(); | 
 | 293 |     if (fPreallocBuffersInUse > 0) { | 
 | 294 |         uint32_t prevPreallocBuffer = (fPreallocBuffersInUse + | 
 | 295 |                                        fFirstPreallocBuffer + | 
 | 296 |                                        (fPreallocBuffers.count() - 1)) % | 
 | 297 |                                       fPreallocBuffers.count(); | 
 | 298 |         if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) { | 
 | 299 |             --fPreallocBuffersInUse; | 
 | 300 |         } | 
 | 301 |     } | 
 | 302 |     GrAssert(!block.fBuffer->isLocked()); | 
 | 303 |     block.fBuffer->unref(); | 
 | 304 |     fBlocks.pop_back(); | 
 | 305 |     fBufferPtr = NULL; | 
 | 306 | } | 
 | 307 |  | 
 | 308 | void GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer, | 
 | 309 |                                      size_t flushSize) { | 
 | 310 |     GrAssert(NULL != buffer); | 
 | 311 |     GrAssert(!buffer->isLocked()); | 
 | 312 |     GrAssert(fCpuData.get() == fBufferPtr); | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 313 |     GrAssert(flushSize <= buffer->sizeInBytes()); | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 314 |  | 
 | 315 |     bool updated = false; | 
 | 316 |     if (fGpu->supportsBufferLocking() && | 
 | 317 |         flushSize > GR_GEOM_BUFFER_LOCK_THRESHOLD) { | 
 | 318 |         void* data = buffer->lock(); | 
 | 319 |         if (NULL != data) { | 
 | 320 |             memcpy(data, fBufferPtr, flushSize); | 
 | 321 |             buffer->unlock(); | 
 | 322 |             updated = true; | 
 | 323 |         } | 
 | 324 |     } | 
 | 325 |     buffer->updateData(fBufferPtr, flushSize); | 
 | 326 | } | 
 | 327 |  | 
 | 328 | GrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) { | 
 | 329 |     if (kIndex_BufferType == fBufferType) { | 
 | 330 |         return fGpu->createIndexBuffer(size, true); | 
 | 331 |     } else { | 
 | 332 |         GrAssert(kVertex_BufferType == fBufferType); | 
 | 333 |         return fGpu->createVertexBuffer(size, true); | 
 | 334 |     } | 
 | 335 | } | 
 | 336 |  | 
 | 337 | //////////////////////////////////////////////////////////////////////////////// | 
 | 338 |  | 
 | 339 | GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu, | 
 | 340 |                                                  bool frequentResetHint, | 
 | 341 |                                                  size_t bufferSize, | 
 | 342 |                                                  int preallocBufferCnt) | 
 | 343 | : GrBufferAllocPool(gpu, | 
 | 344 |                     kVertex_BufferType, | 
 | 345 |                     frequentResetHint, | 
 | 346 |                     bufferSize, | 
 | 347 |                     preallocBufferCnt) { | 
 | 348 | } | 
 | 349 |  | 
 | 350 | void* GrVertexBufferAllocPool::makeSpace(GrVertexLayout layout, | 
 | 351 |                                          int vertexCount, | 
 | 352 |                                          const GrVertexBuffer** buffer, | 
 | 353 |                                          int* startVertex) { | 
 | 354 |  | 
 | 355 |     GrAssert(vertexCount >= 0); | 
 | 356 |     GrAssert(NULL != buffer); | 
 | 357 |     GrAssert(NULL != startVertex); | 
 | 358 |  | 
 | 359 |     size_t vSize = GrDrawTarget::VertexSize(layout); | 
| bsalomon@google.com | 8b48441 | 2011-04-18 19:07:44 +0000 | [diff] [blame] | 360 |     size_t offset = 0; // assign to suppress warning | 
 | 361 |     const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 362 |     void* ptr = INHERITED::makeSpace(vSize * vertexCount, | 
 | 363 |                                      vSize, | 
 | 364 |                                      &geomBuffer, | 
 | 365 |                                      &offset); | 
 | 366 |  | 
 | 367 |     *buffer = (const GrVertexBuffer*) geomBuffer; | 
 | 368 |     GrAssert(0 == offset % vSize); | 
 | 369 |     *startVertex = offset / vSize; | 
 | 370 |     return ptr; | 
 | 371 | } | 
 | 372 |  | 
 | 373 | bool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout, | 
 | 374 |                                              int vertexCount, | 
 | 375 |                                              const void* vertices, | 
 | 376 |                                              const GrVertexBuffer** buffer, | 
 | 377 |                                              int* startVertex) { | 
 | 378 |     void* space = makeSpace(layout, vertexCount, buffer, startVertex); | 
 | 379 |     if (NULL != space) { | 
 | 380 |         memcpy(space, | 
 | 381 |                vertices, | 
 | 382 |                GrDrawTarget::VertexSize(layout) * vertexCount); | 
 | 383 |         return true; | 
 | 384 |     } else { | 
 | 385 |         return false; | 
 | 386 |     } | 
 | 387 | } | 
 | 388 |  | 
 | 389 | int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const { | 
 | 390 |     return INHERITED::preallocatedBufferSize() / | 
 | 391 |             GrDrawTarget::VertexSize(layout); | 
 | 392 | } | 
 | 393 |  | 
 | 394 | int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const { | 
 | 395 |     return currentBufferItems(GrDrawTarget::VertexSize(layout)); | 
 | 396 | } | 
 | 397 |  | 
 | 398 | //////////////////////////////////////////////////////////////////////////////// | 
 | 399 |  | 
 | 400 | GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu, | 
 | 401 |                                                bool frequentResetHint, | 
 | 402 |                                                size_t bufferSize, | 
 | 403 |                                                int preallocBufferCnt) | 
 | 404 | : GrBufferAllocPool(gpu, | 
 | 405 |                     kIndex_BufferType, | 
 | 406 |                     frequentResetHint, | 
 | 407 |                     bufferSize, | 
 | 408 |                     preallocBufferCnt) { | 
 | 409 | } | 
 | 410 |  | 
 | 411 | void* GrIndexBufferAllocPool::makeSpace(int indexCount, | 
 | 412 |                                         const GrIndexBuffer** buffer, | 
 | 413 |                                         int* startIndex) { | 
 | 414 |  | 
 | 415 |     GrAssert(indexCount >= 0); | 
 | 416 |     GrAssert(NULL != buffer); | 
 | 417 |     GrAssert(NULL != startIndex); | 
 | 418 |  | 
| bsalomon@google.com | 8b48441 | 2011-04-18 19:07:44 +0000 | [diff] [blame] | 419 |     size_t offset = 0; // assign to suppress warning | 
 | 420 |     const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning | 
| bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 421 |     void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t), | 
 | 422 |                                      sizeof(uint16_t), | 
 | 423 |                                      &geomBuffer, | 
 | 424 |                                      &offset); | 
 | 425 |  | 
 | 426 |     *buffer = (const GrIndexBuffer*) geomBuffer; | 
 | 427 |     GrAssert(0 == offset % sizeof(uint16_t)); | 
 | 428 |     *startIndex = offset / sizeof(uint16_t); | 
 | 429 |     return ptr; | 
 | 430 | } | 
 | 431 |  | 
 | 432 | bool GrIndexBufferAllocPool::appendIndices(int indexCount, | 
 | 433 |                                            const void* indices, | 
 | 434 |                                            const GrIndexBuffer** buffer, | 
 | 435 |                                            int* startIndex) { | 
 | 436 |     void* space = makeSpace(indexCount, buffer, startIndex); | 
 | 437 |     if (NULL != space) { | 
 | 438 |         memcpy(space, indices, sizeof(uint16_t) * indexCount); | 
 | 439 |         return true; | 
 | 440 |     } else { | 
 | 441 |         return false; | 
 | 442 |     } | 
 | 443 | } | 
 | 444 |  | 
 | 445 | int GrIndexBufferAllocPool::preallocatedBufferIndices() const { | 
 | 446 |     return INHERITED::preallocatedBufferSize() / sizeof(uint16_t); | 
 | 447 | } | 
 | 448 |  | 
 | 449 | int GrIndexBufferAllocPool::currentBufferIndices() const { | 
 | 450 |     return currentBufferItems(sizeof(uint16_t)); | 
 | 451 | } |