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/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;