13f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 23f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/* 33f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Copyright 2010 Google Inc. 43f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * 53f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 63f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * found in the LICENSE file. 73f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */ 83f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 93f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrBufferAllocPool.h" 11516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrDrawTargetCaps.h" 12516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrGpu.h" 13516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrIndexBuffer.h" 143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrTypes.h" 153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrVertexBuffer.h" 163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG 183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com #define VALIDATE validate 193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#else 2085f3b52a22c623fc8846d920660fc0b0a4b7afa7sugoi@google.com static void VALIDATE(bool = false) {} 213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif 223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com// page size 243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12) 253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu, 273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferType bufferType, 283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool frequentResetHint, 293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t blockSize, 303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int preallocBufferCnt) : 313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBlocks(GrMax(8, 2*preallocBufferCnt)) { 323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != gpu); 343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu = gpu; 353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu->ref(); 363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpuIsReffed = true; 373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferType = bufferType; 393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fFrequentResetHint = frequentResetHint; 403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = NULL; 413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize); 423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBytesInUse = 0; 440cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com 453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fPreallocBuffersInUse = 0; 460cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBufferStartIdx = 0; 473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com for (int i = 0; i < preallocBufferCnt; ++i) { 483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize); 493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != buffer) { 503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *fPreallocBuffers.append() = buffer; 513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrBufferAllocPool::~GrBufferAllocPool() { 563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fBlocks.count()) { 583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrGeometryBuffer* buffer = fBlocks.back().fBuffer; 593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (buffer->isLocked()) { 603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com buffer->unlock(); 613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com while (!fBlocks.empty()) { 643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com destroyBlock(); 653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fPreallocBuffers.unrefAll(); 673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com releaseGpuRef(); 683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::releaseGpuRef() { 713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fGpuIsReffed) { 723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu->unref(); 733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpuIsReffed = false; 743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::reset() { 783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBytesInUse = 0; 803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fBlocks.count()) { 813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrGeometryBuffer* buffer = fBlocks.back().fBuffer; 823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (buffer->isLocked()) { 833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com buffer->unlock(); 843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 860cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com // fPreallocBuffersInUse will be decremented down to zero in the while loop 870cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com int preallocBuffersInUse = fPreallocBuffersInUse; 883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com while (!fBlocks.empty()) { 890cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com this->destroyBlock(); 903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fPreallocBuffers.count()) { 923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // must set this after above loop. 930cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBufferStartIdx = (fPreallocBufferStartIdx + 940cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com preallocBuffersInUse) % 950cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBuffers.count(); 963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 975b0459ce765d52ff913e277892de83d5a5884fffbsalomon@google.com // we may have created a large cpu mirror of a large VB. Reset the size 985b0459ce765d52ff913e277892de83d5a5884fffbsalomon@google.com // to match our pre-allocated VBs. 995b0459ce765d52ff913e277892de83d5a5884fffbsalomon@google.com fCpuData.reset(fMinBlockSize); 1003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(0 == fPreallocBuffersInUse); 1013f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 1023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::unlock() { 1053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 1063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1073f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != fBufferPtr) { 1083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& block = fBlocks.back(); 1093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (block.fBuffer->isLocked()) { 1103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer->unlock(); 1113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 1123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t flushSize = block.fBuffer->sizeInBytes() - block.fBytesFree; 1133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com flushCpuData(fBlocks.back().fBuffer, flushSize); 1143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = NULL; 1163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 1183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG 1213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::validate(bool unusedBlockAllowed) const { 1223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != fBufferPtr) { 1233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!fBlocks.empty()); 1243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fBlocks.back().fBuffer->isLocked()) { 1253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrGeometryBuffer* buf = fBlocks.back().fBuffer; 1263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(buf->lockPtr() == fBufferPtr); 1273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 1283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(fCpuData.get() == fBufferPtr); 1293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 1313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked()); 1323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t bytesInUse = 0; 1343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com for (int i = 0; i < fBlocks.count() - 1; ++i) { 1353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!fBlocks[i].fBuffer->isLocked()); 1363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com for (int i = 0; i < fBlocks.count(); ++i) { 138935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com size_t bytes = fBlocks[i].fBuffer->sizeInBytes() - fBlocks[i].fBytesFree; 1393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bytesInUse += bytes; 1403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(bytes || unusedBlockAllowed); 1413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 142935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 1433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(bytesInUse == fBytesInUse); 1443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (unusedBlockAllowed) { 1453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert((fBytesInUse && !fBlocks.empty()) || 1463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com (!fBytesInUse && (fBlocks.count() < 2))); 1473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 1483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert((0 == fBytesInUse) == fBlocks.empty()); 1493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif 1523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid* GrBufferAllocPool::makeSpace(size_t size, 1543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t alignment, 1553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrGeometryBuffer** buffer, 1563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t* offset) { 1573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 1583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != buffer); 1603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != offset); 1613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != fBufferPtr) { 1633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& back = fBlocks.back(); 1643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree; 1653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t pad = GrSizeAlignUpPad(usedBytes, 1663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com alignment); 1673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if ((size + pad) <= back.fBytesFree) { 1683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com usedBytes += pad; 1693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *offset = usedBytes; 1703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *buffer = back.fBuffer; 1713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com back.fBytesFree -= size + pad; 172f1f20f0a36e8b74d95f2bcff2069b49f104a46febsalomon@google.com fBytesInUse += size + pad; 173f1f20f0a36e8b74d95f2bcff2069b49f104a46febsalomon@google.com VALIDATE(); 1743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes); 1753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // We could honor the space request using by a partial update of the current 1793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // VB (if there is room). But we don't currently use draw calls to GL that 1803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // allow the driver to know that previously issued draws won't read from 1813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // the part of the buffer we update. Also, the GL buffer implementation 1823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // may be cheating on the actual buffer size by shrinking the buffer on 1833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // updateData() if the amount of data passed is less than the full buffer 1843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // size. 185935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 1863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (!createBlock(size)) { 1873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return NULL; 1883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != fBufferPtr); 1903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *offset = 0; 1923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& back = fBlocks.back(); 1933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *buffer = back.fBuffer; 1943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com back.fBytesFree -= size; 1953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBytesInUse += size; 1963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 1973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fBufferPtr; 1983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrBufferAllocPool::currentBufferItems(size_t itemSize) const { 2013f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 2023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != fBufferPtr) { 2033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const BufferBlock& back = fBlocks.back(); 2043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree; 2053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t pad = GrSizeAlignUpPad(usedBytes, itemSize); 2063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return (back.fBytesFree - pad) / itemSize; 2073f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) { 2083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fMinBlockSize / itemSize; 2093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return 0; 2113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrBufferAllocPool::preallocatedBuffersRemaining() const { 2143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fPreallocBuffers.count() - fPreallocBuffersInUse; 2153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrBufferAllocPool::preallocatedBufferCount() const { 2183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fPreallocBuffers.count(); 2193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::putBack(size_t bytes) { 2223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 2233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2240cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com // if the putBack unwinds all the preallocated buffers then we will 2250cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com // advance the starting index. As blocks are destroyed fPreallocBuffersInUse 2260cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com // will be decremented. I will reach zero if all blocks using preallocated 2270cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com // buffers are released. 2280cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com int preallocBuffersInUse = fPreallocBuffersInUse; 2290cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com 2303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com while (bytes) { 2313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // caller shouldnt try to put back more than they've taken 2323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!fBlocks.empty()); 2333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& block = fBlocks.back(); 2343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t bytesUsed = block.fBuffer->sizeInBytes() - block.fBytesFree; 2353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (bytes >= bytesUsed) { 2363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bytes -= bytesUsed; 2373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBytesInUse -= bytesUsed; 2383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // if we locked a vb to satisfy the make space and we're releasing 2393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // beyond it, then unlock it. 2403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (block.fBuffer->isLocked()) { 2413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer->unlock(); 2423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com this->destroyBlock(); 2443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 2453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBytesFree += bytes; 2463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBytesInUse -= bytes; 2473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bytes = 0; 2483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com break; 2493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2510cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com if (!fPreallocBuffersInUse && fPreallocBuffers.count()) { 2520cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBufferStartIdx = (fPreallocBufferStartIdx + 2530cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com preallocBuffersInUse) % 2540cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBuffers.count(); 2550cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com } 2563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 2573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrBufferAllocPool::createBlock(size_t requestSize) { 2603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t size = GrMax(requestSize, fMinBlockSize); 2623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(size >= GrBufferAllocPool_MIN_BLOCK_SIZE); 2633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(); 2653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& block = fBlocks.push_back(); 2673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (size == fMinBlockSize && 2693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fPreallocBuffersInUse < fPreallocBuffers.count()) { 2703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2710cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com uint32_t nextBuffer = (fPreallocBuffersInUse + 2720cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBufferStartIdx) % 2730cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBuffers.count(); 2743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer = fPreallocBuffers[nextBuffer]; 2753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer->ref(); 2763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com ++fPreallocBuffersInUse; 2773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 2783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer = this->createBuffer(size); 2793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL == block.fBuffer) { 2803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBlocks.pop_back(); 2813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 2823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBytesFree = size; 2863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != fBufferPtr) { 2873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(fBlocks.count() > 1); 2883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& prev = fBlocks.fromBack(1); 2893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (prev.fBuffer->isLocked()) { 2903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com prev.fBuffer->unlock(); 2913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 2923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com flushCpuData(prev.fBuffer, 2933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com prev.fBuffer->sizeInBytes() - prev.fBytesFree); 2943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = NULL; 2963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL == fBufferPtr); 2993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 300407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com // If the buffer is CPU-backed we lock it because it is free to do so and saves a copy. 301407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com // Otherwise when buffer locking is supported: 302407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com // a) If the frequently reset hint is set we only lock when the requested size meets a 303407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com // threshold (since we don't expect it is likely that we will see more vertex data) 304407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com // b) If the hint is not set we lock if the buffer size is greater than the threshold. 305407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com bool attemptLock = block.fBuffer->isCPUBacked(); 30659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com if (!attemptLock && fGpu->caps()->bufferLockSupport()) { 307407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com if (fFrequentResetHint) { 308407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com attemptLock = requestSize > GR_GEOM_BUFFER_LOCK_THRESHOLD; 309407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com } else { 310407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com attemptLock = size > GR_GEOM_BUFFER_LOCK_THRESHOLD; 311407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com } 312407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com } 313407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com 314407c7876a1c8fba9e582a3e48e12ca63e13d99febsalomon@google.com if (attemptLock) { 3153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = block.fBuffer->lock(); 3163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL == fBufferPtr) { 3193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = fCpuData.reset(size); 3203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com VALIDATE(true); 3233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return true; 3253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 3263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::destroyBlock() { 3283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!fBlocks.empty()); 3293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com BufferBlock& block = fBlocks.back(); 3313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (fPreallocBuffersInUse > 0) { 3323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com uint32_t prevPreallocBuffer = (fPreallocBuffersInUse + 3330cef758dcc01b4422d862f1b30c8010f2927da92bsalomon@google.com fPreallocBufferStartIdx + 3343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com (fPreallocBuffers.count() - 1)) % 3353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fPreallocBuffers.count(); 3363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) { 3373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com --fPreallocBuffersInUse; 3383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!block.fBuffer->isLocked()); 3413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com block.fBuffer->unref(); 3423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBlocks.pop_back(); 3433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fBufferPtr = NULL; 3443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 3453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer, 3473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t flushSize) { 3483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != buffer); 3493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(!buffer->isLocked()); 3503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(fCpuData.get() == fBufferPtr); 3513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(flushSize <= buffer->sizeInBytes()); 352f1f20f0a36e8b74d95f2bcff2069b49f104a46febsalomon@google.com VALIDATE(true); 3533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 35459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com if (fGpu->caps()->bufferLockSupport() && 3553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com flushSize > GR_GEOM_BUFFER_LOCK_THRESHOLD) { 3563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* data = buffer->lock(); 3573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != data) { 3583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com memcpy(data, fBufferPtr, flushSize); 3593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com buffer->unlock(); 360028f3a0bf6c7630ab2faf7f8a53108834684648fbsalomon@google.com return; 3613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com buffer->updateData(fBufferPtr, flushSize); 364f1f20f0a36e8b74d95f2bcff2069b49f104a46febsalomon@google.com VALIDATE(true); 3653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 3663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) { 3683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (kIndex_BufferType == fBufferType) { 3693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fGpu->createIndexBuffer(size, true); 3703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 3713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(kVertex_BufferType == fBufferType); 3723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fGpu->createVertexBuffer(size, true); 3733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 3753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 3773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu, 3793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool frequentResetHint, 3803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t bufferSize, 3813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int preallocBufferCnt) 3823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com: GrBufferAllocPool(gpu, 3833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com kVertex_BufferType, 3843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com frequentResetHint, 3853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bufferSize, 3863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com preallocBufferCnt) { 3873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 3883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3894fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.comvoid* GrVertexBufferAllocPool::makeSpace(size_t vertexSize, 3903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int vertexCount, 3913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrVertexBuffer** buffer, 3923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int* startVertex) { 3933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(vertexCount >= 0); 3953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != buffer); 3963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != startVertex); 3973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t offset = 0; // assign to suppress warning 3993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning 4004fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com void* ptr = INHERITED::makeSpace(vertexSize * vertexCount, 4014fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com vertexSize, 4023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com &geomBuffer, 4033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com &offset); 4043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *buffer = (const GrVertexBuffer*) geomBuffer; 4064fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com GrAssert(0 == offset % vertexSize); 4074fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com *startVertex = offset / vertexSize; 4083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return ptr; 4093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4114fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.combool GrVertexBufferAllocPool::appendVertices(size_t vertexSize, 4123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int vertexCount, 4133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const void* vertices, 4143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrVertexBuffer** buffer, 4153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int* startVertex) { 4164fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com void* space = makeSpace(vertexSize, vertexCount, buffer, startVertex); 4173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != space) { 4183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com memcpy(space, 4193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertices, 4204fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com vertexSize * vertexCount); 4213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return true; 4223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 4233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 4243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 4253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4274fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.comint GrVertexBufferAllocPool::preallocatedBufferVertices(size_t vertexSize) const { 4284fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com return INHERITED::preallocatedBufferSize() / vertexSize; 4293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4314fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.comint GrVertexBufferAllocPool::currentBufferVertices(size_t vertexSize) const { 4324fde2435c57236fbc9d681a1fff7acdcb0fec9bajvanverth@google.com return currentBufferItems(vertexSize); 4333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 4363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu, 4383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool frequentResetHint, 4393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t bufferSize, 4403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int preallocBufferCnt) 4413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com: GrBufferAllocPool(gpu, 4423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com kIndex_BufferType, 4433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com frequentResetHint, 4443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bufferSize, 4453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com preallocBufferCnt) { 4463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid* GrIndexBufferAllocPool::makeSpace(int indexCount, 4493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrIndexBuffer** buffer, 4503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int* startIndex) { 4513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(indexCount >= 0); 4533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != buffer); 4543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(NULL != startIndex); 4553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t offset = 0; // assign to suppress warning 4573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning 4583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t), 4593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com sizeof(uint16_t), 4603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com &geomBuffer, 4613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com &offset); 4623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *buffer = (const GrIndexBuffer*) geomBuffer; 4643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAssert(0 == offset % sizeof(uint16_t)); 4653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *startIndex = offset / sizeof(uint16_t); 4663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return ptr; 4673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrIndexBufferAllocPool::appendIndices(int indexCount, 4703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const void* indices, 4713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrIndexBuffer** buffer, 4723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int* startIndex) { 4733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* space = makeSpace(indexCount, buffer, startIndex); 4743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != space) { 4753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com memcpy(space, indices, sizeof(uint16_t) * indexCount); 4763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return true; 4773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 4783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 4793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 4803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrIndexBufferAllocPool::preallocatedBufferIndices() const { 4833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return INHERITED::preallocatedBufferSize() / sizeof(uint16_t); 4843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrIndexBufferAllocPool::currentBufferIndices() const { 4873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return currentBufferItems(sizeof(uint16_t)); 4883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 489