Refactor GrDrawTarget vertex/index api
Review URL: http://codereview.appspot.com/4631056/
git-svn-id: http://skia.googlecode.com/svn/trunk@1662 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrBufferAllocPool.cpp b/gpu/src/GrBufferAllocPool.cpp
index d786b02..73d707f 100644
--- a/gpu/src/GrBufferAllocPool.cpp
+++ b/gpu/src/GrBufferAllocPool.cpp
@@ -23,9 +23,10 @@
#if GR_DEBUG
#define VALIDATE validate
#else
- #define VALIDATE()
+ static void VALIDATE(bool x = false) {}
#endif
+// page size
#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
@@ -45,6 +46,8 @@
fBufferPtr = NULL;
fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
+ fBytesInUse = 0;
+
fPreallocBuffersInUse = 0;
fFirstPreallocBuffer = 0;
for (int i = 0; i < preallocBufferCnt; ++i) {
@@ -80,6 +83,7 @@
void GrBufferAllocPool::reset() {
VALIDATE();
+ fBytesInUse = 0;
if (fBlocks.count()) {
GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
if (buffer->isLocked()) {
@@ -116,7 +120,7 @@
}
#if GR_DEBUG
-void GrBufferAllocPool::validate() const {
+void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
if (NULL != fBufferPtr) {
GrAssert(!fBlocks.empty());
if (fBlocks.back().fBuffer->isLocked()) {
@@ -129,9 +133,23 @@
} else {
GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
}
+ size_t bytesInUse = 0;
for (int i = 0; i < fBlocks.count() - 1; ++i) {
GrAssert(!fBlocks[i].fBuffer->isLocked());
}
+ for (int i = 0; i < fBlocks.count(); ++i) {
+ size_t bytes = fBlocks[i].fBuffer->size() - fBlocks[i].fBytesFree;
+ bytesInUse += bytes;
+ GrAssert(bytes || unusedBlockAllowed);
+ }
+
+ GrAssert(bytesInUse == fBytesInUse);
+ if (unusedBlockAllowed) {
+ GrAssert((fBytesInUse && !fBlocks.empty()) ||
+ (!fBytesInUse && (fBlocks.count() < 2)));
+ } else {
+ GrAssert((0 == fBytesInUse) == fBlocks.empty());
+ }
}
#endif
@@ -154,20 +172,27 @@
*offset = usedBytes;
*buffer = back.fBuffer;
back.fBytesFree -= size + pad;
+ fBytesInUse += size;
return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
}
}
+ // We could honor the space request using updateSubData on the current VB
+ // (if there is room). But we don't currently use draw calls to GL that
+ // allow the driver to know that previously issued draws won't read from
+ // the part of the buffer we update.
+
if (!createBlock(size)) {
return NULL;
}
- VALIDATE();
GrAssert(NULL != fBufferPtr);
*offset = 0;
BufferBlock& back = fBlocks.back();
*buffer = back.fBuffer;
back.fBytesFree -= size;
+ fBytesInUse += size;
+ VALIDATE();
return fBufferPtr;
}
@@ -194,29 +219,24 @@
void GrBufferAllocPool::putBack(size_t bytes) {
VALIDATE();
- if (NULL != fBufferPtr) {
- BufferBlock& back = fBlocks.back();
- size_t bytesUsed = back.fBuffer->size() - back.fBytesFree;
+
+ while (bytes) {
+ // caller shouldnt try to put back more than they've taken
+ GrAssert(!fBlocks.empty());
+ BufferBlock& block = fBlocks.back();
+ size_t bytesUsed = block.fBuffer->size() - block.fBytesFree;
if (bytes >= bytesUsed) {
- destroyBlock();
bytes -= bytesUsed;
+ fBytesInUse -= bytesUsed;
+ destroyBlock();
} else {
- back.fBytesFree += bytes;
- return;
+ block.fBytesFree += bytes;
+ fBytesInUse -= bytes;
+ bytes = 0;
+ break;
}
}
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) {
@@ -269,7 +289,7 @@
fBufferPtr = fCpuData.realloc(size);
}
- VALIDATE();
+ VALIDATE(true);
return true;
}
diff --git a/gpu/src/GrBufferAllocPool.h b/gpu/src/GrBufferAllocPool.h
index 7d70ebb..c18e36b 100644
--- a/gpu/src/GrBufferAllocPool.h
+++ b/gpu/src/GrBufferAllocPool.h
@@ -169,8 +169,10 @@
void destroyBlock();
void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
#if GR_DEBUG
- void validate() const;
+ void validate(bool unusedBlockAllowed = false) const;
#endif
+
+ size_t fBytesInUse;
GrGpu* fGpu;
bool fGpuIsReffed;
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index b5f9259..cc64058 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -18,6 +18,8 @@
#include "GrDrawTarget.h"
#include "GrGpuVertex.h"
#include "GrTexture.h"
+#include "GrVertexBuffer.h"
+#include "GrIndexBuffer.h"
namespace {
@@ -282,17 +284,33 @@
////////////////////////////////////////////////////////////////////////////////
-GrDrawTarget::GrDrawTarget() {
+#define DEBUG_INVAL_BUFFER 0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
+GrDrawTarget::GrDrawTarget()
+: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
#if GR_DEBUG
VertexLayoutUnitTest();
#endif
- fReservedGeometry.fLocked = false;
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
#if GR_DEBUG
- fReservedGeometry.fVertexCount = ~0;
- fReservedGeometry.fIndexCount = ~0;
+ geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
#endif
- fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
- fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+}
+
+GrDrawTarget::~GrDrawTarget() {
+ int popCnt = fGeoSrcStateStack.count() - 1;
+ while (popCnt) {
+ this->popGeometrySource();
+ --popCnt;
+ }
+ this->releasePreviousVertexSource();
+ this->releasePreviousIndexSource();
}
void GrDrawTarget::setClip(const GrClip& clip) {
@@ -429,39 +447,54 @@
fCurrDrawState = srcTarget.fCurrDrawState;
}
+bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ bool acquired = false;
+ if (vertexCount > 0) {
+ GrAssert(NULL != vertices);
+ this->releasePreviousVertexSource();
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
-bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout vertexLayout,
- uint32_t vertexCount,
- uint32_t indexCount,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- fReservedGeometry.fVertexCount = vertexCount;
- fReservedGeometry.fIndexCount = indexCount;
-
- fReservedGeometry.fLocked = this->onAcquireGeometry(vertexLayout,
- vertices,
- indices);
- if (fReservedGeometry.fLocked) {
- if (vertexCount) {
- fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
- fGeometrySrc.fVertexLayout = vertexLayout;
- } else if (NULL != vertices) {
- *vertices = NULL;
- }
- if (indexCount) {
- fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
- } else if (NULL != indices) {
- *indices = NULL;
- }
+ acquired = this->onReserveVertexSpace(vertexLayout,
+ vertexCount,
+ vertices);
}
- return fReservedGeometry.fLocked;
+ if (acquired) {
+ geoSrc.fVertexSrc = kReserved_GeometrySrcType;
+ geoSrc.fVertexCount = vertexCount;
+ geoSrc.fVertexLayout = vertexLayout;
+ } else if (NULL != vertices) {
+ *vertices = NULL;
+ }
+ return acquired;
+}
+
+bool GrDrawTarget::reserveIndexSpace(int indexCount,
+ void** indices) {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ bool acquired = false;
+ if (indexCount > 0) {
+ GrAssert(NULL != indices);
+ this->releasePreviousIndexSource();
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+
+ acquired = this->onReserveIndexSpace(indexCount, indices);
+ }
+ if (acquired) {
+ geoSrc.fIndexSrc = kReserved_GeometrySrcType;
+ geoSrc.fIndexCount = indexCount;
+ } else if (NULL != indices) {
+ *indices = NULL;
+ }
+ return acquired;
+
}
bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
int32_t* vertexCount,
int32_t* indexCount) const {
- GrAssert(!fReservedGeometry.fLocked);
if (NULL != vertexCount) {
*vertexCount = -1;
}
@@ -471,39 +504,199 @@
return false;
}
-void GrDrawTarget::releaseReservedGeometry() {
- GrAssert(fReservedGeometry.fLocked);
- this->onReleaseGeometry();
- fReservedGeometry.fLocked = false;
+void GrDrawTarget::releasePreviousVertexSource() {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ break;
+ case kArray_GeometrySrcType:
+ this->releaseVertexArray();
+ break;
+ case kReserved_GeometrySrcType:
+ this->releaseReservedVertexSpace();
+ break;
+ case kBuffer_GeometrySrcType:
+ geoSrc.fVertexBuffer->unref();
+#if GR_DEBUG
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ GrCrash("Unknown Vertex Source Type.");
+ break;
+ }
+}
+
+void GrDrawTarget::releasePreviousIndexSource() {
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fIndexSrc) {
+ case kNone_GeometrySrcType: // these two don't require
+ break;
+ case kArray_GeometrySrcType:
+ this->releaseIndexArray();
+ break;
+ case kReserved_GeometrySrcType:
+ this->releaseReservedIndexSpace();
+ break;
+ case kBuffer_GeometrySrcType:
+ geoSrc.fIndexBuffer->unref();
+#if GR_DEBUG
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ GrCrash("Unknown Index Source Type.");
+ break;
+ }
}
void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
const void* vertexArray,
int vertexCount) {
- fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
- fGeometrySrc.fVertexLayout = vertexLayout;
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kArray_GeometrySrcType;
+ geoSrc.fVertexLayout = vertexLayout;
+ geoSrc.fVertexCount = vertexCount;
this->onSetVertexSourceToArray(vertexArray, vertexCount);
}
void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
int indexCount) {
- fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kArray_GeometrySrcType;
+ geoSrc.fIndexCount = indexCount;
this->onSetIndexSourceToArray(indexArray, indexCount);
}
void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
const GrVertexBuffer* buffer) {
- fGeometrySrc.fVertexSrc = kBuffer_GeometrySrcType;
- fGeometrySrc.fVertexBuffer = buffer;
- fGeometrySrc.fVertexLayout = vertexLayout;
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
+ geoSrc.fVertexBuffer = buffer;
+ buffer->ref();
+ geoSrc.fVertexLayout = vertexLayout;
}
void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
- fGeometrySrc.fIndexSrc = kBuffer_GeometrySrcType;
- fGeometrySrc.fIndexBuffer = buffer;
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
+ geoSrc.fIndexBuffer = buffer;
+ buffer->ref();
}
-///////////////////////////////////////////////////////////////////////////////
+void GrDrawTarget::resetVertexSource() {
+ this->releasePreviousVertexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::resetIndexSource() {
+ this->releasePreviousIndexSource();
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::pushGeometrySource() {
+ this->geometrySourceWillPush();
+ GeometrySrcState& newState = fGeoSrcStateStack.push_back();
+ newState.fIndexSrc = kNone_GeometrySrcType;
+ newState.fVertexSrc = kNone_GeometrySrcType;
+#if GR_DEBUG
+ newState.fVertexCount = ~0;
+ newState.fVertexBuffer = (GrVertexBuffer*)~0;
+ newState.fIndexCount = ~0;
+ newState.fIndexBuffer = (GrIndexBuffer*)~0;
+#endif
+}
+
+void GrDrawTarget::popGeometrySource() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ // if popping last element then pops are unbalanced with pushes
+ GrAssert(fGeoSrcStateStack.count() > 1);
+
+ this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
+ this->releasePreviousVertexSource();
+ this->releasePreviousIndexSource();
+ fGeoSrcStateStack.pop_back();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
+ int startIndex, int vertexCount,
+ int indexCount) {
+#if GR_DEBUG
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ int maxVertex = startVertex + vertexCount;
+ int maxValidVertex;
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw indexed geom without vertex src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexBuffer->size() /
+ VertexSize(geoSrc.fVertexLayout);
+ break;
+ }
+ if (maxVertex > maxValidVertex) {
+ GrCrash("Indexed drawing outside valid vertex range.");
+ }
+ int maxIndex = startIndex + indexCount;
+ int maxValidIndex;
+ switch (geoSrc.fIndexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw indexed geom without index src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidIndex = geoSrc.fIndexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidIndex = geoSrc.fIndexBuffer->size() / sizeof(uint16_t);
+ break;
+ }
+ if (maxIndex > maxValidIndex) {
+ GrCrash("Indexed drawing outside valid index range.");
+ }
+#endif
+ this->onDrawIndexed(type, startVertex, startIndex,
+ vertexCount, indexCount);
+}
+
+
+void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
+ int startVertex,
+ int vertexCount) {
+#if GR_DEBUG
+ GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ int maxVertex = startVertex + vertexCount;
+ int maxValidVertex;
+ switch (geoSrc.fVertexSrc) {
+ case kNone_GeometrySrcType:
+ GrCrash("Attempting to draw non-indexed geom without vertex src.");
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexCount;
+ break;
+ case kBuffer_GeometrySrcType:
+ maxValidVertex = geoSrc.fVertexBuffer->size() /
+ VertexSize(geoSrc.fVertexLayout);
+ break;
+ }
+ if (maxVertex > maxValidVertex) {
+ GrCrash("Non-indexed drawing outside valid vertex range.");
+ }
+#endif
+ this->onDrawNonIndexed(type, startVertex, vertexCount);
+}
+
+////////////////////////////////////////////////////////////////////////////////
bool GrDrawTarget::canDisableBlend() const {
// If we compute a coverage value (using edge AA or a coverage stage) then
@@ -523,7 +716,7 @@
}
// If we have vertex color without alpha then we can't force blend off
- if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
+ if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
return false;
}
@@ -572,7 +765,8 @@
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
void GrDrawTarget::drawRect(const GrRect& rect,
const GrMatrix* matrix,
StageBitfield stageEnableBitfield,
@@ -648,7 +842,7 @@
}
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::AutoStateRestore::AutoStateRestore() {
fDrawTarget = NULL;
@@ -679,7 +873,7 @@
}
}
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
int stageMask) {
@@ -714,3 +908,62 @@
}
}
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
+ GrDrawTarget* target,
+ GrVertexLayout vertexLayout,
+ int vertexCount,
+ int indexCount) {
+ fTarget = NULL;
+ this->set(target, vertexLayout, vertexCount, indexCount);
+}
+
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
+ fTarget = NULL;
+}
+
+GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
+ this->reset();
+}
+
+bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
+ GrVertexLayout vertexLayout,
+ int vertexCount,
+ int indexCount) {
+ this->reset();
+ fTarget = target;
+ bool success = true;
+ if (NULL != fTarget) {
+ fTarget = target;
+ if (vertexCount > 0) {
+ success = target->reserveVertexSpace(vertexLayout,
+ vertexCount,
+ &fVertices);
+ if (!success) {
+ this->reset();
+ }
+ }
+ if (success && indexCount > 0) {
+ success = target->reserveIndexSpace(indexCount, &fIndices);
+ if (!success) {
+ this->reset();
+ }
+ }
+ }
+ GrAssert(success == (NULL != fTarget));
+ return success;
+}
+
+void GrDrawTarget::AutoReleaseGeometry::reset() {
+ if (NULL != fTarget) {
+ if (NULL != fVertices) {
+ fTarget->resetVertexSource();
+ }
+ if (NULL != fIndices) {
+ fTarget->resetIndexSource();
+ }
+ fTarget = NULL;
+ }
+}
+
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 4f260c7..db7de2c 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -33,27 +33,36 @@
extern void gr_run_unittests();
+#define DEBUG_INVAL_BUFFER 0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
GrGpu::GrGpu()
: f8bitPaletteSupport(false)
- , fCurrPoolVertexBuffer(NULL)
- , fCurrPoolStartVertex(0)
- , fCurrPoolIndexBuffer(NULL)
- , fCurrPoolStartIndex(0)
, fContext(NULL)
, fVertexPool(NULL)
, fIndexPool(NULL)
+ , fVertexPoolUseCnt(0)
+ , fIndexPoolUseCnt(0)
+ , fGeomPoolStateStack(&fGeoSrcStateStackStorage)
, fQuadIndexBuffer(NULL)
, fUnitSquareVertexBuffer(NULL)
, fDefaultPathRenderer(NULL)
, fClientPathRenderer(NULL)
, fContextIsDirty(true)
- , fVertexPoolInUse(false)
- , fIndexPoolInUse(false)
, fResourceHead(NULL) {
#if GR_DEBUG
//gr_run_unittests();
#endif
+
+ fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+ GeometryPoolState& poolState = fGeomPoolStateStack.back();
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+ poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
resetStats();
}
@@ -417,7 +426,7 @@
fClip.setFromRect(bounds);
AutoStateRestore asr(this);
- AutoInternalDrawGeomRestore aidgr(this);
+ AutoGeometryPush agp(this);
this->setViewMatrix(GrMatrix::I());
this->clearStencilClip(clipRect);
@@ -566,15 +575,36 @@
////////////////////////////////////////////////////////////////////////////////
-void GrGpu::drawIndexed(GrPrimitiveType type,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) {
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
- fReservedGeometry.fLocked);
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
- fReservedGeometry.fLocked);
+void GrGpu::geometrySourceWillPush() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ if (kArray_GeometrySrcType == geoSrc.fVertexSrc ||
+ kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
+ this->finalizeReservedVertices();
+ }
+ if (kArray_GeometrySrcType == geoSrc.fIndexSrc ||
+ kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
+ this->finalizeReservedIndices();
+ }
+ GeometryPoolState& newState = fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+ newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ newState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+ newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+ newState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
+}
+
+void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
+ // if popping last entry then pops are unbalanced with pushes
+ GrAssert(fGeomPoolStateStack.count() > 1);
+ fGeomPoolStateStack.pop_back();
+}
+
+void GrGpu::onDrawIndexed(GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
this->handleDirtyContext();
@@ -592,16 +622,13 @@
int sIndex = startIndex;
setupGeometry(&sVertex, &sIndex, vertexCount, indexCount);
- this->onDrawIndexed(type, sVertex, sIndex,
- vertexCount, indexCount);
+ this->onGpuDrawIndexed(type, sVertex, sIndex,
+ vertexCount, indexCount);
}
-void GrGpu::drawNonIndexed(GrPrimitiveType type,
+void GrGpu::onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) {
- GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
- fReservedGeometry.fLocked);
-
this->handleDirtyContext();
if (!this->setupClipAndFlushState(type)) {
@@ -615,7 +642,7 @@
int sVertex = startVertex;
setupGeometry(&sVertex, NULL, vertexCount, 0);
- this->onDrawNonIndexed(type, sVertex, vertexCount);
+ this->onGpuDrawNonIndexed(type, sVertex, vertexCount);
}
void GrGpu::finalizeReservedVertices() {
@@ -630,11 +657,12 @@
void GrGpu::prepareVertexPool() {
if (NULL == fVertexPool) {
+ GrAssert(0 == fVertexPoolUseCnt);
fVertexPool = new GrVertexBufferAllocPool(this, true,
VERTEX_POOL_VB_SIZE,
VERTEX_POOL_VB_COUNT);
fVertexPool->releaseGpuRef();
- } else if (!fVertexPoolInUse) {
+ } else if (!fVertexPoolUseCnt) {
// the client doesn't have valid data in the pool
fVertexPool->reset();
}
@@ -642,81 +670,117 @@
void GrGpu::prepareIndexPool() {
if (NULL == fIndexPool) {
+ GrAssert(0 == fIndexPoolUseCnt);
fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
fIndexPool->releaseGpuRef();
- } else if (!fIndexPoolInUse) {
+ } else if (!fIndexPoolUseCnt) {
// the client doesn't have valid data in the pool
fIndexPool->reset();
}
}
-bool GrGpu::onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- size_t reservedVertexSpace = 0;
-
- if (fReservedGeometry.fVertexCount) {
- GrAssert(NULL != vertices);
-
- this->prepareVertexPool();
-
- *vertices = fVertexPool->makeSpace(vertexLayout,
- fReservedGeometry.fVertexCount,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
- if (NULL == *vertices) {
- return false;
- }
- reservedVertexSpace = VertexSize(vertexLayout) *
- fReservedGeometry.fVertexCount;
+bool GrGpu::onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+
+ GrAssert(vertexCount > 0);
+ GrAssert(NULL != vertices);
+
+ this->prepareVertexPool();
+
+ *vertices = fVertexPool->makeSpace(vertexLayout,
+ vertexCount,
+ &geomPoolState.fPoolVertexBuffer,
+ &geomPoolState.fPoolStartVertex);
+ if (NULL == *vertices) {
+ return false;
}
- if (fReservedGeometry.fIndexCount) {
- GrAssert(NULL != indices);
-
- this->prepareIndexPool();
-
- *indices = fIndexPool->makeSpace(fReservedGeometry.fIndexCount,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
- if (NULL == *indices) {
- fVertexPool->putBack(reservedVertexSpace);
- fCurrPoolVertexBuffer = NULL;
- return false;
- }
- }
+ ++fVertexPoolUseCnt;
return true;
}
-void GrGpu::onReleaseGeometry() {}
+bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+
+ GrAssert(indexCount > 0);
+ GrAssert(NULL != indices);
+
+ this->prepareIndexPool();
+
+ *indices = fIndexPool->makeSpace(indexCount,
+ &geomPoolState.fPoolIndexBuffer,
+ &geomPoolState.fPoolStartIndex);
+ if (NULL == *indices) {
+ return false;
+ }
+ ++fIndexPoolUseCnt;
+ return true;
+}
+
+void GrGpu::releaseReservedVertexSpace() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+ size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ fVertexPool->putBack(bytes);
+ --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseReservedIndexSpace() {
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+ size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+ fIndexPool->putBack(bytes);
+ --fIndexPoolUseCnt;
+}
void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
this->prepareVertexPool();
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
#if GR_DEBUG
bool success =
#endif
- fVertexPool->appendVertices(fGeometrySrc.fVertexLayout,
+ fVertexPool->appendVertices(this->getGeomSrc().fVertexLayout,
vertexCount,
vertexArray,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
+ &geomPoolState.fPoolVertexBuffer,
+ &geomPoolState.fPoolStartVertex);
+ ++fVertexPoolUseCnt;
GR_DEBUGASSERT(success);
}
void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
this->prepareIndexPool();
+ GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
#if GR_DEBUG
bool success =
#endif
fIndexPool->appendIndices(indexCount,
indexArray,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
+ &geomPoolState.fPoolIndexBuffer,
+ &geomPoolState.fPoolStartIndex);
+ ++fIndexPoolUseCnt;
GR_DEBUGASSERT(success);
}
+void GrGpu::releaseVertexArray() {
+ // if vertex source was array, we stowed data in the pool
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc);
+ size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ fVertexPool->putBack(bytes);
+ --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseIndexArray() {
+ // if index source was array, we stowed data in the pool
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+ GrAssert(kArray_GeometrySrcType == geoSrc.fIndexSrc);
+ size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+ fIndexPool->putBack(bytes);
+ --fIndexPoolUseCnt;
+}
+
////////////////////////////////////////////////////////////////////////////////
const GrGpuStats& GrGpu::getStats() const {
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index c73f60f..ffdf496 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -1401,11 +1401,11 @@
#endif
#endif
-void GrGpuGL::onDrawIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount) {
+void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) {
GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex);
@@ -1433,9 +1433,9 @@
#endif
}
-void GrGpuGL::onDrawNonIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t vertexCount) {
+void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount) {
GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
GrAssert(NULL != fHWGeometryState.fVertexBuffer);
@@ -1924,7 +1924,7 @@
}
void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
- fGeometrySrc.fIndexBuffer = buffer;
+ fHWGeometryState.fIndexBuffer = buffer;
}
void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
@@ -2058,17 +2058,19 @@
GrAssert(NULL != extraVertexOffset);
+ const GeometryPoolState& geoPoolState = this->getGeomPoolState();
+
GrGLVertexBuffer* vbuf;
- switch (fGeometrySrc.fVertexSrc) {
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
*extraVertexOffset = 0;
- vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer;
+ vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
break;
case kArray_GeometrySrcType:
case kReserved_GeometrySrcType:
- finalizeReservedVertices();
- *extraVertexOffset = fCurrPoolStartVertex;
- vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer;
+ this->finalizeReservedVertices();
+ *extraVertexOffset = geoPoolState.fPoolStartVertex;
+ vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
break;
default:
vbuf = NULL; // suppress warning
@@ -2087,16 +2089,16 @@
GrAssert(NULL != extraIndexOffset);
GrGLIndexBuffer* ibuf;
- switch (fGeometrySrc.fIndexSrc) {
+ switch (this->getGeomSrc().fIndexSrc) {
case kBuffer_GeometrySrcType:
*extraIndexOffset = 0;
- ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+ ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
break;
case kArray_GeometrySrcType:
case kReserved_GeometrySrcType:
- finalizeReservedIndices();
- *extraIndexOffset = fCurrPoolStartIndex;
- ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer;
+ this->finalizeReservedIndices();
+ *extraIndexOffset = geoPoolState.fPoolStartIndex;
+ ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
break;
default:
ibuf = NULL; // suppress warning
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index f7f62ab..aec55d8 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -91,14 +91,14 @@
int left, int top, int width, int height,
GrPixelConfig, void* buffer);
- virtual void onDrawIndexed(GrPrimitiveType type,
- uint32_t startVertex,
- uint32_t startIndex,
- uint32_t vertexCount,
- uint32_t indexCount);
- virtual void onDrawNonIndexed(GrPrimitiveType type,
- uint32_t vertexCount,
- uint32_t numVertices);
+ virtual void onGpuDrawIndexed(GrPrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount);
+ virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
+ uint32_t vertexCount,
+ uint32_t numVertices);
virtual void flushScissor(const GrIRect* rect);
void clearStencil(uint32_t value, uint32_t mask);
virtual void clearStencilClip(const GrIRect& rect);
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
index 65229dc..baa220b 100644
--- a/gpu/src/GrGpuGLFixed.cpp
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -166,7 +166,7 @@
}
}
- uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+ uint32_t vertColor = (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit);
uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
kColor_VertexLayoutBit);
@@ -250,7 +250,7 @@
int newColorOffset;
int newTexCoordOffsets[kNumStages];
- GrGLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
+ GrGLsizei newStride = VertexSizeAndOffsetsByStage(this->getGeomSrc().fVertexLayout,
newTexCoordOffsets,
&newColorOffset);
int oldColorOffset;
@@ -266,7 +266,7 @@
setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GrGLenum scalarType;
- if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
} else {
scalarType = GrGLType;
@@ -289,7 +289,7 @@
((GrGLTextType != GrGLType) &&
(kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout)));
+ this->getGeomSrc().fVertexLayout)));
if (posAndTexChange) {
GR_GL(VertexPointer(2, scalarType, newStride, (GrGLvoid*)vertexOffset));
@@ -328,6 +328,6 @@
GR_GL(DisableClientState(GR_GL_COLOR_ARRAY));
}
- fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 689c1fc..0b8aad7 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -501,7 +501,7 @@
void GrGpuGLShaders::flushColor() {
const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
- if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
// color will be specified per-vertex as an attribute
// invalidate the const vertex attrib color
fHWDrawState.fColor = GrColor_ILLEGAL;
@@ -613,23 +613,25 @@
int newColorOffset;
int newTexCoordOffsets[kMaxTexCoords];
- GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
- newTexCoordOffsets,
- &newColorOffset);
+ GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
+ this->getGeomSrc().fVertexLayout,
+ newTexCoordOffsets,
+ &newColorOffset);
int oldColorOffset;
int oldTexCoordOffsets[kMaxTexCoords];
- GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
- oldTexCoordOffsets,
- &oldColorOffset);
+ GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
+ fHWGeometryState.fVertexLayout,
+ oldTexCoordOffsets,
+ &oldColorOffset);
bool indexed = NULL != startIndex;
int extraVertexOffset;
int extraIndexOffset;
- setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+ this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
GrGLenum scalarType;
bool texCoordNorm;
- if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
} else {
@@ -654,7 +656,7 @@
(((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
(kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^
- fGeometrySrc.fVertexLayout)));
+ this->getGeomSrc().fVertexLayout)));
if (posAndTexChange) {
int idx = GrGLProgram::PositionAttributeIdx();
@@ -696,7 +698,7 @@
GR_GL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
}
- fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
@@ -704,7 +706,7 @@
GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
// Must initialize all fields or cache will have false negatives!
- desc.fVertexLayout = fGeometrySrc.fVertexLayout;
+ desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
desc.fEmitsPointSize = kPoints_PrimitiveType == type;
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
index 7df1f23..a685620 100644
--- a/gpu/src/GrInOrderDrawBuffer.cpp
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -23,30 +23,34 @@
#include "GrGpu.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
- GrIndexBufferAllocPool* indexPool) :
- fDraws(&fDrawStorage),
- fStates(&fStateStorage),
- fClears(&fClearStorage),
- fClips(&fClipStorage),
- fClipSet(true),
+ GrIndexBufferAllocPool* indexPool)
+ : fDraws(&fDrawStorage)
+ , fStates(&fStateStorage)
+ , fClears(&fClearStorage)
+ , fClips(&fClipStorage)
+ , fClipSet(true)
- fLastRectVertexLayout(0),
- fQuadIndexBuffer(NULL),
- fMaxQuads(0),
- fCurrQuad(0),
+ , fLastRectVertexLayout(0)
+ , fQuadIndexBuffer(NULL)
+ , fMaxQuads(0)
+ , fCurrQuad(0)
- fVertexPool(*vertexPool),
- fCurrPoolVertexBuffer(NULL),
- fCurrPoolStartVertex(0),
- fIndexPool(*indexPool),
- fCurrPoolIndexBuffer(NULL),
- fCurrPoolStartIndex(0),
- fReservedVertexBytes(0),
- fReservedIndexBytes(0),
- fUsedReservedVertexBytes(0),
- fUsedReservedIndexBytes(0) {
+ , fVertexPool(*vertexPool)
+ , fIndexPool(*indexPool)
+ , fGeoPoolStateStack(&fGeoStackStorage) {
+
GrAssert(NULL != vertexPool);
GrAssert(NULL != indexPool);
+
+ GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+ poolState.fPoolStartVertex = ~0;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+ poolState.fPoolStartIndex = ~0;
+#endif
}
GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
@@ -150,19 +154,24 @@
GrAssert(0 == lastDraw.fIndexCount % 6);
GrAssert(0 == lastDraw.fStartIndex);
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
bool clearSinceLastDraw =
fClears.count() &&
fClears.back().fBeforeDrawIdx == fDraws.count();
- appendToPreviousDraw = !clearSinceLastDraw &&
- lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
- (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
+ appendToPreviousDraw =
+ !clearSinceLastDraw &&
+ lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
+ (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
+
if (appendToPreviousDraw) {
lastDraw.fVertexCount += 4;
lastDraw.fIndexCount += 6;
fCurrQuad += 1;
- GrAssert(0 == fUsedReservedVertexBytes);
- fUsedReservedVertexBytes = 4 * vsize;
+ // we reserved above, so we should be the first
+ // use of this vertex reserveation.
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
+ poolState.fUsedPoolVertexBytes = 4 * vsize;
}
}
if (!appendToPreviousDraw) {
@@ -179,11 +188,11 @@
}
}
-void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) {
+void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount) {
if (!vertexCount || !indexCount) {
return;
@@ -191,6 +200,8 @@
fCurrQuad = 0;
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
Draw& draw = fDraws.push_back();
draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
@@ -208,52 +219,56 @@
this->pushState();
}
- draw.fVertexLayout = fGeometrySrc.fVertexLayout;
- switch (fGeometrySrc.fVertexSrc) {
+ draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
- draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+ draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fVertexBuffer = fCurrPoolVertexBuffer;
- draw.fStartVertex += fCurrPoolStartVertex;
+ VertexSize(this->getGeomSrc().fVertexLayout);
+ poolState.fUsedPoolVertexBytes =
+ GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+ draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+ draw.fStartVertex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
draw.fVertexBuffer->ref();
- switch (fGeometrySrc.fIndexSrc) {
+ switch (this->getGeomSrc().fIndexSrc) {
case kBuffer_GeometrySrcType:
- draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+ draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
- fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fIndexBuffer = fCurrPoolIndexBuffer;
- draw.fStartIndex += fCurrPoolStartVertex;
+ poolState.fUsedPoolIndexBytes =
+ GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
+ draw.fIndexBuffer = poolState.fPoolIndexBuffer;
+ draw.fStartIndex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
draw.fIndexBuffer->ref();
}
-void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
- int startVertex,
- int vertexCount) {
+void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
+ int startVertex,
+ int vertexCount) {
if (!vertexCount) {
return;
}
fCurrQuad = 0;
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
Draw& draw = fDraws.push_back();
draw.fPrimitiveType = primitiveType;
draw.fStartVertex = startVertex;
@@ -271,21 +286,21 @@
this->pushState();
}
- draw.fVertexLayout = fGeometrySrc.fVertexLayout;
- switch (fGeometrySrc.fVertexSrc) {
+ draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
- draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+ draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
break;
- case kReserved_GeometrySrcType: {
+ case kReserved_GeometrySrcType: // fallthrough
+ case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(fGeometrySrc.fVertexLayout);
- fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
- vertexBytes);
- } // fallthrough
- case kArray_GeometrySrcType:
- draw.fVertexBuffer = fCurrPoolVertexBuffer;
- draw.fStartVertex += fCurrPoolStartVertex;
+ VertexSize(this->getGeomSrc().fVertexLayout);
+ poolState.fUsedPoolVertexBytes =
+ GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+ draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+ draw.fStartVertex += poolState.fPoolStartVertex;
break;
+ }
default:
GrCrash("unknown geom src type");
}
@@ -311,7 +326,9 @@
}
void GrInOrderDrawBuffer::reset() {
- GrAssert(!fReservedGeometry.fLocked);
+ GrAssert(1 == fGeoPoolStateStack.count());
+ this->resetVertexSource();
+ this->resetIndexSource();
uint32_t numStates = fStates.count();
for (uint32_t i = 0; i < numStates; ++i) {
const DrState& dstate = this->accessSavedDrawState(fStates[i]);
@@ -341,7 +358,8 @@
}
void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
- GrAssert(!fReservedGeometry.fLocked);
+ GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
+ GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
GrAssert(NULL != target);
GrAssert(target != this); // not considered and why?
@@ -355,9 +373,7 @@
GrDrawTarget::AutoStateRestore asr(target);
GrDrawTarget::AutoClipRestore acr(target);
- // important to not mess with reserve/lock geometry in the target with this
- // on the stack.
- GrDrawTarget::AutoGeometrySrcRestore agsr(target);
+ AutoGeometryPush agp(target);
int currState = ~0;
int currClip = ~0;
@@ -435,89 +451,143 @@
return flush;
}
-bool GrInOrderDrawBuffer::onAcquireGeometry(GrVertexLayout vertexLayout,
- void** vertices,
- void** indices) {
- GrAssert(!fReservedGeometry.fLocked);
- if (fReservedGeometry.fVertexCount) {
- GrAssert(NULL != vertices);
- GrAssert(0 == fReservedVertexBytes);
- GrAssert(0 == fUsedReservedVertexBytes);
+bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
+ int vertexCount,
+ void** vertices) {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(vertexCount > 0);
+ GrAssert(NULL != vertices);
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
+
+ *vertices = fVertexPool.makeSpace(vertexLayout,
+ vertexCount,
+ &poolState.fPoolVertexBuffer,
+ &poolState.fPoolStartVertex);
+ return NULL != *vertices;
+}
+
+bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(indexCount > 0);
+ GrAssert(NULL != indices);
+ GrAssert(0 == poolState.fUsedPoolIndexBytes);
- fReservedVertexBytes = VertexSize(vertexLayout) *
- fReservedGeometry.fVertexCount;
- *vertices = fVertexPool.makeSpace(vertexLayout,
- fReservedGeometry.fVertexCount,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
- if (NULL == *vertices) {
- return false;
- }
- }
- if (fReservedGeometry.fIndexCount) {
- 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;
- }
- }
- return true;
+ *indices = fIndexPool.makeSpace(indexCount,
+ &poolState.fPoolIndexBuffer,
+ &poolState.fPoolStartIndex);
+ return NULL != *indices;
}
-void GrInOrderDrawBuffer::onReleaseGeometry() {
- GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
- GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
-
- size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
- fVertexPool.putBack(vertexSlack);
-
- size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
- fIndexPool.putBack(indexSlack);
-
- fReservedVertexBytes = 0;
- fReservedIndexBytes = 0;
- fUsedReservedVertexBytes = 0;
- fUsedReservedIndexBytes = 0;
- fCurrPoolVertexBuffer = 0;
- fCurrPoolStartVertex = 0;
-
+void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+
+ size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+ geoSrc.fVertexCount;
+ fVertexPool.putBack(reservedVertexBytes -
+ poolState.fUsedPoolVertexBytes);
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fPoolVertexBuffer = 0;
}
+void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+
+ size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+ fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+ poolState.fUsedPoolIndexBytes = 0;
+ poolState.fPoolStartVertex = 0;
+}
+
void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
int vertexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(0 == poolState.fUsedPoolVertexBytes);
#if GR_DEBUG
bool success =
#endif
- fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
+ fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
vertexCount,
vertexArray,
- &fCurrPoolVertexBuffer,
- &fCurrPoolStartVertex);
+ &poolState.fPoolVertexBuffer,
+ &poolState.fPoolStartVertex);
GR_DEBUGASSERT(success);
}
void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
int indexCount) {
- GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ GrAssert(0 == poolState.fUsedPoolIndexBytes);
#if GR_DEBUG
bool success =
#endif
fIndexPool.appendIndices(indexCount,
indexArray,
- &fCurrPoolIndexBuffer,
- &fCurrPoolStartIndex);
+ &poolState.fPoolIndexBuffer,
+ &poolState.fPoolStartIndex);
GR_DEBUGASSERT(success);
}
+void GrInOrderDrawBuffer::geometrySourceWillPush() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+ poolState.fUsedPoolVertexBytes = 0;
+ poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+ poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+ poolState.fPoolStartVertex = ~0;
+ poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+ poolState.fPoolStartIndex = ~0;
+#endif
+}
+
+void GrInOrderDrawBuffer::releaseVertexArray() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+ geoSrc.fVertexCount;
+ fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
+
+ poolState.fUsedPoolVertexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::releaseIndexArray() {
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ const GeometrySrcState& geoSrc = this->getGeomSrc();
+
+ size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+ fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+
+ poolState.fUsedPoolIndexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::geometrySourceWillPop(
+ const GeometrySrcState& restoredState) {
+ GrAssert(fGeoPoolStateStack.count() > 1);
+ fGeoPoolStateStack.pop_back();
+ GeometryPoolState& poolState = fGeoPoolStateStack.back();
+ // we have to assume that any slack we had in our vertex/index data
+ // is now unreleasable because data may have been appended later in the
+ // pool.
+ if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
+ kArray_GeometrySrcType == restoredState.fVertexSrc) {
+ poolState.fUsedPoolVertexBytes =
+ VertexSize(restoredState.fVertexLayout) *
+ restoredState.fVertexCount;
+ }
+ if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
+ kArray_GeometrySrcType == restoredState.fIndexSrc) {
+ poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
+ restoredState.fIndexCount;
+ }
+}
+
bool GrInOrderDrawBuffer::needsNewState() const {
if (fStates.empty()) {
return true;
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
index 41e4a85..5d0f9f7 100644
--- a/gpu/src/GrTextContext.cpp
+++ b/gpu/src/GrTextContext.cpp
@@ -72,7 +72,7 @@
fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
0, 0, fCurrVertex, nIndices);
- fDrawTarget->releaseReservedGeometry();
+ fDrawTarget->resetVertexSource();
fVertices = NULL;
fMaxVertices = 0;
fCurrVertex = 0;
@@ -284,10 +284,9 @@
// don't exceed the limit of the index buffer
fMaxVertices = maxQuadVertices;
}
- bool success = fDrawTarget->reserveAndLockGeometry(fVertexLayout,
- fMaxVertices, 0,
- GrTCast<void**>(&fVertices),
- NULL);
+ bool success = fDrawTarget->reserveVertexSpace(fVertexLayout,
+ fMaxVertices,
+ GrTCast<void**>(&fVertices));
GrAlwaysAssert(success);
}