OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 | 10 |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 * distance with negative being inside, positive outside. The edge is specified
in | 498 * distance with negative being inside, positive outside. The edge is specified
in |
499 * window space (y-down). If either the third or fourth component of the interpo
lated | 499 * window space (y-down). If either the third or fourth component of the interpo
lated |
500 * vertex coord is > 0 then the pixel is considered outside the edge. This is us
ed to | 500 * vertex coord is > 0 then the pixel is considered outside the edge. This is us
ed to |
501 * attempt to trim to a portion of the infinite quad. | 501 * attempt to trim to a portion of the infinite quad. |
502 * Requires shader derivative instruction support. | 502 * Requires shader derivative instruction support. |
503 */ | 503 */ |
504 | 504 |
505 class QuadEdgeEffect : public GrGeometryProcessor { | 505 class QuadEdgeEffect : public GrGeometryProcessor { |
506 public: | 506 public: |
507 | 507 |
508 static GrGeometryProcessor* Create(GrColor color) { | 508 static GrGeometryProcessor* Create(GrColor color, const SkMatrix& localMatri
x) { |
509 return SkNEW_ARGS(QuadEdgeEffect, (color)); | 509 return SkNEW_ARGS(QuadEdgeEffect, (color, localMatrix)); |
510 } | 510 } |
511 | 511 |
512 virtual ~QuadEdgeEffect() {} | 512 virtual ~QuadEdgeEffect() {} |
513 | 513 |
514 virtual const char* name() const SK_OVERRIDE { return "QuadEdge"; } | 514 virtual const char* name() const SK_OVERRIDE { return "QuadEdge"; } |
515 | 515 |
516 const GrAttribute* inPosition() const { return fInPosition; } | 516 const GrAttribute* inPosition() const { return fInPosition; } |
517 const GrAttribute* inQuadEdge() const { return fInQuadEdge; } | 517 const GrAttribute* inQuadEdge() const { return fInQuadEdge; } |
518 | 518 |
519 class GLProcessor : public GrGLGeometryProcessor { | 519 class GLProcessor : public GrGLGeometryProcessor { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 const GrBatchTracker& t) const SK_OVERRIDE { | 619 const GrBatchTracker& t) const SK_OVERRIDE { |
620 const BatchTracker& mine = m.cast<BatchTracker>(); | 620 const BatchTracker& mine = m.cast<BatchTracker>(); |
621 const BatchTracker& theirs = t.cast<BatchTracker>(); | 621 const BatchTracker& theirs = t.cast<BatchTracker>(); |
622 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 622 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
623 that, theirs.fUsesLocalCoords) && | 623 that, theirs.fUsesLocalCoords) && |
624 CanCombineOutput(mine.fInputColorType, mine.fColor, | 624 CanCombineOutput(mine.fInputColorType, mine.fColor, |
625 theirs.fInputColorType, theirs.fColor); | 625 theirs.fInputColorType, theirs.fColor); |
626 } | 626 } |
627 | 627 |
628 private: | 628 private: |
629 QuadEdgeEffect(GrColor color) : INHERITED(color) { | 629 QuadEdgeEffect(GrColor color, const SkMatrix& localMatrix) |
| 630 : INHERITED(color, false, localMatrix) { |
630 this->initClassID<QuadEdgeEffect>(); | 631 this->initClassID<QuadEdgeEffect>(); |
631 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 632 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
632 fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_Gr
VertexAttribType)); | 633 fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_Gr
VertexAttribType)); |
633 } | 634 } |
634 | 635 |
635 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 636 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
636 return true; | 637 return true; |
637 } | 638 } |
638 | 639 |
639 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const
SK_OVERRIDE { | 640 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const
SK_OVERRIDE { |
(...skipping 14 matching lines...) Expand all Loading... |
654 typedef GrGeometryProcessor INHERITED; | 655 typedef GrGeometryProcessor INHERITED; |
655 }; | 656 }; |
656 | 657 |
657 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect); | 658 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect); |
658 | 659 |
659 GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random, | 660 GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random, |
660 GrContext*, | 661 GrContext*, |
661 const GrDrawTargetCaps& caps, | 662 const GrDrawTargetCaps& caps, |
662 GrTexture*[]) { | 663 GrTexture*[]) { |
663 // Doesn't work without derivative instructions. | 664 // Doesn't work without derivative instructions. |
664 return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create(GrRandomColor
(random)) : NULL; | 665 return caps.shaderDerivativeSupport() ? |
| 666 QuadEdgeEffect::Create(GrRandomColor(random), |
| 667 GrProcessorUnitTest::TestMatrix(random)) : NUL
L; |
665 } | 668 } |
666 | 669 |
667 /////////////////////////////////////////////////////////////////////////////// | 670 /////////////////////////////////////////////////////////////////////////////// |
668 | 671 |
669 bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, | 672 bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, |
670 const GrDrawState*, | 673 const GrDrawState*, |
671 const SkPath& path, | 674 const SkPath& path, |
672 const SkStrokeRec& stroke, | 675 const SkStrokeRec& stroke, |
673 bool antiAlias) const { | 676 bool antiAlias) const { |
674 return (target->caps()->shaderDerivativeSupport() && antiAlias && | 677 return (target->caps()->shaderDerivativeSupport() && antiAlias && |
675 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); | 678 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); |
676 } | 679 } |
677 | 680 |
678 bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, | 681 bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, |
679 GrDrawState* drawState, | 682 GrDrawState* drawState, |
680 GrColor color, | 683 GrColor color, |
681 const SkPath& origPath, | 684 const SkPath& origPath, |
682 const SkStrokeRec&, | 685 const SkStrokeRec&, |
683 bool antiAlias) { | 686 bool antiAlias) { |
684 | 687 |
685 const SkPath* path = &origPath; | 688 const SkPath* path = &origPath; |
686 if (path->isEmpty()) { | 689 if (path->isEmpty()) { |
687 return true; | 690 return true; |
688 } | 691 } |
689 | 692 |
690 SkMatrix viewMatrix = drawState->getViewMatrix(); | 693 SkMatrix viewMatrix = drawState->getViewMatrix(); |
691 GrDrawState::AutoViewMatrixRestore avmr; | 694 SkMatrix invert; |
692 if (!avmr.setIdentity(drawState)) { | 695 if (!viewMatrix.invert(&invert)) { |
693 return false; | 696 return false; |
694 } | 697 } |
695 | 698 |
| 699 GrDrawState::AutoViewMatrixRestore avmr(drawState); |
| 700 |
696 // We use the fact that SkPath::transform path does subdivision based on | 701 // We use the fact that SkPath::transform path does subdivision based on |
697 // perspective. Otherwise, we apply the view matrix when copying to the | 702 // perspective. Otherwise, we apply the view matrix when copying to the |
698 // segment representation. | 703 // segment representation. |
699 SkPath tmpPath; | 704 SkPath tmpPath; |
700 if (viewMatrix.hasPerspective()) { | 705 if (viewMatrix.hasPerspective()) { |
701 origPath.transform(viewMatrix, &tmpPath); | 706 origPath.transform(viewMatrix, &tmpPath); |
702 path = &tmpPath; | 707 path = &tmpPath; |
703 viewMatrix = SkMatrix::I(); | 708 viewMatrix = SkMatrix::I(); |
704 } | 709 } |
705 | 710 |
(...skipping 12 matching lines...) Expand all Loading... |
718 // We can't simply use the path bounds because we may degenerate cubics to q
uads which produces | 723 // We can't simply use the path bounds because we may degenerate cubics to q
uads which produces |
719 // new control points outside the original convex hull. | 724 // new control points outside the original convex hull. |
720 SkRect devBounds; | 725 SkRect devBounds; |
721 if (!get_segments(*path, viewMatrix, &segments, &fanPt, &vCount, &iCount, &d
evBounds)) { | 726 if (!get_segments(*path, viewMatrix, &segments, &fanPt, &vCount, &iCount, &d
evBounds)) { |
722 return false; | 727 return false; |
723 } | 728 } |
724 | 729 |
725 // Our computed verts should all be within one pixel of the segment control
points. | 730 // Our computed verts should all be within one pixel of the segment control
points. |
726 devBounds.outset(SK_Scalar1, SK_Scalar1); | 731 devBounds.outset(SK_Scalar1, SK_Scalar1); |
727 | 732 |
728 SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(color
)); | 733 SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(color
, invert)); |
729 | 734 |
730 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVert
exStride(), iCount); | 735 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVert
exStride(), iCount); |
731 SkASSERT(quadProcessor->getVertexStride() == sizeof(QuadVertex)); | 736 SkASSERT(quadProcessor->getVertexStride() == sizeof(QuadVertex)); |
732 if (!arg.succeeded()) { | 737 if (!arg.succeeded()) { |
733 return false; | 738 return false; |
734 } | 739 } |
735 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); | 740 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); |
736 idxs = reinterpret_cast<uint16_t*>(arg.indices()); | 741 idxs = reinterpret_cast<uint16_t*>(arg.indices()); |
737 | 742 |
738 SkSTArray<kPreallocDrawCnt, Draw, true> draws; | 743 SkSTArray<kPreallocDrawCnt, Draw, true> draws; |
(...skipping 20 matching lines...) Expand all Loading... |
759 vOffset, // start vertex | 764 vOffset, // start vertex |
760 0, // start index | 765 0, // start index |
761 draw.fVertexCnt, | 766 draw.fVertexCnt, |
762 draw.fIndexCnt, | 767 draw.fIndexCnt, |
763 &devBounds); | 768 &devBounds); |
764 vOffset += draw.fVertexCnt; | 769 vOffset += draw.fVertexCnt; |
765 } | 770 } |
766 | 771 |
767 return true; | 772 return true; |
768 } | 773 } |
OLD | NEW |