105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2010 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */
805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrBufferAllocPool.h"
1105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrTypes.h"
1205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrVertexBuffer.h"
1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrIndexBuffer.h"
1405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrGpu.h"
1505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if GR_DEBUG
1705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    #define VALIDATE validate
1805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#else
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void VALIDATE(bool x = false) {}
2005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
2105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// page size
2305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
2405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
2605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     BufferType bufferType,
2705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     bool frequentResetHint,
2805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     size_t blockSize,
2905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     int preallocBufferCnt) :
3005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fBlocks(GrMax(8, 2*preallocBufferCnt)) {
3187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != gpu);
3305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fGpu = gpu;
3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fGpu->ref();
3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fGpuIsReffed = true;
3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fBufferType = bufferType;
3805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fFrequentResetHint = frequentResetHint;
3905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fBufferPtr = NULL;
4005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
4105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fBytesInUse = 0;
434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
4405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fPreallocBuffersInUse = 0;
454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fPreallocBufferStartIdx = 0;
4605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    for (int i = 0; i < preallocBufferCnt; ++i) {
4705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
4805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (NULL != buffer) {
4905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            *fPreallocBuffers.append() = buffer;
5005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
5105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
5205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
5305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
5405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrBufferAllocPool::~GrBufferAllocPool() {
5505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
5605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fBlocks.count()) {
5705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
5805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (buffer->isLocked()) {
5905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            buffer->unlock();
6005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
6105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
6205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    while (!fBlocks.empty()) {
6305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        destroyBlock();
6405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fPreallocBuffers.unrefAll();
6687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    releaseGpuRef();
6787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger}
6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
6987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid GrBufferAllocPool::releaseGpuRef() {
7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (fGpuIsReffed) {
7187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fGpu->unref();
7287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fGpuIsReffed = false;
7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
7405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
7505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrBufferAllocPool::reset() {
7705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fBytesInUse = 0;
7905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fBlocks.count()) {
8005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
8105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (buffer->isLocked()) {
8205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            buffer->unlock();
8305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
8405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // fPreallocBuffersInUse will be decremented down to zero in the while loop
864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int preallocBuffersInUse = fPreallocBuffersInUse;
8705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    while (!fBlocks.empty()) {
884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        this->destroyBlock();
8905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
9005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fPreallocBuffers.count()) {
9105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // must set this after above loop.
924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                   preallocBuffersInUse) %
944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  fPreallocBuffers.count();
9505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we may have created a large cpu mirror of a large VB. Reset the size
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // to match our pre-allocated VBs.
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fCpuData.reset(fMinBlockSize);
9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(0 == fPreallocBuffersInUse);
10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrBufferAllocPool::unlock() {
10405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
10505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fBufferPtr) {
10705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        BufferBlock& block = fBlocks.back();
10805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (block.fBuffer->isLocked()) {
10905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            block.fBuffer->unlock();
11005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        } else {
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            size_t flushSize = block.fBuffer->sizeInBytes() - block.fBytesFree;
11205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            flushCpuData(fBlocks.back().fBuffer, flushSize);
11305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
11405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fBufferPtr = NULL;
11505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
11605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
11705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
11805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if GR_DEBUG
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
12105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fBufferPtr) {
12205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(!fBlocks.empty());
12305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (fBlocks.back().fBuffer->isLocked()) {
12405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            GrGeometryBuffer* buf = fBlocks.back().fBuffer;
12505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            GrAssert(buf->lockPtr() == fBufferPtr);
12605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        } else {
12705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            GrAssert(fCpuData.get() == fBufferPtr);
12805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
12905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
13005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
13105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t bytesInUse = 0;
13305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    for (int i = 0; i < fBlocks.count() - 1; ++i) {
13405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(!fBlocks[i].fBuffer->isLocked());
13505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < fBlocks.count(); ++i) {
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t bytes = fBlocks[i].fBuffer->sizeInBytes() - fBlocks[i].fBytesFree;
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bytesInUse += bytes;
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(bytes || unusedBlockAllowed);
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(bytesInUse == fBytesInUse);
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (unusedBlockAllowed) {
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert((fBytesInUse && !fBlocks.empty()) ||
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 (!fBytesInUse && (fBlocks.count() < 2)));
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert((0 == fBytesInUse) == fBlocks.empty());
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
15005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
15105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid* GrBufferAllocPool::makeSpace(size_t size,
15305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                   size_t alignment,
15405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                   const GrGeometryBuffer** buffer,
15505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                   size_t* offset) {
15605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
15705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != buffer);
15905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != offset);
16005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
16105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fBufferPtr) {
16205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        BufferBlock& back = fBlocks.back();
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree;
16405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        size_t pad = GrSizeAlignUpPad(usedBytes,
16505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                      alignment);
16605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if ((size + pad) <= back.fBytesFree) {
16705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            usedBytes += pad;
16805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            *offset = usedBytes;
16905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            *buffer = back.fBuffer;
17005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            back.fBytesFree -= size + pad;
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBytesInUse += size;
17205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
17305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
17405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
17505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We could honor the space request using by a partial update of the current
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // VB (if there is room). But we don't currently use draw calls to GL that
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // allow the driver to know that previously issued draws won't read from
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the part of the buffer we update. Also, the GL buffer implementation
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // may be cheating on the actual buffer size by shrinking the buffer on
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // updateData() if the amount of data passed is less than the full buffer
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // size.
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!createBlock(size)) {
18505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return NULL;
18605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
18705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != fBufferPtr);
18805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
18905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *offset = 0;
19005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    BufferBlock& back = fBlocks.back();
19105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *buffer = back.fBuffer;
19205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    back.fBytesFree -= size;
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fBytesInUse += size;
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    VALIDATE();
19505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fBufferPtr;
19605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
19705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
19805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrBufferAllocPool::currentBufferItems(size_t itemSize) const {
19905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
20005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fBufferPtr) {
20105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        const BufferBlock& back = fBlocks.back();
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t usedBytes = back.fBuffer->sizeInBytes() - back.fBytesFree;
20305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        size_t pad = GrSizeAlignUpPad(usedBytes, itemSize);
20405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return (back.fBytesFree - pad) / itemSize;
20505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
20605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return fMinBlockSize / itemSize;
20705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
20805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return 0;
20905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
21005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrBufferAllocPool::preallocatedBuffersRemaining() const {
21205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fPreallocBuffers.count() - fPreallocBuffersInUse;
21305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
21405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrBufferAllocPool::preallocatedBufferCount() const {
21605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fPreallocBuffers.count();
21705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
21805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrBufferAllocPool::putBack(size_t bytes) {
22005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // if the putBack unwinds all the preallocated buffers then we will
2234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // advance the starting index. As blocks are destroyed fPreallocBuffersInUse
2244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // will be decremented. I will reach zero if all blocks using preallocated
2254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // buffers are released.
2264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int preallocBuffersInUse = fPreallocBuffersInUse;
2274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    while (bytes) {
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // caller shouldnt try to put back more than they've taken
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(!fBlocks.empty());
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        BufferBlock& block = fBlocks.back();
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t bytesUsed = block.fBuffer->sizeInBytes() - block.fBytesFree;
23305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (bytes >= bytesUsed) {
23405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            bytes -= bytesUsed;
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBytesInUse -= bytesUsed;
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // if we locked a vb to satisfy the make space and we're releasing
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // beyond it, then unlock it.
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (block.fBuffer->isLocked()) {
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                block.fBuffer->unlock();
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->destroyBlock();
24205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        } else {
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            block.fBytesFree += bytes;
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBytesInUse -= bytes;
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bytes = 0;
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            break;
24705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
24805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!fPreallocBuffersInUse && fPreallocBuffers.count()) {
2504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
2514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                       preallocBuffersInUse) %
2524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                      fPreallocBuffers.count();
2534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
25405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
25505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
25605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
25705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool GrBufferAllocPool::createBlock(size_t requestSize) {
25805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
25905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t size = GrMax(requestSize, fMinBlockSize);
26005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(size >= GrBufferAllocPool_MIN_BLOCK_SIZE);
26105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    VALIDATE();
26305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    BufferBlock& block = fBlocks.push_back();
26505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (size == fMinBlockSize &&
26705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fPreallocBuffersInUse < fPreallocBuffers.count()) {
26805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        uint32_t nextBuffer = (fPreallocBuffersInUse +
2704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                               fPreallocBufferStartIdx) %
2714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                              fPreallocBuffers.count();
27205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        block.fBuffer = fPreallocBuffers[nextBuffer];
27305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        block.fBuffer->ref();
27405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        ++fPreallocBuffersInUse;
27505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
27605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        block.fBuffer = this->createBuffer(size);
27705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (NULL == block.fBuffer) {
27805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            fBlocks.pop_back();
27905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return false;
28005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
28105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
28205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
28305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    block.fBytesFree = size;
28405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fBufferPtr) {
28505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(fBlocks.count() > 1);
28605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        BufferBlock& prev = fBlocks.fromBack(1);
28705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (prev.fBuffer->isLocked()) {
28805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            prev.fBuffer->unlock();
28905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        } else {
29005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            flushCpuData(prev.fBuffer,
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         prev.fBuffer->sizeInBytes() - prev.fBytesFree);
29205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
29305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fBufferPtr = NULL;
29405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
29505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
29605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL == fBufferPtr);
29705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fGpu->getCaps().fBufferLockSupport &&
29905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        size > GR_GEOM_BUFFER_LOCK_THRESHOLD &&
30005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        (!fFrequentResetHint || requestSize > GR_GEOM_BUFFER_LOCK_THRESHOLD)) {
30105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fBufferPtr = block.fBuffer->lock();
30205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
30305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
30405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == fBufferPtr) {
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fBufferPtr = fCpuData.reset(size);
30605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
30705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    VALIDATE(true);
30905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
31005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
31105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
31205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
31305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrBufferAllocPool::destroyBlock() {
31405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(!fBlocks.empty());
31505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
31605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    BufferBlock& block = fBlocks.back();
31705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fPreallocBuffersInUse > 0) {
31805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
3194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                       fPreallocBufferStartIdx +
32005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                       (fPreallocBuffers.count() - 1)) %
32105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                      fPreallocBuffers.count();
32205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {
32305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            --fPreallocBuffersInUse;
32405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
32505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
32605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(!block.fBuffer->isLocked());
32705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    block.fBuffer->unref();
32805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fBlocks.pop_back();
32905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fBufferPtr = NULL;
33005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
33105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
33205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer,
33305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     size_t flushSize) {
33405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != buffer);
33505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(!buffer->isLocked());
33605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(fCpuData.get() == fBufferPtr);
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(flushSize <= buffer->sizeInBytes());
33805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fGpu->getCaps().fBufferLockSupport &&
34005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        flushSize > GR_GEOM_BUFFER_LOCK_THRESHOLD) {
34105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        void* data = buffer->lock();
34205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (NULL != data) {
34305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            memcpy(data, fBufferPtr, flushSize);
34405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            buffer->unlock();
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
34605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
34705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
34805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    buffer->updateData(fBufferPtr, flushSize);
34905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
35005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
35105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) {
35205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (kIndex_BufferType == fBufferType) {
35305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return fGpu->createIndexBuffer(size, true);
35405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
35505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(kVertex_BufferType == fBufferType);
35605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return fGpu->createVertexBuffer(size, true);
35705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
35805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
35905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
36005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
36105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
36205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
36305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                                 bool frequentResetHint,
36405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                                 size_t bufferSize,
36505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                                 int preallocBufferCnt)
36605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger: GrBufferAllocPool(gpu,
36705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    kVertex_BufferType,
36805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    frequentResetHint,
36905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    bufferSize,
37005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    preallocBufferCnt) {
37105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
37205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
37305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid* GrVertexBufferAllocPool::makeSpace(GrVertexLayout layout,
37405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         int vertexCount,
37505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         const GrVertexBuffer** buffer,
37605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         int* startVertex) {
37705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
37805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(vertexCount >= 0);
37905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != buffer);
38005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != startVertex);
38105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
38205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t vSize = GrDrawTarget::VertexSize(layout);
38335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    size_t offset = 0; // assign to suppress warning
38435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
38505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    void* ptr = INHERITED::makeSpace(vSize * vertexCount,
38605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     vSize,
38705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     &geomBuffer,
38805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     &offset);
38905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
39005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *buffer = (const GrVertexBuffer*) geomBuffer;
39105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(0 == offset % vSize);
39205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *startVertex = offset / vSize;
39305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return ptr;
39405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
39505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
39605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout,
39705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                             int vertexCount,
39805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                             const void* vertices,
39905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                             const GrVertexBuffer** buffer,
40005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                             int* startVertex) {
40105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    void* space = makeSpace(layout, vertexCount, buffer, startVertex);
40205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != space) {
40305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        memcpy(space,
40405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger               vertices,
40505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger               GrDrawTarget::VertexSize(layout) * vertexCount);
40605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return true;
40705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
40805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
40905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
41005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
41105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
41205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
41305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return INHERITED::preallocatedBufferSize() /
41405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            GrDrawTarget::VertexSize(layout);
41505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
41605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
41705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
41805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return currentBufferItems(GrDrawTarget::VertexSize(layout));
41905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
42005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
42105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
42205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
42305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu,
42405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                               bool frequentResetHint,
42505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                               size_t bufferSize,
42605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                               int preallocBufferCnt)
42705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger: GrBufferAllocPool(gpu,
42805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    kIndex_BufferType,
42905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    frequentResetHint,
43005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    bufferSize,
43105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    preallocBufferCnt) {
43205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
43305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
43405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid* GrIndexBufferAllocPool::makeSpace(int indexCount,
43505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                        const GrIndexBuffer** buffer,
43605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                        int* startIndex) {
43705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
43805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(indexCount >= 0);
43905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != buffer);
44005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(NULL != startIndex);
44105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
44235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    size_t offset = 0; // assign to suppress warning
44335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
44405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
44505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     sizeof(uint16_t),
44605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     &geomBuffer,
44705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     &offset);
44805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
44905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *buffer = (const GrIndexBuffer*) geomBuffer;
45005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(0 == offset % sizeof(uint16_t));
45105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *startIndex = offset / sizeof(uint16_t);
45205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return ptr;
45305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
45405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
45505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool GrIndexBufferAllocPool::appendIndices(int indexCount,
45605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                           const void* indices,
45705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                           const GrIndexBuffer** buffer,
45805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                           int* startIndex) {
45905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    void* space = makeSpace(indexCount, buffer, startIndex);
46005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != space) {
46105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        memcpy(space, indices, sizeof(uint16_t) * indexCount);
46205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return true;
46305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
46405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
46505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
46605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
46705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
46805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrIndexBufferAllocPool::preallocatedBufferIndices() const {
46905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return INHERITED::preallocatedBufferSize() / sizeof(uint16_t);
47005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
47105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
47205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerint GrIndexBufferAllocPool::currentBufferIndices() const {
47305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return currentBufferItems(sizeof(uint16_t));
47405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
475