Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: src/gpu/batches/GrDrawVerticesBatch.cpp

Issue 1276333004: GrDrawVertices to batches (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/batches/GrDrawVerticesBatch.h ('k') | src/gpu/batches/GrTestBatch.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "GrDrawVerticesBatch.h"
9
10 #include "GrBatchTarget.h"
11 #include "GrInvariantOutput.h"
12 #include "GrDefaultGeoProcFactory.h"
13
14 static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords,
15 bool hasColors,
16 int* colorOffset,
17 int* texOffset,
18 GrColor color,
19 const SkMatrix& viewMatr ix,
20 bool coverageIgnored) {
21 using namespace GrDefaultGeoProcFactory;
22 *texOffset = -1;
23 *colorOffset = -1;
24 Color gpColor(color);
25 if (hasColors) {
26 gpColor.fType = Color::kAttribute_Type;
27 }
28
29 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type);
30 LocalCoords localCoords(hasLocalCoords ? LocalCoords::kHasExplicit_Type :
31 LocalCoords::kUsePosition_Type);
32 if (hasLocalCoords && hasColors) {
33 *colorOffset = sizeof(SkPoint);
34 *texOffset = sizeof(SkPoint) + sizeof(GrColor);
35 } else if (hasLocalCoords) {
36 *texOffset = sizeof(SkPoint);
37 } else if (hasColors) {
38 *colorOffset = sizeof(SkPoint);
39 }
40 return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewM atrix);
41 }
42
43 GrDrawVerticesBatch::GrDrawVerticesBatch(const Geometry& geometry, GrPrimitiveTy pe primitiveType,
44 const SkMatrix& viewMatrix,
45 const SkPoint* positions, int vertexCou nt,
46 const uint16_t* indices, int indexCount ,
47 const GrColor* colors, const SkPoint* l ocalCoords,
48 const SkRect& bounds) {
49 this->initClassID<GrDrawVerticesBatch>();
50 SkASSERT(positions);
51
52 fBatch.fViewMatrix = viewMatrix;
53 Geometry& installedGeo = fGeoData.push_back(geometry);
54
55 installedGeo.fPositions.append(vertexCount, positions);
56 if (indices) {
57 installedGeo.fIndices.append(indexCount, indices);
58 fBatch.fHasIndices = true;
59 } else {
60 fBatch.fHasIndices = false;
61 }
62
63 if (colors) {
64 installedGeo.fColors.append(vertexCount, colors);
65 fBatch.fHasColors = true;
66 } else {
67 fBatch.fHasColors = false;
68 }
69
70 if (localCoords) {
71 installedGeo.fLocalCoords.append(vertexCount, localCoords);
72 fBatch.fHasLocalCoords = true;
73 } else {
74 fBatch.fHasLocalCoords = false;
75 }
76 fBatch.fVertexCount = vertexCount;
77 fBatch.fIndexCount = indexCount;
78 fBatch.fPrimitiveType = primitiveType;
79
80 this->setBounds(bounds);
81 }
82
83 void GrDrawVerticesBatch::getInvariantOutputColor(GrInitInvariantOutput* out) co nst {
84 // When this is called on a batch, there is only one geometry bundle
85 if (this->hasColors()) {
86 out->setUnknownFourComponents();
87 } else {
88 out->setKnownFourComponents(fGeoData[0].fColor);
89 }
90 }
91
92 void GrDrawVerticesBatch::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
93 out->setKnownSingleComponent(0xff);
94 }
95
96 void GrDrawVerticesBatch::initBatchTracker(const GrPipelineInfo& init) {
97 // Handle any color overrides
98 if (!init.readsColor()) {
99 fGeoData[0].fColor = GrColor_ILLEGAL;
100 }
101 init.getOverrideColorIfSet(&fGeoData[0].fColor);
102
103 // setup batch properties
104 fBatch.fColorIgnored = !init.readsColor();
105 fBatch.fColor = fGeoData[0].fColor;
106 fBatch.fUsesLocalCoords = init.readsLocalCoords();
107 fBatch.fCoverageIgnored = !init.readsCoverage();
108 }
109
110 void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) {
111 int colorOffset = -1, texOffset = -1;
112 SkAutoTUnref<const GrGeometryProcessor> gp(
113 set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &co lorOffset,
114 &texOffset, this->color(), this->viewMatrix(),
115 this->coverageIgnored()));
116
117 batchTarget->initDraw(gp, this->pipeline());
118
119 size_t vertexStride = gp->getVertexStride();
120
121 SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof( SkPoint) : 0)
122 + (this->hasColors() ? sizeof(GrCol or) : 0));
123
124 int instanceCount = fGeoData.count();
125
126 const GrVertexBuffer* vertexBuffer;
127 int firstVertex;
128
129 void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(),
130 &vertexBuffer, &firstVertex);
131
132 if (!verts) {
133 SkDebugf("Could not allocate vertices\n");
134 return;
135 }
136
137 const GrIndexBuffer* indexBuffer = NULL;
138 int firstIndex = 0;
139
140 uint16_t* indices = NULL;
141 if (this->hasIndices()) {
142 indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex);
143
144 if (!indices) {
145 SkDebugf("Could not allocate indices\n");
146 return;
147 }
148 }
149
150 int indexOffset = 0;
151 int vertexOffset = 0;
152 for (int i = 0; i < instanceCount; i++) {
153 const Geometry& args = fGeoData[i];
154
155 // TODO we can actually cache this interleaved and then just memcopy
156 if (this->hasIndices()) {
157 for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) {
158 *(indices + indexOffset) = args.fIndices[j] + vertexOffset;
159 }
160 }
161
162 for (int j = 0; j < args.fPositions.count(); ++j) {
163 *((SkPoint*)verts) = args.fPositions[j];
164 if (this->hasColors()) {
165 *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
166 }
167 if (this->hasLocalCoords()) {
168 *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
169 }
170 verts = (void*)((intptr_t)verts + vertexStride);
171 vertexOffset++;
172 }
173 }
174
175 GrVertices vertices;
176 if (this->hasIndices()) {
177 vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, f irstVertex,
178 firstIndex, this->vertexCount(), this->indexCount() );
179
180 } else {
181 vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->ve rtexCount());
182 }
183 batchTarget->draw(vertices);
184 }
185
186 bool GrDrawVerticesBatch::onCombineIfPossible(GrBatch* t) {
187 if (!this->pipeline()->isEqual(*t->pipeline())) {
188 return false;
189 }
190
191 GrDrawVerticesBatch* that = t->cast<GrDrawVerticesBatch>();
192
193 if (!this->batchablePrimitiveType() || this->primitiveType() != that->primit iveType()) {
194 return false;
195 }
196
197 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
198
199 // We currently use a uniform viewmatrix for this batch
200 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
201 return false;
202 }
203
204 if (this->hasColors() != that->hasColors()) {
205 return false;
206 }
207
208 if (this->hasIndices() != that->hasIndices()) {
209 return false;
210 }
211
212 if (this->hasLocalCoords() != that->hasLocalCoords()) {
213 return false;
214 }
215
216 if (!this->hasColors() && this->color() != that->color()) {
217 return false;
218 }
219
220 if (this->color() != that->color()) {
221 fBatch.fColor = GrColor_ILLEGAL;
222 }
223 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
224 fBatch.fVertexCount += that->vertexCount();
225 fBatch.fIndexCount += that->indexCount();
226
227 this->joinBounds(that->bounds());
228 return true;
229 }
230
231 //////////////////////////////////////////////////////////////////////////////// ///////////////////
232
233 #ifdef GR_TEST_UTILS
234
235 #include "GrBatchTest.h"
236
237 static uint32_t seed_vertices(GrPrimitiveType type) {
238 switch (type) {
239 case kTriangles_GrPrimitiveType:
240 case kTriangleStrip_GrPrimitiveType:
241 case kTriangleFan_GrPrimitiveType:
242 return 3;
243 case kPoints_GrPrimitiveType:
244 return 1;
245 case kLines_GrPrimitiveType:
246 case kLineStrip_GrPrimitiveType:
247 return 2;
248 }
249 SkFAIL("Incomplete switch\n");
250 return 0;
251 }
252
253 static uint32_t primitive_vertices(GrPrimitiveType type) {
254 switch (type) {
255 case kTriangles_GrPrimitiveType:
256 return 3;
257 case kLines_GrPrimitiveType:
258 return 2;
259 case kTriangleStrip_GrPrimitiveType:
260 case kTriangleFan_GrPrimitiveType:
261 case kPoints_GrPrimitiveType:
262 case kLineStrip_GrPrimitiveType:
263 return 1;
264 }
265 SkFAIL("Incomplete switch\n");
266 return 0;
267 }
268
269 static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
270 SkPoint p;
271 p.fX = random->nextRangeScalar(min, max);
272 p.fY = random->nextRangeScalar(min, max);
273 return p;
274 }
275
276 static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkSca lar max,
277 SkRandom* random,
278 SkTArray<SkPoint>* positions,
279 SkTArray<SkPoint>* texCoords, bool hasTexCoords,
280 SkTArray<GrColor>* colors, bool hasColors,
281 SkTArray<uint16_t>* indices, bool hasIndices) {
282 for (uint32_t v = 0; v < count; v++) {
283 positions->push_back(random_point(random, min, max));
284 if (hasTexCoords) {
285 texCoords->push_back(random_point(random, min, max));
286 }
287 if (hasColors) {
288 colors->push_back(GrRandomColor(random));
289 }
290 if (hasIndices) {
291 SkASSERT(maxVertex <= SK_MaxU16);
292 indices->push_back(random->nextULessThan((uint16_t)maxVertex));
293 }
294 }
295 }
296
297 BATCH_TEST_DEFINE(VerticesBatch) {
298 GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimiti veType + 1));
299 uint32_t primitiveCount = random->nextRangeU(1, 100);
300
301 // TODO make 'sensible' indexbuffers
302 SkTArray<SkPoint> positions;
303 SkTArray<SkPoint> texCoords;
304 SkTArray<GrColor> colors;
305 SkTArray<uint16_t> indices;
306
307 bool hasTexCoords = random->nextBool();
308 bool hasIndices = random->nextBool();
309 bool hasColors = random->nextBool();
310
311 uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitiv e_vertices(type);
312
313 static const SkScalar kMinVertExtent = -100.f;
314 static const SkScalar kMaxVertExtent = 100.f;
315 randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertE xtent,
316 random,
317 &positions,
318 &texCoords, hasTexCoords,
319 &colors, hasColors,
320 &indices, hasIndices);
321
322 for (uint32_t i = 1; i < primitiveCount; i++) {
323 randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
324 random,
325 &positions,
326 &texCoords, hasTexCoords,
327 &colors, hasColors,
328 &indices, hasIndices);
329 }
330
331 SkMatrix viewMatrix = GrTest::TestMatrix(random);
332 SkRect bounds;
333 SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexC ount);
334 SkASSERT(result);
335
336 viewMatrix.mapRect(&bounds);
337
338 GrDrawVerticesBatch::Geometry geometry;
339 geometry.fColor = GrRandomColor(random);
340 return GrDrawVerticesBatch::Create(geometry, type, viewMatrix,
341 positions.begin(), vertexCount,
342 indices.begin(), hasIndices ? vertexCount : 0,
343 colors.begin(),
344 texCoords.begin(),
345 bounds);
346 }
347
348 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrDrawVerticesBatch.h ('k') | src/gpu/batches/GrTestBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698