blob: b0fa58fb068e5a5077603b4eaf39e5ba44bb135e [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
8#include "GrBufferAllocPool.h"
Hal Canary50dbc092018-06-12 14:50:37 -04009
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"
Robert Phillips6be756b2018-01-16 15:07:54 -050013#include "GrContextPriv.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000014#include "GrGpu.h"
robertphillips1b8e1b52015-06-24 06:54:10 -070015#include "GrResourceProvider.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000016#include "GrTypes.h"
Hal Canary50dbc092018-06-12 14:50:37 -040017#include "SkMacros.h"
Mike Reedfe266c22018-01-17 11:55:07 -050018#include "SkSafeMath.h"
bsalomon3512eda2014-06-26 12:56:22 -070019#include "SkTraceEvent.h"
20
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000021#ifdef SK_DEBUG
bsalomon@google.com1c13c962011-02-14 16:51:21 +000022 #define VALIDATE validate
23#else
sugoi@google.come0e385c2013-03-11 18:50:03 +000024 static void VALIDATE(bool = false) {}
bsalomon@google.com1c13c962011-02-14 16:51:21 +000025#endif
26
bsalomon3512eda2014-06-26 12:56:22 -070027#define UNMAP_BUFFER(block) \
28do { \
Brian Osman39c08ac2017-07-26 09:36:09 -040029 TRACE_EVENT_INSTANT1("skia.gpu", \
bsalomon3512eda2014-06-26 12:56:22 -070030 "GrBufferAllocPool Unmapping Buffer", \
31 TRACE_EVENT_SCOPE_THREAD, \
32 "percent_unwritten", \
33 (float)((block).fBytesFree) / (block).fBuffer->gpuMemorySize()); \
34 (block).fBuffer->unmap(); \
35} while (false)
36
Brian Salomon58f153c2018-10-18 21:51:15 -040037constexpr size_t GrBufferAllocPool::kDefaultBufferSize;
bsalomon@google.com11f0b512011-03-29 20:52:23 +000038
Brian Salomon58f153c2018-10-18 21:51:15 -040039GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu, GrBufferType bufferType, void* initialBuffer)
40 : fBlocks(8), fGpu(gpu), fBufferType(bufferType), fInitialCpuData(initialBuffer) {
41 if (fInitialCpuData) {
42 fCpuDataSize = kDefaultBufferSize;
43 fCpuData = fInitialCpuData;
44 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000045}
46
robertphillips1b8e1b52015-06-24 06:54:10 -070047void GrBufferAllocPool::deleteBlocks() {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000048 if (fBlocks.count()) {
cdalton397536c2016-03-25 12:15:03 -070049 GrBuffer* buffer = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000050 if (buffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070051 UNMAP_BUFFER(fBlocks.back());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000052 }
53 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000054 while (!fBlocks.empty()) {
robertphillips91d06bc2015-05-06 04:38:36 -070055 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000056 }
robertphillips1b8e1b52015-06-24 06:54:10 -070057 SkASSERT(!fBufferPtr);
58}
59
60GrBufferAllocPool::~GrBufferAllocPool() {
61 VALIDATE();
62 this->deleteBlocks();
Brian Salomon58f153c2018-10-18 21:51:15 -040063 if (fCpuData != fInitialCpuData) {
64 sk_free(fCpuData);
65 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000066}
67
68void GrBufferAllocPool::reset() {
69 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000070 fBytesInUse = 0;
robertphillips1b8e1b52015-06-24 06:54:10 -070071 this->deleteBlocks();
Brian Salomon58f153c2018-10-18 21:51:15 -040072 this->resetCpuData(0);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000073 VALIDATE();
74}
75
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000076void GrBufferAllocPool::unmap() {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000077 VALIDATE();
78
bsalomon49f085d2014-09-05 13:34:00 -070079 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000080 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000081 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -070082 UNMAP_BUFFER(block);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000083 } else {
commit-bot@chromium.org089a7802014-05-02 21:38:22 +000084 size_t flushSize = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon3512eda2014-06-26 12:56:22 -070085 this->flushCpuData(fBlocks.back(), flushSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000086 }
bsalomon7dea7b72015-08-19 08:26:51 -070087 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000088 }
89 VALIDATE();
90}
91
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000092#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000093void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
bsalomon71cb0c22014-11-14 12:10:14 -080094 bool wasDestroyed = false;
bsalomon49f085d2014-09-05 13:34:00 -070095 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000096 SkASSERT(!fBlocks.empty());
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000097 if (fBlocks.back().fBuffer->isMapped()) {
cdalton397536c2016-03-25 12:15:03 -070098 GrBuffer* buf = fBlocks.back().fBuffer;
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000099 SkASSERT(buf->mapPtr() == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000100 } else {
bsalomon7dea7b72015-08-19 08:26:51 -0700101 SkASSERT(fCpuData == fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000102 }
103 } else {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000104 SkASSERT(fBlocks.empty() || !fBlocks.back().fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000105 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000106 size_t bytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000107 for (int i = 0; i < fBlocks.count() - 1; ++i) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000108 SkASSERT(!fBlocks[i].fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000109 }
bsalomon71cb0c22014-11-14 12:10:14 -0800110 for (int i = 0; !wasDestroyed && i < fBlocks.count(); ++i) {
111 if (fBlocks[i].fBuffer->wasDestroyed()) {
112 wasDestroyed = true;
113 } else {
114 size_t bytes = fBlocks[i].fBuffer->gpuMemorySize() - fBlocks[i].fBytesFree;
115 bytesInUse += bytes;
116 SkASSERT(bytes || unusedBlockAllowed);
117 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000118 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000119
bsalomon71cb0c22014-11-14 12:10:14 -0800120 if (!wasDestroyed) {
121 SkASSERT(bytesInUse == fBytesInUse);
122 if (unusedBlockAllowed) {
123 SkASSERT((fBytesInUse && !fBlocks.empty()) ||
124 (!fBytesInUse && (fBlocks.count() < 2)));
125 } else {
126 SkASSERT((0 == fBytesInUse) == fBlocks.empty());
127 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000128 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000129}
130#endif
131
132void* GrBufferAllocPool::makeSpace(size_t size,
133 size_t alignment,
cdalton397536c2016-03-25 12:15:03 -0700134 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000135 size_t* offset) {
136 VALIDATE();
137
bsalomon49f085d2014-09-05 13:34:00 -0700138 SkASSERT(buffer);
139 SkASSERT(offset);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000140
bsalomon49f085d2014-09-05 13:34:00 -0700141 if (fBufferPtr) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000142 BufferBlock& back = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000143 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
robertphillips1b8e1b52015-06-24 06:54:10 -0700144 size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
Brian Salomon6cfcc582018-10-18 14:58:16 -0400145 SkSafeMath safeMath;
146 size_t alignedSize = safeMath.add(pad, size);
147 if (!safeMath.ok()) {
148 return nullptr;
149 }
150 if (alignedSize <= back.fBytesFree) {
dongseong.hwang8f25c662015-01-22 10:40:20 -0800151 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000152 usedBytes += pad;
153 *offset = usedBytes;
154 *buffer = back.fBuffer;
Brian Salomon6cfcc582018-10-18 14:58:16 -0400155 back.fBytesFree -= alignedSize;
156 fBytesInUse += alignedSize;
bsalomon@google.comd5108092012-03-08 15:10:39 +0000157 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000158 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
159 }
160 }
161
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000162 // We could honor the space request using by a partial update of the current
163 // VB (if there is room). But we don't currently use draw calls to GL that
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 // allow the driver to know that previously issued draws won't read from
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000165 // the part of the buffer we update. Also, the GL buffer implementation
166 // may be cheating on the actual buffer size by shrinking the buffer on
167 // updateData() if the amount of data passed is less than the full buffer
168 // size.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000169
robertphillips91d06bc2015-05-06 04:38:36 -0700170 if (!this->createBlock(size)) {
bsalomon7dea7b72015-08-19 08:26:51 -0700171 return nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000172 }
bsalomon49f085d2014-09-05 13:34:00 -0700173 SkASSERT(fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000174
175 *offset = 0;
176 BufferBlock& back = fBlocks.back();
177 *buffer = back.fBuffer;
178 back.fBytesFree -= size;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000179 fBytesInUse += size;
180 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000181 return fBufferPtr;
182}
183
Brian Osman49b7b6f2017-06-20 14:43:58 -0400184void* GrBufferAllocPool::makeSpaceAtLeast(size_t minSize,
185 size_t fallbackSize,
186 size_t alignment,
187 const GrBuffer** buffer,
188 size_t* offset,
189 size_t* actualSize) {
190 VALIDATE();
191
192 SkASSERT(buffer);
193 SkASSERT(offset);
194 SkASSERT(actualSize);
195
196 if (fBufferPtr) {
197 BufferBlock& back = fBlocks.back();
198 size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
199 size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
200 if ((minSize + pad) <= back.fBytesFree) {
201 // Consume padding first, to make subsequent alignment math easier
202 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
203 usedBytes += pad;
204 back.fBytesFree -= pad;
205 fBytesInUse += pad;
206
Brian Salomon4b8178f2018-10-12 13:18:27 -0400207 // Give caller all remaining space in this block up to fallbackSize (but aligned
208 // correctly)
209 size_t size;
210 if (back.fBytesFree >= fallbackSize) {
211 SkASSERT(GrSizeAlignDown(fallbackSize, alignment) == fallbackSize);
212 size = fallbackSize;
213 } else {
214 size = GrSizeAlignDown(back.fBytesFree, alignment);
215 }
Brian Osman49b7b6f2017-06-20 14:43:58 -0400216 *offset = usedBytes;
217 *buffer = back.fBuffer;
218 *actualSize = size;
219 back.fBytesFree -= size;
220 fBytesInUse += size;
221 VALIDATE();
222 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
223 }
224 }
225
226 // We could honor the space request using by a partial update of the current
227 // VB (if there is room). But we don't currently use draw calls to GL that
228 // allow the driver to know that previously issued draws won't read from
229 // the part of the buffer we update. Also, the GL buffer implementation
230 // may be cheating on the actual buffer size by shrinking the buffer on
231 // updateData() if the amount of data passed is less than the full buffer
232 // size.
233
234 if (!this->createBlock(fallbackSize)) {
235 return nullptr;
236 }
237 SkASSERT(fBufferPtr);
238
239 *offset = 0;
240 BufferBlock& back = fBlocks.back();
241 *buffer = back.fBuffer;
242 *actualSize = fallbackSize;
243 back.fBytesFree -= fallbackSize;
244 fBytesInUse += fallbackSize;
245 VALIDATE();
246 return fBufferPtr;
247}
248
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000249void GrBufferAllocPool::putBack(size_t bytes) {
250 VALIDATE();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000251
252 while (bytes) {
robertphillips91d06bc2015-05-06 04:38:36 -0700253 // caller shouldn't try to put back more than they've taken
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000254 SkASSERT(!fBlocks.empty());
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000255 BufferBlock& block = fBlocks.back();
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000256 size_t bytesUsed = block.fBuffer->gpuMemorySize() - block.fBytesFree;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000257 if (bytes >= bytesUsed) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000258 bytes -= bytesUsed;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000259 fBytesInUse -= bytesUsed;
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000260 // if we locked a vb to satisfy the make space and we're releasing
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000261 // beyond it, then unmap it.
262 if (block.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700263 UNMAP_BUFFER(block);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000264 }
265 this->destroyBlock();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000266 } else {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000267 block.fBytesFree += bytes;
268 fBytesInUse -= bytes;
269 bytes = 0;
270 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000271 }
272 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700273
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000274 VALIDATE();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000275}
276
277bool GrBufferAllocPool::createBlock(size_t requestSize) {
Brian Salomon58f153c2018-10-18 21:51:15 -0400278 size_t size = SkTMax(requestSize, kDefaultBufferSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000279
280 VALIDATE();
281
282 BufferBlock& block = fBlocks.push_back();
283
robertphillips1b8e1b52015-06-24 06:54:10 -0700284 block.fBuffer = this->getBuffer(size);
bsalomon7dea7b72015-08-19 08:26:51 -0700285 if (!block.fBuffer) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700286 fBlocks.pop_back();
287 return false;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000288 }
289
robertphillips1b8e1b52015-06-24 06:54:10 -0700290 block.fBytesFree = block.fBuffer->gpuMemorySize();
bsalomon49f085d2014-09-05 13:34:00 -0700291 if (fBufferPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000292 SkASSERT(fBlocks.count() > 1);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000293 BufferBlock& prev = fBlocks.fromBack(1);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000294 if (prev.fBuffer->isMapped()) {
bsalomon3512eda2014-06-26 12:56:22 -0700295 UNMAP_BUFFER(prev);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000296 } else {
bsalomon3512eda2014-06-26 12:56:22 -0700297 this->flushCpuData(prev, prev.fBuffer->gpuMemorySize() - prev.fBytesFree);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000298 }
bsalomon7dea7b72015-08-19 08:26:51 -0700299 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000300 }
301
bsalomon7dea7b72015-08-19 08:26:51 -0700302 SkASSERT(!fBufferPtr);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000303
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000304 // 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 -0700305 // Otherwise when buffer mapping is supported we map if the buffer size is greater than the
306 // threshold.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000307 bool attemptMap = block.fBuffer->isCPUBacked();
bsalomon4b91f762015-05-19 09:29:46 -0700308 if (!attemptMap && GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags()) {
Brian Salomon58f153c2018-10-18 21:51:15 -0400309 attemptMap = size > fGpu->caps()->bufferMapThreshold();
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +0000310 }
311
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000312 if (attemptMap) {
313 fBufferPtr = block.fBuffer->map();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000314 }
315
bsalomon7dea7b72015-08-19 08:26:51 -0700316 if (!fBufferPtr) {
317 fBufferPtr = this->resetCpuData(block.fBytesFree);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000318 }
319
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000320 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000321
322 return true;
323}
324
325void GrBufferAllocPool::destroyBlock() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000326 SkASSERT(!fBlocks.empty());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000327
328 BufferBlock& block = fBlocks.back();
robertphillips1b8e1b52015-06-24 06:54:10 -0700329
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000330 SkASSERT(!block.fBuffer->isMapped());
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000331 block.fBuffer->unref();
332 fBlocks.pop_back();
bsalomon7dea7b72015-08-19 08:26:51 -0700333 fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000334}
335
bsalomon7dea7b72015-08-19 08:26:51 -0700336void* GrBufferAllocPool::resetCpuData(size_t newSize) {
Brian Salomon58f153c2018-10-18 21:51:15 -0400337 if (newSize <= fCpuDataSize) {
338 SkASSERT(!newSize || fCpuData);
339 return fCpuData;
bsalomon7dea7b72015-08-19 08:26:51 -0700340 }
Brian Salomon58f153c2018-10-18 21:51:15 -0400341 if (fCpuData != fInitialCpuData) {
342 sk_free(fCpuData);
343 }
344 if (fGpu->caps()->mustClearUploadedBufferData()) {
345 fCpuData = sk_calloc_throw(newSize);
346 } else {
347 fCpuData = sk_malloc_throw(newSize);
348 }
349 fCpuDataSize = newSize;
bsalomon7dea7b72015-08-19 08:26:51 -0700350 return fCpuData;
351}
352
353
bsalomon3512eda2014-06-26 12:56:22 -0700354void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize) {
cdalton397536c2016-03-25 12:15:03 -0700355 GrBuffer* buffer = block.fBuffer;
bsalomon49f085d2014-09-05 13:34:00 -0700356 SkASSERT(buffer);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000357 SkASSERT(!buffer->isMapped());
bsalomon7dea7b72015-08-19 08:26:51 -0700358 SkASSERT(fCpuData == fBufferPtr);
commit-bot@chromium.org089a7802014-05-02 21:38:22 +0000359 SkASSERT(flushSize <= buffer->gpuMemorySize());
bsalomon@google.comd5108092012-03-08 15:10:39 +0000360 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000361
bsalomon4b91f762015-05-19 09:29:46 -0700362 if (GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags() &&
Brian Salomon58f153c2018-10-18 21:51:15 -0400363 flushSize > fGpu->caps()->bufferMapThreshold()) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000364 void* data = buffer->map();
bsalomon49f085d2014-09-05 13:34:00 -0700365 if (data) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000366 memcpy(data, fBufferPtr, flushSize);
bsalomon3512eda2014-06-26 12:56:22 -0700367 UNMAP_BUFFER(block);
bsalomon@google.com71bd1ef2011-12-12 20:42:26 +0000368 return;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000369 }
370 }
371 buffer->updateData(fBufferPtr, flushSize);
bsalomon@google.comd5108092012-03-08 15:10:39 +0000372 VALIDATE(true);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000373}
374
cdalton397536c2016-03-25 12:15:03 -0700375GrBuffer* GrBufferAllocPool::getBuffer(size_t size) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700376
Robert Phillips6be756b2018-01-16 15:07:54 -0500377 auto resourceProvider = fGpu->getContext()->contextPriv().resourceProvider();
robertphillips1b8e1b52015-06-24 06:54:10 -0700378
halcanary6950de62015-11-07 05:29:00 -0800379 // Shouldn't have to use this flag (https://bug.skia.org/4156)
Chris Daltond004e0b2018-09-27 09:28:03 -0600380 static const auto kFlags = GrResourceProvider::Flags::kNoPendingIO;
Robert Phillips6be756b2018-01-16 15:07:54 -0500381 return resourceProvider->createBuffer(size, fBufferType, kDynamic_GrAccessPattern, kFlags);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000382}
383
384////////////////////////////////////////////////////////////////////////////////
385
Brian Salomon58f153c2018-10-18 21:51:15 -0400386GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu, void* initialCpuBuffer)
387 : GrBufferAllocPool(gpu, kVertex_GrBufferType, initialCpuBuffer) {}
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000388
jvanverth@google.coma6338982013-01-31 21:34:25 +0000389void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000390 int vertexCount,
cdalton397536c2016-03-25 12:15:03 -0700391 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000392 int* startVertex) {
393
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000394 SkASSERT(vertexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700395 SkASSERT(buffer);
396 SkASSERT(startVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000397
Robert Phillipsc787e492017-02-28 11:26:32 -0500398 size_t offset SK_INIT_TO_AVOID_WARNING;
Mike Reedfe266c22018-01-17 11:55:07 -0500399 void* ptr = INHERITED::makeSpace(SkSafeMath::Mul(vertexSize, vertexCount),
jvanverth@google.coma6338982013-01-31 21:34:25 +0000400 vertexSize,
cdalton397536c2016-03-25 12:15:03 -0700401 buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000402 &offset);
403
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000404 SkASSERT(0 == offset % vertexSize);
robertphillips@google.comadacc702013-10-14 21:53:24 +0000405 *startVertex = static_cast<int>(offset / vertexSize);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000406 return ptr;
407}
408
Brian Osman49b7b6f2017-06-20 14:43:58 -0400409void* GrVertexBufferAllocPool::makeSpaceAtLeast(size_t vertexSize, int minVertexCount,
410 int fallbackVertexCount, const GrBuffer** buffer,
411 int* startVertex, int* actualVertexCount) {
412
413 SkASSERT(minVertexCount >= 0);
414 SkASSERT(fallbackVertexCount >= minVertexCount);
415 SkASSERT(buffer);
416 SkASSERT(startVertex);
417 SkASSERT(actualVertexCount);
418
419 size_t offset SK_INIT_TO_AVOID_WARNING;
420 size_t actualSize SK_INIT_TO_AVOID_WARNING;
Mike Reedfe266c22018-01-17 11:55:07 -0500421 void* ptr = INHERITED::makeSpaceAtLeast(SkSafeMath::Mul(vertexSize, minVertexCount),
422 SkSafeMath::Mul(vertexSize, fallbackVertexCount),
Brian Osman49b7b6f2017-06-20 14:43:58 -0400423 vertexSize,
424 buffer,
425 &offset,
426 &actualSize);
427
428 SkASSERT(0 == offset % vertexSize);
429 *startVertex = static_cast<int>(offset / vertexSize);
430
431 SkASSERT(0 == actualSize % vertexSize);
432 SkASSERT(actualSize >= vertexSize * minVertexCount);
433 *actualVertexCount = static_cast<int>(actualSize / vertexSize);
434
435 return ptr;
436}
437
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000438////////////////////////////////////////////////////////////////////////////////
439
Brian Salomon58f153c2018-10-18 21:51:15 -0400440GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu, void* initialCpuBuffer)
441 : GrBufferAllocPool(gpu, kIndex_GrBufferType, initialCpuBuffer) {}
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000442
443void* GrIndexBufferAllocPool::makeSpace(int indexCount,
cdalton397536c2016-03-25 12:15:03 -0700444 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000445 int* startIndex) {
446
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000447 SkASSERT(indexCount >= 0);
bsalomon49f085d2014-09-05 13:34:00 -0700448 SkASSERT(buffer);
449 SkASSERT(startIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000450
Robert Phillipsc787e492017-02-28 11:26:32 -0500451 size_t offset SK_INIT_TO_AVOID_WARNING;
Mike Reedfe266c22018-01-17 11:55:07 -0500452 void* ptr = INHERITED::makeSpace(SkSafeMath::Mul(indexCount, sizeof(uint16_t)),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000453 sizeof(uint16_t),
cdalton397536c2016-03-25 12:15:03 -0700454 buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000455 &offset);
456
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000457 SkASSERT(0 == offset % sizeof(uint16_t));
robertphillips@google.comadacc702013-10-14 21:53:24 +0000458 *startIndex = static_cast<int>(offset / sizeof(uint16_t));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000459 return ptr;
460}
Brian Osman49b7b6f2017-06-20 14:43:58 -0400461
462void* GrIndexBufferAllocPool::makeSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
463 const GrBuffer** buffer, int* startIndex,
464 int* actualIndexCount) {
465 SkASSERT(minIndexCount >= 0);
466 SkASSERT(fallbackIndexCount >= minIndexCount);
467 SkASSERT(buffer);
468 SkASSERT(startIndex);
469 SkASSERT(actualIndexCount);
470
471 size_t offset SK_INIT_TO_AVOID_WARNING;
472 size_t actualSize SK_INIT_TO_AVOID_WARNING;
Mike Reedfe266c22018-01-17 11:55:07 -0500473 void* ptr = INHERITED::makeSpaceAtLeast(SkSafeMath::Mul(minIndexCount, sizeof(uint16_t)),
474 SkSafeMath::Mul(fallbackIndexCount, sizeof(uint16_t)),
Brian Osman49b7b6f2017-06-20 14:43:58 -0400475 sizeof(uint16_t),
476 buffer,
477 &offset,
478 &actualSize);
479
480 SkASSERT(0 == offset % sizeof(uint16_t));
481 *startIndex = static_cast<int>(offset / sizeof(uint16_t));
482
483 SkASSERT(0 == actualSize % sizeof(uint16_t));
484 SkASSERT(actualSize >= minIndexCount * sizeof(uint16_t));
485 *actualIndexCount = static_cast<int>(actualSize / sizeof(uint16_t));
486 return ptr;
487}