1cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon/*
2cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * Copyright 2015 Google Inc.
3cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon *
4cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * Use of this source code is governed by a BSD-style license that can be
5cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * found in the LICENSE file.
6cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon */
7cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
8cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#ifndef GrVertices_DEFINED
9cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#define GrVertices_DEFINED
10cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
11cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#include "GrIndexBuffer.h"
12cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#include "GrVertexBuffer.h"
13cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
14e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomonclass GrNonInstancedVertices {
15e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomonpublic:
16e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    GrPrimitiveType primitiveType() const { return fPrimitiveType; }
17e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int startVertex() const { return fStartVertex; }
18e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int startIndex() const { return fStartIndex; }
19e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int vertexCount() const { return fVertexCount; }
20e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int indexCount() const { return fIndexCount; }
21e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    bool isIndexed() const { return fIndexCount > 0; }
22e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon
23e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
24e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
25e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon
26e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomonprotected:
27e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    GrPrimitiveType         fPrimitiveType;
28e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int                     fStartVertex;
29e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int                     fStartIndex;
30e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int                     fVertexCount;
31e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int                     fIndexCount;
32e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
33e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType>  fIndexBuffer;
34e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    friend class GrVertices;
35e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon};
36e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon
37cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon/**
38cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrBatch to
39cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
40cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
41cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon * already (stride, attribute mappings).
42cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon */
43e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomonclass GrVertices : public GrNonInstancedVertices {
44cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomonpublic:
45cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    GrVertices() {}
46cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    GrVertices(const GrVertices& di) { (*this) = di; }
47cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    GrVertices& operator =(const GrVertices& di);
48cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
49cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    void init(GrPrimitiveType primType, const GrVertexBuffer* vertexBuffer, int startVertex,
50cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                int vertexCount) {
51cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(vertexBuffer);
52cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(vertexCount);
53cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(startVertex >= 0);
54cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fPrimitiveType = primType;
55301f989c65daff2f081d86d49c6f90f250ea0e8cbsalomon        fVertexBuffer.reset(vertexBuffer);
56cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndexBuffer.reset(NULL);
57cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartVertex = startVertex;
58cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartIndex = 0;
59cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVertexCount = vertexCount;
60cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndexCount = 0;
61cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fInstanceCount = 0;
62cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVerticesPerInstance = 0;
63cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndicesPerInstance = 0;
64e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        fMaxInstancesPerDraw = 0;
65cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    }
66cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
67cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    void initIndexed(GrPrimitiveType primType,
68cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        const GrVertexBuffer* vertexBuffer,
69cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        const GrIndexBuffer* indexBuffer,
70cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int startVertex,
71cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int startIndex,
72cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int vertexCount,
73cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int indexCount) {
74cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(indexBuffer);
75cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(vertexBuffer);
76cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(indexCount);
77cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(vertexCount);
78cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(startIndex >= 0);
79cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(startVertex >= 0);
80cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fPrimitiveType = primType;
81301f989c65daff2f081d86d49c6f90f250ea0e8cbsalomon        fVertexBuffer.reset(vertexBuffer);
82301f989c65daff2f081d86d49c6f90f250ea0e8cbsalomon        fIndexBuffer.reset(indexBuffer);
83cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartVertex = startVertex;
84cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartIndex = startIndex;
85cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVertexCount = vertexCount;
86cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndexCount = indexCount;
87cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fInstanceCount = 0;
88cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVerticesPerInstance = 0;
89cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndicesPerInstance = 0;
90e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        fMaxInstancesPerDraw = 0;
91cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    }
92cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
93e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon
94e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    /** Variation of the above that may be used when the total number of instances may exceed
95e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        the number of instances supported by the index buffer. To be used with
96e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        nextInstances() to draw in max-sized batches.*/
97cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    void initInstanced(GrPrimitiveType primType,
98cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        const GrVertexBuffer* vertexBuffer,
99cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        const GrIndexBuffer* indexBuffer,
100cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int startVertex,
101cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int verticesPerInstance,
102cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                        int indicesPerInstance,
103e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                        int instanceCount,
104e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                        int maxInstancesPerDraw) {
105cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(vertexBuffer);
106cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(indexBuffer);
107cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(instanceCount);
108cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(verticesPerInstance);
109cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(indicesPerInstance);
110cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkASSERT(startVertex >= 0);
111cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fPrimitiveType = primType;
112301f989c65daff2f081d86d49c6f90f250ea0e8cbsalomon        fVertexBuffer.reset(vertexBuffer);
113301f989c65daff2f081d86d49c6f90f250ea0e8cbsalomon        fIndexBuffer.reset(indexBuffer);
114cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartVertex = startVertex;
115cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fStartIndex = 0;
116cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVerticesPerInstance = verticesPerInstance;
117cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndicesPerInstance = indicesPerInstance;
118cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fInstanceCount = instanceCount;
119cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fVertexCount = instanceCount * fVerticesPerInstance;
120cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        fIndexCount = instanceCount * fIndicesPerInstance;
121e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        fMaxInstancesPerDraw = maxInstancesPerDraw;
122cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    }
123cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
124cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
125cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    /** These return 0 if initInstanced was not used to initialize the GrVertices. */
126cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int verticesPerInstance() const { return fVerticesPerInstance; }
127cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int indicesPerInstance() const { return fIndicesPerInstance; }
128cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int instanceCount() const { return fInstanceCount; }
129cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
130cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    bool isInstanced() const { return fInstanceCount > 0; }
131cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
132e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    class Iterator {
133e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    public:
134e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        const GrNonInstancedVertices* init(const GrVertices& vertices) {
135e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fVertices = &vertices;
136e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            if (vertices.fInstanceCount <= vertices.fMaxInstancesPerDraw) {
137e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                fInstancesRemaining = 0;
138e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                // Note, this also covers the non-instanced case!
139e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                return &vertices;
140e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            }
141e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            SkASSERT(vertices.isInstanced());
142e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fIndexBuffer.reset(vertices.fIndexBuffer.get());
143e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fVertexBuffer.reset(vertices.fVertexBuffer.get());
144e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fIndexCount = vertices.fMaxInstancesPerDraw *
145e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                                         vertices.fIndicesPerInstance;
146e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fVertexCount = vertices.fMaxInstancesPerDraw *
147e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                                          vertices.fVerticesPerInstance;
148e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fPrimitiveType = vertices.fPrimitiveType;
149e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fStartIndex = vertices.fStartIndex;
150e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fStartVertex = vertices.fStartVertex;
151e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstancesRemaining = vertices.fInstanceCount - vertices.fMaxInstancesPerDraw;
152e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            return &fInstanceBatch;
153cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        }
154cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
155e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        const GrNonInstancedVertices* next() {
156e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            if (!fInstancesRemaining) {
157e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon                return NULL;
158e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            }
159e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fStartVertex += fInstanceBatch.fVertexCount;
160e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            int instances = SkTMin(fInstancesRemaining, fVertices->fMaxInstancesPerDraw);
161e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fIndexCount = instances * fVertices->fIndicesPerInstance;
162e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstanceBatch.fVertexCount = instances * fVertices->fVerticesPerInstance;
163e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            fInstancesRemaining -= instances;
164e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon            return &fInstanceBatch;
165e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        }
166e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    private:
167e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        GrNonInstancedVertices fInstanceBatch;
168e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        const GrVertices* fVertices;
169e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon        int fInstancesRemaining;
170e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    };
171cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
172cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomonprivate:
173cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int                     fInstanceCount;
174cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int                     fVerticesPerInstance;
175cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon    int                     fIndicesPerInstance;
176e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon    int                     fMaxInstancesPerDraw;
177cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon};
178cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon
179cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#endif
180