Refactor how Gr handles vertex and index data. GrGpu and GrInOrderDrawBuffer both GrBufferAllocPool to manage reserved and set-to-array vertex and index data.
rietveld issue 4188049
git-svn-id: http://skia.googlecode.com/svn/trunk@786 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrBufferAllocPool.cpp b/gpu/src/GrBufferAllocPool.cpp
new file mode 100644
index 0000000..35f0c5e
--- /dev/null
+++ b/gpu/src/GrBufferAllocPool.cpp
@@ -0,0 +1,430 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "GrBufferAllocPool.h"
+#include "GrTypes.h"
+#include "GrVertexBuffer.h"
+#include "GrIndexBuffer.h"
+#include "GrGpu.h"
+
+#if GR_DEBUG
+ #define VALIDATE validate
+#else
+ #define VALIDATE()
+#endif
+
+#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
+
+GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
+ BufferType bufferType,
+ bool frequentResetHint,
+ size_t blockSize,
+ int preallocBufferCnt) :
+ fBlocks(GrMax(8, 2*preallocBufferCnt)) {
+ GrAssert(NULL != gpu);
+ fGpu = gpu;
+ fBufferType = bufferType;
+ fFrequentResetHint = frequentResetHint;
+ fGpu->ref();
+ fBufferPtr = NULL;
+ fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
+
+ fPreallocBuffersInUse = 0;
+ fFirstPreallocBuffer = 0;
+ for (int i = 0; i < preallocBufferCnt; ++i) {
+ GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
+ if (NULL != buffer) {
+ *fPreallocBuffers.append() = buffer;
+ buffer->ref();
+ }
+ }
+}
+
+GrBufferAllocPool::~GrBufferAllocPool() {
+ VALIDATE();
+ if (fBlocks.count()) {
+ GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
+ if (buffer->isLocked()) {
+ buffer->unlock();
+ }
+ }
+ fPreallocBuffers.unrefAll();
+ while (!fBlocks.empty()) {
+ destroyBlock();
+ }
+ fGpu->unref();
+}
+
+void GrBufferAllocPool::reset() {
+ VALIDATE();
+ if (fBlocks.count()) {
+ GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
+ if (buffer->isLocked()) {
+ buffer->unlock();
+ }
+ }
+ while (!fBlocks.empty()) {
+ destroyBlock();
+ }
+ if (fPreallocBuffers.count()) {
+ // must set this after above loop.
+ fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) %
+ fPreallocBuffers.count();
+ }
+ fCpuData.realloc(fGpu->supportsBufferLocking() ? 0 : fMinBlockSize);
+ GrAssert(0 == fPreallocBuffersInUse);
+ VALIDATE();
+}
+
+void GrBufferAllocPool::unlock() {
+ VALIDATE();
+
+ if (NULL != fBufferPtr) {
+ BufferBlock& block = fBlocks.back();
+ if (block.fBuffer->isLocked()) {
+ block.fBuffer->unlock();
+ } else {
+ size_t flushSize = block.fBuffer->size() - block.fBytesFree;
+ flushCpuData(fBlocks.back().fBuffer, flushSize);
+ }
+ fBufferPtr = NULL;
+ }
+ VALIDATE();
+}
+
+#if GR_DEBUG
+void GrBufferAllocPool::validate() const {
+ if (NULL != fBufferPtr) {
+ GrAssert(!fBlocks.empty());
+ if (fBlocks.back().fBuffer->isLocked()) {
+ GrGeometryBuffer* buf = fBlocks.back().fBuffer;
+ GrAssert(buf->lockPtr() == fBufferPtr);
+ } else {
+ GrAssert(fCpuData.get() == fBufferPtr);
+ GrAssert(fCpuData.size() == fBlocks.back().fBuffer->size());
+ }
+ } else {
+ GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
+ }
+ for (int i = 0; i < fBlocks.count() - 1; ++i) {
+ GrAssert(!fBlocks[i].fBuffer->isLocked());
+ }
+}
+#endif
+
+void* GrBufferAllocPool::makeSpace(size_t size,
+ size_t alignment,
+ const GrGeometryBuffer** buffer,
+ size_t* offset) {
+ VALIDATE();
+
+ GrAssert(NULL != buffer);
+ GrAssert(NULL != offset);
+
+ if (NULL != fBufferPtr) {
+ BufferBlock& back = fBlocks.back();
+ size_t usedBytes = back.fBuffer->size() - back.fBytesFree;
+ size_t pad = GrSizeAlignUpPad(usedBytes,
+ alignment);
+ if ((size + pad) <= back.fBytesFree) {
+ usedBytes += pad;
+ *offset = usedBytes;
+ *buffer = back.fBuffer;
+ back.fBytesFree -= size + pad;
+ return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
+ }
+ }
+
+ if (!createBlock(size)) {
+ return NULL;
+ }
+ VALIDATE();
+ GrAssert(NULL != fBufferPtr);
+
+ *offset = 0;
+ BufferBlock& back = fBlocks.back();
+ *buffer = back.fBuffer;
+ back.fBytesFree -= size;
+ return fBufferPtr;
+}
+
+int GrBufferAllocPool::currentBufferItems(size_t itemSize) const {
+ VALIDATE();
+ if (NULL != fBufferPtr) {
+ const BufferBlock& back = fBlocks.back();
+ size_t usedBytes = back.fBuffer->size() - back.fBytesFree;
+ size_t pad = GrSizeAlignUpPad(usedBytes, itemSize);
+ return (back.fBytesFree - pad) / itemSize;
+ } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
+ return fMinBlockSize / itemSize;
+ }
+ return 0;
+}
+
+int GrBufferAllocPool::preallocatedBuffersRemaining() const {
+ return fPreallocBuffers.count() - fPreallocBuffersInUse;
+}
+
+int GrBufferAllocPool::preallocatedBufferCount() const {
+ return fPreallocBuffers.count();
+}
+
+void GrBufferAllocPool::putBack(size_t bytes) {
+ VALIDATE();
+ if (NULL != fBufferPtr) {
+ BufferBlock& back = fBlocks.back();
+ size_t bytesUsed = back.fBuffer->size() - back.fBytesFree;
+ if (bytes >= bytesUsed) {
+ destroyBlock();
+ bytes -= bytesUsed;
+ } else {
+ back.fBytesFree += bytes;
+ return;
+ }
+ }
+ VALIDATE();
+ GrAssert(NULL == fBufferPtr);
+ // we don't partially roll-back buffers because our VB semantics say locking
+ // a VB discards its previous content.
+ // We could honor it by being sure we use updateSubData and not lock
+ // we will roll-back fully released buffers, though.
+ while (!fBlocks.empty() &&
+ bytes >= fBlocks.back().fBuffer->size()) {
+ bytes -= fBlocks.back().fBuffer->size();
+ destroyBlock();
+ }
+ VALIDATE();
+}
+
+bool GrBufferAllocPool::createBlock(size_t requestSize) {
+
+ size_t size = GrMax(requestSize, fMinBlockSize);
+ GrAssert(size >= GrBufferAllocPool_MIN_BLOCK_SIZE);
+
+ VALIDATE();
+
+ BufferBlock& block = fBlocks.push_back();
+
+ if (size == fMinBlockSize &&
+ fPreallocBuffersInUse < fPreallocBuffers.count()) {
+
+ uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) %
+ fPreallocBuffers.count();
+ block.fBuffer = fPreallocBuffers[nextBuffer];
+ block.fBuffer->ref();
+ ++fPreallocBuffersInUse;
+ } else {
+ block.fBuffer = this->createBuffer(size);
+ if (NULL == block.fBuffer) {
+ fBlocks.pop_back();
+ return false;
+ }
+ }
+
+ block.fBytesFree = size;
+ if (NULL != fBufferPtr) {
+ GrAssert(fBlocks.count() > 1);
+ BufferBlock& prev = fBlocks.fromBack(1);
+ if (prev.fBuffer->isLocked()) {
+ prev.fBuffer->unlock();
+ } else {
+ flushCpuData(prev.fBuffer,
+ prev.fBuffer->size() - prev.fBytesFree);
+ }
+ fBufferPtr = NULL;
+ }
+
+ GrAssert(NULL == fBufferPtr);
+
+ if (fGpu->supportsBufferLocking() &&
+ size > GR_GEOM_BUFFER_LOCK_THRESHOLD &&
+ (!fFrequentResetHint || requestSize > GR_GEOM_BUFFER_LOCK_THRESHOLD)) {
+ fBufferPtr = block.fBuffer->lock();
+ }
+
+ if (NULL == fBufferPtr) {
+ fBufferPtr = fCpuData.realloc(size);
+ }
+
+ VALIDATE();
+
+ return true;
+}
+
+void GrBufferAllocPool::destroyBlock() {
+ GrAssert(!fBlocks.empty());
+
+ BufferBlock& block = fBlocks.back();
+ if (fPreallocBuffersInUse > 0) {
+ uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
+ fFirstPreallocBuffer +
+ (fPreallocBuffers.count() - 1)) %
+ fPreallocBuffers.count();
+ if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {
+ --fPreallocBuffersInUse;
+ }
+ }
+ GrAssert(!block.fBuffer->isLocked());
+ block.fBuffer->unref();
+ fBlocks.pop_back();
+ fBufferPtr = NULL;
+}
+
+void GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer,
+ size_t flushSize) {
+ GrAssert(NULL != buffer);
+ GrAssert(!buffer->isLocked());
+ GrAssert(fCpuData.get() == fBufferPtr);
+ GrAssert(fCpuData.size() == buffer->size());
+ GrAssert(flushSize <= buffer->size());
+
+ bool updated = false;
+ if (fGpu->supportsBufferLocking() &&
+ flushSize > GR_GEOM_BUFFER_LOCK_THRESHOLD) {
+ void* data = buffer->lock();
+ if (NULL != data) {
+ memcpy(data, fBufferPtr, flushSize);
+ buffer->unlock();
+ updated = true;
+ }
+ }
+ buffer->updateData(fBufferPtr, flushSize);
+}
+
+GrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) {
+ if (kIndex_BufferType == fBufferType) {
+ return fGpu->createIndexBuffer(size, true);
+ } else {
+ GrAssert(kVertex_BufferType == fBufferType);
+ return fGpu->createVertexBuffer(size, true);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
+ bool frequentResetHint,
+ size_t bufferSize,
+ int preallocBufferCnt)
+: GrBufferAllocPool(gpu,
+ kVertex_BufferType,
+ frequentResetHint,
+ bufferSize,
+ preallocBufferCnt) {
+}
+
+void* GrVertexBufferAllocPool::makeSpace(GrVertexLayout layout,
+ int vertexCount,
+ const GrVertexBuffer** buffer,
+ int* startVertex) {
+
+ GrAssert(vertexCount >= 0);
+ GrAssert(NULL != buffer);
+ GrAssert(NULL != startVertex);
+
+ size_t vSize = GrDrawTarget::VertexSize(layout);
+ size_t offset;
+ const GrGeometryBuffer* geomBuffer;
+ void* ptr = INHERITED::makeSpace(vSize * vertexCount,
+ vSize,
+ &geomBuffer,
+ &offset);
+
+ *buffer = (const GrVertexBuffer*) geomBuffer;
+ GrAssert(0 == offset % vSize);
+ *startVertex = offset / vSize;
+ return ptr;
+}
+
+bool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout,
+ int vertexCount,
+ const void* vertices,
+ const GrVertexBuffer** buffer,
+ int* startVertex) {
+ void* space = makeSpace(layout, vertexCount, buffer, startVertex);
+ if (NULL != space) {
+ memcpy(space,
+ vertices,
+ GrDrawTarget::VertexSize(layout) * vertexCount);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
+ return INHERITED::preallocatedBufferSize() /
+ GrDrawTarget::VertexSize(layout);
+}
+
+int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
+ return currentBufferItems(GrDrawTarget::VertexSize(layout));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu,
+ bool frequentResetHint,
+ size_t bufferSize,
+ int preallocBufferCnt)
+: GrBufferAllocPool(gpu,
+ kIndex_BufferType,
+ frequentResetHint,
+ bufferSize,
+ preallocBufferCnt) {
+}
+
+void* GrIndexBufferAllocPool::makeSpace(int indexCount,
+ const GrIndexBuffer** buffer,
+ int* startIndex) {
+
+ GrAssert(indexCount >= 0);
+ GrAssert(NULL != buffer);
+ GrAssert(NULL != startIndex);
+
+ size_t offset;
+ const GrGeometryBuffer* geomBuffer;
+ void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
+ sizeof(uint16_t),
+ &geomBuffer,
+ &offset);
+
+ *buffer = (const GrIndexBuffer*) geomBuffer;
+ GrAssert(0 == offset % sizeof(uint16_t));
+ *startIndex = offset / sizeof(uint16_t);
+ return ptr;
+}
+
+bool GrIndexBufferAllocPool::appendIndices(int indexCount,
+ const void* indices,
+ const GrIndexBuffer** buffer,
+ int* startIndex) {
+ void* space = makeSpace(indexCount, buffer, startIndex);
+ if (NULL != space) {
+ memcpy(space, indices, sizeof(uint16_t) * indexCount);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int GrIndexBufferAllocPool::preallocatedBufferIndices() const {
+ return INHERITED::preallocatedBufferSize() / sizeof(uint16_t);
+}
+
+int GrIndexBufferAllocPool::currentBufferIndices() const {
+ return currentBufferItems(sizeof(uint16_t));
+}
diff --git a/gpu/src/GrBufferAllocPool.h b/gpu/src/GrBufferAllocPool.h
new file mode 100644
index 0000000..80f16ab
--- /dev/null
+++ b/gpu/src/GrBufferAllocPool.h
@@ -0,0 +1,349 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrBufferAllocPool_DEFINED
+#define GrBufferAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+#include "GrTDArray.h"
+#include "GrTArray.h"
+#include "GrMemory.h"
+
+class GrGeometryBuffer;
+class GrGpu;
+
+/**
+ * A pool of geometry buffers tied to a GrGpu.
+ *
+ * The pool allows a client to make space for geometry and then put back excess
+ * space if it over allocated. When a client is ready to draw from the pool
+ * it calls unlock on the pool ensure buffers are ready for drawing. The pool
+ * can be reset after drawing is completed to recycle space.
+ *
+ * At creation time a minimum per-buffer size can be specified. Additionally,
+ * a number of buffers to preallocate can be specified. These will
+ * be allocated at the min size and kept around until the pool is destroyed.
+ */
+class GrBufferAllocPool : GrNoncopyable {
+protected:
+
+ // We could make the createBuffer a virtual except that we want to use it
+ // in the cons for pre-allocated buffers.
+ enum BufferType {
+ kVertex_BufferType,
+ kIndex_BufferType,
+ };
+
+ /**
+ * Constructor
+ *
+ * @param gpu The GrGpu used to create the buffers.
+ * @param bufferType The type of buffers to create.
+ * @param frequentResetHint A hint that indicates that the pool
+ * should expect frequent unlock() calls
+ * (as opposed to many makeSpace / acquires
+ * between resets).
+ * @param bufferSize The minimum size of created buffers.
+ * This value will be clamped to some
+ * reasonable minimum.
+ * @param preallocBufferCnt The pool will allocate this number of
+ * buffers at bufferSize and keep them until it
+ * is destroyed.
+ */
+ GrBufferAllocPool(GrGpu* gpu,
+ BufferType bufferType,
+ bool frequentResetHint,
+ size_t bufferSize = 0,
+ int preallocBufferCnt = 0);
+
+ virtual ~GrBufferAllocPool();
+
+public:
+ /**
+ * Ensures all buffers are unlocked and have all data written to them.
+ * Call before drawing using buffers from the pool.
+ */
+ void unlock();
+
+ /**
+ * Invalidates all the data in the pool, unrefs non-preallocated buffers.
+ */
+ void reset();
+
+ /**
+ * Gets the number of preallocated buffers that are yet to be used.
+ */
+ int preallocatedBuffersRemaining() const;
+
+ /**
+ * gets the number of preallocated buffers
+ */
+ int preallocatedBufferCount() const;
+
+
+ /**
+ * Frees data from makeSpaces in LIFO order.
+ */
+ void putBack(size_t bytes);
+
+ /**
+ * Gets the GrGpu that this pool is associated with.
+ */
+ GrGpu* getGpu() { return fGpu; }
+
+protected:
+ /**
+ * Gets the size of the preallocated buffers.
+ *
+ * @return the size of preallocated buffers.
+ */
+ size_t preallocatedBufferSize() const {
+ return fPreallocBuffers.count() ? fMinBlockSize : 0;
+ }
+
+ /**
+ * Returns a block of memory to hold data. A buffer designated to hold the
+ * data is given to the caller. The buffer may or may not be locked. The
+ * returned ptr remains valid until any of the following:
+ * *makeSpace is called again.
+ * *unlock is called.
+ * *reset is called.
+ * *this object is destroyed.
+ *
+ * Once unlock on the pool is called the data is guaranteed to be in the
+ * buffer at the offset indicated by offset. Until that time it may be
+ * in temporary storage and/or the buffer may be locked.
+ *
+ * @param size the amount of data to make space for
+ * @param alignment alignment constraint from start of buffer
+ * @param buffer returns the buffer that will hold the data.
+ * @param offset returns the offset into buffer of the data.
+ * @return pointer to where the client should write the data.
+ */
+ void* makeSpace(size_t size,
+ size_t alignment,
+ const GrGeometryBuffer** buffer,
+ size_t* offset);
+
+ /**
+ * Gets the number of items of a size that can be added to the current
+ * buffer without spilling to another buffer. If the pool has been reset, or
+ * the previous makeSpace completely exhausted a buffer then the returned
+ * size will be the size of the next available preallocated buffer, or zero
+ * if no preallocated buffer remains available. It is assumed that items
+ * should be itemSize-aligned from the start of a buffer.
+ *
+ * @return the number of items that would fit in the current buffer.
+ */
+ int currentBufferItems(size_t itemSize) const;
+
+ GrGeometryBuffer* createBuffer(size_t size);
+
+private:
+
+ struct BufferBlock {
+ size_t fBytesFree;
+ GrGeometryBuffer* fBuffer;
+ };
+
+ bool createBlock(size_t requestSize);
+ void destroyBlock();
+ void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
+#if GR_DEBUG
+ void validate() const;
+#endif
+
+ GrGpu* fGpu;
+ bool fFrequentResetHint;
+ GrTDArray<GrGeometryBuffer*> fPreallocBuffers;
+ size_t fMinBlockSize;
+ BufferType fBufferType;
+
+ GrTArray<BufferBlock> fBlocks;
+ int fPreallocBuffersInUse;
+ int fFirstPreallocBuffer;
+ GrAutoMalloc fCpuData;
+ void* fBufferPtr;
+};
+
+class GrVertexBuffer;
+
+/**
+ * A GrBufferAllocPool of vertex buffers
+ */
+class GrVertexBufferAllocPool : public GrBufferAllocPool {
+public:
+ /**
+ * Constructor
+ *
+ * @param gpu The GrGpu used to create the vertex buffers.
+ * @param frequentResetHint A hint that indicates that the pool
+ * should expect frequent unlock() calls
+ * (as opposed to many makeSpace / acquires
+ * between resets).
+ * @param bufferSize The minimum size of created VBs This value
+ * will be clamped to some reasonable minimum.
+ * @param preallocBufferCnt The pool will allocate this number of VBs at
+ * bufferSize and keep them until it is
+ * destroyed.
+ */
+ GrVertexBufferAllocPool(GrGpu* gpu,
+ bool frequentResetHint,
+ size_t bufferSize = 0,
+ int preallocBufferCnt = 0);
+
+ /**
+ * Returns a block of memory to hold vertices. A buffer designated to hold
+ * the vertices given to the caller. The buffer may or may not be locked.
+ * The returned ptr remains valid until any of the following:
+ * *makeSpace is called again.
+ * *unlock is called.
+ * *reset is called.
+ * *this object is destroyed.
+ *
+ * Once unlock on the pool is called the vertices are guaranteed to be in
+ * the buffer at the offset indicated by startVertex. Until that time they
+ * may be in temporary storage and/or the buffer may be locked.
+ *
+ * @param layout specifies type of vertices to allocate space for
+ * @param vertexCount number of vertices to allocate space for
+ * @param buffer returns the vertex buffer that will hold the
+ * vertices.
+ * @param startVertex returns the offset into buffer of the first vertex.
+ * In units of the size of a vertex from layout param.
+ * @return pointer to first vertex.
+ */
+ void* makeSpace(GrVertexLayout layout,
+ int vertexCount,
+ const GrVertexBuffer** buffer,
+ int* startVertex);
+
+ /**
+ * Shortcut to make space and then write verts into the made space.
+ */
+ bool appendVertices(GrVertexLayout layout,
+ int vertexCount,
+ const void* vertices,
+ const GrVertexBuffer** buffer,
+ int* startVertex);
+
+ /**
+ * Gets the number of vertices that can be added to the current VB without
+ * spilling to another VB. If the pool has been reset, or the previous
+ * makeSpace completely exhausted a VB then the returned number of vertices
+ * would fit in the next available preallocated buffer. If any makeSpace
+ * would force a new VB to be created the return value will be zero.
+ *
+ * @param the format of vertices to compute space for.
+ * @return the number of vertices that would fit in the current buffer.
+ */
+ int currentBufferVertices(GrVertexLayout layout) const;
+
+ /**
+ * Gets the number of vertices that can fit in a preallocated vertex buffer.
+ * Zero if no preallocated buffers.
+ *
+ * @param the format of vertices to compute space for.
+ *
+ * @return number of vertices that fit in one of the preallocated vertex
+ * buffers.
+ */
+ int preallocatedBufferVertices(GrVertexLayout layout) const;
+
+private:
+ typedef GrBufferAllocPool INHERITED;
+};
+
+class GrIndexBuffer;
+
+/**
+ * A GrBufferAllocPool of index buffers
+ */
+class GrIndexBufferAllocPool : public GrBufferAllocPool {
+public:
+ /**
+ * Constructor
+ *
+ * @param gpu The GrGpu used to create the index buffers.
+ * @param frequentResetHint A hint that indicates that the pool
+ * should expect frequent unlock() calls
+ * (as opposed to many makeSpace / acquires
+ * between resets).
+ * @param bufferSize The minimum size of created IBs This value
+ * will be clamped to some reasonable minimum.
+ * @param preallocBufferCnt The pool will allocate this number of VBs at
+ * bufferSize and keep them until it is
+ * destroyed.
+ */
+ GrIndexBufferAllocPool(GrGpu* gpu,
+ bool frequentResetHint,
+ size_t bufferSize = 0,
+ int preallocBufferCnt = 0);
+
+ /**
+ * Returns a block of memory to hold indices. A buffer designated to hold
+ * the indices is given to the caller. The buffer may or may not be locked.
+ * The returned ptr remains valid until any of the following:
+ * *makeSpace is called again.
+ * *unlock is called.
+ * *reset is called.
+ * *this object is destroyed.
+ *
+ * Once unlock on the pool is called the indices are guaranteed to be in the
+ * buffer at the offset indicated by startIndex. Until that time they may be
+ * in temporary storage and/or the buffer may be locked.
+ *
+ * @param indexCount number of indices to allocate space for
+ * @param buffer returns the index buffer that will hold the indices.
+ * @param startIndex returns the offset into buffer of the first index.
+ * @return pointer to first index.
+ */
+ void* makeSpace(int indexCount,
+ const GrIndexBuffer** buffer,
+ int* startIndex);
+
+ /**
+ * Shortcut to make space and then write indices into the made space.
+ */
+ bool appendIndices(int indexCount,
+ const void* indices,
+ const GrIndexBuffer** buffer,
+ int* startIndex);
+
+ /**
+ * Gets the number of indices that can be added to the current IB without
+ * spilling to another IB. If the pool has been reset, or the previous
+ * makeSpace completely exhausted a IB then the returned number of indices
+ * would fit in the next available preallocated buffer. If any makeSpace
+ * would force a new IB to be created the return value will be zero.
+ */
+ int currentBufferIndices() const;
+
+ /**
+ * Gets the number of indices that can fit in a preallocated index buffer.
+ * Zero if no preallocated buffers.
+ *
+ * @return number of indices that fit in one of the preallocated index
+ * buffers.
+ */
+ int preallocatedBufferIndices() const;
+
+private:
+ typedef GrBufferAllocPool INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index e224891..d14777e 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -14,7 +14,6 @@
limitations under the License.
*/
-
#include "GrContext.h"
#include "GrTypes.h"
#include "GrTextureCache.h"
@@ -23,23 +22,16 @@
#include "GrPathIter.h"
#include "GrClipIterator.h"
#include "GrIndexBuffer.h"
+#include "GrInOrderDrawBuffer.h"
+#include "GrBufferAllocPool.h"
#define DEFER_TEXT_RENDERING 1
static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
-#if DEFER_TEXT_RENDERING
- static const uint32_t POOL_VB_SIZE = 2048 *
- GrDrawTarget::VertexSize(
- GrDrawTarget::kTextFormat_VertexLayoutBit |
- GrDrawTarget::StageTexCoordVertexLayoutBit(0,0));
- static const uint32_t NUM_POOL_VBS = 8;
-#else
- static const uint32_t POOL_VB_SIZE = 0;
- static const uint32_t NUM_POOL_VBS = 0;
-
-#endif
+static const uint32_t TEXT_POOL_VB_SIZE = 1 << 18; // enough to draw 4K untextured glyphs
+static const uint32_t NUM_TEXT_POOL_VBS = 4;
GrContext* GrContext::Create(GrGpu::Engine engine,
GrGpu::Platform3DContext context3D) {
@@ -60,6 +52,9 @@
fGpu->unref();
delete fTextureCache;
delete fFontCache;
+ delete fTextDrawBuffer;
+ delete fTextVBAllocPool;
+ delete fTextIBAllocPool;
}
void GrContext::abandonAllTextures() {
@@ -487,7 +482,7 @@
const uint16_t indices[],
int indexCount) {
GrVertexLayout layout = 0;
- bool interLeave = false;
+ int vertexSize = sizeof(GrPoint);
GrDrawTarget::AutoReleaseGeometry geo;
@@ -498,18 +493,16 @@
layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
} else {
layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
- interLeave = true;
+ vertexSize += sizeof(GrPoint);
}
}
if (NULL != colors) {
layout |= GrDrawTarget::kColor_VertexLayoutBit;
+ vertexSize += sizeof(GrColor);
}
- static const GrVertexLayout interleaveMask =
- (GrDrawTarget::StageTexCoordVertexLayoutBit(0,0) |
- GrDrawTarget::kColor_VertexLayoutBit);
- if (interleaveMask & layout) {
+ if (sizeof(GrPoint) != vertexSize) {
if (!geo.set(fGpu, layout, vertexCount, 0)) {
GrPrintf("Failed to get space for vertices!");
return;
@@ -533,11 +526,11 @@
curVertex = (void*)((intptr_t)curVertex + vsize);
}
} else {
- fGpu->setVertexSourceToArray(positions, layout);
+ fGpu->setVertexSourceToArray(layout, positions, vertexCount);
}
if (NULL != indices) {
- fGpu->setIndexSourceToArray(indices);
+ fGpu->setIndexSourceToArray(indices, indexCount);
fGpu->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
} else {
fGpu->drawNonIndexed(primitiveType, 0, vertexCount);
@@ -816,7 +809,7 @@
}
case GrPathIter::kCubic_Command: {
generate_cubic_points(pts[0], pts[1], pts[2], pts[3],
- tolSqd, &vert,
+ tolSqd, &vert,
cubic_point_count(pts, tol));
break;
}
@@ -892,8 +885,10 @@
}
void GrContext::flushText() {
- fTextDrawBuffer.playback(fGpu);
- fTextDrawBuffer.reset();
+ if (NULL != fTextDrawBuffer) {
+ fTextDrawBuffer->playback(fGpu);
+ fTextDrawBuffer->reset();
+ }
}
bool GrContext::readPixels(int left, int top, int width, int height,
@@ -1026,16 +1021,28 @@
fGpu->printStats();
}
-GrContext::GrContext(GrGpu* gpu) :
- fVBAllocPool(gpu,
- gpu->supportsBufferLocking() ? POOL_VB_SIZE : 0,
- gpu->supportsBufferLocking() ? NUM_POOL_VBS : 0),
- fTextDrawBuffer(gpu->supportsBufferLocking() ? &fVBAllocPool : NULL) {
+GrContext::GrContext(GrGpu* gpu) {
fGpu = gpu;
fGpu->ref();
fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
MAX_TEXTURE_CACHE_BYTES);
fFontCache = new GrFontCache(fGpu);
+
+#if DEFER_TEXT_RENDERING
+ fTextVBAllocPool = new GrVertexBufferAllocPool(gpu,
+ false,
+ TEXT_POOL_VB_SIZE,
+ NUM_TEXT_POOL_VBS);
+ fTextIBAllocPool = new GrIndexBufferAllocPool(gpu, false, 0, 0);
+
+ fTextDrawBuffer = new GrInOrderDrawBuffer(fTextVBAllocPool,
+ fTextIBAllocPool);
+#else
+ fTextDrawBuffer = NULL;
+ fTextVBAllocPool = NULL;
+ fTextIBAllocPool = NULL;
+#endif
+
}
bool GrContext::finalizeTextureKey(GrTextureKey* key,
@@ -1063,8 +1070,8 @@
GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
GrDrawTarget* target;
#if DEFER_TEXT_RENDERING
- fTextDrawBuffer.initializeDrawStateAndClip(*fGpu);
- target = &fTextDrawBuffer;
+ fTextDrawBuffer->initializeDrawStateAndClip(*fGpu);
+ target = fTextDrawBuffer;
#else
target = fGpu;
#endif
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index 0f31e9a..5cfc6f4 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -458,20 +458,22 @@
fReservedGeometry.fLocked = false;
}
-void GrDrawTarget::setVertexSourceToArray(const void* array,
- GrVertexLayout vertexLayout) {
- fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
- fGeometrySrc.fVertexArray = array;
+void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
+ const void* vertexArray,
+ int vertexCount) {
+ fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
fGeometrySrc.fVertexLayout = vertexLayout;
+ setVertexSourceToArrayHelper(vertexArray, vertexCount);
}
-void GrDrawTarget::setIndexSourceToArray(const void* array) {
- fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
- fGeometrySrc.fIndexArray = array;
+void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
+ int indexCount) {
+ fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
+ setIndexSourceToArrayHelper(indexArray, indexCount);
}
-void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer,
- GrVertexLayout vertexLayout) {
+void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
+ const GrVertexBuffer* buffer) {
fGeometrySrc.fVertexSrc = kBuffer_GeometrySrcType;
fGeometrySrc.fVertexBuffer = buffer;
fGeometrySrc.fVertexLayout = vertexLayout;
diff --git a/gpu/src/GrGLIndexBuffer.cpp b/gpu/src/GrGLIndexBuffer.cpp
index 82cffaa..2dc4154 100644
--- a/gpu/src/GrGLIndexBuffer.cpp
+++ b/gpu/src/GrGLIndexBuffer.cpp
@@ -18,18 +18,14 @@
#include "GrGLIndexBuffer.h"
#include "GrGpuGL.h"
-GrGLIndexBuffer::GrGLIndexBuffer(GLuint id, GrGpuGL* gl, uint32_t sizeInBytes,
- bool dynamic) :
+GrGLIndexBuffer::GrGLIndexBuffer(GLuint id, GrGpuGL* gl, size_t sizeInBytes,
+ bool dynamic) :
INHERITED(sizeInBytes, dynamic),
fGL(gl),
fBufferID(id),
fLockPtr(NULL) {
}
-GLuint GrGLIndexBuffer::bufferID() const {
- return fBufferID;
-}
-
GrGLIndexBuffer::~GrGLIndexBuffer() {
// make sure we've not been abandoned
if (fBufferID) {
@@ -38,8 +34,17 @@
}
}
+void GrGLIndexBuffer::bind() const {
+ GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+ fGL->notifyIndexBufferBind(this);
+}
+
+GLuint GrGLIndexBuffer::bufferID() const {
+ return fBufferID;
+}
+
void GrGLIndexBuffer::abandon() {
- fBufferID = 0;
+ fBufferID = 0;
fGL = NULL;
fLockPtr = NULL;
}
@@ -48,12 +53,9 @@
GrAssert(fBufferID);
GrAssert(!isLocked());
if (fGL->supportsBufferLocking()) {
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- fGL->notifyIndexBufferBind(this);
- // call bufferData with null ptr to allow driver to perform renaming
- // If this call is removed revisit updateData to be sure it doesn't
- // leave buffer undersized (as it currently does).
- GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL,
+ bind();
+ // Let driver know it can discard the old data
+ GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL,
dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
fLockPtr = GR_GLEXT(fGL->extensions(),
MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GR_WRITE_ONLY));
@@ -63,27 +65,27 @@
return NULL;
}
+void* GrGLIndexBuffer::lockPtr() const {
+ return fLockPtr;
+}
+
void GrGLIndexBuffer::unlock() {
GrAssert(fBufferID);
GrAssert(isLocked());
+ GrAssert(fGL->supportsBufferLocking());
- if (fGL->supportsBufferLocking()) {
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- fGL->notifyIndexBufferBind(this);
- GR_GLEXT(fGL->extensions(),
- UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
- fLockPtr = NULL;
- }
+ bind();
+ GR_GLEXT(fGL->extensions(), UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
+ fLockPtr = NULL;
}
bool GrGLIndexBuffer::isLocked() const {
GrAssert(fBufferID);
#if GR_DEBUG
if (fGL->supportsBufferLocking()) {
+ bind();
GLint mapped;
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- fGL->notifyIndexBufferBind(this);
- GR_GL(GetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER,
+ GR_GL(GetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER,
GR_BUFFER_MAPPED, &mapped));
GrAssert(!!mapped == !!fLockPtr);
}
@@ -91,16 +93,33 @@
return NULL != fLockPtr;
}
-bool GrGLIndexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
GrAssert(fBufferID);
GrAssert(!isLocked());
if (srcSizeInBytes > size()) {
return false;
}
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- fGL->notifyIndexBufferBind(this);
- GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src,
- dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+ bind();
+ GLenum usage = dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
+ if (size() == srcSizeInBytes) {
+ GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+ } else {
+ GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL, usage));
+ GR_GL(BufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+ }
+ return true;
+}
+
+bool GrGLIndexBuffer::updateSubData(const void* src,
+ size_t srcSizeInBytes,
+ size_t offset) {
+ GrAssert(fBufferID);
+ GrAssert(!isLocked());
+ if (srcSizeInBytes + offset > size()) {
+ return false;
+ }
+ bind();
+ GR_GL(BufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, srcSizeInBytes, src));
return true;
}
diff --git a/gpu/src/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
index b4ddc24..ec48936 100644
--- a/gpu/src/GrGLVertexBuffer.cpp
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -18,8 +18,8 @@
#include "GrGLVertexBuffer.h"
#include "GrGpuGL.h"
-GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, uint32_t sizeInBytes,
- bool dynamic) :
+GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, size_t sizeInBytes,
+ bool dynamic) :
INHERITED(sizeInBytes, dynamic),
fGL(gl),
fBufferID(id),
@@ -34,11 +34,16 @@
}
}
+void GrGLVertexBuffer::bind() const {
+ GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+ fGL->notifyVertexBufferBind(this);
+}
+
GLuint GrGLVertexBuffer::bufferID() const {
return fBufferID;
}
-void GrGLVertexBuffer::abandon() {
+void GrGLVertexBuffer::abandon() {
fBufferID = 0;
fGL = NULL;
fLockPtr = NULL;
@@ -48,30 +53,29 @@
GrAssert(fBufferID);
GrAssert(!isLocked());
if (fGL->supportsBufferLocking()) {
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
- fGL->notifyVertexBufferBind(this);
- // call bufferData with null ptr to allow driver to perform renaming
- // If this call is removed revisit updateData to be sure it doesn't
- // leave buffer undersized (as it currently does).
- GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL,
+ bind();
+ // Let driver know it can discard the old data
+ GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL,
dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
fLockPtr = GR_GLEXT(fGL->extensions(),
- MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY));
+ MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY));
return fLockPtr;
}
return NULL;
}
+void* GrGLVertexBuffer::lockPtr() const {
+ return fLockPtr;
+}
+
void GrGLVertexBuffer::unlock() {
GrAssert(fBufferID);
GrAssert(isLocked());
- if (fGL->supportsBufferLocking()) {
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
- fGL->notifyVertexBufferBind(this);
- GR_GLEXT(fGL->extensions(),
- UnmapBuffer(GL_ARRAY_BUFFER));
- fLockPtr = NULL;
- }
+ GrAssert(fGL->supportsBufferLocking());
+
+ bind();
+ GR_GLEXT(fGL->extensions(), UnmapBuffer(GL_ARRAY_BUFFER));
+ fLockPtr = NULL;
}
bool GrGLVertexBuffer::isLocked() const {
@@ -79,8 +83,7 @@
#if GR_DEBUG
if (fGL->supportsBufferLocking()) {
GLint mapped;
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
- fGL->notifyVertexBufferBind(this);
+ bind();
GR_GL(GetBufferParameteriv(GL_ARRAY_BUFFER, GR_BUFFER_MAPPED, &mapped));
GrAssert(!!mapped == !!fLockPtr);
}
@@ -88,16 +91,33 @@
return NULL != fLockPtr;
}
-bool GrGLVertexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
GrAssert(fBufferID);
GrAssert(!isLocked());
if (srcSizeInBytes > size()) {
return false;
}
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
- fGL->notifyVertexBufferBind(this);
- GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src,
- dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+ bind();
+ GLenum usage = dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
+ if (size() == srcSizeInBytes) {
+ GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+ } else {
+ GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL, usage));
+ GR_GL(BufferSubData(GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+ }
+ return true;
+}
+
+bool GrGLVertexBuffer::updateSubData(const void* src,
+ size_t srcSizeInBytes,
+ size_t offset) {
+ GrAssert(fBufferID);
+ GrAssert(!isLocked());
+ if (srcSizeInBytes + offset > size()) {
+ return false;
+ }
+ bind();
+ GR_GL(BufferSubData(GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
return true;
}
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 057a8c9..e406f6f 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -14,7 +14,6 @@
limitations under the License.
*/
-
#include "GrGpu.h"
#include "GrMemory.h"
#include "GrTextStrike.h"
@@ -22,6 +21,10 @@
#include "GrClipIterator.h"
#include "GrIndexBuffer.h"
#include "GrVertexBuffer.h"
+#include "GrBufferAllocPool.h"
+
+// probably makes no sense for this to be less than a page
+static size_t VERTEX_POOL_VB_SIZE = 1 << 12;
///////////////////////////////////////////////////////////////////////////////
@@ -57,6 +60,12 @@
extern void gr_run_unittests();
GrGpu::GrGpu() : f8bitPaletteSupport(false),
+ fCurrPoolVertexBuffer(NULL),
+ fCurrPoolStartVertex(0),
+ fCurrPoolIndexBuffer(NULL),
+ fCurrPoolStartIndex(0),
+ fVertexPool(NULL),
+ fIndexPool(NULL),
fQuadIndexBuffer(NULL),
fUnitSquareVertexBuffer(NULL) {
#if GR_DEBUG
@@ -68,6 +77,8 @@
GrGpu::~GrGpu() {
GrSafeUnref(fQuadIndexBuffer);
GrSafeUnref(fUnitSquareVertexBuffer);
+ delete fVertexPool;
+ delete fIndexPool;
}
void GrGpu::resetContext() {
@@ -124,11 +135,11 @@
///////////////////////////////////////////////////////////////////////////////
-static const int MAX_QUADS = 512; // max possible: (1 << 14) - 1;
+static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535);
-static inline void fillIndices(uint16_t* indices, int quadCount) {
+static inline void fill_indices(uint16_t* indices, int quadCount) {
for (int i = 0; i < quadCount; ++i) {
indices[6 * i + 0] = 4 * i + 0;
indices[6 * i + 1] = 4 * i + 1;
@@ -147,11 +158,11 @@
if (NULL != fQuadIndexBuffer) {
uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock();
if (NULL != indices) {
- fillIndices(indices, MAX_QUADS);
+ fill_indices(indices, MAX_QUADS);
fQuadIndexBuffer->unlock();
} else {
indices = (uint16_t*)GrMalloc(SIZE);
- fillIndices(indices, MAX_QUADS);
+ fill_indices(indices, MAX_QUADS);
if (!fQuadIndexBuffer->updateData(indices, SIZE)) {
fQuadIndexBuffer->unref();
fQuadIndexBuffer = NULL;
@@ -222,41 +233,53 @@
AutoStateRestore asr(this);
AutoGeometrySrcRestore agsr(this);
- this->disableState(kClip_StateBit);
- eraseStencilClip();
+
+ // We have to use setVertexSourceToBuffer (and index) in order
+ // to ensure we correctly restore the client's geom sources.
+ // We tack the clip verts onto the vertex pool but we don't
+ // use the various helper functions because of their side effects.
int rectTotal = fClip.countRects();
- static const int PtsPerRect = 4;
- // this may be called while geometry is already reserved by the
- // client. So we use our own vertex array where we avoid malloc
- // if we have 4 or fewer rects.
- GrAutoSTMalloc<PtsPerRect * 4, GrPoint> vertices(PtsPerRect *
- rectTotal);
- this->setVertexSourceToArray(vertices.get(), 0);
+ if (NULL == fVertexPool) {
+ fVertexPool = new GrVertexBufferAllocPool(this,
+ true,
+ VERTEX_POOL_VB_SIZE,
+ 1);
+ }
+ const GrVertexBuffer* vertexBuffer;
+ int vStart;
+ GrPoint* rectVertices =
+ reinterpret_cast<GrPoint*>(fVertexPool->makeSpace(0,
+ rectTotal * 4,
+ &vertexBuffer,
+ &vStart));
+ for (int r = 0; r < rectTotal; ++r) {
+ const GrIRect& rect = fClip.getRects()[r];
+ rectVertices[4 * r].setIRectFan(rect.fLeft, rect.fTop,
+ rect.fRight, rect.fBottom);
+ }
+ fVertexPool->unlock();
+ this->setVertexSourceToBuffer(0, vertexBuffer);
+ this->setIndexSourceToBuffer(quadIndexBuffer());
+ this->setViewMatrix(GrMatrix::I());
+ // don't clip the clip or recurse!
+ this->disableState(kClip_StateBit);
+ this->eraseStencilClip();
+ this->setStencilPass((GrDrawTarget::StencilPass)kSetClip_StencilPass);
int currRect = 0;
while (currRect < rectTotal) {
int rectCount = GrMin(this->maxQuadsInIndexBuffer(),
rectTotal - currRect);
-
- GrPoint* verts = (GrPoint*)vertices +
- (currRect * PtsPerRect);
-
- for (int i = 0; i < rectCount; i++) {
- GrRect r(fClip.getRects()[i + currRect]);
- verts = r.setRectFan(verts);
- }
- this->setIndexSourceToBuffer(quadIndexBuffer());
-
- this->setViewMatrix(GrMatrix::I());
- this->setStencilPass((GrDrawTarget::StencilPass)kSetClip_StencilPass);
- this->drawIndexed(GrGpu::kTriangles_PrimitiveType,
- currRect * PtsPerRect, 0,
- rectCount * PtsPerRect, rectCount * 6);
-
+ this->drawIndexed(kTriangles_PrimitiveType,
+ vStart + currRect * 4,
+ 0,
+ rectCount*4,
+ rectCount*6);
currRect += rectCount;
}
fClipState.fStencilClipTarget = fCurrDrawState.fRenderTarget;
}
+
fClipState.fClipIsDirty = false;
if (!fClipState.fClipInStencil) {
r = &fClip.getBounds();
@@ -274,10 +297,10 @@
///////////////////////////////////////////////////////////////////////////////
void GrGpu::drawIndexed(PrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
fReservedGeometry.fLocked);
GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
@@ -293,15 +316,17 @@
fStats.fDrawCnt += 1;
#endif
- setupGeometry(startVertex, startIndex, vertexCount, indexCount);
+ int sVertex = startVertex;
+ int sIndex = startIndex;
+ setupGeometry(&sVertex, &sIndex, vertexCount, indexCount);
- drawIndexedHelper(type, startVertex, startIndex,
+ drawIndexedHelper(type, sVertex, sIndex,
vertexCount, indexCount);
}
void GrGpu::drawNonIndexed(PrimitiveType type,
- uint32_t startVertex,
- uint32_t vertexCount) {
+ int startVertex,
+ int vertexCount) {
GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
fReservedGeometry.fLocked);
@@ -313,37 +338,103 @@
fStats.fDrawCnt += 1;
#endif
- setupGeometry(startVertex, 0, vertexCount, 0);
+ int sVertex = startVertex;
+ setupGeometry(&sVertex, NULL, vertexCount, 0);
- drawNonIndexedHelper(type, startVertex, vertexCount);
+ drawNonIndexedHelper(type, sVertex, vertexCount);
+}
+
+void GrGpu::finalizeReservedVertices() {
+ GrAssert(NULL != fVertexPool);
+ fVertexPool->unlock();
+}
+
+void GrGpu::finalizeReservedIndices() {
+ GrAssert(NULL != fIndexPool);
+ fIndexPool->unlock();
+}
+
+void GrGpu::prepareVertexPool() {
+ if (NULL == fVertexPool) {
+ fVertexPool = new GrVertexBufferAllocPool(this, true, VERTEX_POOL_VB_SIZE, 1);
+ } else {
+ fVertexPool->reset();
+ }
+}
+
+void GrGpu::prepareIndexPool() {
+ if (NULL == fVertexPool) {
+ fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
+ } else {
+ fIndexPool->reset();
+ }
}
bool GrGpu::acquireGeometryHelper(GrVertexLayout vertexLayout,
void** vertices,
void** indices) {
- GrAssert((fReservedGeometry.fVertexCount == 0) ||
- (NULL != vertices));
- if (NULL != vertices) {
- *vertices = fVertices.realloc(VertexSize(vertexLayout) *
- fReservedGeometry.fVertexCount);
- if (!*vertices && fReservedGeometry.fVertexCount) {
+ GrAssert(!fReservedGeometry.fLocked);
+ size_t reservedVertexSpace = 0;
+
+ if (fReservedGeometry.fVertexCount) {
+ GrAssert(NULL != vertices);
+
+ prepareVertexPool();
+
+ *vertices = fVertexPool->makeSpace(vertexLayout,
+ fReservedGeometry.fVertexCount,
+ &fCurrPoolVertexBuffer,
+ &fCurrPoolStartVertex);
+ if (NULL == *vertices) {
return false;
}
+ reservedVertexSpace = VertexSize(vertexLayout) *
+ fReservedGeometry.fVertexCount;
}
- GrAssert((fReservedGeometry.fIndexCount == 0) ||
- (NULL != indices));
- if (NULL != indices) {
- *indices = fIndices.realloc(sizeof(uint16_t) *
- fReservedGeometry.fIndexCount);
- if (!*indices && fReservedGeometry.fIndexCount) {
+ if (fReservedGeometry.fIndexCount) {
+ GrAssert(NULL != indices);
+
+ prepareIndexPool();
+
+ *indices = fIndexPool->makeSpace(fReservedGeometry.fIndexCount,
+ &fCurrPoolIndexBuffer,
+ &fCurrPoolStartIndex);
+ if (NULL == *indices) {
+ fVertexPool->putBack(reservedVertexSpace);
+ fCurrPoolVertexBuffer = NULL;
return false;
}
}
return true;
}
-void GrGpu::releaseGeometryHelper() {
- return;
+void GrGpu::releaseGeometryHelper() {}
+
+void GrGpu::setVertexSourceToArrayHelper(const void* vertexArray, int vertexCount) {
+ GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+ prepareVertexPool();
+#if GR_DEBUG
+ bool success =
+#endif
+ fVertexPool->appendVertices(fGeometrySrc.fVertexLayout,
+ vertexCount,
+ vertexArray,
+ &fCurrPoolVertexBuffer,
+ &fCurrPoolStartVertex);
+ GR_DEBUGASSERT(success);
+}
+
+void GrGpu::setIndexSourceToArrayHelper(const void* indexArray, int indexCount) {
+ GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+ prepareIndexPool();
+#if GR_DEBUG
+ bool success =
+#endif
+ fIndexPool->appendIndices(indexCount,
+ indexArray,
+ &fCurrPoolIndexBuffer,
+ &fCurrPoolStartIndex);
+ GR_DEBUGASSERT(success);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 0b5927a..8d00af9 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -87,13 +87,6 @@
GrGpuGL::GrGpuGL() {
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
- fClientArrayVB = NULL;
- fClientArrayIB = NULL;
- fOversizeVBDrawCnt = 0;
- fOversizeIBDrawCnt = 0;
-#endif
-
if (gPrintStartupSpew) {
GrPrintf("------------------------- create GrGpuGL %p --------------\n",
this);
@@ -229,7 +222,6 @@
GrPrintf("Single Stencil Pass For Winding: %s\n", (fSingleStencilPassForWinding ? "YES" : "NO"));
}
-
#if GR_SUPPORT_GLDESKTOP
fRGBA8Renderbuffer = true;
#else
@@ -251,6 +243,7 @@
#else
fBufferLockSupport = has_gl_extension("GL_OES_mapbuffer");
#endif
+
if (gPrintStartupSpew) {
GrPrintf("Map Buffer: %s\n", (fBufferLockSupport ? "YES" : "NO"));
}
@@ -372,10 +365,6 @@
}
GrGpuGL::~GrGpuGL() {
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
- GrSafeUnref(fClientArrayVB);
- GrSafeUnref(fClientArrayIB);
-#endif
}
void GrGpuGL::resetContextHelper() {
@@ -430,6 +419,8 @@
fHWDrawState.fReverseFill = false;
fHWDrawState.fStencilPass = kNone_StencilPass;
fHWStencilClip = false;
+ fClipState.fClipIsDirty = true;
+ fClipState.fStencilClipTarget = NULL;
fHWGeometryState.fIndexBuffer = NULL;
fHWGeometryState.fVertexBuffer = NULL;
@@ -445,63 +436,6 @@
resetContextHelper();
}
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
-void GrGpuGL::putClientVertexDataInBuffer(const void* vertexData, size_t vertexDataSize) {
- static const size_t MIN_VB_SIZE = 1 << 11;
- static const int MAX_OVERSIZE_VB_DRAWS = 100;
-
- if (NULL != vertexData) {
- size_t currMinVBSize = GrMax(MIN_VB_SIZE, vertexDataSize);
- // if we don't have a VB, its too small, or too big, create a new one
- if (NULL == fClientArrayVB ||
- fClientArrayVB->size() < currMinVBSize ||
- (fOversizeVBDrawCnt >= MAX_OVERSIZE_VB_DRAWS &&
- currMinVBSize == MIN_VB_SIZE &&
- fClientArrayVB->size() > MIN_VB_SIZE)) {
-
- if (fHWGeometryState.fVertexBuffer == fClientArrayVB) {
- fHWGeometryState.fVertexBuffer = NULL;
- fHWGeometryState.fArrayPtrsDirty = true;
- }
- GrSafeUnref(fClientArrayVB);
- fClientArrayVB = (GrGLVertexBuffer*)createVertexBuffer(currMinVBSize, true);
- fOversizeVBDrawCnt = 0;
- }
- fClientArrayVB->updateData(vertexData, vertexDataSize);
- if (currMinVBSize == MIN_VB_SIZE && fClientArrayVB->size() > MIN_VB_SIZE) {
- ++fOversizeVBDrawCnt;
- }
- }
-}
-
-void GrGpuGL::putClientIndexDataInBuffer(const void* indexData, size_t indexDataSize) {
- static const size_t MIN_IB_SIZE = 1 << 8;
- static const int MAX_OVERSIZE_IB_DRAWS = 100;
-
- if (NULL != indexData) {
- size_t currMinIBSize = GrMax(MIN_IB_SIZE, indexDataSize);
- // if we don't have a IB, its too small, or too big, create a new one
- if (NULL == fClientArrayIB ||
- fClientArrayIB->size() < currMinIBSize ||
- (fOversizeIBDrawCnt >= MAX_OVERSIZE_IB_DRAWS &&
- currMinIBSize == MIN_IB_SIZE &&
- fClientArrayIB->size() > MIN_IB_SIZE)) {
-
- if (fHWGeometryState.fIndexBuffer == fClientArrayIB) {
- fHWGeometryState.fIndexBuffer = NULL;
- }
- GrSafeUnref(fClientArrayIB);
- fClientArrayIB = (GrGLIndexBuffer*)createIndexBuffer(currMinIBSize, true);
- fOversizeIBDrawCnt = 0;
- }
- fClientArrayIB->updateData(indexData, indexDataSize);
- if (currMinIBSize == MIN_IB_SIZE && fClientArrayIB->size() > MIN_IB_SIZE) {
- ++fOversizeIBDrawCnt;
- }
- }
-}
-#endif
-
GrRenderTarget* GrGpuGL::createPlatformRenderTarget(
intptr_t platformRenderTarget,
int width, int height) {
@@ -1202,19 +1136,12 @@
GLvoid* indices = (GLvoid*)(sizeof(uint16_t) * startIndex);
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
- if (kBuffer_GeometrySrcType != fGeometrySrc.fIndexSrc) {
- // we accounted for the startIndex when shoving data into a vb
- indices = NULL;
- }
-#else
- if (kReserved_GeometrySrcType == fGeometrySrc.fIndexSrc) {
- indices = (GLvoid*)((intptr_t)indices + (intptr_t)fIndices.get());
- } else if (kArray_GeometrySrcType == fGeometrySrc.fIndexSrc) {
- indices = (GLvoid*)((intptr_t)indices +
- (intptr_t)fGeometrySrc.fIndexArray);
- }
-#endif
+ GrAssert(NULL != fHWGeometryState.fIndexBuffer);
+ GrAssert(NULL != fHWGeometryState.fVertexBuffer);
+
+ // our setupGeometry better have adjusted this to zero since
+ // DrawElements always draws from the begining of the arrays for idx 0.
+ GrAssert(0 == startVertex);
GR_GL(DrawElements(gPrimitiveType2GLMode[type], indexCount,
GL_UNSIGNED_SHORT, indices));
@@ -1225,6 +1152,15 @@
uint32_t vertexCount) {
GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
+ GrAssert(NULL != fHWGeometryState.fVertexBuffer);
+
+ // our setupGeometry better have adjusted this to zero.
+ // DrawElements doesn't take an offset so we always adjus the startVertex.
+ GrAssert(0 == startVertex);
+
+ // pass 0 for parameter first. We have to adjust gl*Pointer() to
+ // account for startVertex in the DrawElements case. So we always
+ // rely on setupGeometry to have accounted for startVertex.
GR_GL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount));
}
@@ -1330,6 +1266,7 @@
if (!fCurrDrawState.fReverseFill) {
funcRef |= pathStencilMask;
}
+
GR_GL(StencilFunc(GL_EQUAL, funcRef, funcMask));
GR_GL(StencilMask(pathStencilMask));
GR_GL(StencilOp(GL_ZERO, GL_ZERO, GL_ZERO));
@@ -1425,6 +1362,7 @@
GLint funcRef = 0;
GLuint funcMask = pathStencilMask;
GLenum funcFunc;
+
if (stencilClip) {
funcRef |= clipStencilMask;
funcMask |= clipStencilMask;
@@ -1774,84 +1712,62 @@
}
}
+void GrGpuGL::setBuffers(bool indexed,
+ int* extraVertexOffset,
+ int* extraIndexOffset) {
-const GLvoid* GrGpuGL::setBuffersAndGetVertexStart(int vertexStride, int startVertex,
- int startIndex, int vertexCount,
- int indexCount) {
- const GLvoid* posPtr = (GLvoid*)(vertexStride * startVertex);
+ GrAssert(NULL != extraVertexOffset);
- if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
- GrAssert(NULL != fGeometrySrc.fVertexBuffer);
- GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
- if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
- GrGLVertexBuffer* buf =
- (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
- fHWGeometryState.fArrayPtrsDirty = true;
- fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
- }
- } else {
- if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
- posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray +
- (intptr_t)posPtr);
- } else {
- GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
- posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);
- }
- #if GR_GL_NO_CLIENT_SIDE_ARRAYS
- putClientVertexDataInBuffer(posPtr, vertexCount * vertexStride);
- posPtr = NULL;
- if (fHWGeometryState.fVertexBuffer != fClientArrayVB) {
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, fClientArrayVB->bufferID()));
- fHWGeometryState.fArrayPtrsDirty = true;
- fHWGeometryState.fVertexBuffer = fClientArrayVB;
- }
- #else
- if (NULL != fHWGeometryState.fVertexBuffer) {
- GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
- fHWGeometryState.fArrayPtrsDirty = true;
- fHWGeometryState.fVertexBuffer = NULL;
- }
- #endif
+ GrGLVertexBuffer* vbuf;
+ switch (fGeometrySrc.fVertexSrc) {
+ case kBuffer_GeometrySrcType:
+ *extraVertexOffset = 0;
+ vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer;
+ break;
+ case kArray_GeometrySrcType:
+ case kReserved_GeometrySrcType:
+ finalizeReservedVertices();
+ *extraVertexOffset = fCurrPoolStartVertex;
+ vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer;
+ break;
+ default:
+ vbuf = NULL; // suppress warning
+ GrCrash("Unknown geometry src type!");
}
- if (0 != indexCount) {
-
- if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
- GrAssert(NULL != fGeometrySrc.fIndexBuffer);
- GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
- if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
- GrGLIndexBuffer* buf =
- (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
- fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
- }
- }
- #if GR_GL_NO_CLIENT_SIDE_ARRAYS
- else {
- const uint16_t* indices;
- if (kArray_GeometrySrcType == fGeometrySrc.fIndexSrc) {
- indices = reinterpret_cast<const uint16_t*>(fGeometrySrc.fIndexArray);
- } else {
- GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fIndexSrc);
- indices = reinterpret_cast<const uint16_t*>(fIndices.get());
- }
- // we shove just the referenced part of the index data into the begining
- // of the buffer and drawIndexedHelper ignores startIndex.
- putClientIndexDataInBuffer(indices + startIndex, indexCount * sizeof(uint16_t));
- if (fHWGeometryState.fIndexBuffer != fClientArrayIB) {
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fClientArrayIB->bufferID()));
- fHWGeometryState.fIndexBuffer = fClientArrayIB;
- }
- }
- #else
- else if (NULL != fHWGeometryState.fIndexBuffer) {
- // we rely on drawIndexedHelper to pass to client side
- // ptr to DrawElements
- GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
- fHWGeometryState.fIndexBuffer = NULL;
- }
- #endif
+ GrAssert(NULL != vbuf);
+ GrAssert(!vbuf->isLocked());
+ if (fHWGeometryState.fVertexBuffer != vbuf) {
+ GR_GL(BindBuffer(GL_ARRAY_BUFFER, vbuf->bufferID()));
+ fHWGeometryState.fArrayPtrsDirty = true;
+ fHWGeometryState.fVertexBuffer = vbuf;
}
- return posPtr;
+
+ if (indexed) {
+ GrAssert(NULL != extraIndexOffset);
+
+ GrGLIndexBuffer* ibuf;
+ switch (fGeometrySrc.fIndexSrc) {
+ case kBuffer_GeometrySrcType:
+ *extraIndexOffset = 0;
+ ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+ break;
+ case kArray_GeometrySrcType:
+ case kReserved_GeometrySrcType:
+ finalizeReservedIndices();
+ *extraIndexOffset = fCurrPoolStartIndex;
+ ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer;
+ break;
+ default:
+ ibuf = NULL; // suppress warning
+ GrCrash("Unknown geometry src type!");
+ }
+
+ GrAssert(NULL != ibuf);
+ GrAssert(!ibuf->isLocked());
+ if (fHWGeometryState.fIndexBuffer != ibuf) {
+ GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID()));
+ fHWGeometryState.fIndexBuffer = ibuf;
+ }
+ }
}
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index e46c2ce..d89b8d5 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -61,8 +61,7 @@
protected:
struct {
- const void*
- fPositionPtr;
+ size_t fVertexOffset;
GrVertexLayout fVertexLayout;
const GrVertexBuffer* fVertexBuffer;
const GrIndexBuffer* fIndexBuffer;
@@ -72,28 +71,27 @@
DrState fHWDrawState;
bool fHWStencilClip;
+ // GrGpu overrides
virtual void drawIndexedHelper(PrimitiveType type,
uint32_t startVertex,
uint32_t startIndex,
uint32_t vertexCount,
uint32_t indexCount);
-
virtual void drawNonIndexedHelper(PrimitiveType type,
uint32_t vertexCount,
uint32_t numVertices);
-
virtual void flushScissor(const GrIRect* rect);
-
void eraseStencil(uint32_t value, uint32_t mask);
virtual void eraseStencilClip();
+ // binds texture unit in GL
void setTextureUnit(int unitIdx);
- // binds appropriate vertex and index buffers and returns either the ptr
- // to client memory or offset into a VB of the first vertex
- const GLvoid* setBuffersAndGetVertexStart(int vertexStride, int startVertex,
- int startIndex, int vertexCount,
- int indexCount);
+ // binds appropriate vertex and index buffers, also returns any extra
+ // extra verts or indices to offset by.
+ void setBuffers(bool indexed,
+ int* extraVertexOffset,
+ int* extraIndexOffset);
// flushes state that is common to fixed and programmable GL
// dither
@@ -118,13 +116,6 @@
GrGLExts fExts;
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
- void putClientVertexDataInBuffer(const void* vertexData,
- size_t vertexDataSize);
- void putClientIndexDataInBuffer(const void* indexData,
- size_t indexDataSize);
-#endif
-
private:
void resetContextHelper();
@@ -174,13 +165,6 @@
int fActiveTextureUnitIdx;
typedef GrGpu INHERITED;
-
-#if GR_GL_NO_CLIENT_SIDE_ARRAYS
- GrGLVertexBuffer* fClientArrayVB;
- GrGLIndexBuffer* fClientArrayIB;
- int fOversizeVBDrawCnt;
- int fOversizeIBDrawCnt;
-#endif
};
bool has_gl_extension(const char* ext);
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
index a028cba..76494de 100644
--- a/gpu/src/GrGpuGLFixed.cpp
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -95,7 +95,7 @@
}
fHWGeometryState.fVertexLayout = 0;
- fHWGeometryState.fPositionPtr = (void*) ~0;
+ fHWGeometryState.fVertexOffset = ~0;
GR_GL(EnableClientState(GL_VERTEX_ARRAY));
GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
GR_GL(ShadeModel(GL_FLAT));
@@ -246,10 +246,10 @@
return true;
}
-void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrGpuGLFixed::setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount) {
int newColorOffset;
int newTexCoordOffsets[kNumStages];
@@ -263,9 +263,11 @@
oldTexCoordOffsets,
&oldColorOffset);
- const GLvoid* posPtr = setBuffersAndGetVertexStart(newStride, startVertex,
- startIndex, vertexCount,
- indexCount);
+ bool indexed = NULL == startIndex;
+
+ int extraVertexOffset;
+ int extraIndexOffset;
+ setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GLenum scalarType;
if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
@@ -274,32 +276,43 @@
scalarType = GrGLType;
}
- bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
- bool scalarChange =
- (GrGLTextType != GrGLType) &&
- (kTextFormat_VertexLayoutBit &
- (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
- bool strideChange = newStride != oldStride;
- bool posChange = baseChange || scalarChange || strideChange;
+ size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+ *startVertex = 0;
+ if (indexed) {
+ *startIndex += extraIndexOffset;
+ }
- if (posChange || fHWGeometryState.fArrayPtrsDirty) {
- GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
- fHWGeometryState.fPositionPtr = posPtr;
+ // all the Pointers must be set if any of these are true
+ bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
+ vertexOffset != fHWGeometryState.fVertexOffset ||
+ newStride != oldStride;
+
+ // position and tex coord offsets change if above conditions are true
+ // or the type changed based on text vs nontext type coords.
+ bool posAndTexChange = allOffsetsChange ||
+ ((GrGLTextType != GrGLType) &&
+ (kTextFormat_VertexLayoutBit &
+ (fHWGeometryState.fVertexLayout ^
+ fGeometrySrc.fVertexLayout)));
+
+ if (posAndTexChange) {
+ GR_GL(VertexPointer(2, scalarType, newStride, (GLvoid*)vertexOffset));
+ fHWGeometryState.fVertexOffset = vertexOffset;
}
for (int s = 0; s < kNumStages; ++s) {
// need to enable array if tex coord offset is 0
// (using positions as coords)
if (newTexCoordOffsets[s] >= 0) {
- GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[s];
+ GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[s]);
if (oldTexCoordOffsets[s] < 0) {
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
- GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
- } else if (fHWGeometryState.fArrayPtrsDirty || posChange ||
+ GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
+ } else if (posAndTexChange ||
newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
- GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
+ GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
}
} else if (oldTexCoordOffsets[s] >= 0) {
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
@@ -308,13 +321,12 @@
}
if (newColorOffset > 0) {
- GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+ GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset);
if (oldColorOffset <= 0) {
GR_GL(EnableClientState(GL_COLOR_ARRAY));
- GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
- } else if (fHWGeometryState.fArrayPtrsDirty || posChange ||
- newColorOffset != oldColorOffset) {
- GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
+ GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
+ } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
+ GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
}
} else if (oldColorOffset > 0) {
GR_GL(DisableClientState(GL_COLOR_ARRAY));
diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h
index 85db830..abb11aa 100644
--- a/gpu/src/GrGpuGLFixed.h
+++ b/gpu/src/GrGpuGLFixed.h
@@ -25,24 +25,24 @@
public:
GrGpuGLFixed();
virtual ~GrGpuGLFixed();
-
+
virtual void resetContext();
protected:
// overrides from GrGpu
virtual bool flushGraphicsState(PrimitiveType type);
- virtual void setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount);
+ virtual void setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount);
private:
void resetContextHelper();
// when the texture is GL_RGBA we set the GL_COMBINE texture
// environment rgb operand 0 to be GL_COLOR to modulate each incoming
- // R,G, & B by the texture's R, G, & B. When the texture is alpha-only we
- // set the operand to GL_ALPHA so that the incoming frag's R, G, &B are all
+ // R,G, & B by the texture's R, G, & B. When the texture is alpha-only we
+ // set the operand to GL_ALPHA so that the incoming frag's R, G, &B are all
// modulated by the texture's A.
enum TextureEnvRGBOperands {
kAlpha_TextureEnvRGBOperand,
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index b3bfc9a..cf41b1d 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -546,7 +546,7 @@
fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
fHWGeometryState.fVertexLayout = 0;
- fHWGeometryState.fPositionPtr = (void*) ~0;
+ fHWGeometryState.fVertexOffset = ~0;
GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
GR_GL(EnableVertexAttribArray(GR_GL_POS_ATTR_LOCATION));
@@ -838,10 +838,10 @@
return true;
}
-void GrGpuGLShaders::setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrGpuGLShaders::setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount) {
int newColorOffset;
int newTexCoordOffsets[kNumStages];
@@ -854,10 +854,11 @@
GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
oldTexCoordOffsets,
&oldColorOffset);
+ bool indexed = NULL == startIndex;
- const GLvoid* posPtr = setBuffersAndGetVertexStart(newStride, startVertex,
- startIndex, vertexCount,
- indexCount);
+ int extraVertexOffset;
+ int extraIndexOffset;
+ setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GLenum scalarType;
bool texCoordNorm;
@@ -869,49 +870,58 @@
texCoordNorm = false;
}
- bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
- bool scalarChange = (GrGLTextType != GrGLType) &&
- (kTextFormat_VertexLayoutBit &
- (fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout));
- bool strideChange = newStride != oldStride;
- bool posChange = baseChange || scalarChange || strideChange;
+ size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+ *startVertex = 0;
+ if (indexed) {
+ *startIndex += extraIndexOffset;
+ }
- if (fHWGeometryState.fArrayPtrsDirty || posChange) {
+ // all the Pointers must be set if any of these are true
+ bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
+ vertexOffset != fHWGeometryState.fVertexOffset ||
+ newStride != oldStride;
+
+ // position and tex coord offsets change if above conditions are true
+ // or the type/normalization changed based on text vs nontext type coords.
+ bool posAndTexChange = allOffsetsChange ||
+ (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
+ (kTextFormat_VertexLayoutBit &
+ (fHWGeometryState.fVertexLayout ^
+ fGeometrySrc.fVertexLayout)));
+
+ if (posAndTexChange) {
GR_GL(VertexAttribPointer(GR_GL_POS_ATTR_LOCATION, 2, scalarType,
- false, newStride, posPtr));
- fHWGeometryState.fPositionPtr = posPtr;
+ false, newStride, (GLvoid*)vertexOffset));
+ fHWGeometryState.fVertexOffset = vertexOffset;
}
// this class only supports one stage.
if (newTexCoordOffsets[0] > 0) {
- GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[0];
+ GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[0]);
if (oldTexCoordOffsets[0] <= 0) {
GR_GL(EnableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType,
- texCoordNorm, newStride, texCoordPtr));
- } else if (fHWGeometryState.fArrayPtrsDirty || posChange ||
- newTexCoordOffsets[0] != oldTexCoordOffsets[0]) {
+ texCoordNorm, newStride, texCoordOffset));
+ } else if (posAndTexChange ||
+ newTexCoordOffsets[0] != oldTexCoordOffsets[0]) {
GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType,
- texCoordNorm, newStride, texCoordPtr));
+ texCoordNorm, newStride, texCoordOffset));
}
} else if (oldTexCoordOffsets[0] > 0) {
GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
}
if (newColorOffset > 0) {
- GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+ GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset);
if (oldColorOffset <= 0) {
GR_GL(EnableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
GR_GL(VertexAttribPointer(GR_GL_COL_ATTR_LOCATION, 4,
GL_UNSIGNED_BYTE,
- true, newStride, colorPtr));
- }
- if (fHWGeometryState.fArrayPtrsDirty || posChange ||
- newColorOffset != oldColorOffset) {
+ true, newStride, colorOffset));
+ } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
GR_GL(VertexAttribPointer(GR_GL_COL_ATTR_LOCATION, 4,
GL_UNSIGNED_BYTE,
- true, newStride, colorPtr));
+ true, newStride, colorOffset));
}
} else if (oldColorOffset > 0) {
GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
diff --git a/gpu/src/GrGpuGLShaders.h b/gpu/src/GrGpuGLShaders.h
index e5a5665..a048e93 100644
--- a/gpu/src/GrGpuGLShaders.h
+++ b/gpu/src/GrGpuGLShaders.h
@@ -25,7 +25,7 @@
public:
GrGpuGLShaders();
virtual ~GrGpuGLShaders();
-
+
virtual void resetContext();
// type of colors used by a program
@@ -37,27 +37,27 @@
protected:
// overrides from GrGpu
virtual bool flushGraphicsState(PrimitiveType type);
- virtual void setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount);
-
+ virtual void setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount);
+
private:
void resetContextHelper();
-
+
// sets the texture matrix uniform for currently bound program
- void flushTexMatrix(GLint location,
+ void flushTexMatrix(GLint location,
GrGLTexture::Orientation orientation);
// sets the MVP matrix uniform for currently bound program
void flushMatrix(GLint location);
-
+
void flushTwoPointRadial(GLint paramsLocation, const GrSamplerState&);
-
+
// reads shader from array and compiles it with GL, returns shader ID or 0 if failed
GLuint loadShader(GLenum type, const char* src);
-
+
struct ProgramData;
- // creates a GL program with two shaders attached.
+ // creates a GL program with two shaders attached.
// Gets the relevant uniform locations.
// Sets the texture sampler if present to texture 0
// Binds the program
@@ -74,17 +74,17 @@
void flushProgram(PrimitiveType type);
enum Programs {
- // use vertex coordinates
+ // use vertex coordinates
kTextureVertCoords_Program = 0,
kTextureVertCoordsProj_Program,
-
+
// use separate tex coords
kTextureTexCoords_Program,
kTextureTexCoordsProj_Program,
// constant color texture, no proj
// verts as a tex coords
- kTextureVertCoordsNoColor_Program,
+ kTextureVertCoordsNoColor_Program,
// constant color texture, no proj
// separate tex coords
@@ -99,12 +99,12 @@
// programs for sweep texture lookup
kSweepTextureVertCoords_Program,
- kSweepTextureTexCoords_Program,
-
+ kSweepTextureTexCoords_Program,
+
// programs for two-point radial lookup
kTwoPointRadialTextureVertCoords_Program,
kTwoPointRadialTextureTexCoords_Program,
-
+
// color only drawing
kNoTexture_Program,
@@ -113,23 +113,23 @@
// Records per-program information
// we can specify the attribute locations so that they are constant
- // across our shaders. But the driver determines the uniform locations
+ // across our shaders. But the driver determines the uniform locations
// at link time. We don't need to remember the sampler uniform location
// because we will bind a texture slot to it and never change it
- // Uniforms are program-local so we can't rely on fHWState to hold the
+ // Uniforms are program-local so we can't rely on fHWState to hold the
// previous uniform state after a program change.
struct ProgramData {
// IDs
GLuint fVShaderID;
GLuint fFShaderID;
GLuint fProgramID;
-
+
// shader uniform locations (-1 if shader doesn't use them)
GLint fMatrixLocation;
GLint fTexMatrixLocation;
GLint fColorLocation;
GLint fTwoPointParamsLocation;
-
+
ColorType fColorType;
// these reflect the current values of uniforms
@@ -142,10 +142,10 @@
GrScalar fRadial2Radius0;
bool fRadial2PosRoot;
};
-
+
ProgramData fPrograms[kProgramCount];
Programs fHWProgram;
-
+
GrGLTexture::Orientation fTextureOrientation;
typedef GrGpuGL INHERITED;
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
index 81f83c9..d423ee2 100644
--- a/gpu/src/GrGpuGLShaders2.cpp
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -983,7 +983,7 @@
// Must initialize all fields or cache will have false negatives!
desc->fVertexLayout = fGeometrySrc.fVertexLayout;
-
+
desc->fOptFlags = 0;
if (kPoints_PrimitiveType != primType) {
desc->fOptFlags |= ProgramDesc::kNotPoints_OptFlagBit;
@@ -1112,7 +1112,7 @@
fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
fHWGeometryState.fVertexLayout = 0;
- fHWGeometryState.fPositionPtr = (void*) ~0;
+ fHWGeometryState.fVertexOffset = ~0;
GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
for (int t = 0; t < kMaxTexCoords; ++t) {
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
@@ -1315,10 +1315,10 @@
return true;
}
-void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrGpuGLShaders2::setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount) {
int newColorOffset;
int newTexCoordOffsets[kMaxTexCoords];
@@ -1331,10 +1331,11 @@
GLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
oldTexCoordOffsets,
&oldColorOffset);
+ bool indexed = NULL != startIndex;
- const GLvoid* posPtr = setBuffersAndGetVertexStart(newStride, startVertex,
- startIndex, vertexCount,
- indexCount);
+ int extraVertexOffset;
+ int extraIndexOffset;
+ setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GLenum scalarType;
bool texCoordNorm;
@@ -1346,31 +1347,42 @@
texCoordNorm = false;
}
- bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
- bool scalarChange = (GrGLTextType != GrGLType) &&
- (kTextFormat_VertexLayoutBit &
- (fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout));
- bool strideChange = newStride != oldStride;
- bool posChange = baseChange || scalarChange || strideChange;
+ size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+ *startVertex = 0;
+ if (indexed) {
+ *startIndex += extraIndexOffset;
+ }
- if (fHWGeometryState.fArrayPtrsDirty || posChange) {
+ // all the Pointers must be set if any of these are true
+ bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
+ vertexOffset != fHWGeometryState.fVertexOffset ||
+ newStride != oldStride;
+
+ // position and tex coord offsets change if above conditions are true
+ // or the type/normalization changed based on text vs nontext type coords.
+ bool posAndTexChange = allOffsetsChange ||
+ (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
+ (kTextFormat_VertexLayoutBit &
+ (fHWGeometryState.fVertexLayout ^
+ fGeometrySrc.fVertexLayout)));
+
+ if (posAndTexChange) {
GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
- false, newStride, posPtr));
- fHWGeometryState.fPositionPtr = posPtr;
+ false, newStride, (GLvoid*)vertexOffset));
+ fHWGeometryState.fVertexOffset = vertexOffset;
}
for (int t = 0; t < kMaxTexCoords; ++t) {
if (newTexCoordOffsets[t] > 0) {
- GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[t];
+ GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[t]);
if (oldTexCoordOffsets[t] <= 0) {
GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
- texCoordNorm, newStride, texCoordPtr));
- } else if (fHWGeometryState.fArrayPtrsDirty || posChange ||
- newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
+ texCoordNorm, newStride, texCoordOffset));
+ } else if (posAndTexChange ||
+ newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
- texCoordNorm, newStride, texCoordPtr));
+ texCoordNorm, newStride, texCoordOffset));
}
} else if (oldTexCoordOffsets[t] > 0) {
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
@@ -1378,23 +1390,23 @@
}
if (newColorOffset > 0) {
- GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+ GLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
if (oldColorOffset <= 0) {
GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
GL_UNSIGNED_BYTE,
- true, newStride, colorPtr));
- } else if (fHWGeometryState.fArrayPtrsDirty || posChange ||
- newColorOffset != oldColorOffset) {
+ true, newStride, colorOffset));
+ } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
GL_UNSIGNED_BYTE,
- true, newStride, colorPtr));
+ true, newStride, colorOffset));
}
} else if (oldColorOffset > 0) {
GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
}
fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fArrayPtrsDirty = false;
}
#endif
diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h
index bba63f6..bb710e3 100644
--- a/gpu/src/GrGpuGLShaders2.h
+++ b/gpu/src/GrGpuGLShaders2.h
@@ -31,10 +31,10 @@
protected:
// overrides from GrGpu
virtual bool flushGraphicsState(PrimitiveType type);
- virtual void setupGeometry(uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount);
+ virtual void setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount);
private:
@@ -42,7 +42,7 @@
// sets the texture matrix uniform for currently bound program
void flushTextureMatrix(int stage);
-
+
// sets the MVP matrix uniform for currently bound program
void flushViewMatrix();
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
index 494f227..49b8901 100644
--- a/gpu/src/GrInOrderDrawBuffer.cpp
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -17,25 +17,27 @@
#include "GrInOrderDrawBuffer.h"
#include "GrTexture.h"
-#include "GrVertexBufferAllocPool.h"
+#include "GrBufferAllocPool.h"
#include "GrGpu.h"
-GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* pool) :
+GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
+ GrIndexBufferAllocPool* indexPool) :
fDraws(DRAWS_BLOCK_SIZE, fDrawsStorage),
fStates(STATES_BLOCK_SIZE, fStatesStorage),
fClips(CLIPS_BLOCK_SIZE, fClipsStorage),
fClipChanged(true),
- fCPUVertices((NULL == pool) ? 0 : VERTEX_BLOCK_SIZE),
- fBufferVertices(pool),
- fIndices(INDEX_BLOCK_SIZE),
- fCurrReservedVertices(NULL),
- fCurrReservedIndices(NULL),
- fCurrVertexBuffer(NULL),
+ fVertexPool(*vertexPool),
+ fCurrPoolVertexBuffer(NULL),
+ fCurrPoolStartVertex(0),
+ fIndexPool(*indexPool),
+ fCurrPoolIndexBuffer(NULL),
+ fCurrPoolStartIndex(0),
fReservedVertexBytes(0),
fReservedIndexBytes(0),
fUsedReservedVertexBytes(0),
fUsedReservedIndexBytes(0) {
- GrAssert(NULL == pool || pool->getGpu()->supportsBufferLocking());
+ GrAssert(NULL != vertexPool);
+ GrAssert(NULL != indexPool);
}
GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
@@ -47,108 +49,95 @@
this->setClip(target.getClip());
}
-void GrInOrderDrawBuffer::drawIndexed(PrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrInOrderDrawBuffer::drawIndexed(PrimitiveType primitiveType,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
if (!vertexCount || !indexCount) {
return;
}
Draw& draw = fDraws.push_back();
- draw.fType = type;
+ draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
draw.fStartIndex = startIndex;
draw.fVertexCount = vertexCount;
draw.fIndexCount = indexCount;
draw.fClipChanged = grabClip();
- draw.fStateChange = grabState();
+ draw.fStateChanged = grabState();
draw.fVertexLayout = fGeometrySrc.fVertexLayout;
switch (fGeometrySrc.fVertexSrc) {
- case kArray_GeometrySrcType:
- draw.fUseVertexBuffer = false;
- draw.fVertexArray = fGeometrySrc.fVertexArray;
- break;
- case kReserved_GeometrySrcType: {
- draw.fUseVertexBuffer = NULL != fBufferVertices;
- if (draw.fUseVertexBuffer) {
- draw.fVertexBuffer = fCurrVertexBuffer;
- draw.fStartVertex += fCurrStartVertex;
- } else {
- draw.fVertexArray = fCurrReservedVertices;
- }
- size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
- vertexBytes);
- } break;
case kBuffer_GeometrySrcType:
- draw.fUseVertexBuffer = true;
draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
break;
+ case kReserved_GeometrySrcType: {
+ size_t vertexBytes = (vertexCount + startVertex) *
+ VertexSize(fGeometrySrc.fVertexLayout);
+ fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
+ vertexBytes);
+ } // fallthrough
+ case kArray_GeometrySrcType:
+ draw.fVertexBuffer = fCurrPoolVertexBuffer;
+ draw.fStartVertex += fCurrPoolStartVertex;
+ break;
+ default:
+ GrCrash("unknown geom src type");
}
switch (fGeometrySrc.fIndexSrc) {
- case kArray_GeometrySrcType:
- draw.fUseIndexBuffer = false;
- draw.fIndexArray = fGeometrySrc.fIndexArray;
- break;
- case kReserved_GeometrySrcType: {
- draw.fUseIndexBuffer = false;
- draw.fIndexArray = fCurrReservedIndices;
- size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
- fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
- } break;
case kBuffer_GeometrySrcType:
- draw.fUseIndexBuffer = true;
draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
break;
+ case kReserved_GeometrySrcType: {
+ size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
+ fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
+ } // fallthrough
+ case kArray_GeometrySrcType:
+ draw.fIndexBuffer = fCurrPoolIndexBuffer;
+ draw.fStartIndex += fCurrPoolStartVertex;
+ break;
+ default:
+ GrCrash("unknown geom src type");
}
}
-void GrInOrderDrawBuffer::drawNonIndexed(PrimitiveType type,
- uint32_t startVertex,
- uint32_t vertexCount) {
+void GrInOrderDrawBuffer::drawNonIndexed(PrimitiveType primitiveType,
+ int startVertex,
+ int vertexCount) {
if (!vertexCount) {
return;
}
Draw& draw = fDraws.push_back();
- draw.fType = type;
+ draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
draw.fStartIndex = 0;
draw.fVertexCount = vertexCount;
draw.fIndexCount = 0;
draw.fClipChanged = grabClip();
- draw.fStateChange = grabState();
+ draw.fStateChanged = grabState();
draw.fVertexLayout = fGeometrySrc.fVertexLayout;
switch (fGeometrySrc.fVertexSrc) {
- case kArray_GeometrySrcType:
- draw.fUseVertexBuffer = false;
- draw.fVertexArray = fGeometrySrc.fVertexArray;
- break;
- case kReserved_GeometrySrcType: {
- draw.fUseVertexBuffer = NULL != fBufferVertices;
- if (draw.fUseVertexBuffer) {
- draw.fVertexBuffer = fCurrVertexBuffer;
- draw.fStartVertex += fCurrStartVertex;
- } else {
- draw.fVertexArray = fCurrReservedVertices;
- }
- size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
- vertexBytes);
- } break;
case kBuffer_GeometrySrcType:
- draw.fUseVertexBuffer = true;
draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
break;
+ case kReserved_GeometrySrcType: {
+ size_t vertexBytes = (vertexCount + startVertex) *
+ VertexSize(fGeometrySrc.fVertexLayout);
+ fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
+ vertexBytes);
+ } // fallthrough
+ case kArray_GeometrySrcType:
+ draw.fVertexBuffer = fCurrPoolVertexBuffer;
+ draw.fStartVertex += fCurrPoolStartVertex;
+ break;
+ default:
+ GrCrash("unknown geom src type");
}
}
@@ -165,12 +154,10 @@
}
fDraws.reset();
fStates.reset();
- if (NULL == fBufferVertices) {
- fCPUVertices.reset();
- } else {
- fBufferVertices->reset();
- }
- fIndices.reset();
+
+ fVertexPool.reset();
+ fIndexPool.reset();
+
fClips.reset();
}
@@ -183,9 +170,8 @@
return;
}
- if (NULL != fBufferVertices) {
- fBufferVertices->unlock();
- }
+ fVertexPool.unlock();
+ fIndexPool.unlock();
GrDrawTarget::AutoStateRestore asr(target);
GrDrawTarget::AutoClipRestore acr(target);
@@ -198,7 +184,7 @@
for (uint32_t i = 0; i < numDraws; ++i) {
const Draw& draw = fDraws[i];
- if (draw.fStateChange) {
+ if (draw.fStateChanged) {
++currState;
target->restoreDrawState(fStates[currState]);
}
@@ -206,52 +192,58 @@
++currClip;
target->setClip(fClips[currClip]);
}
- if (draw.fUseVertexBuffer) {
- target->setVertexSourceToBuffer(draw.fVertexBuffer, draw.fVertexLayout);
- } else {
- target->setVertexSourceToArray(draw.fVertexArray, draw.fVertexLayout);
- }
+ uint32_t vertexReserveCount = 0;
+ uint32_t indexReserveCount = 0;
+
+ target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
+
if (draw.fIndexCount) {
- if (draw.fUseIndexBuffer) {
- target->setIndexSourceToBuffer(draw.fIndexBuffer);
- } else {
- target->setIndexSourceToArray(draw.fIndexArray);
- }
- target->drawIndexed(draw.fType,
+ target->setIndexSourceToBuffer(draw.fIndexBuffer);
+ }
+
+ if (draw.fIndexCount) {
+ target->drawIndexed(draw.fPrimitiveType,
draw.fStartVertex,
draw.fStartIndex,
draw.fVertexCount,
draw.fIndexCount);
} else {
- target->drawNonIndexed(draw.fType,
+ target->drawNonIndexed(draw.fPrimitiveType,
draw.fStartVertex,
draw.fVertexCount);
}
+ if (vertexReserveCount || indexReserveCount) {
+ target->releaseReservedGeometry();
+ }
}
}
bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
- int32_t* vertexCount,
- int32_t* indexCount) const {
+ int* vertexCount,
+ int* indexCount) const {
+ // we will recommend a flush if the data could fit in a single
+ // preallocated buffer but none are left and it can't fit
+ // in the current buffer (which may not be prealloced).
bool flush = false;
if (NULL != indexCount) {
- *indexCount = -1;
+ int32_t currIndices = fIndexPool.currentBufferIndices();
+ if (*indexCount > currIndices &&
+ (!fIndexPool.preallocatedBuffersRemaining() &&
+ *indexCount <= fIndexPool.preallocatedBufferIndices())) {
+
+ flush = true;
+ }
+ *indexCount = currIndices;
}
if (NULL != vertexCount) {
- if (NULL != fBufferVertices) {
- // we will recommend a flush if the verts could fit in a single
- // preallocated vertex buffer but none are left and it can't fit
- // in the current VB (which may not be prealloced).
- if (*vertexCount > fBufferVertices->currentBufferVertices(vertexLayout) &&
- (!fBufferVertices->preallocatedBuffersRemaining() &&
- *vertexCount <= fBufferVertices->preallocatedBufferVertices(vertexLayout))) {
+ int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
+ if (*vertexCount > currVertices &&
+ (!fVertexPool.preallocatedBuffersRemaining() &&
+ *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
- flush = true;
- }
- *vertexCount = fBufferVertices->currentBufferVertices(vertexLayout);
- } else {
- *vertexCount = -1;
+ flush = true;
}
+ *vertexCount = currVertices;
}
return flush;
}
@@ -259,31 +251,34 @@
bool GrInOrderDrawBuffer::acquireGeometryHelper(GrVertexLayout vertexLayout,
void** vertices,
void** indices) {
+ GrAssert(!fReservedGeometry.fLocked);
if (fReservedGeometry.fVertexCount) {
+ GrAssert(NULL != vertices);
+ GrAssert(0 == fReservedVertexBytes);
+ GrAssert(0 == fUsedReservedVertexBytes);
+
fReservedVertexBytes = VertexSize(vertexLayout) *
fReservedGeometry.fVertexCount;
- if (NULL == fBufferVertices) {
- fCurrReservedVertices = fCPUVertices.alloc(fReservedVertexBytes);
- } else {
- fCurrReservedVertices = fBufferVertices->alloc(vertexLayout,
- fReservedGeometry.fVertexCount,
- &fCurrVertexBuffer,
- &fCurrStartVertex);
- }
- if (NULL != vertices) {
- *vertices = fCurrReservedVertices;
- }
- if (NULL == fCurrReservedVertices) {
+ *vertices = fVertexPool.makeSpace(vertexLayout,
+ fReservedGeometry.fVertexCount,
+ &fCurrPoolVertexBuffer,
+ &fCurrPoolStartVertex);
+ if (NULL == *vertices) {
return false;
}
}
if (fReservedGeometry.fIndexCount) {
- fReservedIndexBytes = sizeof(uint16_t) * fReservedGeometry.fIndexCount;
- fCurrReservedIndices = fIndices.alloc(fReservedIndexBytes);
- if (NULL != indices) {
- *indices = fCurrReservedIndices;
- }
- if (NULL == fCurrReservedIndices) {
+ GrAssert(NULL != indices);
+ GrAssert(0 == fReservedIndexBytes);
+ GrAssert(0 == fUsedReservedIndexBytes);
+
+ *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
+ &fCurrPoolIndexBuffer,
+ &fCurrPoolStartIndex);
+ if (NULL == *indices) {
+ fVertexPool.putBack(fReservedVertexBytes);
+ fReservedVertexBytes = 0;
+ fCurrPoolVertexBuffer = NULL;
return false;
}
}
@@ -295,22 +290,45 @@
GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
- if (NULL == fBufferVertices) {
- fCPUVertices.release(vertexSlack);
- } else {
- fBufferVertices->release(vertexSlack);
- GR_DEBUGCODE(fCurrVertexBuffer = NULL);
- GR_DEBUGCODE(fCurrStartVertex = 0);
- }
+ fVertexPool.putBack(vertexSlack);
- fIndices.release(fReservedIndexBytes - fUsedReservedIndexBytes);
+ size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
+ fIndexPool.putBack(indexSlack);
- fCurrReservedVertices = NULL;
- fCurrReservedIndices = NULL;
fReservedVertexBytes = 0;
fReservedIndexBytes = 0;
fUsedReservedVertexBytes = 0;
fUsedReservedIndexBytes = 0;
+ fCurrPoolVertexBuffer = 0;
+ fCurrPoolStartVertex = 0;
+
+}
+
+void GrInOrderDrawBuffer::setVertexSourceToArrayHelper(const void* vertexArray,
+ int vertexCount) {
+ GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+#if GR_DEBUG
+ bool success =
+#endif
+ fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
+ vertexCount,
+ vertexArray,
+ &fCurrPoolVertexBuffer,
+ &fCurrPoolStartVertex);
+ GR_DEBUGASSERT(success);
+}
+
+void GrInOrderDrawBuffer::setIndexSourceToArrayHelper(const void* indexArray,
+ int indexCount) {
+ GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+#if GR_DEBUG
+ bool success =
+#endif
+ fIndexPool.appendIndices(indexCount,
+ indexArray,
+ &fCurrPoolIndexBuffer,
+ &fCurrPoolStartIndex);
+ GR_DEBUGASSERT(success);
}
bool GrInOrderDrawBuffer::grabState() {
diff --git a/gpu/src/GrVertexBufferAllocPool.cpp b/gpu/src/GrVertexBufferAllocPool.cpp
deleted file mode 100644
index 360a086..0000000
--- a/gpu/src/GrVertexBufferAllocPool.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- Copyright 2010 Google Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-
-#include "GrVertexBufferAllocPool.h"
-#include "GrVertexBuffer.h"
-#include "GrGpu.h"
-
-#define GrVertexBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 10)
-
-GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
- size_t blockSize,
- int preallocBufferCnt) :
- fBlocks(GrMax(8, 2*preallocBufferCnt)) {
- GrAssert(NULL != gpu);
- fGpu = gpu;
- fGpu->ref();
- fBufferPtr = NULL;
- fMinBlockSize = GrMax(GrVertexBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
-
- fPreallocBuffersInUse = 0;
- fFirstPreallocBuffer = 0;
- for (int i = 0; i < preallocBufferCnt; ++i) {
- GrVertexBuffer* buffer = gpu->createVertexBuffer(fMinBlockSize, true);
- if (NULL != buffer) {
- *fPreallocBuffers.append() = buffer;
- buffer->ref();
- }
- }
-}
-
-GrVertexBufferAllocPool::~GrVertexBufferAllocPool() {
- fPreallocBuffers.unrefAll();
- while (!fBlocks.empty()) {
- destroyBlock();
- }
- fGpu->unref();
-}
-
-void GrVertexBufferAllocPool::reset() {
- while (!fBlocks.empty()) {
- destroyBlock();
- }
- if (fPreallocBuffers.count()) {
- // must set this after above loop.
- fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) %
- fPreallocBuffers.count();
- }
- GrAssert(0 == fPreallocBuffersInUse);
-}
-
-void GrVertexBufferAllocPool::unlock() {
- GrAssert((NULL == fBufferPtr) ? (!fBlocks.empty() ||
- !fBlocks.back().fVertexBuffer->isLocked()) :
- (!fBlocks.empty() &&
- fBlocks.back().fVertexBuffer->isLocked()));
- if (NULL != fBufferPtr) {
- GrAssert(!fBlocks.empty());
- GrAssert(fBlocks.back().fVertexBuffer->isLocked());
- fBufferPtr = NULL;
- fBlocks.back().fVertexBuffer->unlock();
- }
-#if GR_DEBUG
- for (uint32_t i = 0; i < fBlocks.count(); ++i) {
- GrAssert(!fBlocks[i].fVertexBuffer->isLocked());
- }
-#endif
-}
-
-void* GrVertexBufferAllocPool::alloc(GrVertexLayout layout,
- uint32_t vertexCount,
- GrVertexBuffer** buffer,
- uint32_t* startVertex) {
- GrAssert(NULL != buffer);
- size_t vSize = GrDrawTarget::VertexSize(layout);
- size_t bytes = vSize * vertexCount;
-
- if (NULL != fBufferPtr) {
- GrAssert(!fBlocks.empty());
- GrAssert(fBlocks.back().fVertexBuffer->isLocked());
- BufferBlock& back = fBlocks.back();
- uint32_t usedBytes = back.fVertexBuffer->size() - back.fBytesFree;
- uint32_t pad = GrUIAlignUpPad(usedBytes,
- GrDrawTarget::VertexSize(layout));
- if ((bytes + pad) <= back.fBytesFree) {
- usedBytes += pad;
- *startVertex = usedBytes / vSize;
- *buffer = back.fVertexBuffer;
- back.fBytesFree -= bytes + pad;
- return (void*)((intptr_t)fBufferPtr + usedBytes);
- }
- }
-
- if (!createBlock(GrMax(bytes, fMinBlockSize))) {
- return NULL;
- }
- *startVertex = 0;
- GrAssert(NULL != fBufferPtr);
- BufferBlock& back = fBlocks.back();
- *buffer = back.fVertexBuffer;
- back.fBytesFree -= bytes;
- return fBufferPtr;
-}
-
-int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
- if (NULL != fBufferPtr) {
- GrAssert(!fBlocks.empty());
- const BufferBlock& back = fBlocks.back();
- GrAssert(back.fVertexBuffer->isLocked());
- return back.fBytesFree / GrDrawTarget::VertexSize(layout);
- } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
- return fMinBlockSize / GrDrawTarget::VertexSize(layout);
- }
- return 0;
-}
-
-int GrVertexBufferAllocPool::preallocatedBuffersRemaining() const {
- return fPreallocBuffers.count() - fPreallocBuffersInUse;
-}
-
-int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
- return fPreallocBuffers.count() ?
- (fMinBlockSize / GrDrawTarget::VertexSize(layout)) :
- 0;
-}
-
-int GrVertexBufferAllocPool::preallocatedBufferCount() const {
- return fPreallocBuffers.count();
-}
-
-void GrVertexBufferAllocPool::release(size_t bytes) {
- if (NULL != fBufferPtr) {
- GrAssert(!fBlocks.empty());
- BufferBlock& back = fBlocks.back();
- GrAssert(back.fVertexBuffer->isLocked());
- size_t bytesUsed = back.fVertexBuffer->size() - back.fBytesFree;
- if (bytes >= bytesUsed) {
- destroyBlock();
- bytes -= bytesUsed;
- } else {
- back.fBytesFree += bytes;
- return;
- }
- }
- GrAssert(NULL == fBufferPtr);
- GrAssert(fBlocks.empty() ||
- !fBlocks.back().fVertexBuffer->isLocked());
- // we don't honor release if it is within an already unlocked VB
- // Our VB semantics say locking a VB discards its previous content
- while (!fBlocks.empty() &&
- bytes >= fBlocks.back().fVertexBuffer->size()) {
- bytes -= fBlocks.back().fVertexBuffer->size();
- destroyBlock();
- }
-}
-
-bool GrVertexBufferAllocPool::createBlock(size_t size) {
- GrAssert(size >= GrVertexBufferAllocPool_MIN_BLOCK_SIZE);
-
- BufferBlock& block = fBlocks.push_back();
-
- if (size == fMinBlockSize &&
- fPreallocBuffersInUse < fPreallocBuffers.count()) {
-
- uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) %
- fPreallocBuffers.count();
- block.fVertexBuffer = fPreallocBuffers[nextBuffer];
- block.fVertexBuffer->ref();
- ++fPreallocBuffersInUse;
- } else {
- block.fVertexBuffer = fGpu->createVertexBuffer(size, true);
- if (NULL == block.fVertexBuffer) {
- fBlocks.pop_back();
- return false;
- }
- }
-
- block.fBytesFree = size;
- if (NULL != fBufferPtr) {
- GrAssert(fBlocks.count() > 1);
- BufferBlock& prev = fBlocks.fromBack(1);
- GrAssert(prev.fVertexBuffer->isLocked());
- fBufferPtr = NULL;
- prev.fVertexBuffer->unlock();
- }
- fBufferPtr = block.fVertexBuffer->lock();
- return true;
-}
-
-void GrVertexBufferAllocPool::destroyBlock() {
- GrAssert(!fBlocks.empty());
-
- BufferBlock& block = fBlocks.back();
- if (fPreallocBuffersInUse > 0) {
- uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
- fFirstPreallocBuffer +
- (fPreallocBuffers.count() - 1)) %
- fPreallocBuffers.count();
- if (block.fVertexBuffer == fPreallocBuffers[prevPreallocBuffer]) {
- --fPreallocBuffersInUse;
- }
- }
- block.fVertexBuffer->unref();
- fBlocks.pop_back();
- fBufferPtr = NULL;
-}
-
-
diff --git a/gpu/src/gr_files.mk b/gpu/src/gr_files.mk
index 67d2838..4c06345 100644
--- a/gpu/src/gr_files.mk
+++ b/gpu/src/gr_files.mk
@@ -22,4 +22,4 @@
GrTextureCache.cpp \
GrTextContext.cpp \
GrTextStrike.cpp \
- GrVertexBufferAllocPool.cpp
+ GrBufferAllocPool.cpp