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