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 "GrAAHairLinePathRenderer.h" | 8 #include "GrAAHairLinePathRenderer.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 return tolDevBounds.contains(actualBounds); | 669 return tolDevBounds.contains(actualBounds); |
670 } | 670 } |
671 | 671 |
672 return true; | 672 return true; |
673 } | 673 } |
674 | 674 |
675 class AAHairlineBatch : public GrVertexBatch { | 675 class AAHairlineBatch : public GrVertexBatch { |
676 public: | 676 public: |
677 DEFINE_BATCH_CLASS_ID | 677 DEFINE_BATCH_CLASS_ID |
678 | 678 |
679 struct Geometry { | 679 AAHairlineBatch(GrColor color, |
680 GrColor fColor; | 680 uint8_t coverage, |
681 uint8_t fCoverage; | 681 const SkMatrix& viewMatrix, |
682 SkMatrix fViewMatrix; | 682 const SkPath& path, |
683 SkPath fPath; | 683 SkIRect devClipBounds) : INHERITED(ClassID()) { |
684 SkIRect fDevClipBounds; | 684 fGeoData.emplace_back(Geometry{color, coverage, viewMatrix, path, devCli
pBounds}); |
685 }; | |
686 | 685 |
687 static GrDrawBatch* Create(const Geometry& geometry) { return new AAHairline
Batch(geometry); } | 686 // compute bounds |
| 687 fBounds = path.getBounds(); |
| 688 viewMatrix.mapRect(&fBounds); |
| 689 |
| 690 // This is b.c. hairlines are notionally infinitely thin so without expa
nsion |
| 691 // two overlapping lines could be reordered even though they hit the sam
e pixels. |
| 692 fBounds.outset(0.5f, 0.5f); |
| 693 } |
688 | 694 |
689 const char* name() const override { return "AAHairlineBatch"; } | 695 const char* name() const override { return "AAHairlineBatch"; } |
690 | 696 |
691 void computePipelineOptimizations(GrInitInvariantOutput* color, | 697 void computePipelineOptimizations(GrInitInvariantOutput* color, |
692 GrInitInvariantOutput* coverage, | 698 GrInitInvariantOutput* coverage, |
693 GrBatchToXPOverrides* overrides) const ove
rride { | 699 GrBatchToXPOverrides* overrides) const ove
rride { |
694 // When this is called on a batch, there is only one geometry bundle | 700 // When this is called on a batch, there is only one geometry bundle |
695 color->setKnownFourComponents(fGeoData[0].fColor); | 701 color->setKnownFourComponents(fGeoData[0].fColor); |
696 coverage->setUnknownSingleComponent(); | 702 coverage->setUnknownSingleComponent(); |
697 } | 703 } |
698 | 704 |
699 private: | 705 private: |
700 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 706 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
701 // Handle any color overrides | 707 // Handle any color overrides |
702 if (!overrides.readsColor()) { | 708 if (!overrides.readsColor()) { |
703 fGeoData[0].fColor = GrColor_ILLEGAL; | 709 fGeoData[0].fColor = GrColor_ILLEGAL; |
704 } | 710 } |
705 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | 711 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
706 | 712 |
707 // setup batch properties | 713 // setup batch properties |
708 fBatch.fColorIgnored = !overrides.readsColor(); | 714 fBatch.fColorIgnored = !overrides.readsColor(); |
709 fBatch.fColor = fGeoData[0].fColor; | 715 fBatch.fColor = fGeoData[0].fColor; |
710 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); | 716 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
711 fBatch.fCoverageIgnored = !overrides.readsCoverage(); | 717 fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
712 fBatch.fCoverage = fGeoData[0].fCoverage; | 718 fBatch.fCoverage = fGeoData[0].fCoverage; |
713 } | 719 } |
714 | 720 |
715 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | |
716 | |
717 void onPrepareDraws(Target*) const override; | 721 void onPrepareDraws(Target*) const override; |
718 | 722 |
719 typedef SkTArray<SkPoint, true> PtArray; | 723 typedef SkTArray<SkPoint, true> PtArray; |
720 typedef SkTArray<int, true> IntArray; | 724 typedef SkTArray<int, true> IntArray; |
721 typedef SkTArray<float, true> FloatArray; | 725 typedef SkTArray<float, true> FloatArray; |
722 | 726 |
723 AAHairlineBatch(const Geometry& geometry) : INHERITED(ClassID()) { | |
724 fGeoData.push_back(geometry); | |
725 | |
726 // compute bounds | |
727 fBounds = geometry.fPath.getBounds(); | |
728 geometry.fViewMatrix.mapRect(&fBounds); | |
729 | |
730 // This is b.c. hairlines are notionally infinitely thin so without expa
nsion | |
731 // two overlapping lines could be reordered even though they hit the sam
e pixels. | |
732 fBounds.outset(0.5f, 0.5f); | |
733 } | |
734 | |
735 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 727 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
736 AAHairlineBatch* that = t->cast<AAHairlineBatch>(); | 728 AAHairlineBatch* that = t->cast<AAHairlineBatch>(); |
737 | 729 |
738 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 730 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
739 that->bounds(), caps)) { | 731 that->bounds(), caps)) { |
740 return false; | 732 return false; |
741 } | 733 } |
742 | 734 |
743 if (this->viewMatrix().hasPerspective() != that->viewMatrix().hasPerspec
tive()) { | 735 if (this->viewMatrix().hasPerspective() != that->viewMatrix().hasPerspec
tive()) { |
744 return false; | 736 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
759 | 751 |
760 if (this->color() != that->color()) { | 752 if (this->color() != that->color()) { |
761 return false; | 753 return false; |
762 } | 754 } |
763 | 755 |
764 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 756 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
765 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 757 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { |
766 return false; | 758 return false; |
767 } | 759 } |
768 | 760 |
769 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 761 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); |
770 this->joinBounds(that->bounds()); | 762 this->joinBounds(that->bounds()); |
771 return true; | 763 return true; |
772 } | 764 } |
773 | 765 |
774 GrColor color() const { return fBatch.fColor; } | 766 GrColor color() const { return fBatch.fColor; } |
775 uint8_t coverage() const { return fBatch.fCoverage; } | 767 uint8_t coverage() const { return fBatch.fCoverage; } |
776 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 768 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
777 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 769 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
778 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | 770 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
779 | 771 |
| 772 |
| 773 struct Geometry { |
| 774 GrColor fColor; |
| 775 uint8_t fCoverage; |
| 776 SkMatrix fViewMatrix; |
| 777 SkPath fPath; |
| 778 SkIRect fDevClipBounds; |
| 779 }; |
| 780 |
780 struct BatchTracker { | 781 struct BatchTracker { |
781 GrColor fColor; | 782 GrColor fColor; |
782 uint8_t fCoverage; | 783 uint8_t fCoverage; |
783 SkRect fDevBounds; | 784 SkRect fDevBounds; |
784 bool fUsesLocalCoords; | 785 bool fUsesLocalCoords; |
785 bool fColorIgnored; | 786 bool fColorIgnored; |
786 bool fCoverageIgnored; | 787 bool fCoverageIgnored; |
787 }; | 788 }; |
788 | 789 |
789 BatchTracker fBatch; | 790 BatchTracker fBatch; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 const SkMatrix& viewMatrix, | 947 const SkMatrix& viewMatrix, |
947 const SkPath& path, | 948 const SkPath& path, |
948 const GrStyle& style, | 949 const GrStyle& style, |
949 const SkIRect& devClipBounds) { | 950 const SkIRect& devClipBounds) { |
950 SkScalar hairlineCoverage; | 951 SkScalar hairlineCoverage; |
951 uint8_t newCoverage = 0xff; | 952 uint8_t newCoverage = 0xff; |
952 if (GrPathRenderer::IsStrokeHairlineOrEquivalent(style, viewMatrix, &hairlin
eCoverage)) { | 953 if (GrPathRenderer::IsStrokeHairlineOrEquivalent(style, viewMatrix, &hairlin
eCoverage)) { |
953 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); | 954 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); |
954 } | 955 } |
955 | 956 |
956 AAHairlineBatch::Geometry geometry; | 957 return new AAHairlineBatch(color, newCoverage, viewMatrix, path, devClipBoun
ds); |
957 geometry.fColor = color; | |
958 geometry.fCoverage = newCoverage; | |
959 geometry.fViewMatrix = viewMatrix; | |
960 geometry.fPath = path; | |
961 geometry.fDevClipBounds = devClipBounds; | |
962 | |
963 return AAHairlineBatch::Create(geometry); | |
964 } | 958 } |
965 | 959 |
966 bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) { | 960 bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) { |
967 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 961 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
968 "GrAAHairlinePathRenderer::onDrawPath"); | 962 "GrAAHairlinePathRenderer::onDrawPath"); |
969 SkASSERT(!args.fDrawContext->isUnifiedMultisampled()); | 963 SkASSERT(!args.fDrawContext->isUnifiedMultisampled()); |
970 | 964 |
971 SkIRect devClipBounds; | 965 SkIRect devClipBounds; |
972 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont
ext->height(), | 966 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont
ext->height(), |
973 &devClipBounds); | 967 &devClipBounds); |
(...skipping 17 matching lines...) Expand all Loading... |
991 DRAW_BATCH_TEST_DEFINE(AAHairlineBatch) { | 985 DRAW_BATCH_TEST_DEFINE(AAHairlineBatch) { |
992 GrColor color = GrRandomColor(random); | 986 GrColor color = GrRandomColor(random); |
993 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 987 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
994 SkPath path = GrTest::TestPath(random); | 988 SkPath path = GrTest::TestPath(random); |
995 SkIRect devClipBounds; | 989 SkIRect devClipBounds; |
996 devClipBounds.setEmpty(); | 990 devClipBounds.setEmpty(); |
997 return create_hairline_batch(color, viewMatrix, path, GrStyle::SimpleHairlin
e(), devClipBounds); | 991 return create_hairline_batch(color, viewMatrix, path, GrStyle::SimpleHairlin
e(), devClipBounds); |
998 } | 992 } |
999 | 993 |
1000 #endif | 994 #endif |
OLD | NEW |