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

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

Issue 1279343004: Revise DrawAtlasBatch to get rid of one copy when generating the batch. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Picky picky Windows 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/GrDrawAtlasBatch.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrDrawAtlasBatch.h" 8 #include "GrDrawAtlasBatch.h"
9 #include "GrBatchTest.h" 9 #include "GrBatchTest.h"
10 #include "SkGr.h"
10 #include "SkRandom.h" 11 #include "SkRandom.h"
12 #include "SkRSXform.h"
11 13
12 void GrDrawAtlasBatch::initBatchTracker(const GrPipelineOptimizations& opt) { 14 void GrDrawAtlasBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
13 // Handle any color overrides 15 // Handle any color overrides
14 if (!opt.readsColor()) { 16 if (!opt.readsColor()) {
15 fGeoData[0].fColor = GrColor_ILLEGAL; 17 fGeoData[0].fColor = GrColor_ILLEGAL;
16 } 18 }
17 opt.getOverrideColorIfSet(&fGeoData[0].fColor); 19 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
18 20
19 // setup batch properties 21 // setup batch properties
20 fColorIgnored = !opt.readsColor(); 22 fColorIgnored = !opt.readsColor();
21 fColor = fGeoData[0].fColor; 23 fColor = fGeoData[0].fColor;
22 // We'd like to assert this, but we can't because of GLPrograms test 24 // We'd like to assert this, but we can't because of GLPrograms test
23 //SkASSERT(init.readsLocalCoords()); 25 //SkASSERT(init.readsLocalCoords());
24 fCoverageIgnored = !opt.readsCoverage(); 26 fCoverageIgnored = !opt.readsCoverage();
25 } 27 }
26 28
27 static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, 29 static const GrGeometryProcessor* set_vertex_attributes(bool hasColors,
28 bool hasColors,
29 int* colorOffset,
30 int* texOffset,
31 GrColor color, 30 GrColor color,
32 const SkMatrix& viewMatr ix, 31 const SkMatrix& viewMatr ix,
33 bool coverageIgnored) { 32 bool coverageIgnored) {
34 using namespace GrDefaultGeoProcFactory; 33 using namespace GrDefaultGeoProcFactory;
35 *texOffset = -1;
36 *colorOffset = -1;
37 Color gpColor(color); 34 Color gpColor(color);
38 if (hasColors) { 35 if (hasColors) {
39 gpColor.fType = Color::kAttribute_Type; 36 gpColor.fType = Color::kAttribute_Type;
40 } 37 }
41 38
42 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type); 39 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type);
43 LocalCoords localCoords(hasLocalCoords ? LocalCoords::kHasExplicit_Type : 40 LocalCoords localCoords(LocalCoords::kHasExplicit_Type);
44 LocalCoords::kUsePosition_Type);
45 if (hasLocalCoords && hasColors) {
46 *colorOffset = sizeof(SkPoint);
47 *texOffset = sizeof(SkPoint) + sizeof(GrColor);
48 } else if (hasLocalCoords) {
49 *texOffset = sizeof(SkPoint);
50 } else if (hasColors) {
51 *colorOffset = sizeof(SkPoint);
52 }
53 return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewM atrix); 41 return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewM atrix);
54 } 42 }
55 43
56 void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { 44 void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) {
57 int colorOffset = -1, texOffset = -1;
58 // Setup geometry processor 45 // Setup geometry processor
59 SkAutoTUnref<const GrGeometryProcessor> gp( 46 SkAutoTUnref<const GrGeometryProcessor> gp(set_vertex_attributes(this->hasCo lors(),
60 set_vertex_attributes(true, this->hasColors(), & colorOffset, 47 this->color (),
61 &texOffset, this->color(), this->viewMatrix(), 48 this->viewM atrix(),
62 this->coverageIgnored())); 49 this->cover ageIgnored()));
63 50
64 batchTarget->initDraw(gp, this->pipeline()); 51 batchTarget->initDraw(gp, this->pipeline());
65 52
66 int instanceCount = fGeoData.count(); 53 int instanceCount = fGeoData.count();
67 size_t vertexStride = gp->getVertexStride(); 54 size_t vertexStride = gp->getVertexStride();
68 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) 55 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint)
69 + (this->hasColors() ? sizeof(GrColor) : 0)); 56 + (this->hasColors() ? sizeof(GrColor) : 0));
70 57
71 QuadHelper helper; 58 QuadHelper helper;
72 int numQuads = this->vertexCount()/4; 59 int numQuads = this->quadCount();
73 void* verts = helper.init(batchTarget, vertexStride, numQuads); 60 void* verts = helper.init(batchTarget, vertexStride, numQuads);
74 if (!verts) { 61 if (!verts) {
75 SkDebugf("Could not allocate vertices\n"); 62 SkDebugf("Could not allocate vertices\n");
76 return; 63 return;
77 } 64 }
78 65
79 int vertexOffset = 0; 66 uint8_t* vertPtr = reinterpret_cast<uint8_t*>(verts);
80 for (int i = 0; i < instanceCount; i++) { 67 for (int i = 0; i < instanceCount; i++) {
81 const Geometry& args = fGeoData[i]; 68 const Geometry& args = fGeoData[i];
82 69
83 for (int j = 0; j < args.fPositions.count(); ++j) { 70 size_t allocSize = args.fVerts.count();
84 *((SkPoint*)verts) = args.fPositions[j]; 71 memcpy(vertPtr, args.fVerts.begin(), allocSize);
85 if (this->hasColors()) { 72 vertPtr += allocSize;
86 *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
87 }
88 *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
89 verts = (void*)((intptr_t)verts + vertexStride);
90 vertexOffset++;
91 }
92 } 73 }
93 helper.issueDraw(batchTarget); 74 helper.issueDraw(batchTarget);
94 } 75 }
95 76
96 GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& vie wMatrix, 77 GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& vie wMatrix,
97 const SkPoint* positions, int vertexCount, 78 int spriteCount, const SkRSXform* xforms, con st SkRect* rects,
98 const GrColor* colors, const SkPoint* localCo ords, 79 const SkColor* colors) {
99 const SkRect& bounds) {
100 this->initClassID<GrDrawAtlasBatch>(); 80 this->initClassID<GrDrawAtlasBatch>();
101 SkASSERT(positions); 81 SkASSERT(xforms);
102 SkASSERT(localCoords); 82 SkASSERT(rects);
103 83
104 fViewMatrix = viewMatrix; 84 fViewMatrix = viewMatrix;
105 Geometry& installedGeo = fGeoData.push_back(geometry); 85 Geometry& installedGeo = fGeoData.push_back(geometry);
106 86
107 installedGeo.fPositions.append(vertexCount, positions); 87 // Figure out stride and offsets
108 88 // Order within the vertex is: position [color] texCoord
89 size_t texOffset = sizeof(SkPoint);
90 size_t vertexStride = 2*sizeof(SkPoint);
91 fHasColors = SkToBool(colors);
109 if (colors) { 92 if (colors) {
110 installedGeo.fColors.append(vertexCount, colors); 93 texOffset += sizeof(GrColor);
111 fHasColors = true; 94 vertexStride += sizeof(GrColor);
112 } else {
113 fHasColors = false;
114 } 95 }
115 96
116 installedGeo.fLocalCoords.append(vertexCount, localCoords); 97 // Compute buffer size and alloc buffer
117 fVertexCount = vertexCount; 98 fQuadCount = spriteCount;
99 int allocSize = static_cast<int>(4*vertexStride*spriteCount);
100 installedGeo.fVerts.reset(allocSize);
101 uint8_t* currVertex = installedGeo.fVerts.begin();
118 102
103 SkRect bounds;
104 bounds.setLargestInverted();
105 int paintAlpha = GrColorUnpackA(installedGeo.fColor);
106 for (int spriteIndex = 0; spriteIndex < spriteCount; ++spriteIndex) {
107 // Transform rect
108 SkPoint quad[4];
109 const SkRect& currRect = rects[spriteIndex];
110 xforms[spriteIndex].toQuad(currRect.width(), currRect.height(), quad);
111
112 // Copy colors if necessary
113 if (colors) {
114 // convert to GrColor
115 SkColor color = colors[spriteIndex];
116 if (paintAlpha != 255) {
117 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paintAlpha));
118 }
119 GrColor grColor = SkColor2GrColor(color);
120
121 *(reinterpret_cast<GrColor*>(currVertex+sizeof(SkPoint))) = grColor;
122 *(reinterpret_cast<GrColor*>(currVertex+vertexStride+sizeof(SkPoint) )) = grColor;
123 *(reinterpret_cast<GrColor*>(currVertex+2*vertexStride+sizeof(SkPoin t))) = grColor;
124 *(reinterpret_cast<GrColor*>(currVertex+3*vertexStride+sizeof(SkPoin t))) = grColor;
125 }
126
127 // Copy position and uv to verts
128 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[0];
129 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) = SkPoint::Make(curr Rect.fLeft,
130 curr Rect.fTop);
131 bounds.growToInclude(quad[0].fX, quad[0].fY);
132 currVertex += vertexStride;
133
134 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[1];
135 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) = SkPoint::Make(curr Rect.fRight,
136 curr Rect.fTop);
137 bounds.growToInclude(quad[1].fX, quad[1].fY);
138 currVertex += vertexStride;
139
140 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[2];
141 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) = SkPoint::Make(curr Rect.fRight,
142 curr Rect.fBottom);
143 bounds.growToInclude(quad[2].fX, quad[2].fY);
144 currVertex += vertexStride;
145
146 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[3];
147 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) = SkPoint::Make(curr Rect.fLeft,
148 curr Rect.fBottom);
149 bounds.growToInclude(quad[3].fX, quad[3].fY);
150 currVertex += vertexStride;
151 }
152
153 viewMatrix.mapRect(&bounds);
154 // Outset for a half pixel in each direction to account for snapping in non- AA case
155 bounds.outset(0.5f, 0.5f);
119 this->setBounds(bounds); 156 this->setBounds(bounds);
120 } 157 }
121 158
122 bool GrDrawAtlasBatch::onCombineIfPossible(GrBatch* t) { 159 bool GrDrawAtlasBatch::onCombineIfPossible(GrBatch* t) {
123 if (!this->pipeline()->isEqual(*t->pipeline())) { 160 if (!this->pipeline()->isEqual(*t->pipeline())) {
124 return false; 161 return false;
125 } 162 }
126 163
127 GrDrawAtlasBatch* that = t->cast<GrDrawAtlasBatch>(); 164 GrDrawAtlasBatch* that = t->cast<GrDrawAtlasBatch>();
128 165
129 // We currently use a uniform viewmatrix for this batch 166 // We currently use a uniform viewmatrix for this batch
130 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 167 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
131 return false; 168 return false;
132 } 169 }
133 170
134 if (this->hasColors() != that->hasColors()) { 171 if (this->hasColors() != that->hasColors()) {
135 return false; 172 return false;
136 } 173 }
137 174
138 if (!this->hasColors() && this->color() != that->color()) { 175 if (!this->hasColors() && this->color() != that->color()) {
139 return false; 176 return false;
140 } 177 }
141 178
142 if (this->color() != that->color()) { 179 if (this->color() != that->color()) {
143 fColor = GrColor_ILLEGAL; 180 fColor = GrColor_ILLEGAL;
144 } 181 }
145 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 182 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
146 fVertexCount += that->vertexCount(); 183 fQuadCount += that->quadCount();
147 184
148 this->joinBounds(that->bounds()); 185 this->joinBounds(that->bounds());
149 return true; 186 return true;
150 } 187 }
151 188
152 #ifdef GR_TEST_UTILS 189 #ifdef GR_TEST_UTILS
153 190
154 static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { 191 static SkRSXform random_xform(SkRandom* random) {
155 SkPoint p; 192 static const SkScalar kMinExtent = -100.f;
156 p.fX = random->nextRangeScalar(min, max); 193 static const SkScalar kMaxExtent = 100.f;
157 p.fY = random->nextRangeScalar(min, max); 194 static const SkScalar kMinScale = 0.1f;
158 return p; 195 static const SkScalar kMaxScale = 100.f;
196 static const SkScalar kMinRotate = -SK_ScalarPI;
197 static const SkScalar kMaxRotate = SK_ScalarPI;
198
199 SkRSXform xform = SkRSXform::MakeFromRadians(random->nextRangeScalar(kMinSca le, kMaxScale),
200 random->nextRangeScalar(kMinRot ate, kMaxRotate),
201 random->nextRangeScalar(kMinExt ent, kMaxExtent),
202 random->nextRangeScalar(kMinExt ent, kMaxExtent),
203 random->nextRangeScalar(kMinExt ent, kMaxExtent),
204 random->nextRangeScalar(kMinExt ent, kMaxExtent));
205 return xform;
159 } 206 }
160 207
161 static void randomize_params(size_t count, SkScalar min, SkScalar max, 208 static SkRect random_texRect(SkRandom* random) {
162 SkRandom* random, 209 static const SkScalar kMinCoord = 0.0f;
163 SkTArray<SkPoint>* positions, 210 static const SkScalar kMaxCoord = 1024.f;
164 SkTArray<SkPoint>* texCoords, 211
212 SkRect texRect = SkRect::MakeLTRB(random->nextRangeScalar(kMinCoord, kMaxCoo rd),
213 random->nextRangeScalar(kMinCoord, kMaxCoo rd),
214 random->nextRangeScalar(kMinCoord, kMaxCoo rd),
215 random->nextRangeScalar(kMinCoord, kMaxCoo rd));
216 texRect.sort();
217 return texRect;
218 }
219
220 static void randomize_params(uint32_t count, SkRandom* random,
221 SkTArray<SkRSXform>* xforms,
222 SkTArray<SkRect>* texRects,
165 SkTArray<GrColor>* colors, bool hasColors) { 223 SkTArray<GrColor>* colors, bool hasColors) {
166 for (uint32_t v = 0; v < count; v++) { 224 for (uint32_t v = 0; v < count; v++) {
167 positions->push_back(random_point(random, min, max)); 225 xforms->push_back(random_xform(random));
168 texCoords->push_back(random_point(random, min, max)); 226 texRects->push_back(random_texRect(random));
169 if (hasColors) { 227 if (hasColors) {
170 colors->push_back(GrRandomColor(random)); 228 colors->push_back(GrRandomColor(random));
171 } 229 }
172 } 230 }
173 } 231 }
174 232
175
176 BATCH_TEST_DEFINE(GrDrawAtlasBatch) { 233 BATCH_TEST_DEFINE(GrDrawAtlasBatch) {
177 uint32_t spriteCount = random->nextRangeU(1, 100); 234 uint32_t spriteCount = random->nextRangeU(1, 100);
178 235
179 // TODO make 'sensible' indexbuffers 236 SkTArray<SkRSXform> xforms(spriteCount);
180 SkTArray<SkPoint> positions; 237 SkTArray<SkRect> texRects(spriteCount);
181 SkTArray<SkPoint> texCoords; 238 SkTArray<GrColor> colors(spriteCount);
182 SkTArray<GrColor> colors;
183 239
184 bool hasColors = random->nextBool(); 240 bool hasColors = random->nextBool();
185 241
186 uint32_t vertexCount = 4*spriteCount; 242 randomize_params(spriteCount,
187
188 static const SkScalar kMinVertExtent = -100.f;
189 static const SkScalar kMaxVertExtent = 100.f;
190 randomize_params(vertexCount, kMinVertExtent, kMaxVertExtent,
191 random, 243 random,
192 &positions, 244 &xforms,
193 &texCoords, 245 &texRects,
194 &colors, hasColors); 246 &colors, hasColors);
195 247
196 SkMatrix viewMatrix = GrTest::TestMatrix(random); 248 SkMatrix viewMatrix = GrTest::TestMatrix(random);
197 SkRect bounds;
198 SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexC ount);
199 SkASSERT(result);
200
201 viewMatrix.mapRect(&bounds);
202 249
203 GrDrawAtlasBatch::Geometry geometry; 250 GrDrawAtlasBatch::Geometry geometry;
204 geometry.fColor = GrRandomColor(random); 251 geometry.fColor = GrRandomColor(random);
205 return GrDrawAtlasBatch::Create(geometry, viewMatrix, 252 return GrDrawAtlasBatch::Create(geometry, viewMatrix, spriteCount, xforms.be gin(),
206 positions.begin(), vertexCount, 253 texRects.begin(), colors.begin());
207 colors.begin(),
208 texCoords.begin(),
209 bounds);
210 } 254 }
211 255
212 #endif 256 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrDrawAtlasBatch.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698