blob: 13ae404d3d7b730897f61de02c7841fcef12474e [file] [log] [blame]
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2010 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
bsalomon@google.com1c13c962011-02-14 16:51:21 +00006 */
7
epoger@google.comec3ed6a2011-07-28 14:26:00 +00008
bsalomon@google.com1c13c962011-02-14 16:51:21 +00009#include "GrBufferAllocPool.h"
cdalton397536c2016-03-25 12:15:03 -070010#include "GrBuffer.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070011#include "GrCaps.h"
robertphillips1b8e1b52015-06-24 06:54:10 -070012#include "GrContext.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000013#include "GrGpu.h"
robertphillips1b8e1b52015-06-24 06:54:10 -070014#include "GrResourceProvider.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000015#include "GrTypes.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
robertphillips1b8e1b52015-06-24 06:54:10 -070025static const size_t MIN_VERTEX_BUFFER_SIZE = 1 << 15;
26static const size_t MIN_INDEX_BUFFER_SIZE = 1 << 12;
27
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000028// page size
joshualitt0709ca02015-06-04 09:13:46 -070029#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 15)
bsalomon@google.com1c13c962011-02-14 16:51:21 +000030
bsalomon3512eda2014-06-26 12:56:22 -070031#define UNMAP_BUFFER(block) \
32do { \
Brian Osman39c08ac2017-07-26 09:36:09 -040033 TRACE_EVENT_INSTANT1("skia.gpu", \
bsalomon3512eda2014-06-26 12:56:22 -070034 "GrBufferAllocPool Unmapping Buffer", \
35 TRACE_EVENT_SCOPE_THREAD, \
36 "percent_unwritten", \
37 (float)((block).fBytesFree) / (block).fBuffer->gpuMemorySize()); \
38 (block).fBuffer->unmap(); \
39} while (false)
40
Robert Phillipsbdda0ba2017-08-31 09:17:43 -040041GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu, GrBufferType bufferType, size_t blockSize)
42 : fBlocks(8) {
bsalomon@google.com11f0b512011-03-29 20:52:23 +000043
bsalomonecb8e3e2015-04-29 04:33:52 -070044 fGpu = SkRef(gpu);
bsalomon7dea7b72015-08-19 08:26:51 -070045 fCpuData = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000046 fBufferType = bufferType;
bsalomon7dea7b72015-08-19 08:26:51 -070047 fBufferPtr = nullptr;
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;
robertphillipseea2ff72015-05-14 05:24:53 -070051
cdalton397536c2016-03-25 12:15:03 -070052 fBufferMapThreshold = gpu->caps()->bufferMapThreshold();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000053}
54
robertphillips1b8e1b52015-06-24 06:54:10 -070055void GrBufferAllocPool::deleteBlocks() {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000056 if (fBlocks.count()) {
cdalton397536c2016-03-25 12:15:03 -070057 GrBuffer* buffer = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000058 if (buffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070059 UNMAP_BUFFER(fBlocks.back());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000060 }
61 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000062 while (!fBlocks.empty()) {
robertphillips91d06bc2015-05-06 04:38:36 -070063 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000064 }
robertphillips1b8e1b52015-06-24 06:54:10 -070065 SkASSERT(!fBufferPtr);
66}
67
68GrBufferAllocPool::~GrBufferAllocPool() {
69 VALIDATE();
70 this->deleteBlocks();
bsalomon7dea7b72015-08-19 08:26:51 -070071 sk_free(fCpuData);
bsalomonecb8e3e2015-04-29 04:33:52 -070072 fGpu->unref();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000073}
74
75void GrBufferAllocPool::reset() {
76 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000077 fBytesInUse = 0;
robertphillips1b8e1b52015-06-24 06:54:10 -070078 this->deleteBlocks();
robertphillips48d91b52016-08-18 14:01:14 -070079 this->resetCpuData(0); // delete all the cpu-side memory
bsalomon@google.com1c13c962011-02-14 16:51:21 +000080 VALIDATE();
81}
82
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000083void GrBufferAllocPool::unmap() {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000084 VALIDATE();
85
bsalomon49f085d2014-09-05 13:34:00 -070086 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000087 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000088 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070089 UNMAP_BUFFER(block);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000090 } else {
commit-bot@chromium.org089a7802014-05-02 21:38:22 +000091 size_t flushSize = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon3512eda2014-06-26 12:56:22 -070092 this->flushCpuData(fBlocks.back(), flushSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000093 }
bsalomon7dea7b72015-08-19 08:26:51 -070094 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000095 }
96 VALIDATE();
97}
98
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000099#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000100void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800101 bool wasDestroyed = false;
bsalomon49f085d2014-09-05 13:34:00 -0700102 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000103 SkASSERT(!fBlocks.empty());
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000104 if (fBlocks.back().fBuffer->isMapped()) {
cdalton397536c2016-03-25 12:15:03 -0700105 GrBuffer* buf = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000106 SkASSERT(buf->mapPtr() == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000107 } else {
bsalomon7dea7b72015-08-19 08:26:51 -0700108 SkASSERT(fCpuData == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000109 }
110 } else {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000111 SkASSERT(fBlocks.empty() || !fBlocks.back().fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000112 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000113 size_t bytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000114 for (int i = 0; i < fBlocks.count() - 1; ++i) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000115 SkASSERT(!fBlocks[i].fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000116 }
bsalomon71cb0c22014-11-14 12:10:14 -0800117 for (int i = 0; !wasDestroyed && i < fBlocks.count(); ++i) {
118 if (fBlocks[i].fBuffer->wasDestroyed()) {
119 wasDestroyed = true;
120 } else {
121 size_t bytes = fBlocks[i].fBuffer->gpuMemorySize() - fBlocks[i].fBytesFree;
122 bytesInUse += bytes;
123 SkASSERT(bytes || unusedBlockAllowed);
124 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000125 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000126
bsalomon71cb0c22014-11-14 12:10:14 -0800127 if (!wasDestroyed) {
128 SkASSERT(bytesInUse == fBytesInUse);
129 if (unusedBlockAllowed) {
130 SkASSERT((fBytesInUse && !fBlocks.empty()) ||
131 (!fBytesInUse && (fBlocks.count() < 2)));
132 } else {
133 SkASSERT((0 == fBytesInUse) == fBlocks.empty());
134 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000135 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000136}
137#endif
138
139void* GrBufferAllocPool::makeSpace(size_t size,
140 size_t alignment,
cdalton397536c2016-03-25 12:15:03 -0700141 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000142 size_t* offset) {
143 VALIDATE();
144
bsalomon49f085d2014-09-05 13:34:00 -0700145 SkASSERT(buffer);
146 SkASSERT(offset);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000147
bsalomon49f085d2014-09-05 13:34:00 -0700148 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000149 BufferBlock& back = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000150 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
robertphillips1b8e1b52015-06-24 06:54:10 -0700151 size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000152 if ((size + pad) <= back.fBytesFree) {
dongseong.hwang8f25c662015-01-22 10:40:20 -0800153 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000154 usedBytes += pad;
155 *offset = usedBytes;
156 *buffer = back.fBuffer;
157 back.fBytesFree -= size + pad;
bsalomon@google.comd5108092012-03-08 15:10:39 +0000158 fBytesInUse += size + pad;
159 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000160 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
161 }
162 }
163
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000164 // We could honor the space request using by a partial update of the current
165 // VB (if there is room). But we don't currently use draw calls to GL that
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000166 // allow the driver to know that previously issued draws won't read from
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000167 // the part of the buffer we update. Also, the GL buffer implementation
168 // may be cheating on the actual buffer size by shrinking the buffer on
169 // updateData() if the amount of data passed is less than the full buffer
170 // size.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000171
robertphillips91d06bc2015-05-06 04:38:36 -0700172 if (!this->createBlock(size)) {
bsalomon7dea7b72015-08-19 08:26:51 -0700173 return nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000174 }
bsalomon49f085d2014-09-05 13:34:00 -0700175 SkASSERT(fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000176
177 *offset = 0;
178 BufferBlock& back = fBlocks.back();
179 *buffer = back.fBuffer;
180 back.fBytesFree -= size;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000181 fBytesInUse += size;
182 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000183 return fBufferPtr;
184}
185
Brian Osman49b7b6f2017-06-20 14:43:58 -0400186void* GrBufferAllocPool::makeSpaceAtLeast(size_t minSize,
187 size_t fallbackSize,
188 size_t alignment,
189 const GrBuffer** buffer,
190 size_t* offset,
191 size_t* actualSize) {
192 VALIDATE();
193
194 SkASSERT(buffer);
195 SkASSERT(offset);
196 SkASSERT(actualSize);
197
198 if (fBufferPtr) {
199 BufferBlock& back = fBlocks.back();
200 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
201 size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
202 if ((minSize + pad) <= back.fBytesFree) {
203 // Consume padding first, to make subsequent alignment math easier
204 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
205 usedBytes += pad;
206 back.fBytesFree -= pad;
207 fBytesInUse += pad;
208
209 // Give caller all remaining space in this block (but aligned correctly)
210 size_t size = GrSizeAlignDown(back.fBytesFree, alignment);
211 *offset = usedBytes;
212 *buffer = back.fBuffer;
213 *actualSize = size;
214 back.fBytesFree -= size;
215 fBytesInUse += size;
216 VALIDATE();
217 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
218 }
219 }
220
221 // We could honor the space request using by a partial update of the current
222 // VB (if there is room). But we don't currently use draw calls to GL that
223 // allow the driver to know that previously issued draws won't read from
224 // the part of the buffer we update. Also, the GL buffer implementation
225 // may be cheating on the actual buffer size by shrinking the buffer on
226 // updateData() if the amount of data passed is less than the full buffer
227 // size.
228
229 if (!this->createBlock(fallbackSize)) {
230 return nullptr;
231 }
232 SkASSERT(fBufferPtr);
233
234 *offset = 0;
235 BufferBlock& back = fBlocks.back();
236 *buffer = back.fBuffer;
237 *actualSize = fallbackSize;
238 back.fBytesFree -= fallbackSize;
239 fBytesInUse += fallbackSize;
240 VALIDATE();
241 return fBufferPtr;
242}
243
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000244void GrBufferAllocPool::putBack(size_t bytes) {
245 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246
247 while (bytes) {
robertphillips91d06bc2015-05-06 04:38:36 -0700248 // caller shouldn't try to put back more than they've taken
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000249 SkASSERT(!fBlocks.empty());
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000250 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000251 size_t bytesUsed = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000252 if (bytes >= bytesUsed) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000253 bytes -= bytesUsed;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000254 fBytesInUse -= bytesUsed;
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000255 // if we locked a vb to satisfy the make space and we're releasing
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000256 // beyond it, then unmap it.
257 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700258 UNMAP_BUFFER(block);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000259 }
260 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000261 } else {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000262 block.fBytesFree += bytes;
263 fBytesInUse -= bytes;
264 bytes = 0;
265 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000266 }
267 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700268
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000269 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000270}
271
272bool GrBufferAllocPool::createBlock(size_t requestSize) {
273
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000274 size_t size = SkTMax(requestSize, fMinBlockSize);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000275 SkASSERT(size >= GrBufferAllocPool_MIN_BLOCK_SIZE);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000276
277 VALIDATE();
278
279 BufferBlock& block = fBlocks.push_back();
280
robertphillips1b8e1b52015-06-24 06:54:10 -0700281 block.fBuffer = this->getBuffer(size);
bsalomon7dea7b72015-08-19 08:26:51 -0700282 if (!block.fBuffer) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700283 fBlocks.pop_back();
284 return false;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000285 }
286
robertphillips1b8e1b52015-06-24 06:54:10 -0700287 block.fBytesFree = block.fBuffer->gpuMemorySize();
bsalomon49f085d2014-09-05 13:34:00 -0700288 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000289 SkASSERT(fBlocks.count() > 1);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000290 BufferBlock& prev = fBlocks.fromBack(1);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000291 if (prev.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700292 UNMAP_BUFFER(prev);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000293 } else {
bsalomon3512eda2014-06-26 12:56:22 -0700294 this->flushCpuData(prev, prev.fBuffer->gpuMemorySize() - prev.fBytesFree);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000295 }
bsalomon7dea7b72015-08-19 08:26:51 -0700296 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000297 }
298
bsalomon7dea7b72015-08-19 08:26:51 -0700299 SkASSERT(!fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000300
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000301 // 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 -0700302 // Otherwise when buffer mapping is supported we map if the buffer size is greater than the
303 // threshold.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000304 bool attemptMap = block.fBuffer->isCPUBacked();
bsalomon4b91f762015-05-19 09:29:46 -0700305 if (!attemptMap && GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags()) {
cdalton397536c2016-03-25 12:15:03 -0700306 attemptMap = size > fBufferMapThreshold;
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +0000307 }
308
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000309 if (attemptMap) {
310 fBufferPtr = block.fBuffer->map();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000311 }
312
bsalomon7dea7b72015-08-19 08:26:51 -0700313 if (!fBufferPtr) {
314 fBufferPtr = this->resetCpuData(block.fBytesFree);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000315 }
316
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000317 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000318
319 return true;
320}
321
322void GrBufferAllocPool::destroyBlock() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000323 SkASSERT(!fBlocks.empty());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000324
325 BufferBlock& block = fBlocks.back();
robertphillips1b8e1b52015-06-24 06:54:10 -0700326
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000327 SkASSERT(!block.fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000328 block.fBuffer->unref();
329 fBlocks.pop_back();
bsalomon7dea7b72015-08-19 08:26:51 -0700330 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000331}
332
bsalomon7dea7b72015-08-19 08:26:51 -0700333void* GrBufferAllocPool::resetCpuData(size_t newSize) {
334 sk_free(fCpuData);
335 if (newSize) {
336 if (fGpu->caps()->mustClearUploadedBufferData()) {
mtkleinabda35d2016-07-14 06:57:31 -0700337 fCpuData = sk_calloc_throw(newSize);
bsalomon7dea7b72015-08-19 08:26:51 -0700338 } else {
339 fCpuData = sk_malloc_throw(newSize);
340 }
341 } else {
342 fCpuData = nullptr;
343 }
344 return fCpuData;
345}
346
347
bsalomon3512eda2014-06-26 12:56:22 -0700348void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize) {
cdalton397536c2016-03-25 12:15:03 -0700349 GrBuffer* buffer = block.fBuffer;
bsalomon49f085d2014-09-05 13:34:00 -0700350 SkASSERT(buffer);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000351 SkASSERT(!buffer->isMapped());
bsalomon7dea7b72015-08-19 08:26:51 -0700352 SkASSERT(fCpuData == fBufferPtr);
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000353 SkASSERT(flushSize <= buffer->gpuMemorySize());
bsalomon@google.comd5108092012-03-08 15:10:39 +0000354 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000355
bsalomon4b91f762015-05-19 09:29:46 -0700356 if (GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags() &&
cdalton397536c2016-03-25 12:15:03 -0700357 flushSize > fBufferMapThreshold) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000358 void* data = buffer->map();
bsalomon49f085d2014-09-05 13:34:00 -0700359 if (data) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000360 memcpy(data, fBufferPtr, flushSize);
bsalomon3512eda2014-06-26 12:56:22 -0700361 UNMAP_BUFFER(block);
bsalomon@google.com71bd1ef2011-12-12 20:42:26 +0000362 return;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000363 }
364 }
365 buffer->updateData(fBufferPtr, flushSize);
bsalomon@google.comd5108092012-03-08 15:10:39 +0000366 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000367}
368
cdalton397536c2016-03-25 12:15:03 -0700369GrBuffer* GrBufferAllocPool::getBuffer(size_t size) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700370
371 GrResourceProvider* rp = fGpu->getContext()->resourceProvider();
372
halcanary6950de62015-11-07 05:29:00 -0800373 // Shouldn't have to use this flag (https://bug.skia.org/4156)
bsalomoneae62002015-07-31 13:59:30 -0700374 static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
cdaltone2e71c22016-04-07 18:13:29 -0700375 return rp->createBuffer(size, fBufferType, kDynamic_GrAccessPattern, kFlags);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000376}
377
378////////////////////////////////////////////////////////////////////////////////
379
robertphillips1b8e1b52015-06-24 06:54:10 -0700380GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu)
cdalton397536c2016-03-25 12:15:03 -0700381 : GrBufferAllocPool(gpu, kVertex_GrBufferType, MIN_VERTEX_BUFFER_SIZE) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000382}
383
jvanverth@google.coma6338982013-01-31 21:34:25 +0000384void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000385 int vertexCount,
cdalton397536c2016-03-25 12:15:03 -0700386 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000387 int* startVertex) {
388
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000389 SkASSERT(vertexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700390 SkASSERT(buffer);
391 SkASSERT(startVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000392
Robert Phillipsc787e492017-02-28 11:26:32 -0500393 size_t offset SK_INIT_TO_AVOID_WARNING;
jvanverth@google.coma6338982013-01-31 21:34:25 +0000394 void* ptr = INHERITED::makeSpace(vertexSize * vertexCount,
395 vertexSize,
cdalton397536c2016-03-25 12:15:03 -0700396 buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000397 &offset);
398
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000399 SkASSERT(0 == offset % vertexSize);
robertphillips@google.comadacc702013-10-14 21:53:24 +0000400 *startVertex = static_cast<int>(offset / vertexSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000401 return ptr;
402}
403
Brian Osman49b7b6f2017-06-20 14:43:58 -0400404void* GrVertexBufferAllocPool::makeSpaceAtLeast(size_t vertexSize, int minVertexCount,
405 int fallbackVertexCount, const GrBuffer** buffer,
406 int* startVertex, int* actualVertexCount) {
407
408 SkASSERT(minVertexCount >= 0);
409 SkASSERT(fallbackVertexCount >= minVertexCount);
410 SkASSERT(buffer);
411 SkASSERT(startVertex);
412 SkASSERT(actualVertexCount);
413
414 size_t offset SK_INIT_TO_AVOID_WARNING;
415 size_t actualSize SK_INIT_TO_AVOID_WARNING;
416 void* ptr = INHERITED::makeSpaceAtLeast(vertexSize * minVertexCount,
417 vertexSize * fallbackVertexCount,
418 vertexSize,
419 buffer,
420 &offset,
421 &actualSize);
422
423 SkASSERT(0 == offset % vertexSize);
424 *startVertex = static_cast<int>(offset / vertexSize);
425
426 SkASSERT(0 == actualSize % vertexSize);
427 SkASSERT(actualSize >= vertexSize * minVertexCount);
428 *actualVertexCount = static_cast<int>(actualSize / vertexSize);
429
430 return ptr;
431}
432
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000433////////////////////////////////////////////////////////////////////////////////
434
robertphillips1b8e1b52015-06-24 06:54:10 -0700435GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu)
cdalton397536c2016-03-25 12:15:03 -0700436 : GrBufferAllocPool(gpu, kIndex_GrBufferType, MIN_INDEX_BUFFER_SIZE) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437}
438
439void* GrIndexBufferAllocPool::makeSpace(int indexCount,
cdalton397536c2016-03-25 12:15:03 -0700440 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 int* startIndex) {
442
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000443 SkASSERT(indexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700444 SkASSERT(buffer);
445 SkASSERT(startIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000446
Robert Phillipsc787e492017-02-28 11:26:32 -0500447 size_t offset SK_INIT_TO_AVOID_WARNING;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000448 void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
449 sizeof(uint16_t),
cdalton397536c2016-03-25 12:15:03 -0700450 buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000451 &offset);
452
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000453 SkASSERT(0 == offset % sizeof(uint16_t));
robertphillips@google.comadacc702013-10-14 21:53:24 +0000454 *startIndex = static_cast<int>(offset / sizeof(uint16_t));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000455 return ptr;
456}
Brian Osman49b7b6f2017-06-20 14:43:58 -0400457
458void* GrIndexBufferAllocPool::makeSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
459 const GrBuffer** buffer, int* startIndex,
460 int* actualIndexCount) {
461 SkASSERT(minIndexCount >= 0);
462 SkASSERT(fallbackIndexCount >= minIndexCount);
463 SkASSERT(buffer);
464 SkASSERT(startIndex);
465 SkASSERT(actualIndexCount);
466
467 size_t offset SK_INIT_TO_AVOID_WARNING;
468 size_t actualSize SK_INIT_TO_AVOID_WARNING;
469 void* ptr = INHERITED::makeSpaceAtLeast(minIndexCount * sizeof(uint16_t),
470 fallbackIndexCount * sizeof(uint16_t),
471 sizeof(uint16_t),
472 buffer,
473 &offset,
474 &actualSize);
475
476 SkASSERT(0 == offset % sizeof(uint16_t));
477 *startIndex = static_cast<int>(offset / sizeof(uint16_t));
478
479 SkASSERT(0 == actualSize % sizeof(uint16_t));
480 SkASSERT(actualSize >= minIndexCount * sizeof(uint16_t));
481 *actualIndexCount = static_cast<int>(actualSize / sizeof(uint16_t));
482 return ptr;
483}