blob: bdb62f5f0f29c5e0b05926161539e92d9f7ea138 [file] [log] [blame]
bsalomoncb8979d2015-05-05 09:51:38 -07001/*
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
egdaniel0e1853c2016-03-17 11:35:45 -07008#ifndef GrMesh_DEFINED
9#define GrMesh_DEFINED
bsalomoncb8979d2015-05-05 09:51:38 -070010
cdalton397536c2016-03-25 12:15:03 -070011#include "GrBuffer.h"
Hal Canary466c7d62017-07-03 15:11:49 -040012#include "GrGpuResourceRef.h"
bsalomoncb8979d2015-05-05 09:51:38 -070013
Chris Dalton114a3c02017-05-26 15:17:19 -060014class GrPrimitiveProcessor;
15
bsalomoncb8979d2015-05-05 09:51:38 -070016/**
Brian Salomon25a88092016-12-01 09:36:50 -050017 * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrOp to
bsalomoncb8979d2015-05-05 09:51:38 -070018 * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
19 * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
20 * already (stride, attribute mappings).
21 */
Chris Daltonbca46e22017-05-15 11:03:26 -060022class GrMesh {
23public:
24 GrMesh(GrPrimitiveType primitiveType)
Chris Dalton114a3c02017-05-26 15:17:19 -060025 : fPrimitiveType(primitiveType)
26 , fBaseVertex(0) {
Chris Dalton1d616352017-05-31 12:51:23 -060027 SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
Chris Daltonbca46e22017-05-15 11:03:26 -060028 }
29
Chris Dalton114a3c02017-05-26 15:17:19 -060030 GrPrimitiveType primitiveType() const { return fPrimitiveType; }
31 bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }
Chris Dalton1d616352017-05-31 12:51:23 -060032 bool isInstanced() const { return SkToBool(fInstanceBuffer.get()); }
Chris Dalton114a3c02017-05-26 15:17:19 -060033 bool hasVertexData() const { return SkToBool(fVertexBuffer.get()); }
34
Chris Dalton1d616352017-05-31 12:51:23 -060035 void setNonIndexedNonInstanced(int vertexCount);
36
Chris Dalton114a3c02017-05-26 15:17:19 -060037 void setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
38 uint16_t minIndexValue, uint16_t maxIndexValue);
39 void setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount, int vertexCount,
Chris Daltonbca46e22017-05-15 11:03:26 -060040 int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer);
41
Chris Dalton1d616352017-05-31 12:51:23 -060042 void setInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
43 int vertexCount);
44 void setIndexedInstanced(const GrBuffer* indexBuffer, int indexCount,
45 const GrBuffer* instanceBuffer, int instanceCount, int baseInstance=0);
46
Chris Dalton114a3c02017-05-26 15:17:19 -060047 void setVertexData(const GrBuffer* vertexBuffer, int baseVertex = 0);
Chris Daltonbca46e22017-05-15 11:03:26 -060048
Chris Dalton114a3c02017-05-26 15:17:19 -060049 class SendToGpuImpl {
50 public:
51 virtual void sendMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
52 const GrBuffer* vertexBuffer, int vertexCount,
53 int baseVertex) = 0;
Chris Daltonbca46e22017-05-15 11:03:26 -060054
Chris Dalton114a3c02017-05-26 15:17:19 -060055 virtual void sendIndexedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
56 const GrBuffer* indexBuffer, int indexCount,
57 int baseIndex, uint16_t minIndexValue,
58 uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
59 int baseVertex) = 0;
Chris Daltonbca46e22017-05-15 11:03:26 -060060
Chris Dalton1d616352017-05-31 12:51:23 -060061 virtual void sendInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
62 const GrBuffer* vertexBuffer, int vertexCount,
63 int baseVertex, const GrBuffer* instanceBuffer,
64 int instanceCount, int baseInstance) = 0;
65
66 virtual void sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
67 const GrBuffer* indexBuffer, int indexCount,
68 int baseIndex, const GrBuffer* vertexBuffer,
69 int baseVertex, const GrBuffer* instanceBuffer,
70 int instanceCount, int baseInstance) = 0;
71
Chris Dalton114a3c02017-05-26 15:17:19 -060072 virtual ~SendToGpuImpl() {}
73 };
74
75 void sendToGpu(const GrPrimitiveProcessor&, SendToGpuImpl*) const;
Chris Daltonbca46e22017-05-15 11:03:26 -060076
77 struct PatternBatch;
78
79private:
Chris Daltonff926502017-05-03 14:36:54 -040080 using PendingBuffer = GrPendingIOResource<const GrBuffer, kRead_GrIOType>;
81
82 GrPrimitiveType fPrimitiveType;
Chris Daltonff926502017-05-03 14:36:54 -040083 PendingBuffer fIndexBuffer;
Chris Dalton1d616352017-05-31 12:51:23 -060084 PendingBuffer fInstanceBuffer;
Chris Daltonff926502017-05-03 14:36:54 -040085 PendingBuffer fVertexBuffer;
Chris Daltonbca46e22017-05-15 11:03:26 -060086 int fBaseVertex;
Chris Daltonff926502017-05-03 14:36:54 -040087
Chris Dalton114a3c02017-05-26 15:17:19 -060088 union {
Chris Dalton1d616352017-05-31 12:51:23 -060089 struct { // When fIndexBuffer == nullptr and fInstanceBuffer == nullptr.
Chris Dalton114a3c02017-05-26 15:17:19 -060090 int fVertexCount;
Chris Dalton1d616352017-05-31 12:51:23 -060091 } fNonIndexNonInstanceData;
Chris Dalton114a3c02017-05-26 15:17:19 -060092
Chris Dalton1d616352017-05-31 12:51:23 -060093 struct { // When fIndexBuffer != nullptr and fInstanceBuffer == nullptr.
Chris Dalton114a3c02017-05-26 15:17:19 -060094 struct {
95 int fIndexCount;
96 int fPatternRepeatCount;
97 } fIndexData;
98
99 union {
100 struct { // When fPatternRepeatCount == 0.
101 int fBaseIndex;
102 uint16_t fMinIndexValue;
103 uint16_t fMaxIndexValue;
104 } fNonPatternIndexData;
105
106 struct { // When fPatternRepeatCount != 0.
107 int fVertexCount;
108 int fMaxPatternRepetitionsInIndexBuffer;
109 } fPatternData;
110 };
111 };
Chris Dalton1d616352017-05-31 12:51:23 -0600112
113 struct { // When fInstanceBuffer != nullptr.
114 struct {
115 int fInstanceCount;
116 int fBaseInstance;
117 } fInstanceData;
118
119 union { // When fIndexBuffer == nullptr.
120 struct {
121 int fVertexCount;
122 } fInstanceNonIndexData;
123
124 struct { // When fIndexBuffer != nullptr.
125 int fIndexCount;
126 } fInstanceIndexData;
127 };
128 };
Chris Dalton114a3c02017-05-26 15:17:19 -0600129 };
Chris Daltonff926502017-05-03 14:36:54 -0400130};
131
Chris Dalton1d616352017-05-31 12:51:23 -0600132inline void GrMesh::setNonIndexedNonInstanced(int vertexCount) {
Chris Daltonbca46e22017-05-15 11:03:26 -0600133 fIndexBuffer.reset(nullptr);
Chris Dalton1d616352017-05-31 12:51:23 -0600134 fInstanceBuffer.reset(nullptr);
135 fNonIndexNonInstanceData.fVertexCount = vertexCount;
Chris Daltonbca46e22017-05-15 11:03:26 -0600136}
137
Chris Dalton114a3c02017-05-26 15:17:19 -0600138inline void GrMesh::setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex,
139 uint16_t minIndexValue, uint16_t maxIndexValue) {
Chris Daltonbca46e22017-05-15 11:03:26 -0600140 SkASSERT(indexBuffer);
141 SkASSERT(indexCount >= 1);
142 SkASSERT(baseIndex >= 0);
Chris Daltona88da482017-06-06 12:25:28 -0600143 SkASSERT(maxIndexValue >= minIndexValue);
Chris Daltonbca46e22017-05-15 11:03:26 -0600144 fIndexBuffer.reset(indexBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600145 fInstanceBuffer.reset(nullptr);
Chris Dalton114a3c02017-05-26 15:17:19 -0600146 fIndexData.fIndexCount = indexCount;
147 fIndexData.fPatternRepeatCount = 0;
148 fNonPatternIndexData.fBaseIndex = baseIndex;
149 fNonPatternIndexData.fMinIndexValue = minIndexValue;
150 fNonPatternIndexData.fMaxIndexValue = maxIndexValue;
Chris Daltonbca46e22017-05-15 11:03:26 -0600151}
152
153inline void GrMesh::setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount,
Chris Dalton114a3c02017-05-26 15:17:19 -0600154 int vertexCount, int patternRepeatCount,
Chris Daltonbca46e22017-05-15 11:03:26 -0600155 int maxPatternRepetitionsInIndexBuffer) {
156 SkASSERT(indexBuffer);
157 SkASSERT(indexCount >= 1);
Chris Dalton114a3c02017-05-26 15:17:19 -0600158 SkASSERT(vertexCount >= 1);
Chris Daltonbca46e22017-05-15 11:03:26 -0600159 SkASSERT(patternRepeatCount >= 1);
160 SkASSERT(maxPatternRepetitionsInIndexBuffer >= 1);
161 fIndexBuffer.reset(indexBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600162 fInstanceBuffer.reset(nullptr);
Chris Dalton114a3c02017-05-26 15:17:19 -0600163 fIndexData.fIndexCount = indexCount;
164 fIndexData.fPatternRepeatCount = patternRepeatCount;
165 fPatternData.fVertexCount = vertexCount;
166 fPatternData.fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer;
Chris Daltonbca46e22017-05-15 11:03:26 -0600167}
168
Chris Dalton1d616352017-05-31 12:51:23 -0600169inline void GrMesh::setInstanced(const GrBuffer* instanceBuffer, int instanceCount,
170 int baseInstance, int vertexCount) {
171 SkASSERT(instanceBuffer);
172 SkASSERT(instanceCount >= 1);
173 SkASSERT(baseInstance >= 0);
174 fIndexBuffer.reset(nullptr);
175 fInstanceBuffer.reset(instanceBuffer);
176 fInstanceData.fInstanceCount = instanceCount;
177 fInstanceData.fBaseInstance = baseInstance;
178 fInstanceNonIndexData.fVertexCount = vertexCount;
179}
180
181inline void GrMesh::setIndexedInstanced(const GrBuffer* indexBuffer, int indexCount,
182 const GrBuffer* instanceBuffer, int instanceCount,
183 int baseInstance) {
184 SkASSERT(indexBuffer);
185 SkASSERT(indexCount >= 1);
186 SkASSERT(instanceBuffer);
187 SkASSERT(instanceCount >= 1);
188 SkASSERT(baseInstance >= 0);
189 fIndexBuffer.reset(indexBuffer);
190 fInstanceBuffer.reset(instanceBuffer);
191 fInstanceData.fInstanceCount = instanceCount;
192 fInstanceData.fBaseInstance = baseInstance;
193 fInstanceIndexData.fIndexCount = indexCount;
194}
195
Chris Dalton114a3c02017-05-26 15:17:19 -0600196inline void GrMesh::setVertexData(const GrBuffer* vertexBuffer, int baseVertex) {
197 SkASSERT(baseVertex >= 0);
Chris Daltonbca46e22017-05-15 11:03:26 -0600198 fVertexBuffer.reset(vertexBuffer);
Chris Daltonbca46e22017-05-15 11:03:26 -0600199 fBaseVertex = baseVertex;
200}
201
Chris Dalton114a3c02017-05-26 15:17:19 -0600202inline void GrMesh::sendToGpu(const GrPrimitiveProcessor& primProc, SendToGpuImpl* impl) const {
Chris Dalton1d616352017-05-31 12:51:23 -0600203 if (this->isInstanced()) {
204 if (!this->isIndexed()) {
205 impl->sendInstancedMeshToGpu(primProc, fPrimitiveType, fVertexBuffer.get(),
206 fInstanceNonIndexData.fVertexCount, fBaseVertex,
207 fInstanceBuffer.get(), fInstanceData.fInstanceCount,
208 fInstanceData.fBaseInstance);
209 } else {
210 impl->sendIndexedInstancedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(),
211 fInstanceIndexData.fIndexCount, 0,
212 fVertexBuffer.get(), fBaseVertex,
213 fInstanceBuffer.get(), fInstanceData.fInstanceCount,
214 fInstanceData.fBaseInstance);
215 }
216 return;
217 }
218
Chris Dalton114a3c02017-05-26 15:17:19 -0600219 if (!this->isIndexed()) {
Chris Dalton1d616352017-05-31 12:51:23 -0600220 SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0);
Chris Dalton114a3c02017-05-26 15:17:19 -0600221 impl->sendMeshToGpu(primProc, fPrimitiveType, fVertexBuffer.get(),
Chris Dalton1d616352017-05-31 12:51:23 -0600222 fNonIndexNonInstanceData.fVertexCount, fBaseVertex);
Chris Dalton114a3c02017-05-26 15:17:19 -0600223 return;
bsalomoncb8979d2015-05-05 09:51:38 -0700224 }
225
Chris Dalton114a3c02017-05-26 15:17:19 -0600226 if (0 == fIndexData.fPatternRepeatCount) {
227 impl->sendIndexedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(),
228 fIndexData.fIndexCount, fNonPatternIndexData.fBaseIndex,
229 fNonPatternIndexData.fMinIndexValue,
230 fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(),
231 fBaseVertex);
232 return;
bsalomoncb8979d2015-05-05 09:51:38 -0700233 }
234
Chris Dalton114a3c02017-05-26 15:17:19 -0600235 SkASSERT(fIndexData.fPatternRepeatCount > 0);
236 int baseRepetition = 0;
237 do {
238 int repeatCount = SkTMin(fPatternData.fMaxPatternRepetitionsInIndexBuffer,
239 fIndexData.fPatternRepeatCount - baseRepetition);
240 // A patterned index buffer must contain indices in the range [0..vertexCount].
241 int minIndexValue = 0;
242 int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1;
243 impl->sendIndexedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(),
244 fIndexData.fIndexCount * repeatCount, 0, minIndexValue,
245 maxIndexValue, fVertexBuffer.get(),
246 fBaseVertex + fPatternData.fVertexCount * baseRepetition);
247 baseRepetition += repeatCount;
248 } while (baseRepetition < fIndexData.fPatternRepeatCount);
Chris Daltonff926502017-05-03 14:36:54 -0400249}
250
bsalomoncb8979d2015-05-05 09:51:38 -0700251#endif