Index: src/gpu/GrVertices.h |
diff --git a/src/gpu/GrVertices.h b/src/gpu/GrVertices.h |
index f03482662e40d2613fcf9a1d0ef56834d1cf6e51..10b2679da4dc059d5a2a97b53789f235a4779f79 100644 |
--- a/src/gpu/GrVertices.h |
+++ b/src/gpu/GrVertices.h |
@@ -11,13 +11,36 @@ |
#include "GrIndexBuffer.h" |
#include "GrVertexBuffer.h" |
+class GrNonInstancedVertices { |
+public: |
+ GrPrimitiveType primitiveType() const { return fPrimitiveType; } |
+ int startVertex() const { return fStartVertex; } |
+ int startIndex() const { return fStartIndex; } |
+ int vertexCount() const { return fVertexCount; } |
+ int indexCount() const { return fIndexCount; } |
+ bool isIndexed() const { return fIndexCount > 0; } |
+ |
+ const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); } |
+ const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); } |
+ |
+protected: |
+ GrPrimitiveType fPrimitiveType; |
+ int fStartVertex; |
+ int fStartIndex; |
+ int fVertexCount; |
+ int fIndexCount; |
+ GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer; |
+ GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer; |
+ friend class GrVertices; |
+}; |
+ |
/** |
* Used to communicate index and vertex buffers, counts, and offsets for a draw from GrBatch to |
* GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this |
* and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there |
* already (stride, attribute mappings). |
*/ |
-class GrVertices { |
+class GrVertices : public GrNonInstancedVertices { |
public: |
GrVertices() {} |
GrVertices(const GrVertices& di) { (*this) = di; } |
@@ -38,6 +61,7 @@ public: |
fInstanceCount = 0; |
fVerticesPerInstance = 0; |
fIndicesPerInstance = 0; |
+ fMaxInstancesPerDraw = 0; |
} |
void initIndexed(GrPrimitiveType primType, |
@@ -63,15 +87,21 @@ public: |
fInstanceCount = 0; |
fVerticesPerInstance = 0; |
fIndicesPerInstance = 0; |
+ fMaxInstancesPerDraw = 0; |
} |
+ |
+ /** Variation of the above that may be used when the total number of instances may exceed |
+ the number of instances supported by the index buffer. To be used with |
+ nextInstances() to draw in max-sized batches.*/ |
void initInstanced(GrPrimitiveType primType, |
const GrVertexBuffer* vertexBuffer, |
const GrIndexBuffer* indexBuffer, |
int startVertex, |
int verticesPerInstance, |
int indicesPerInstance, |
- int instanceCount) { |
+ int instanceCount, |
+ int maxInstancesPerDraw) { |
SkASSERT(vertexBuffer); |
SkASSERT(indexBuffer); |
SkASSERT(instanceCount); |
@@ -88,74 +118,62 @@ public: |
fInstanceCount = instanceCount; |
fVertexCount = instanceCount * fVerticesPerInstance; |
fIndexCount = instanceCount * fIndicesPerInstance; |
+ fMaxInstancesPerDraw = maxInstancesPerDraw; |
} |
- /** Variation of the above that may be used when the total number of instances may exceed |
- the number of instances supported by the index buffer. To be used with |
- nextInstances() to draw in max-sized batches.*/ |
- void initInstanced(GrPrimitiveType primType, |
- const GrVertexBuffer* vertexBuffer, |
- const GrIndexBuffer* indexBuffer, |
- int startVertex, |
- int verticesPerInstance, |
- int indicesPerInstance, |
- int* instancesRemaining, |
- int maxInstancesPerDraw) { |
- int instanceCount = SkTMin(*instancesRemaining, maxInstancesPerDraw); |
- *instancesRemaining -= instanceCount; |
- this->initInstanced(primType, vertexBuffer, indexBuffer, startVertex, |
- verticesPerInstance, indicesPerInstance, instanceCount); |
- } |
- |
- GrPrimitiveType primitiveType() const { return fPrimitiveType; } |
- int startVertex() const { return fStartVertex; } |
- int startIndex() const { return fStartIndex; } |
- int vertexCount() const { return fVertexCount; } |
- int indexCount() const { return fIndexCount; } |
/** These return 0 if initInstanced was not used to initialize the GrVertices. */ |
int verticesPerInstance() const { return fVerticesPerInstance; } |
int indicesPerInstance() const { return fIndicesPerInstance; } |
int instanceCount() const { return fInstanceCount; } |
- bool isIndexed() const { return fIndexCount > 0; } |
bool isInstanced() const { return fInstanceCount > 0; } |
- /** Called after using this draw info to draw the next set of instances. |
- The vertex offset is advanced while the index buffer is reused at the same |
- position. instancesRemaining is number of instances that remain, maxInstances is |
- the most number of instances that can be used with the index buffer. If there |
- are no instances remaining, the GrVertices is unmodified and false is returned.*/ |
- bool nextInstances(int* instancesRemaining, int maxInstances) { |
- SkASSERT(this->isInstanced()); |
- if (!*instancesRemaining) { |
- return false; |
+ class Iterator { |
+ public: |
+ const GrNonInstancedVertices* init(const GrVertices& vertices) { |
+ fVertices = &vertices; |
+ if (vertices.fInstanceCount <= vertices.fMaxInstancesPerDraw) { |
+ fInstancesRemaining = 0; |
+ // Note, this also covers the non-instanced case! |
+ return &vertices; |
+ } |
+ SkASSERT(vertices.isInstanced()); |
+ fInstanceBatch.fIndexBuffer.reset(vertices.fIndexBuffer.get()); |
+ fInstanceBatch.fVertexBuffer.reset(vertices.fVertexBuffer.get()); |
+ fInstanceBatch.fIndexCount = vertices.fMaxInstancesPerDraw * |
+ vertices.fIndicesPerInstance; |
+ fInstanceBatch.fVertexCount = vertices.fMaxInstancesPerDraw * |
+ vertices.fVerticesPerInstance; |
+ fInstanceBatch.fPrimitiveType = vertices.fPrimitiveType; |
+ fInstanceBatch.fStartIndex = vertices.fStartIndex; |
+ fInstanceBatch.fStartVertex = vertices.fStartVertex; |
+ fInstancesRemaining = vertices.fInstanceCount - vertices.fMaxInstancesPerDraw; |
+ return &fInstanceBatch; |
} |
- fStartVertex += fVertexCount; |
- fInstanceCount = SkTMin(*instancesRemaining, maxInstances); |
- fVertexCount = fInstanceCount * fVerticesPerInstance; |
- fIndexCount = fInstanceCount * fIndicesPerInstance; |
- *instancesRemaining -= fInstanceCount; |
- return true; |
- } |
- const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); } |
- const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); } |
+ const GrNonInstancedVertices* next() { |
+ if (!fInstancesRemaining) { |
+ return NULL; |
+ } |
+ fInstanceBatch.fStartVertex += fInstanceBatch.fVertexCount; |
+ int instances = SkTMin(fInstancesRemaining, fVertices->fMaxInstancesPerDraw); |
+ fInstanceBatch.fIndexCount = instances * fVertices->fIndicesPerInstance; |
+ fInstanceBatch.fVertexCount = instances * fVertices->fVerticesPerInstance; |
+ fInstancesRemaining -= instances; |
+ return &fInstanceBatch; |
+ } |
+ private: |
+ GrNonInstancedVertices fInstanceBatch; |
+ const GrVertices* fVertices; |
+ int fInstancesRemaining; |
+ }; |
private: |
- GrPrimitiveType fPrimitiveType; |
- |
- int fStartVertex; |
- int fStartIndex; |
- int fVertexCount; |
- int fIndexCount; |
- |
int fInstanceCount; |
int fVerticesPerInstance; |
int fIndicesPerInstance; |
- |
- GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer; |
- GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer; |
+ int fMaxInstancesPerDraw; |
}; |
#endif |