| 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 |