OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "GrMSAAPathRenderer.h" | 8 #include "GrMSAAPathRenderer.h" |
9 | 9 |
10 #include "GrAuditTrail.h" | 10 #include "GrAuditTrail.h" |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 218 |
219 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 219 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
220 | 220 |
221 typedef GrGeometryProcessor INHERITED; | 221 typedef GrGeometryProcessor INHERITED; |
222 }; | 222 }; |
223 | 223 |
224 class MSAAPathBatch : public GrVertexBatch { | 224 class MSAAPathBatch : public GrVertexBatch { |
225 public: | 225 public: |
226 DEFINE_BATCH_CLASS_ID | 226 DEFINE_BATCH_CLASS_ID |
227 | 227 |
228 struct Geometry { | 228 MSAAPathBatch(GrColor color, const SkPath& path, const SkMatrix& viewMatrix, |
229 GrColor fColor; | 229 const SkRect& devBounds) |
230 SkPath fPath; | 230 : INHERITED(ClassID()) |
231 SkScalar fTolerance; | 231 , fViewMatrix(viewMatrix) { |
232 }; | 232 fPaths.emplace_back(PathInfo{color, path}); |
233 | 233 this->setBounds(devBounds); |
234 static MSAAPathBatch* Create(const Geometry& geometry, const SkMatrix& viewM
atrix, | 234 int contourCount; |
235 const SkRect& devBounds) { | 235 this->computeWorstCasePointCount(path, &contourCount, &fMaxLineVertices,
&fMaxQuadVertices); |
236 return new MSAAPathBatch(geometry, viewMatrix, devBounds); | 236 fMaxLineIndices = fMaxLineVertices * 3; |
| 237 fMaxQuadIndices = fMaxQuadVertices * 3; |
| 238 fIsIndexed = contourCount > 1; |
237 } | 239 } |
238 | 240 |
239 const char* name() const override { return "MSAAPathBatch"; } | 241 const char* name() const override { return "MSAAPathBatch"; } |
240 | 242 |
241 void computePipelineOptimizations(GrInitInvariantOutput* color, | 243 void computePipelineOptimizations(GrInitInvariantOutput* color, |
242 GrInitInvariantOutput* coverage, | 244 GrInitInvariantOutput* coverage, |
243 GrBatchToXPOverrides* overrides) const ove
rride { | 245 GrBatchToXPOverrides* overrides) const ove
rride { |
244 // When this is called on a batch, there is only one geometry bundle | 246 // When this is called on a batch, there is only one path |
245 color->setKnownFourComponents(fGeoData[0].fColor); | 247 color->setKnownFourComponents(fPaths[0].fColor); |
246 coverage->setKnownSingleComponent(0xff); | 248 coverage->setKnownSingleComponent(0xff); |
247 } | 249 } |
248 | 250 |
249 bool isValid() const { | 251 bool isValid() const { |
250 return !fIsIndexed || fMaxLineIndices <= SK_MaxU16; | 252 return !fIsIndexed || fMaxLineIndices <= SK_MaxU16; |
251 } | 253 } |
252 | 254 |
253 private: | 255 private: |
254 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 256 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
255 // Handle any color overrides | 257 // Handle any color overrides |
256 if (!overrides.readsColor()) { | 258 if (!overrides.readsColor()) { |
257 fGeoData[0].fColor = GrColor_ILLEGAL; | 259 fPaths[0].fColor = GrColor_ILLEGAL; |
258 } | 260 } |
259 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | 261 overrides.getOverrideColorIfSet(&fPaths[0].fColor); |
260 } | 262 } |
261 | 263 |
262 void computeWorstCasePointCount(const SkPath& path, int* subpaths, SkScalar
tol, | 264 void computeWorstCasePointCount(const SkPath& path, int* subpaths, int* outL
inePointCount, |
263 int* outLinePointCount, int* outQuadPointCou
nt) const { | 265 int* outQuadPointCount) const { |
264 int linePointCount = 0; | 266 int linePointCount = 0; |
265 int quadPointCount = 0; | 267 int quadPointCount = 0; |
266 *subpaths = 1; | 268 *subpaths = 1; |
267 | 269 |
268 bool first = true; | 270 bool first = true; |
269 | 271 |
270 SkPath::Iter iter(path, false); | 272 SkPath::Iter iter(path, false); |
271 SkPath::Verb verb; | 273 SkPath::Verb verb; |
272 | 274 |
273 SkPoint pts[4]; | 275 SkPoint pts[4]; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 if (fIsIndexed) { | 365 if (fIsIndexed) { |
364 quads.indices = (uint16_t*) sk_malloc_throw(fMaxQuadIndices * sizeof
(uint16_t)); | 366 quads.indices = (uint16_t*) sk_malloc_throw(fMaxQuadIndices * sizeof
(uint16_t)); |
365 quadIndexPtr.set(quads.indices); | 367 quadIndexPtr.set(quads.indices); |
366 quads.nextIndex = quads.indices; | 368 quads.nextIndex = quads.indices; |
367 } else { | 369 } else { |
368 quads.indices = nullptr; | 370 quads.indices = nullptr; |
369 quads.nextIndex = nullptr; | 371 quads.nextIndex = nullptr; |
370 } | 372 } |
371 | 373 |
372 // fill buffers | 374 // fill buffers |
373 for (int i = 0; i < fGeoData.count(); i++) { | 375 for (int i = 0; i < fPaths.count(); i++) { |
374 const Geometry& args = fGeoData[i]; | 376 const PathInfo& pathInfo = fPaths[i]; |
375 | 377 |
376 if (!this->createGeom(lines, | 378 if (!this->createGeom(lines, |
377 quads, | 379 quads, |
378 args.fPath, | 380 pathInfo.fPath, |
379 args.fTolerance, | |
380 fViewMatrix, | 381 fViewMatrix, |
381 args.fColor, | 382 pathInfo.fColor, |
382 fIsIndexed)) { | 383 fIsIndexed)) { |
383 return; | 384 return; |
384 } | 385 } |
385 } | 386 } |
386 int lineVertexOffset = (int) (lines.nextVertex - lines.vertices); | 387 int lineVertexOffset = (int) (lines.nextVertex - lines.vertices); |
387 int lineIndexOffset = (int) (lines.nextIndex - lines.indices); | 388 int lineIndexOffset = (int) (lines.nextIndex - lines.indices); |
388 SkASSERT(lineVertexOffset <= fMaxLineVertices && lineIndexOffset <= fMax
LineIndices); | 389 SkASSERT(lineVertexOffset <= fMaxLineVertices && lineIndexOffset <= fMax
LineIndices); |
389 int quadVertexOffset = (int) (quads.nextVertex - quads.vertices); | 390 int quadVertexOffset = (int) (quads.nextVertex - quads.vertices); |
390 int quadIndexOffset = (int) (quads.nextIndex - quads.indices); | 391 int quadIndexOffset = (int) (quads.nextIndex - quads.indices); |
391 SkASSERT(quadVertexOffset <= fMaxQuadVertices && quadIndexOffset <= fMax
QuadIndices); | 392 SkASSERT(quadVertexOffset <= fMaxQuadVertices && quadIndexOffset <= fMax
QuadIndices); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 quadIndexBuffer, firstQuadVertex, firstQu
adIndex, | 436 quadIndexBuffer, firstQuadVertex, firstQu
adIndex, |
436 quadVertexOffset, quadIndexOffset); | 437 quadVertexOffset, quadIndexOffset); |
437 } else { | 438 } else { |
438 quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, fi
rstQuadVertex, | 439 quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, fi
rstQuadVertex, |
439 quadVertexOffset); | 440 quadVertexOffset); |
440 } | 441 } |
441 target->draw(quadGP, quadMeshes); | 442 target->draw(quadGP, quadMeshes); |
442 } | 443 } |
443 } | 444 } |
444 | 445 |
445 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | |
446 | |
447 MSAAPathBatch(const Geometry& geometry, const SkMatrix& viewMatrix, const Sk
Rect& devBounds) | |
448 : INHERITED(ClassID()) | |
449 , fViewMatrix(viewMatrix) { | |
450 fGeoData.push_back(geometry); | |
451 this->setBounds(devBounds); | |
452 int contourCount; | |
453 this->computeWorstCasePointCount(geometry.fPath, &contourCount, kToleran
ce, | |
454 &fMaxLineVertices, &fMaxQuadVertices); | |
455 fMaxLineIndices = fMaxLineVertices * 3; | |
456 fMaxQuadIndices = fMaxQuadVertices * 3; | |
457 fIsIndexed = contourCount > 1; | |
458 } | |
459 | |
460 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 446 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
461 MSAAPathBatch* that = t->cast<MSAAPathBatch>(); | 447 MSAAPathBatch* that = t->cast<MSAAPathBatch>(); |
462 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 448 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
463 that->bounds(), caps)) { | 449 that->bounds(), caps)) { |
464 return false; | 450 return false; |
465 } | 451 } |
466 | 452 |
467 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { | 453 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { |
468 return false; | 454 return false; |
469 } | 455 } |
470 | 456 |
471 if ((fMaxLineIndices + that->fMaxLineIndices > SK_MaxU16) || | 457 if ((fMaxLineIndices + that->fMaxLineIndices > SK_MaxU16) || |
472 (fMaxQuadIndices + that->fMaxQuadIndices > SK_MaxU16)) { | 458 (fMaxQuadIndices + that->fMaxQuadIndices > SK_MaxU16)) { |
473 return false; | 459 return false; |
474 } | 460 } |
475 | 461 |
476 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 462 fPaths.push_back_n(that->fPaths.count(), that->fPaths.begin()); |
477 this->joinBounds(that->bounds()); | 463 this->joinBounds(that->bounds()); |
478 fIsIndexed = true; | 464 fIsIndexed = true; |
479 fMaxLineVertices += that->fMaxLineVertices; | 465 fMaxLineVertices += that->fMaxLineVertices; |
480 fMaxQuadVertices += that->fMaxQuadVertices; | 466 fMaxQuadVertices += that->fMaxQuadVertices; |
481 fMaxLineIndices += that->fMaxLineIndices; | 467 fMaxLineIndices += that->fMaxLineIndices; |
482 fMaxQuadIndices += that->fMaxQuadIndices; | 468 fMaxQuadIndices += that->fMaxQuadIndices; |
483 return true; | 469 return true; |
484 } | 470 } |
485 | 471 |
486 bool createGeom(MSAALineVertices& lines, | 472 bool createGeom(MSAALineVertices& lines, |
487 MSAAQuadVertices& quads, | 473 MSAAQuadVertices& quads, |
488 const SkPath& path, | 474 const SkPath& path, |
489 SkScalar srcSpaceTol, | |
490 const SkMatrix& m, | 475 const SkMatrix& m, |
491 SkColor color, | 476 SkColor color, |
492 bool isIndexed) const { | 477 bool isIndexed) const { |
493 { | 478 { |
494 uint16_t subpathIdxStart = (uint16_t) (lines.nextVertex - lines.vert
ices); | 479 uint16_t subpathIdxStart = (uint16_t) (lines.nextVertex - lines.vert
ices); |
495 | 480 |
496 SkPoint pts[4]; | 481 SkPoint pts[4]; |
497 | 482 |
498 bool first = true; | 483 bool first = true; |
499 SkPath::Iter iter(path, false); | 484 SkPath::Iter iter(path, false); |
(...skipping 16 matching lines...) Expand all Loading... |
516 if (prevIdx > subpathIdxStart) { | 501 if (prevIdx > subpathIdxStart) { |
517 append_contour_edge_indices(subpathIdxStart, pre
vIdx, lines); | 502 append_contour_edge_indices(subpathIdxStart, pre
vIdx, lines); |
518 } | 503 } |
519 } | 504 } |
520 SkASSERT(lines.nextVertex < lines.verticesEnd); | 505 SkASSERT(lines.nextVertex < lines.verticesEnd); |
521 *(lines.nextVertex++) = { pts[1], color }; | 506 *(lines.nextVertex++) = { pts[1], color }; |
522 break; | 507 break; |
523 case SkPath::kConic_Verb: { | 508 case SkPath::kConic_Verb: { |
524 SkScalar weight = iter.conicWeight(); | 509 SkScalar weight = iter.conicWeight(); |
525 SkAutoConicToQuads converter; | 510 SkAutoConicToQuads converter; |
526 const SkPoint* quadPts = converter.computeQuads(pts, wei
ght, | 511 const SkPoint* quadPts = converter.computeQuads(pts, wei
ght, kTolerance); |
527 kToleran
ce); | |
528 for (int i = 0; i < converter.countQuads(); ++i) { | 512 for (int i = 0; i < converter.countQuads(); ++i) { |
529 add_quad(lines, quads, quadPts + i * 2, color, isInd
exed, | 513 add_quad(lines, quads, quadPts + i * 2, color, isInd
exed, |
530 subpathIdxStart); | 514 subpathIdxStart); |
531 } | 515 } |
532 break; | 516 break; |
533 } | 517 } |
534 case SkPath::kQuad_Verb: { | 518 case SkPath::kQuad_Verb: { |
535 add_quad(lines, quads, pts, color, isIndexed, subpathIdx
Start); | 519 add_quad(lines, quads, pts, color, isIndexed, subpathIdx
Start); |
536 break; | 520 break; |
537 } | 521 } |
(...skipping 10 matching lines...) Expand all Loading... |
548 break; | 532 break; |
549 case SkPath::kDone_Verb: | 533 case SkPath::kDone_Verb: |
550 done = true; | 534 done = true; |
551 } | 535 } |
552 first = false; | 536 first = false; |
553 } | 537 } |
554 } | 538 } |
555 return true; | 539 return true; |
556 } | 540 } |
557 | 541 |
558 SkSTArray<1, Geometry, true> fGeoData; | 542 struct PathInfo { |
| 543 GrColor fColor; |
| 544 SkPath fPath; |
| 545 }; |
| 546 |
| 547 SkSTArray<1, PathInfo, true> fPaths; |
559 | 548 |
560 SkMatrix fViewMatrix; | 549 SkMatrix fViewMatrix; |
561 int fMaxLineVertices; | 550 int fMaxLineVertices; |
562 int fMaxQuadVertices; | 551 int fMaxQuadVertices; |
563 int fMaxLineIndices; | 552 int fMaxLineIndices; |
564 int fMaxQuadIndices; | 553 int fMaxQuadIndices; |
565 bool fIsIndexed; | 554 bool fIsIndexed; |
566 | 555 |
567 typedef GrVertexBatch INHERITED; | 556 typedef GrVertexBatch INHERITED; |
568 }; | 557 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); | 662 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); |
674 pipelineBuilder.setDrawFace(drawFace[p]); | 663 pipelineBuilder.setDrawFace(drawFace[p]); |
675 if (passes[p]) { | 664 if (passes[p]) { |
676 pipelineBuilder.setUserStencil(passes[p]); | 665 pipelineBuilder.setUserStencil(passes[p]); |
677 } else { | 666 } else { |
678 pipelineBuilder.setUserStencil(userStencilSettings); | 667 pipelineBuilder.setUserStencil(userStencilSettings); |
679 } | 668 } |
680 | 669 |
681 drawContext->drawBatch(pipelineBuilder, clip, batch); | 670 drawContext->drawBatch(pipelineBuilder, clip, batch); |
682 } else { | 671 } else { |
683 MSAAPathBatch::Geometry geometry; | 672 SkAutoTUnref<MSAAPathBatch> batch(new MSAAPathBatch(color, path, vie
wMatrix, |
684 geometry.fColor = color; | 673 devBounds)); |
685 geometry.fPath = path; | |
686 geometry.fTolerance = kTolerance; | |
687 | |
688 SkAutoTUnref<MSAAPathBatch> batch(MSAAPathBatch::Create(geometry, vi
ewMatrix, | |
689 devBounds)); | |
690 if (!batch->isValid()) { | 674 if (!batch->isValid()) { |
691 return false; | 675 return false; |
692 } | 676 } |
693 | 677 |
694 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); | 678 GrPipelineBuilder pipelineBuilder(paint, drawContext->mustUseHWAA(pa
int)); |
695 pipelineBuilder.setDrawFace(drawFace[p]); | 679 pipelineBuilder.setDrawFace(drawFace[p]); |
696 if (passes[p]) { | 680 if (passes[p]) { |
697 pipelineBuilder.setUserStencil(passes[p]); | 681 pipelineBuilder.setUserStencil(passes[p]); |
698 } else { | 682 } else { |
699 pipelineBuilder.setUserStencil(userStencilSettings); | 683 pipelineBuilder.setUserStencil(userStencilSettings); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 | 727 |
744 GrPaint paint; | 728 GrPaint paint; |
745 paint.setXPFactory(GrDisableColorXPFactory::Make()); | 729 paint.setXPFactory(GrDisableColorXPFactory::Make()); |
746 paint.setAntiAlias(args.fIsAA); | 730 paint.setAntiAlias(args.fIsAA); |
747 | 731 |
748 this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUn
used, *args.fClip, | 732 this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUn
used, *args.fClip, |
749 GrColor_WHITE, *args.fViewMatrix, *args.fShape, true)
; | 733 GrColor_WHITE, *args.fViewMatrix, *args.fShape, true)
; |
750 } | 734 } |
751 | 735 |
752 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 736 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
OLD | NEW |