blob: d1ae03754f468642d12145ac8b476557dfaeee21 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.com1c13c962011-02-14 16:51:21 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.com1c13c962011-02-14 16:51:21 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.com1c13c962011-02-14 16:51:21 +000010#include "GrBufferAllocPool.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000011#include "GrDrawTargetCaps.h"
12#include "GrGpu.h"
13#include "GrIndexBuffer.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000014#include "GrTypes.h"
15#include "GrVertexBuffer.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000016
bsalomon3512eda2014-06-26 12:56:22 -070017#include "SkTraceEvent.h"
18
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000019#ifdef SK_DEBUG
bsalomon@google.com1c13c962011-02-14 16:51:21 +000020 #define VALIDATE validate
21#else
sugoi@google.come0e385c2013-03-11 18:50:03 +000022 static void VALIDATE(bool = false) {}
bsalomon@google.com1c13c962011-02-14 16:51:21 +000023#endif
24
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000025// page size
bsalomon@google.com1c13c962011-02-14 16:51:21 +000026#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
27
bsalomon3512eda2014-06-26 12:56:22 -070028#define UNMAP_BUFFER(block) \
29do { \
30 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), \
31 "GrBufferAllocPool Unmapping Buffer", \
32 TRACE_EVENT_SCOPE_THREAD, \
33 "percent_unwritten", \
34 (float)((block).fBytesFree) / (block).fBuffer->gpuMemorySize()); \
35 (block).fBuffer->unmap(); \
36} while (false)
37
bsalomon@google.com1c13c962011-02-14 16:51:21 +000038GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
39 BufferType bufferType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000040 size_t blockSize,
41 int preallocBufferCnt) :
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000042 fBlocks(SkTMax(8, 2*preallocBufferCnt)) {
bsalomon@google.com11f0b512011-03-29 20:52:23 +000043
bsalomonecb8e3e2015-04-29 04:33:52 -070044 fGpu = SkRef(gpu);
bsalomon@google.com11f0b512011-03-29 20:52:23 +000045
bsalomon@google.com1c13c962011-02-14 16:51:21 +000046 fBufferType = bufferType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000047 fBufferPtr = NULL;
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000048 fMinBlockSize = SkTMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000049
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000050 fBytesInUse = 0;
bsalomon@google.comb665a6b2012-03-01 20:59:28 +000051
bsalomon@google.com1c13c962011-02-14 16:51:21 +000052 fPreallocBuffersInUse = 0;
bsalomon@google.comb665a6b2012-03-01 20:59:28 +000053 fPreallocBufferStartIdx = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000054 for (int i = 0; i < preallocBufferCnt; ++i) {
55 GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
bsalomon49f085d2014-09-05 13:34:00 -070056 if (buffer) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000057 *fPreallocBuffers.append() = buffer;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000058 }
59 }
60}
61
62GrBufferAllocPool::~GrBufferAllocPool() {
63 VALIDATE();
64 if (fBlocks.count()) {
65 GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000066 if (buffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070067 UNMAP_BUFFER(fBlocks.back());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000068 }
69 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000070 while (!fBlocks.empty()) {
71 destroyBlock();
72 }
bsalomon@google.com11f0b512011-03-29 20:52:23 +000073 fPreallocBuffers.unrefAll();
bsalomonecb8e3e2015-04-29 04:33:52 -070074 fGpu->unref();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000075}
76
77void GrBufferAllocPool::reset() {
78 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000079 fBytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000080 if (fBlocks.count()) {
81 GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000082 if (buffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070083 UNMAP_BUFFER(fBlocks.back());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000084 }
85 }
bsalomon@google.comb665a6b2012-03-01 20:59:28 +000086 // fPreallocBuffersInUse will be decremented down to zero in the while loop
87 int preallocBuffersInUse = fPreallocBuffersInUse;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000088 while (!fBlocks.empty()) {
bsalomon@google.comb665a6b2012-03-01 20:59:28 +000089 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000090 }
91 if (fPreallocBuffers.count()) {
92 // must set this after above loop.
bsalomon@google.comb665a6b2012-03-01 20:59:28 +000093 fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
94 preallocBuffersInUse) %
95 fPreallocBuffers.count();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000096 }
bsalomon@google.com987dbc02011-12-14 14:44:19 +000097 // we may have created a large cpu mirror of a large VB. Reset the size
98 // to match our pre-allocated VBs.
99 fCpuData.reset(fMinBlockSize);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000100 SkASSERT(0 == fPreallocBuffersInUse);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000101 VALIDATE();
102}
103
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000104void GrBufferAllocPool::unmap() {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000105 VALIDATE();
106
bsalomon49f085d2014-09-05 13:34:00 -0700107 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000108 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000109 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700110 UNMAP_BUFFER(block);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000111 } else {
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000112 size_t flushSize = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon3512eda2014-06-26 12:56:22 -0700113 this->flushCpuData(fBlocks.back(), flushSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000114 }
115 fBufferPtr = NULL;
116 }
117 VALIDATE();
118}
119
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000120#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000121void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800122 bool wasDestroyed = false;
bsalomon49f085d2014-09-05 13:34:00 -0700123 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000124 SkASSERT(!fBlocks.empty());
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000125 if (fBlocks.back().fBuffer->isMapped()) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000126 GrGeometryBuffer* buf = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000127 SkASSERT(buf->mapPtr() == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000128 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000129 SkASSERT(fCpuData.get() == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000130 }
131 } else {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000132 SkASSERT(fBlocks.empty() || !fBlocks.back().fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000133 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000134 size_t bytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000135 for (int i = 0; i < fBlocks.count() - 1; ++i) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000136 SkASSERT(!fBlocks[i].fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000137 }
bsalomon71cb0c22014-11-14 12:10:14 -0800138 for (int i = 0; !wasDestroyed && i < fBlocks.count(); ++i) {
139 if (fBlocks[i].fBuffer->wasDestroyed()) {
140 wasDestroyed = true;
141 } else {
142 size_t bytes = fBlocks[i].fBuffer->gpuMemorySize() - fBlocks[i].fBytesFree;
143 bytesInUse += bytes;
144 SkASSERT(bytes || unusedBlockAllowed);
145 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000146 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000147
bsalomon71cb0c22014-11-14 12:10:14 -0800148 if (!wasDestroyed) {
149 SkASSERT(bytesInUse == fBytesInUse);
150 if (unusedBlockAllowed) {
151 SkASSERT((fBytesInUse && !fBlocks.empty()) ||
152 (!fBytesInUse && (fBlocks.count() < 2)));
153 } else {
154 SkASSERT((0 == fBytesInUse) == fBlocks.empty());
155 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000156 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000157}
158#endif
159
160void* GrBufferAllocPool::makeSpace(size_t size,
161 size_t alignment,
162 const GrGeometryBuffer** buffer,
163 size_t* offset) {
164 VALIDATE();
165
bsalomon49f085d2014-09-05 13:34:00 -0700166 SkASSERT(buffer);
167 SkASSERT(offset);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000168
bsalomon49f085d2014-09-05 13:34:00 -0700169 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000170 BufferBlock& back = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000171 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000172 size_t pad = GrSizeAlignUpPad(usedBytes,
173 alignment);
174 if ((size + pad) <= back.fBytesFree) {
dongseong.hwang8f25c662015-01-22 10:40:20 -0800175 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000176 usedBytes += pad;
177 *offset = usedBytes;
178 *buffer = back.fBuffer;
179 back.fBytesFree -= size + pad;
bsalomon@google.comd5108092012-03-08 15:10:39 +0000180 fBytesInUse += size + pad;
181 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000182 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
183 }
184 }
185
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000186 // We could honor the space request using by a partial update of the current
187 // VB (if there is room). But we don't currently use draw calls to GL that
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000188 // allow the driver to know that previously issued draws won't read from
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000189 // the part of the buffer we update. Also, the GL buffer implementation
190 // may be cheating on the actual buffer size by shrinking the buffer on
191 // updateData() if the amount of data passed is less than the full buffer
192 // size.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000193
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000194 if (!createBlock(size)) {
195 return NULL;
196 }
bsalomon49f085d2014-09-05 13:34:00 -0700197 SkASSERT(fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000198
199 *offset = 0;
200 BufferBlock& back = fBlocks.back();
201 *buffer = back.fBuffer;
202 back.fBytesFree -= size;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000203 fBytesInUse += size;
204 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000205 return fBufferPtr;
206}
207
208int GrBufferAllocPool::currentBufferItems(size_t itemSize) const {
209 VALIDATE();
bsalomon49f085d2014-09-05 13:34:00 -0700210 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000211 const BufferBlock& back = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000212 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000213 size_t pad = GrSizeAlignUpPad(usedBytes, itemSize);
robertphillips@google.comadacc702013-10-14 21:53:24 +0000214 return static_cast<int>((back.fBytesFree - pad) / itemSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000215 } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
robertphillips@google.comadacc702013-10-14 21:53:24 +0000216 return static_cast<int>(fMinBlockSize / itemSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000217 }
218 return 0;
219}
220
221int GrBufferAllocPool::preallocatedBuffersRemaining() const {
222 return fPreallocBuffers.count() - fPreallocBuffersInUse;
223}
224
225int GrBufferAllocPool::preallocatedBufferCount() const {
226 return fPreallocBuffers.count();
227}
228
229void GrBufferAllocPool::putBack(size_t bytes) {
230 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000231
bsalomon@google.comb665a6b2012-03-01 20:59:28 +0000232 // if the putBack unwinds all the preallocated buffers then we will
233 // advance the starting index. As blocks are destroyed fPreallocBuffersInUse
234 // will be decremented. I will reach zero if all blocks using preallocated
235 // buffers are released.
236 int preallocBuffersInUse = fPreallocBuffersInUse;
237
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000238 while (bytes) {
239 // caller shouldnt try to put back more than they've taken
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000240 SkASSERT(!fBlocks.empty());
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000242 size_t bytesUsed = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000243 if (bytes >= bytesUsed) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000244 bytes -= bytesUsed;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000245 fBytesInUse -= bytesUsed;
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000246 // if we locked a vb to satisfy the make space and we're releasing
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000247 // beyond it, then unmap it.
248 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700249 UNMAP_BUFFER(block);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000250 }
251 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000252 } else {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000253 block.fBytesFree += bytes;
254 fBytesInUse -= bytes;
255 bytes = 0;
256 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000257 }
258 }
bsalomon@google.comb665a6b2012-03-01 20:59:28 +0000259 if (!fPreallocBuffersInUse && fPreallocBuffers.count()) {
260 fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
261 preallocBuffersInUse) %
262 fPreallocBuffers.count();
263 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000264 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000265}
266
267bool GrBufferAllocPool::createBlock(size_t requestSize) {
268
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000269 size_t size = SkTMax(requestSize, fMinBlockSize);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000270 SkASSERT(size >= GrBufferAllocPool_MIN_BLOCK_SIZE);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000271
272 VALIDATE();
273
274 BufferBlock& block = fBlocks.push_back();
275
276 if (size == fMinBlockSize &&
277 fPreallocBuffersInUse < fPreallocBuffers.count()) {
278
bsalomon@google.comb665a6b2012-03-01 20:59:28 +0000279 uint32_t nextBuffer = (fPreallocBuffersInUse +
280 fPreallocBufferStartIdx) %
281 fPreallocBuffers.count();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000282 block.fBuffer = fPreallocBuffers[nextBuffer];
283 block.fBuffer->ref();
284 ++fPreallocBuffersInUse;
285 } else {
286 block.fBuffer = this->createBuffer(size);
287 if (NULL == block.fBuffer) {
288 fBlocks.pop_back();
289 return false;
290 }
291 }
292
293 block.fBytesFree = size;
bsalomon49f085d2014-09-05 13:34:00 -0700294 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000295 SkASSERT(fBlocks.count() > 1);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000296 BufferBlock& prev = fBlocks.fromBack(1);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000297 if (prev.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700298 UNMAP_BUFFER(prev);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000299 } else {
bsalomon3512eda2014-06-26 12:56:22 -0700300 this->flushCpuData(prev, prev.fBuffer->gpuMemorySize() - prev.fBytesFree);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000301 }
302 fBufferPtr = NULL;
303 }
304
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000305 SkASSERT(NULL == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000306
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000307 // If the buffer is CPU-backed we map it because it is free to do so and saves a copy.
bsalomonecb8e3e2015-04-29 04:33:52 -0700308 // Otherwise when buffer mapping is supported we map if the buffer size is greater than the
309 // threshold.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000310 bool attemptMap = block.fBuffer->isCPUBacked();
311 if (!attemptMap && GrDrawTargetCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags()) {
bsalomonecb8e3e2015-04-29 04:33:52 -0700312 attemptMap = size > GR_GEOM_BUFFER_MAP_THRESHOLD;
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +0000313 }
314
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000315 if (attemptMap) {
316 fBufferPtr = block.fBuffer->map();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000317 }
318
319 if (NULL == fBufferPtr) {
bsalomon@google.com7d4679a2011-09-02 22:06:24 +0000320 fBufferPtr = fCpuData.reset(size);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000321 }
322
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000323 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000324
325 return true;
326}
327
328void GrBufferAllocPool::destroyBlock() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000329 SkASSERT(!fBlocks.empty());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000330
331 BufferBlock& block = fBlocks.back();
332 if (fPreallocBuffersInUse > 0) {
333 uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
bsalomon@google.comb665a6b2012-03-01 20:59:28 +0000334 fPreallocBufferStartIdx +
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000335 (fPreallocBuffers.count() - 1)) %
336 fPreallocBuffers.count();
337 if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {
338 --fPreallocBuffersInUse;
339 }
340 }
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000341 SkASSERT(!block.fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000342 block.fBuffer->unref();
343 fBlocks.pop_back();
344 fBufferPtr = NULL;
345}
346
bsalomon3512eda2014-06-26 12:56:22 -0700347void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize) {
348 GrGeometryBuffer* buffer = block.fBuffer;
bsalomon49f085d2014-09-05 13:34:00 -0700349 SkASSERT(buffer);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000350 SkASSERT(!buffer->isMapped());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000351 SkASSERT(fCpuData.get() == fBufferPtr);
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000352 SkASSERT(flushSize <= buffer->gpuMemorySize());
bsalomon@google.comd5108092012-03-08 15:10:39 +0000353 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000354
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000355 if (GrDrawTargetCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags() &&
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000356 flushSize > GR_GEOM_BUFFER_MAP_THRESHOLD) {
357 void* data = buffer->map();
bsalomon49f085d2014-09-05 13:34:00 -0700358 if (data) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000359 memcpy(data, fBufferPtr, flushSize);
bsalomon3512eda2014-06-26 12:56:22 -0700360 UNMAP_BUFFER(block);
bsalomon@google.com71bd1ef2011-12-12 20:42:26 +0000361 return;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000362 }
363 }
364 buffer->updateData(fBufferPtr, flushSize);
bsalomon@google.comd5108092012-03-08 15:10:39 +0000365 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000366}
367
368GrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) {
369 if (kIndex_BufferType == fBufferType) {
370 return fGpu->createIndexBuffer(size, true);
371 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000372 SkASSERT(kVertex_BufferType == fBufferType);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000373 return fGpu->createVertexBuffer(size, true);
374 }
375}
376
377////////////////////////////////////////////////////////////////////////////////
378
379GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000380 size_t bufferSize,
381 int preallocBufferCnt)
382: GrBufferAllocPool(gpu,
383 kVertex_BufferType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000384 bufferSize,
385 preallocBufferCnt) {
386}
387
jvanverth@google.coma6338982013-01-31 21:34:25 +0000388void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000389 int vertexCount,
390 const GrVertexBuffer** buffer,
391 int* startVertex) {
392
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000393 SkASSERT(vertexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700394 SkASSERT(buffer);
395 SkASSERT(startVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000396
bsalomon@google.com8b484412011-04-18 19:07:44 +0000397 size_t offset = 0; // assign to suppress warning
398 const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
jvanverth@google.coma6338982013-01-31 21:34:25 +0000399 void* ptr = INHERITED::makeSpace(vertexSize * vertexCount,
400 vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000401 &geomBuffer,
402 &offset);
403
404 *buffer = (const GrVertexBuffer*) geomBuffer;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000405 SkASSERT(0 == offset % vertexSize);
robertphillips@google.comadacc702013-10-14 21:53:24 +0000406 *startVertex = static_cast<int>(offset / vertexSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000407 return ptr;
408}
409
jvanverth@google.coma6338982013-01-31 21:34:25 +0000410int GrVertexBufferAllocPool::preallocatedBufferVertices(size_t vertexSize) const {
robertphillips@google.comadacc702013-10-14 21:53:24 +0000411 return static_cast<int>(INHERITED::preallocatedBufferSize() / vertexSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000412}
413
jvanverth@google.coma6338982013-01-31 21:34:25 +0000414int GrVertexBufferAllocPool::currentBufferVertices(size_t vertexSize) const {
415 return currentBufferItems(vertexSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000416}
417
418////////////////////////////////////////////////////////////////////////////////
419
420GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000421 size_t bufferSize,
422 int preallocBufferCnt)
423: GrBufferAllocPool(gpu,
424 kIndex_BufferType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000425 bufferSize,
426 preallocBufferCnt) {
427}
428
429void* GrIndexBufferAllocPool::makeSpace(int indexCount,
430 const GrIndexBuffer** buffer,
431 int* startIndex) {
432
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000433 SkASSERT(indexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700434 SkASSERT(buffer);
435 SkASSERT(startIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000436
bsalomon@google.com8b484412011-04-18 19:07:44 +0000437 size_t offset = 0; // assign to suppress warning
438 const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000439 void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
440 sizeof(uint16_t),
441 &geomBuffer,
442 &offset);
443
444 *buffer = (const GrIndexBuffer*) geomBuffer;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000445 SkASSERT(0 == offset % sizeof(uint16_t));
robertphillips@google.comadacc702013-10-14 21:53:24 +0000446 *startIndex = static_cast<int>(offset / sizeof(uint16_t));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000447 return ptr;
448}
449
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000450int GrIndexBufferAllocPool::preallocatedBufferIndices() const {
robertphillips@google.comadacc702013-10-14 21:53:24 +0000451 return static_cast<int>(INHERITED::preallocatedBufferSize() / sizeof(uint16_t));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000452}
453
454int GrIndexBufferAllocPool::currentBufferIndices() const {
455 return currentBufferItems(sizeof(uint16_t));
456}