OLD | NEW |
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 "GrDefaultPathRenderer.h" | 8 #include "GrDefaultPathRenderer.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 append_countour_edge_indices(isHairline, subpathIdxStart, | 90 append_countour_edge_indices(isHairline, subpathIdxStart, |
91 firstQPtIdx + i, idx); | 91 firstQPtIdx + i, idx); |
92 } | 92 } |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 class DefaultPathBatch : public GrVertexBatch { | 96 class DefaultPathBatch : public GrVertexBatch { |
97 public: | 97 public: |
98 DEFINE_BATCH_CLASS_ID | 98 DEFINE_BATCH_CLASS_ID |
99 | 99 |
100 struct Geometry { | 100 DefaultPathBatch(GrColor color, const SkPath& path, SkScalar tolerance, |
101 GrColor fColor; | 101 uint8_t coverage, const SkMatrix& viewMatrix, bool isHairli
ne, |
102 SkPath fPath; | 102 const SkRect& devBounds) |
103 SkScalar fTolerance; | 103 : INHERITED(ClassID()) { |
104 }; | 104 fBatch.fCoverage = coverage; |
| 105 fBatch.fIsHairline = isHairline; |
| 106 fBatch.fViewMatrix = viewMatrix; |
| 107 fGeoData.emplace_back(Geometry{color, path, tolerance}); |
105 | 108 |
106 static GrDrawBatch* Create(const Geometry& geometry, uint8_t coverage, | 109 this->setBounds(devBounds); |
107 const SkMatrix& viewMatrix, bool isHairline, | 110 |
108 const SkRect& devBounds) { | 111 // This is b.c. hairlines are notionally infinitely thin so without expa
nsion |
109 return new DefaultPathBatch(geometry, coverage, viewMatrix, isHairline,
devBounds); | 112 // two overlapping lines could be reordered even though they hit the sam
e pixels. |
| 113 if (isHairline) { |
| 114 fBounds.outset(0.5f, 0.5f); |
| 115 } |
110 } | 116 } |
111 | 117 |
112 const char* name() const override { return "DefaultPathBatch"; } | 118 const char* name() const override { return "DefaultPathBatch"; } |
113 | 119 |
114 void computePipelineOptimizations(GrInitInvariantOutput* color, | 120 void computePipelineOptimizations(GrInitInvariantOutput* color, |
115 GrInitInvariantOutput* coverage, | 121 GrInitInvariantOutput* coverage, |
116 GrBatchToXPOverrides* overrides) const ove
rride { | 122 GrBatchToXPOverrides* overrides) const ove
rride { |
117 // When this is called on a batch, there is only one geometry bundle | 123 // When this is called on a batch, there is only one geometry bundle |
118 color->setKnownFourComponents(fGeoData[0].fColor); | 124 color->setKnownFourComponents(fGeoData[0].fColor); |
119 coverage->setKnownSingleComponent(this->coverage()); | 125 coverage->setKnownSingleComponent(this->coverage()); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 } else { | 255 } else { |
250 mesh.init(primitiveType, vertexBuffer, firstVertex, vertexOffset); | 256 mesh.init(primitiveType, vertexBuffer, firstVertex, vertexOffset); |
251 } | 257 } |
252 target->draw(gp.get(), mesh); | 258 target->draw(gp.get(), mesh); |
253 | 259 |
254 // put back reserves | 260 // put back reserves |
255 target->putBackIndices((size_t)(maxIndices - indexOffset)); | 261 target->putBackIndices((size_t)(maxIndices - indexOffset)); |
256 target->putBackVertices((size_t)(maxVertices - vertexOffset), (size_t)ve
rtexStride); | 262 target->putBackVertices((size_t)(maxVertices - vertexOffset), (size_t)ve
rtexStride); |
257 } | 263 } |
258 | 264 |
259 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | |
260 | |
261 DefaultPathBatch(const Geometry& geometry, uint8_t coverage, const SkMatrix&
viewMatrix, | |
262 bool isHairline, const SkRect& devBounds) | |
263 : INHERITED(ClassID()) { | |
264 fBatch.fCoverage = coverage; | |
265 fBatch.fIsHairline = isHairline; | |
266 fBatch.fViewMatrix = viewMatrix; | |
267 fGeoData.push_back(geometry); | |
268 | |
269 this->setBounds(devBounds); | |
270 | |
271 // This is b.c. hairlines are notionally infinitely thin so without expa
nsion | |
272 // two overlapping lines could be reordered even though they hit the sam
e pixels. | |
273 if (isHairline) { | |
274 fBounds.outset(0.5f, 0.5f); | |
275 } | |
276 } | |
277 | |
278 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 265 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
279 DefaultPathBatch* that = t->cast<DefaultPathBatch>(); | 266 DefaultPathBatch* that = t->cast<DefaultPathBatch>(); |
280 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 267 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
281 that->bounds(), caps)) { | 268 that->bounds(), caps)) { |
282 return false; | 269 return false; |
283 } | 270 } |
284 | 271 |
285 if (this->color() != that->color()) { | 272 if (this->color() != that->color()) { |
286 return false; | 273 return false; |
287 } | 274 } |
288 | 275 |
289 if (this->coverage() != that->coverage()) { | 276 if (this->coverage() != that->coverage()) { |
290 return false; | 277 return false; |
291 } | 278 } |
292 | 279 |
293 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | 280 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
294 return false; | 281 return false; |
295 } | 282 } |
296 | 283 |
297 if (this->isHairline() != that->isHairline()) { | 284 if (this->isHairline() != that->isHairline()) { |
298 return false; | 285 return false; |
299 } | 286 } |
300 | 287 |
301 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 288 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); |
302 this->joinBounds(that->bounds()); | 289 this->joinBounds(that->bounds()); |
303 return true; | 290 return true; |
304 } | 291 } |
305 | 292 |
306 bool createGeom(void* vertices, | 293 bool createGeom(void* vertices, |
307 size_t vertexOffset, | 294 size_t vertexOffset, |
308 void* indices, | 295 void* indices, |
309 size_t indexOffset, | 296 size_t indexOffset, |
310 int* vertexCnt, | 297 int* vertexCnt, |
311 int* indexCnt, | 298 int* indexCnt, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 struct BatchTracker { | 397 struct BatchTracker { |
411 GrColor fColor; | 398 GrColor fColor; |
412 uint8_t fCoverage; | 399 uint8_t fCoverage; |
413 SkMatrix fViewMatrix; | 400 SkMatrix fViewMatrix; |
414 bool fUsesLocalCoords; | 401 bool fUsesLocalCoords; |
415 bool fColorIgnored; | 402 bool fColorIgnored; |
416 bool fCoverageIgnored; | 403 bool fCoverageIgnored; |
417 bool fIsHairline; | 404 bool fIsHairline; |
418 }; | 405 }; |
419 | 406 |
| 407 struct Geometry { |
| 408 GrColor fColor; |
| 409 SkPath fPath; |
| 410 SkScalar fTolerance; |
| 411 }; |
| 412 |
420 BatchTracker fBatch; | 413 BatchTracker fBatch; |
421 SkSTArray<1, Geometry, true> fGeoData; | 414 SkSTArray<1, Geometry, true> fGeoData; |
422 | 415 |
423 typedef GrVertexBatch INHERITED; | 416 typedef GrVertexBatch INHERITED; |
424 }; | 417 }; |
425 | 418 |
426 bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext, | 419 bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext, |
427 const GrPaint& paint, | 420 const GrPaint& paint, |
428 const GrUserStencilSettings* userSt
encilSettings, | 421 const GrUserStencilSettings* userSt
encilSettings, |
429 const GrClip& clip, | 422 const GrClip& clip, |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); | 563 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); |
571 pipelineBuilder.setDrawFace(drawFace[p]); | 564 pipelineBuilder.setDrawFace(drawFace[p]); |
572 if (passes[p]) { | 565 if (passes[p]) { |
573 pipelineBuilder.setUserStencil(passes[p]); | 566 pipelineBuilder.setUserStencil(passes[p]); |
574 } else { | 567 } else { |
575 pipelineBuilder.setUserStencil(userStencilSettings); | 568 pipelineBuilder.setUserStencil(userStencilSettings); |
576 } | 569 } |
577 | 570 |
578 drawContext->drawBatch(pipelineBuilder, clip, batch); | 571 drawContext->drawBatch(pipelineBuilder, clip, batch); |
579 } else { | 572 } else { |
580 DefaultPathBatch::Geometry geometry; | 573 SkAutoTUnref<GrDrawBatch> batch(new DefaultPathBatch(color, path, sr
cSpaceTol, |
581 geometry.fColor = color; | 574 newCoverage, vi
ewMatrix, |
582 geometry.fPath = path; | 575 isHairline, dev
Bounds)); |
583 geometry.fTolerance = srcSpaceTol; | |
584 | |
585 SkAutoTUnref<GrDrawBatch> batch(DefaultPathBatch::Create(geometry, n
ewCoverage, | |
586 viewMatrix,
isHairline, | |
587 devBounds))
; | |
588 | 576 |
589 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); | 577 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); |
590 pipelineBuilder.setDrawFace(drawFace[p]); | 578 pipelineBuilder.setDrawFace(drawFace[p]); |
591 if (passes[p]) { | 579 if (passes[p]) { |
592 pipelineBuilder.setUserStencil(passes[p]); | 580 pipelineBuilder.setUserStencil(passes[p]); |
593 } else { | 581 } else { |
594 pipelineBuilder.setUserStencil(userStencilSettings); | 582 pipelineBuilder.setUserStencil(userStencilSettings); |
595 } | 583 } |
596 if (passCount > 1) { | 584 if (passCount > 1) { |
597 pipelineBuilder.setDisableColorXPFactory(); | 585 pipelineBuilder.setDisableColorXPFactory(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // For now just hairlines because the other types of draws require two batch
es. | 635 // For now just hairlines because the other types of draws require two batch
es. |
648 // TODO we should figure out a way to combine the stencil and cover steps in
to one batch | 636 // TODO we should figure out a way to combine the stencil and cover steps in
to one batch |
649 GrStyle style(SkStrokeRec::kHairline_InitStyle); | 637 GrStyle style(SkStrokeRec::kHairline_InitStyle); |
650 SkPath path = GrTest::TestPath(random); | 638 SkPath path = GrTest::TestPath(random); |
651 | 639 |
652 // Compute srcSpaceTol | 640 // Compute srcSpaceTol |
653 SkRect bounds = path.getBounds(); | 641 SkRect bounds = path.getBounds(); |
654 SkScalar tol = GrPathUtils::kDefaultTolerance; | 642 SkScalar tol = GrPathUtils::kDefaultTolerance; |
655 SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, bou
nds); | 643 SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, bou
nds); |
656 | 644 |
657 DefaultPathBatch::Geometry geometry; | |
658 geometry.fColor = color; | |
659 geometry.fPath = path; | |
660 geometry.fTolerance = srcSpaceTol; | |
661 | |
662 viewMatrix.mapRect(&bounds); | 645 viewMatrix.mapRect(&bounds); |
663 uint8_t coverage = GrRandomCoverage(random); | 646 uint8_t coverage = GrRandomCoverage(random); |
664 return DefaultPathBatch::Create(geometry, coverage, viewMatrix, true, bounds
); | 647 return new DefaultPathBatch(color, path, srcSpaceTol, coverage, viewMatrix,
true, bounds); |
665 } | 648 } |
666 | 649 |
667 #endif | 650 #endif |
OLD | NEW |