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

Side by Side Diff: src/gpu/GrInOrderDrawBuffer.cpp

Issue 944743005: Revert of non-aa rects batch (Closed) Base URL: https://skia.googlesource.com/skia.git@dash
Patch Set: Created 5 years, 10 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 | « no previous file | 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 2011 Google Inc. 2 * Copyright 2011 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 "GrInOrderDrawBuffer.h" 8 #include "GrInOrderDrawBuffer.h"
9 9
10 #include "GrBufferAllocPool.h" 10 #include "GrBufferAllocPool.h"
(...skipping 20 matching lines...) Expand all
31 fPathIndexBuffer.setReserve(kPathIdxBufferMinReserve); 31 fPathIndexBuffer.setReserve(kPathIdxBufferMinReserve);
32 fPathTransformBuffer.setReserve(kPathXformBufferMinReserve); 32 fPathTransformBuffer.setReserve(kPathXformBufferMinReserve);
33 } 33 }
34 34
35 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() { 35 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
36 this->reset(); 36 this->reset();
37 } 37 }
38 38
39 //////////////////////////////////////////////////////////////////////////////// 39 ////////////////////////////////////////////////////////////////////////////////
40 40
41 namespace {
42 void get_vertex_bounds(const void* vertices,
43 size_t vertexSize,
44 int vertexCount,
45 SkRect* bounds) {
46 SkASSERT(vertexSize >= sizeof(SkPoint));
47 SkASSERT(vertexCount > 0);
48 const SkPoint* point = static_cast<const SkPoint*>(vertices);
49 bounds->fLeft = bounds->fRight = point->fX;
50 bounds->fTop = bounds->fBottom = point->fY;
51 for (int i = 1; i < vertexCount; ++i) {
52 point = reinterpret_cast<SkPoint*>(reinterpret_cast<intptr_t>(point) + v ertexSize);
53 bounds->growToInclude(point->fX, point->fY);
54 }
55 }
56 }
57
41 /** We always use per-vertex colors so that rects can be batched across color ch anges. Sometimes we 58 /** We always use per-vertex colors so that rects can be batched across color ch anges. Sometimes we
42 have explicit local coords and sometimes not. We *could* always provide expl icit local coords 59 have explicit local coords and sometimes not. We *could* always provide expl icit local coords
43 and just duplicate the positions when the caller hasn't provided a local coo rd rect, but we 60 and just duplicate the positions when the caller hasn't provided a local coo rd rect, but we
44 haven't seen a use case which frequently switches between local rect and no local rect draws. 61 haven't seen a use case which frequently switches between local rect and no local rect draws.
45 62
46 The color param is used to determine whether the opaque hint can be set on t he draw state. 63 The color param is used to determine whether the opaque hint can be set on t he draw state.
47 The caller must populate the vertex colors itself. 64 The caller must populate the vertex colors itself.
48 65
49 The vertex attrib order is always pos, color, [local coords]. 66 The vertex attrib order is always pos, color, [local coords].
50 */ 67 */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 // allocated space, and leave enough for 50% growth over last time. 99 // allocated space, and leave enough for 50% growth over last time.
83 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minRese rve) { 100 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minRese rve) {
84 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2); 101 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2);
85 buffer->reset(); 102 buffer->reset();
86 buffer->setReserve(reserve); 103 buffer->setReserve(reserve);
87 } else { 104 } else {
88 buffer->rewind(); 105 buffer->rewind();
89 } 106 }
90 } 107 }
91 108
92 class RectBatch : public GrBatch {
93 public:
94 struct Geometry {
95 GrColor fColor;
96 SkMatrix fViewMatrix;
97 SkRect fRect;
98 bool fHasLocalRect;
99 bool fHasLocalMatrix;
100 SkRect fLocalRect;
101 SkMatrix fLocalMatrix;
102 };
103
104 static GrBatch* Create(const Geometry& geometry) {
105 return SkNEW_ARGS(RectBatch, (geometry));
106 }
107
108 const char* name() const SK_OVERRIDE { return "RectBatch"; }
109
110 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
111 // When this is called on a batch, there is only one geometry bundle
112 if (GrColorIsOpaque(fGeoData[0].fColor)) {
113 out->setUnknownOpaqueFourComponents();
114 } else {
115 out->setUnknownFourComponents();
116 }
117 }
118
119 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E {
120 out->setUnknownSingleComponent();
121 }
122
123 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
124 // Handle any color overrides
125 if (init.fColorIgnored) {
126 fGeoData[0].fColor = GrColor_ILLEGAL;
127 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
128 fGeoData[0].fColor = init.fOverrideColor;
129 }
130
131 // setup batch properties
132 fBatch.fColorIgnored = init.fColorIgnored;
133 fBatch.fColor = fGeoData[0].fColor;
134 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
135 fBatch.fCoverageIgnored = init.fCoverageIgnored;
136 }
137
138 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) SK_OVERRIDE {
139 // Go to device coords to allow batching across matrix changes
140 SkMatrix invert = SkMatrix::I();
141
142 // if we have a local rect, then we apply the localMatrix directly to th e localRect to
143 // generate vertex local coords
144 bool hasExplicitLocalCoords = this->hasLocalRect();
145 if (!hasExplicitLocalCoords) {
146 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(& invert)) {
147 SkDebugf("Could not invert\n");
148 return;
149 }
150
151 if (this->hasLocalMatrix()) {
152 invert.preConcat(this->localMatrix());
153 }
154 }
155
156 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLoc alCoords,
157 this->color(),
158 &invert));
159
160 batchTarget->initDraw(gp, pipeline);
161
162 // TODO this is hacky, but the only way we have to initialize the GP is to use the
163 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
164 // everywhere we can remove this nastiness
165 GrPipelineInfo init;
166 init.fColorIgnored = fBatch.fColorIgnored;
167 init.fOverrideColor = GrColor_ILLEGAL;
168 init.fCoverageIgnored = fBatch.fCoverageIgnored;
169 init.fUsesLocalCoords = this->usesLocalCoords();
170 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
171
172 size_t vertexStride = gp->getVertexStride();
173
174 SkASSERT(hasExplicitLocalCoords ?
175 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) :
176 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr));
177
178 int instanceCount = fGeoData.count();
179 int vertexCount = kVertsPerRect * instanceCount;
180
181 const GrVertexBuffer* vertexBuffer;
182 int firstVertex;
183
184 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
185 vertexCount,
186 &vertexBuffer,
187 &firstVertex);
188
189 for (int i = 0; i < instanceCount; i++) {
190 const Geometry& args = fGeoData[i];
191
192 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
193 SkPoint* positions = GrTCast<SkPoint*>(offset);
194
195 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
196 args.fRect.fRight, args.fRect.fBottom, vertexS tride);
197 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerts PerRect);
198
199 if (args.fHasLocalRect) {
200 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor );
201 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
202 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
203 args.fLocalRect.fRight, args.fLocalRect.fBott om,
204 vertexStride);
205 if (args.fHasLocalMatrix) {
206 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
207 }
208 }
209
210 static const int kColorOffset = sizeof(SkPoint);
211 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
212 for (int j = 0; j < 4; ++j) {
213 *vertColor = args.fColor;
214 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
215 }
216 }
217
218 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
219
220 GrDrawTarget::DrawInfo drawInfo;
221 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
222 drawInfo.setStartVertex(0);
223 drawInfo.setStartIndex(0);
224 drawInfo.setVerticesPerInstance(kVertsPerRect);
225 drawInfo.setIndicesPerInstance(kIndicesPerRect);
226 drawInfo.adjustStartVertex(firstVertex);
227 drawInfo.setVertexBuffer(vertexBuffer);
228 drawInfo.setIndexBuffer(quadIndexBuffer);
229
230 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
231 while (instanceCount) {
232 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw) );
233 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices PerInstance());
234 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe rInstance());
235
236 batchTarget->draw(drawInfo);
237
238 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun t());
239 instanceCount -= drawInfo.instanceCount();
240 }
241 }
242
243 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
244
245 private:
246 RectBatch(const Geometry& geometry) {
247 this->initClassID<RectBatch>();
248 fGeoData.push_back(geometry);
249 }
250
251 GrColor color() const { return fBatch.fColor; }
252 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
253 bool colorIgnored() const { return fBatch.fColorIgnored; }
254 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
255 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
256 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
257 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
258
259 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
260 RectBatch* that = t->cast<RectBatch>();
261
262 if (this->hasLocalRect() != that->hasLocalRect()) {
263 return false;
264 }
265
266 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
267 if (!this->hasLocalRect() && this->usesLocalCoords()) {
268 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
269 return false;
270 }
271
272 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
273 return false;
274 }
275
276 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that ->localMatrix())) {
277 return false;
278 }
279 }
280
281 if (this->color() != that->color()) {
282 fBatch.fColor = GrColor_ILLEGAL;
283 }
284 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
285 return true;
286 }
287
288 struct BatchTracker {
289 GrColor fColor;
290 bool fUsesLocalCoords;
291 bool fColorIgnored;
292 bool fCoverageIgnored;
293 };
294
295 const static int kVertsPerRect = 4;
296 const static int kIndicesPerRect = 6;
297
298 BatchTracker fBatch;
299 SkSTArray<1, Geometry, true> fGeoData;
300 };
301
302 void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder, 109 void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
303 GrColor color, 110 GrColor color,
304 const SkMatrix& viewMatrix, 111 const SkMatrix& viewMatrix,
305 const SkRect& rect, 112 const SkRect& rect,
306 const SkRect* localRect, 113 const SkRect* localRect,
307 const SkMatrix* localMatrix) { 114 const SkMatrix* localMatrix) {
308 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder); 115 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
309 RectBatch::Geometry geometry; 116
310 geometry.fColor = color; 117 // Go to device coords to allow batching across matrix changes
311 geometry.fViewMatrix = viewMatrix; 118 SkMatrix invert = SkMatrix::I();
312 geometry.fRect = rect; 119
120 // if we have a local rect, then we apply the localMatrix directly to the lo calRect to generate
121 // vertex local coords
122 bool hasExplicitLocalCoords = SkToBool(localRect);
123 if (!hasExplicitLocalCoords) {
124 if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
125 SkDebugf("Could not invert\n");
126 return;
127 }
128
129 if (localMatrix) {
130 invert.preConcat(*localMatrix);
131 }
132 }
133
134 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCo ords,
135 color,
136 &invert));
137
138 size_t vstride = gp->getVertexStride();
139 SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
140 0));
141 AutoReleaseGeometry geo(this, 4, vstride, 0);
142 if (!geo.succeeded()) {
143 SkDebugf("Failed to get space for vertices!\n");
144 return;
145 }
146
147 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom , vstride);
148 viewMatrix.mapPointsWithStride(geo.positions(), vstride, 4);
149
150 // When the caller has provided an explicit source rect for a stage then we don't want to
151 // modify that stage's matrix. Otherwise if the effect is generating its sou rce rect from
152 // the vertex positions then we have to account for the view matrix
153 SkRect devBounds;
154
155 // since we already computed the dev verts, set the bounds hint. This will h elp us avoid
156 // unnecessary clipping in our onDraw().
157 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
313 158
314 if (localRect) { 159 if (localRect) {
315 geometry.fHasLocalRect = true; 160 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
316 geometry.fLocalRect = *localRect; 161 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
317 } else { 162 coords->setRectFan(localRect->fLeft, localRect->fTop,
318 geometry.fHasLocalRect = false; 163 localRect->fRight, localRect->fBottom,
164 vstride);
165 if (localMatrix) {
166 localMatrix->mapPointsWithStride(coords, vstride, 4);
167 }
319 } 168 }
320 169
321 if (localMatrix) { 170 static const int kColorOffset = sizeof(SkPoint);
322 geometry.fHasLocalMatrix = true; 171 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k ColorOffset);
323 geometry.fLocalMatrix = *localMatrix; 172 for (int i = 0; i < 4; ++i) {
324 } else { 173 *vertColor = color;
325 geometry.fHasLocalMatrix = false; 174 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
326 } 175 }
327 176
328 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry)); 177 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
329 178 this->drawIndexedInstances(pipelineBuilder, gp, kTriangles_GrPrimitiveType, 1, 4, 6,
330 SkRect bounds = rect; 179 &devBounds);
331 viewMatrix.mapRect(&bounds);
332 this->drawBatch(pipelineBuilder, batch, &bounds);
333 } 180 }
334 181
335 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { 182 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
336 SkASSERT(!fCmdBuffer.empty()); 183 SkASSERT(!fCmdBuffer.empty());
337 SkASSERT(info.isInstanced()); 184 SkASSERT(info.isInstanced());
338 185
339 const GeometrySrcState& geomSrc = this->getGeomSrc(); 186 const GeometrySrcState& geomSrc = this->getGeomSrc();
340 187
341 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index 188 // we only attempt to concat the case when reserved verts are used with a cl ient-specified index
342 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated 189 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 281
435 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder , 282 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder ,
436 const GrPathProcessor* pathProc, 283 const GrPathProcessor* pathProc,
437 const GrPath* path, 284 const GrPath* path,
438 const GrScissorState& scissorState, 285 const GrScissorState& scissorState,
439 const GrStencilSettings& stencilSettings ) { 286 const GrStencilSettings& stencilSettings ) {
440 this->closeBatch(); 287 this->closeBatch();
441 288
442 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, 289 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
443 (path, pipelineBuilder.getRenderT arget())); 290 (path, pipelineBuilder.getRenderT arget()));
444
445 sp->fScissor = scissorState; 291 sp->fScissor = scissorState;
446 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); 292 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
447 sp->fViewMatrix = pathProc->viewMatrix(); 293 sp->fViewMatrix = pathProc->viewMatrix();
448 sp->fStencil = stencilSettings; 294 sp->fStencil = stencilSettings;
449 this->recordTraceMarkersIfNecessary(); 295 this->recordTraceMarkersIfNecessary();
450 } 296 }
451 297
452 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, 298 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
453 const GrPath* path, 299 const GrPath* path,
454 const GrStencilSettings& stencilSettings, 300 const GrStencilSettings& stencilSettings,
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 } 624 }
779 } 625 }
780 626
781 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, 627 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
782 size_t vertexStride, 628 size_t vertexStride,
783 int indexCount) { 629 int indexCount) {
784 this->closeBatch(); 630 this->closeBatch();
785 631
786 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i ndexCount); 632 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i ndexCount);
787 } 633 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698