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