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

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: Re-enable batching for DrawAtlas 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 "SkRandom.h" 10 #include "SkRandom.h"
11 #include "SkRSXform.h"
11 12
12 void GrDrawAtlasBatch::initBatchTracker(const GrPipelineOptimizations& opt) { 13 void GrDrawAtlasBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
13 // Handle any color overrides 14 // Handle any color overrides
14 if (!opt.readsColor()) { 15 if (!opt.readsColor()) {
15 fGeoData[0].fColor = GrColor_ILLEGAL; 16 fGeoData[0].fColor = GrColor_ILLEGAL;
16 } 17 }
17 opt.getOverrideColorIfSet(&fGeoData[0].fColor); 18 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
18 19
19 // setup batch properties 20 // setup batch properties
20 fColorIgnored = !opt.readsColor(); 21 fColorIgnored = !opt.readsColor();
21 fColor = fGeoData[0].fColor; 22 fColor = fGeoData[0].fColor;
22 // We'd like to assert this, but we can't because of GLPrograms test 23 // We'd like to assert this, but we can't because of GLPrograms test
23 //SkASSERT(init.readsLocalCoords()); 24 //SkASSERT(init.readsLocalCoords());
24 fCoverageIgnored = !opt.readsCoverage(); 25 fCoverageIgnored = !opt.readsCoverage();
25 } 26 }
26 27
27 static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, 28 static const GrGeometryProcessor* set_vertex_attributes(bool hasColors,
28 bool hasColors,
29 int* colorOffset,
30 int* texOffset,
31 GrColor color, 29 GrColor color,
32 const SkMatrix& viewMatr ix, 30 const SkMatrix& viewMatr ix,
33 bool coverageIgnored) { 31 bool coverageIgnored) {
34 using namespace GrDefaultGeoProcFactory; 32 using namespace GrDefaultGeoProcFactory;
35 *texOffset = -1;
36 *colorOffset = -1;
37 Color gpColor(color); 33 Color gpColor(color);
38 if (hasColors) { 34 if (hasColors) {
39 gpColor.fType = Color::kAttribute_Type; 35 gpColor.fType = Color::kAttribute_Type;
40 } 36 }
41 37
42 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type); 38 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type);
43 LocalCoords localCoords(hasLocalCoords ? LocalCoords::kHasExplicit_Type : 39 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); 40 return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewM atrix);
54 } 41 }
55 42
56 void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { 43 void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) {
57 int colorOffset = -1, texOffset = -1;
58 // Setup geometry processor 44 // Setup geometry processor
59 SkAutoTUnref<const GrGeometryProcessor> gp( 45 SkAutoTUnref<const GrGeometryProcessor> gp(set_vertex_attributes(this->hasCo lors(),
60 set_vertex_attributes(true, this->hasColors(), & colorOffset, 46 this->color (),
61 &texOffset, this->color(), this->viewMatrix(), 47 this->viewM atrix(),
62 this->coverageIgnored())); 48 this->cover ageIgnored()));
63 49
64 batchTarget->initDraw(gp, this->pipeline()); 50 batchTarget->initDraw(gp, this->pipeline());
65 51
66 int instanceCount = fGeoData.count(); 52 int instanceCount = fGeoData.count();
67 size_t vertexStride = gp->getVertexStride(); 53 size_t vertexStride = gp->getVertexStride();
68 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) 54 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint)
69 + (this->hasColors() ? sizeof(GrColor) : 0)); 55 + (this->hasColors() ? sizeof(GrColor) : 0));
70 56
71 QuadHelper helper; 57 QuadHelper helper;
72 int numQuads = this->vertexCount()/4; 58 int numQuads = this->quadCount();
73 void* verts = helper.init(batchTarget, vertexStride, numQuads); 59 void* verts = helper.init(batchTarget, vertexStride, numQuads);
74 if (!verts) { 60 if (!verts) {
75 SkDebugf("Could not allocate vertices\n"); 61 SkDebugf("Could not allocate vertices\n");
76 return; 62 return;
77 } 63 }
78 64
79 int vertexOffset = 0; 65 uint8_t* vertPtr = reinterpret_cast<uint8_t*>(verts);
80 for (int i = 0; i < instanceCount; i++) { 66 for (int i = 0; i < instanceCount; i++) {
81 const Geometry& args = fGeoData[i]; 67 const Geometry& args = fGeoData[i];
82 68
83 for (int j = 0; j < args.fPositions.count(); ++j) { 69 size_t allocSize = args.fVerts.count();
84 *((SkPoint*)verts) = args.fPositions[j]; 70 memcpy(vertPtr, args.fVerts.begin(), allocSize);
85 if (this->hasColors()) { 71 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 } 72 }
93 helper.issueDraw(batchTarget); 73 helper.issueDraw(batchTarget);
94 } 74 }
95 75
96 GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& vie wMatrix, 76 GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& vie wMatrix,
97 const SkPoint* positions, int vertexCount, 77 int spriteCount, const SkRSXform* xforms, con st SkRect* rects,
robertphillips 2015/08/11 15:32:06 Don't we assume these are premul?
jvanverth1 2015/08/11 20:22:55 Added the GrColor conversion back in.
98 const GrColor* colors, const SkPoint* localCo ords, 78 const SkColor* colors) {
99 const SkRect& bounds) {
100 this->initClassID<GrDrawAtlasBatch>(); 79 this->initClassID<GrDrawAtlasBatch>();
101 SkASSERT(positions); 80 SkASSERT(xforms);
102 SkASSERT(localCoords); 81 SkASSERT(rects);
103 82
104 fViewMatrix = viewMatrix; 83 fViewMatrix = viewMatrix;
105 Geometry& installedGeo = fGeoData.push_back(geometry); 84 Geometry& installedGeo = fGeoData.push_back(geometry);
106 85
107 installedGeo.fPositions.append(vertexCount, positions); 86 // figure out stride and offsets
108 87 SkColor dummyColor;
88 const SkColor* colorPtr = &dummyColor;
89 size_t colorStep = 0;
90 size_t colorOffset = sizeof(SkPoint);
91 size_t texOffset = sizeof(SkPoint);
92 size_t stride = 2*sizeof(SkPoint);
93 fHasColors = false;
109 if (colors) { 94 if (colors) {
110 installedGeo.fColors.append(vertexCount, colors); 95 colorOffset = sizeof(SkPoint);
96 texOffset += sizeof(GrColor);
97 stride += sizeof(GrColor);
98 colorPtr = colors;
99 colorStep = sizeof(GrColor);
111 fHasColors = true; 100 fHasColors = true;
112 } else {
113 fHasColors = false;
114 } 101 }
115 102
116 installedGeo.fLocalCoords.append(vertexCount, localCoords); 103 // compute buffer size and alloc buffer
117 fVertexCount = vertexCount; 104 fQuadCount = spriteCount;
105 size_t allocSize = 4*stride*spriteCount;
106 installedGeo.fVerts.reset(allocSize);
107 uint8_t* currVertex = installedGeo.fVerts.begin();
118 108
109 SkRect bounds;
110 sk_bzero(&bounds, sizeof(SkRect));
111 for (int spriteIndex = 0; spriteIndex < spriteCount; ++spriteIndex) {
112 // transform rect
113 SkPoint quad[4];
114 xforms[spriteIndex].toQuad(rects[spriteIndex].width(), rects[spriteIndex ].height(), quad);
115
116 // copy to verts
117 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[0];
118 *(reinterpret_cast<SkColor*>(currVertex+colorOffset)) = *colorPtr;
119 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) =
120 SkPoint::Make(rects[spriteIndex].fLeft, rects[sprite Index].fTop);
121 bounds.growToInclude(quad[0].fX, quad[0].fY);
122 currVertex += stride;
123
124 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[1];
125 *(reinterpret_cast<SkColor*>(currVertex+colorOffset)) = *colorPtr;
126 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) =
127 SkPoint::Make(rects[spriteIndex].fRight, rects[sprit eIndex].fTop);
128 bounds.growToInclude(quad[1].fX, quad[1].fY);
129 currVertex += stride;
130
131 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[2];
132 *(reinterpret_cast<SkColor*>(currVertex+colorOffset)) = *colorPtr;
133 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) =
134 SkPoint::Make(rects[spriteIndex].fRight, rects[sprit eIndex].fBottom);
135 bounds.growToInclude(quad[2].fX, quad[2].fY);
136 currVertex += stride;
137
138 *(reinterpret_cast<SkPoint*>(currVertex)) = quad[3];
139 *(reinterpret_cast<SkColor*>(currVertex+colorOffset)) = *colorPtr;
140 *(reinterpret_cast<SkPoint*>(currVertex+texOffset)) =
141 SkPoint::Make(rects[spriteIndex].fLeft, rects[sprite Index].fBottom);
142 bounds.growToInclude(quad[3].fX, quad[3].fY);
143 currVertex += stride;
144
145 // step to next sprite
146 colorPtr += colorStep;
147 }
148
149 viewMatrix.mapRect(&bounds);
150 // outset for a half pixel in each direction to account for snapping in non- AA case
151 bounds.outset(0.5f, 0.5f);
119 this->setBounds(bounds); 152 this->setBounds(bounds);
120 } 153 }
121 154
122 bool GrDrawAtlasBatch::onCombineIfPossible(GrBatch* t) { 155 bool GrDrawAtlasBatch::onCombineIfPossible(GrBatch* t) {
123 if (!this->pipeline()->isEqual(*t->pipeline())) { 156 if (!this->pipeline()->isEqual(*t->pipeline())) {
124 return false; 157 return false;
125 } 158 }
126 159
127 GrDrawAtlasBatch* that = t->cast<GrDrawAtlasBatch>(); 160 GrDrawAtlasBatch* that = t->cast<GrDrawAtlasBatch>();
128 161
129 // We currently use a uniform viewmatrix for this batch 162 // We currently use a uniform viewmatrix for this batch
130 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 163 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
131 return false; 164 return false;
132 } 165 }
133 166
134 if (this->hasColors() != that->hasColors()) { 167 if (this->hasColors() != that->hasColors()) {
135 return false; 168 return false;
136 } 169 }
137 170
138 if (!this->hasColors() && this->color() != that->color()) { 171 if (!this->hasColors() && this->color() != that->color()) {
139 return false; 172 return false;
140 } 173 }
141 174
142 if (this->color() != that->color()) { 175 if (this->color() != that->color()) {
143 fColor = GrColor_ILLEGAL; 176 fColor = GrColor_ILLEGAL;
144 } 177 }
145 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 178 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
146 fVertexCount += that->vertexCount(); 179 fQuadCount += that->quadCount();
147 180
148 this->joinBounds(that->bounds()); 181 this->joinBounds(that->bounds());
149 return true; 182 return true;
150 } 183 }
151 184
152 #ifdef GR_TEST_UTILS 185 #ifdef GR_TEST_UTILS
153 186
154 static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { 187 static SkRSXform random_xform(SkRandom* random) {
155 SkPoint p; 188 static const SkScalar kMinExtent = -100.f;
156 p.fX = random->nextRangeScalar(min, max); 189 static const SkScalar kMaxExtent = 100.f;
157 p.fY = random->nextRangeScalar(min, max); 190 static const SkScalar kMinScale = 0.1f;
158 return p; 191 static const SkScalar kMaxScale = 100.f;
192 static const SkScalar kMinRotate = -SK_ScalarPI;
193 static const SkScalar kMaxRotate = SK_ScalarPI;
194
195 SkRSXform xform = SkRSXform::MakeFromRadians(random->nextRangeScalar(kMinSca le, kMaxScale),
196 random->nextRangeScalar(kMinRot ate, kMaxRotate),
197 random->nextRangeScalar(kMinExt ent, kMaxExtent),
198 random->nextRangeScalar(kMinExt ent, kMaxExtent),
199 0.0, 0.0f);
200 return xform;
159 } 201 }
160 202
161 static void randomize_params(size_t count, SkScalar min, SkScalar max, 203 static SkRect random_texRect(SkRandom* random) {
162 SkRandom* random, 204 static const SkScalar kMinCoord = 0.0f;
163 SkTArray<SkPoint>* positions, 205 static const SkScalar kMaxCoord = 1024.f;
164 SkTArray<SkPoint>* texCoords, 206 SkRect texRect = SkRect::MakeLTRB(random->nextRangeScalar(kMinCoord, kMaxCoo rd),
207 random->nextRangeScalar(kMinCoord, kMaxCoo rd),
208 random->nextRangeScalar(kMinCoord, kMaxCoo rd),
209 random->nextRangeScalar(kMinCoord, kMaxCoo rd));
210 return texRect;
211 }
212
213 static void randomize_params(size_t count, SkRandom* random,
214 SkTArray<SkRSXform>* xforms,
215 SkTArray<SkRect>* texRects,
165 SkTArray<GrColor>* colors, bool hasColors) { 216 SkTArray<GrColor>* colors, bool hasColors) {
166 for (uint32_t v = 0; v < count; v++) { 217 for (uint32_t v = 0; v < count; v++) {
167 positions->push_back(random_point(random, min, max)); 218 xforms->push_back(random_xform(random));
168 texCoords->push_back(random_point(random, min, max)); 219 texRects->push_back(random_texRect(random));
169 if (hasColors) { 220 if (hasColors) {
170 colors->push_back(GrRandomColor(random)); 221 colors->push_back(GrRandomColor(random));
171 } 222 }
172 } 223 }
173 } 224 }
174 225
175
176 BATCH_TEST_DEFINE(GrDrawAtlasBatch) { 226 BATCH_TEST_DEFINE(GrDrawAtlasBatch) {
177 uint32_t spriteCount = random->nextRangeU(1, 100); 227 uint32_t spriteCount = random->nextRangeU(1, 100);
178 228
179 // TODO make 'sensible' indexbuffers 229 SkTArray<SkRSXform> xforms;
180 SkTArray<SkPoint> positions; 230 SkTArray<SkRect> texRects;
181 SkTArray<SkPoint> texCoords;
182 SkTArray<GrColor> colors; 231 SkTArray<GrColor> colors;
183 232
184 bool hasColors = random->nextBool(); 233 bool hasColors = random->nextBool();
185 234
186 uint32_t vertexCount = 4*spriteCount; 235 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, 236 random,
192 &positions, 237 &xforms,
193 &texCoords, 238 &texRects,
194 &colors, hasColors); 239 &colors, hasColors);
195 240
196 SkMatrix viewMatrix = GrTest::TestMatrix(random); 241 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 242
203 GrDrawAtlasBatch::Geometry geometry; 243 GrDrawAtlasBatch::Geometry geometry;
204 geometry.fColor = GrRandomColor(random); 244 geometry.fColor = GrRandomColor(random);
205 return GrDrawAtlasBatch::Create(geometry, viewMatrix, 245 return GrDrawAtlasBatch::Create(geometry, viewMatrix, spriteCount, xforms.be gin(),
206 positions.begin(), vertexCount, 246 texRects.begin(), colors.begin());
207 colors.begin(),
208 texCoords.begin(),
209 bounds);
210 } 247 }
211 248
212 #endif 249 #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