Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 2391133004: Reduce geometry size for circles to help fill rate. (Closed)
Patch Set: Chop out center of stroked circles Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "GrOvalRenderer.h" 8 #include "GrOvalRenderer.h"
9 9
10 #include "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor); 548 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor);
549 549
550 sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTes tData* d) { 550 sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTes tData* d) {
551 return sk_sp<GrGeometryProcessor>( 551 return sk_sp<GrGeometryProcessor>(
552 new DIEllipseGeometryProcessor(GrTest::TestMatrix(d->fRandom), 552 new DIEllipseGeometryProcessor(GrTest::TestMatrix(d->fRandom),
553 (DIEllipseStyle)(d->fRandom->nextRangeU(0 ,2)))); 553 (DIEllipseStyle)(d->fRandom->nextRangeU(0 ,2))));
554 } 554 }
555 555
556 /////////////////////////////////////////////////////////////////////////////// 556 ///////////////////////////////////////////////////////////////////////////////
557 557
558 // We have two possible cases for geometry for a circle:
559
560 // In the case of a normal fill, we draw geometry for the circle as an octagon.
561 static const uint16_t gFillCircleIndices[] = {
562 // enter the octagon
563 0, 1, 8, 1, 2, 8,
564 2, 3, 8, 3, 4, 8,
565 4, 5, 8, 5, 6, 8,
566 6, 7, 8, 7, 0, 8,
567 };
568
569 // For stroked circles, we use two nested octagons.
570 static const uint16_t gStrokeCircleIndices[] = {
571 // enter the octagon
572 0, 1, 9, 0, 9, 8,
573 1, 2, 10, 1, 10, 9,
574 2, 3, 11, 2, 11, 10,
575 3, 4, 12, 3, 12, 11,
576 4, 5, 13, 4, 13, 12,
577 5, 6, 14, 5, 14, 13,
578 6, 7, 15, 6, 15, 14,
579 7, 0, 8, 7, 8, 15,
580 };
581
582 static const int kIndicesPerFillCircle = SK_ARRAY_COUNT(gFillCircleIndices);
583 static const int kIndicesPerStrokeCircle = SK_ARRAY_COUNT(gStrokeCircleIndices);
584 static const int kVertsPerStrokeCircle = 16;
585 static const int kVertsPerFillCircle = 9;
586
587 static int circle_type_to_vert_count(bool stroked) {
588 return stroked ? kVertsPerStrokeCircle : kVertsPerFillCircle;
589 }
590
591 static int circle_type_to_index_count(bool stroked) {
592 return stroked ? kIndicesPerStrokeCircle : kIndicesPerFillCircle;
593 }
594
595 static const uint16_t* circle_type_to_indices(bool stroked) {
596 return stroked ? gStrokeCircleIndices : gFillCircleIndices;
597 }
598
599 ///////////////////////////////////////////////////////////////////////////////
600
558 class CircleBatch : public GrVertexBatch { 601 class CircleBatch : public GrVertexBatch {
559 public: 602 public:
560 DEFINE_BATCH_CLASS_ID 603 DEFINE_BATCH_CLASS_ID
561 604
562 /** Optional extra params to render a partial arc rather than a full circle. */ 605 /** Optional extra params to render a partial arc rather than a full circle. */
563 struct ArcParams { 606 struct ArcParams {
564 SkScalar fStartAngleRadians; 607 SkScalar fStartAngleRadians;
565 SkScalar fSweepAngleRadians; 608 SkScalar fSweepAngleRadians;
566 bool fUseCenter; 609 bool fUseCenter;
567 }; 610 };
(...skipping 26 matching lines...) Expand all
594 } 637 }
595 638
596 viewMatrix.mapPoints(&center, 1); 639 viewMatrix.mapPoints(&center, 1);
597 radius = viewMatrix.mapRadius(radius); 640 radius = viewMatrix.mapRadius(radius);
598 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); 641 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
599 642
600 bool isStrokeOnly = SkStrokeRec::kStroke_Style == recStyle || 643 bool isStrokeOnly = SkStrokeRec::kStroke_Style == recStyle ||
601 SkStrokeRec::kHairline_Style == recStyle; 644 SkStrokeRec::kHairline_Style == recStyle;
602 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == re cStyle; 645 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == re cStyle;
603 646
604 SkScalar innerRadius = 0.0f; 647 SkScalar innerRadius = -SK_ScalarHalf;
605 SkScalar outerRadius = radius; 648 SkScalar outerRadius = radius;
606 SkScalar halfWidth = 0; 649 SkScalar halfWidth = 0;
607 if (hasStroke) { 650 if (hasStroke) {
608 if (SkScalarNearlyZero(strokeWidth)) { 651 if (SkScalarNearlyZero(strokeWidth)) {
609 halfWidth = SK_ScalarHalf; 652 halfWidth = SK_ScalarHalf;
610 } else { 653 } else {
611 halfWidth = SkScalarHalf(strokeWidth); 654 halfWidth = SkScalarHalf(strokeWidth);
612 } 655 }
613 656
614 outerRadius += halfWidth; 657 outerRadius += halfWidth;
615 if (isStrokeOnly) { 658 if (isStrokeOnly) {
616 innerRadius = radius - halfWidth; 659 innerRadius = radius - halfWidth;
617 } 660 }
618 } 661 }
619 662
620 // The radii are outset for two reasons. First, it allows the shader to simply perform 663 // The radii are outset for two reasons. First, it allows the shader to simply perform
621 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius. 664 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius.
622 // Second, the outer radius is used to compute the verts of the bounding box that is 665 // Second, the outer radius is used to compute the verts of the bounding box that is
623 // rendered and the outset ensures the box will cover all partially cove red by the circle. 666 // rendered and the outset ensures the box will cover all partially cove red by the circle.
624 outerRadius += SK_ScalarHalf; 667 outerRadius += SK_ScalarHalf;
625 innerRadius -= SK_ScalarHalf; 668 innerRadius -= SK_ScalarHalf;
669 bool stroked = isStrokeOnly && innerRadius > 0.0f;
626 CircleBatch* batch = new CircleBatch(); 670 CircleBatch* batch = new CircleBatch();
627 batch->fViewMatrixIfUsingLocalCoords = viewMatrix; 671 batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
628 672
629 // This makes every point fully inside the intersection plane. 673 // This makes every point fully inside the intersection plane.
630 static constexpr SkScalar kUnusedIsectPlane[] = {0.f, 0.f, 1.f}; 674 static constexpr SkScalar kUnusedIsectPlane[] = {0.f, 0.f, 1.f};
631 // This makes every point fully outside the union plane. 675 // This makes every point fully outside the union plane.
632 static constexpr SkScalar kUnusedUnionPlane[] = {0.f, 0.f, 0.f}; 676 static constexpr SkScalar kUnusedUnionPlane[] = {0.f, 0.f, 0.f};
633 SkRect devBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius, 677 SkRect devBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius,
634 center.fX + outerRadius, center.fY + outerRadius); 678 center.fX + outerRadius, center.fY + outerRadius);
635
636 if (arcParams) { 679 if (arcParams) {
637 // The shader operates in a space where the circle is translated to be centered at the 680 // The shader operates in a space where the circle is translated to be centered at the
638 // origin. Here we compute points on the unit circle at the starting and ending angles. 681 // origin. Here we compute points on the unit circle at the starting and ending angles.
639 SkPoint startPoint, stopPoint; 682 SkPoint startPoint, stopPoint;
640 startPoint.fY = SkScalarSinCos(arcParams->fStartAngleRadians, &start Point.fX); 683 startPoint.fY = SkScalarSinCos(arcParams->fStartAngleRadians, &start Point.fX);
641 SkScalar endAngle = arcParams->fStartAngleRadians + arcParams->fSwee pAngleRadians; 684 SkScalar endAngle = arcParams->fStartAngleRadians + arcParams->fSwee pAngleRadians;
642 stopPoint.fY = SkScalarSinCos(endAngle, &stopPoint.fX); 685 stopPoint.fY = SkScalarSinCos(endAngle, &stopPoint.fX);
643 // Like a fill without useCenter, butt-cap stroke can be implemented by clipping against 686 // Like a fill without useCenter, butt-cap stroke can be implemented by clipping against
644 // radial lines. However, in both cases we have to be careful about the half-circle. 687 // radial lines. However, in both cases we have to be careful about the half-circle.
645 // case. In that case the two radial lines are equal and so that edg e gets clipped 688 // case. In that case the two radial lines are equal and so that edg e gets clipped
(...skipping 12 matching lines...) Expand all
658 } 701 }
659 batch->fClipPlane = true; 702 batch->fClipPlane = true;
660 if (SkScalarAbs(arcParams->fSweepAngleRadians) > SK_ScalarPI) { 703 if (SkScalarAbs(arcParams->fSweepAngleRadians) > SK_ScalarPI) {
661 batch->fGeoData.emplace_back(Geometry { 704 batch->fGeoData.emplace_back(Geometry {
662 color, 705 color,
663 innerRadius, 706 innerRadius,
664 outerRadius, 707 outerRadius,
665 {norm0.fX, norm0.fY, 0.5f}, 708 {norm0.fX, norm0.fY, 0.5f},
666 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnused IsectPlane[2]}, 709 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnused IsectPlane[2]},
667 {norm1.fX, norm1.fY, 0.5f}, 710 {norm1.fX, norm1.fY, 0.5f},
668 devBounds 711 devBounds,
712 stroked
669 }); 713 });
670 batch->fClipPlaneIsect = false; 714 batch->fClipPlaneIsect = false;
671 batch->fClipPlaneUnion = true; 715 batch->fClipPlaneUnion = true;
672 } else { 716 } else {
673 batch->fGeoData.emplace_back(Geometry { 717 batch->fGeoData.emplace_back(Geometry {
674 color, 718 color,
675 innerRadius, 719 innerRadius,
676 outerRadius, 720 outerRadius,
677 {norm0.fX, norm0.fY, 0.5f}, 721 {norm0.fX, norm0.fY, 0.5f},
678 {norm1.fX, norm1.fY, 0.5f}, 722 {norm1.fX, norm1.fY, 0.5f},
679 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnused UnionPlane[2]}, 723 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnused UnionPlane[2]},
680 devBounds 724 devBounds,
725 stroked
681 }); 726 });
682 batch->fClipPlaneIsect = true; 727 batch->fClipPlaneIsect = true;
683 batch->fClipPlaneUnion = false; 728 batch->fClipPlaneUnion = false;
684 } 729 }
685 } else { 730 } else {
686 // We clip to a secant of the original circle. 731 // We clip to a secant of the original circle.
687 startPoint.scale(radius); 732 startPoint.scale(radius);
688 stopPoint.scale(radius); 733 stopPoint.scale(radius);
689 SkVector norm = {startPoint.fY - stopPoint.fY, stopPoint.fX - st artPoint.fX}; 734 SkVector norm = {startPoint.fY - stopPoint.fY, stopPoint.fX - st artPoint.fX};
690 norm.normalize(); 735 norm.normalize();
691 if (arcParams->fSweepAngleRadians > 0) { 736 if (arcParams->fSweepAngleRadians > 0) {
692 norm.negate(); 737 norm.negate();
693 } 738 }
694 SkScalar d = -norm.dot(startPoint) + 0.5f; 739 SkScalar d = -norm.dot(startPoint) + 0.5f;
695 740
696 batch->fGeoData.emplace_back(Geometry { 741 batch->fGeoData.emplace_back(Geometry {
697 color, 742 color,
698 innerRadius, 743 innerRadius,
699 outerRadius, 744 outerRadius,
700 {norm.fX, norm.fY, d}, 745 {norm.fX, norm.fY, d},
701 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsec tPlane[2]}, 746 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsec tPlane[2]},
702 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnio nPlane[2]}, 747 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnio nPlane[2]},
703 devBounds 748 devBounds,
749 stroked
704 }); 750 });
705 batch->fClipPlane = true; 751 batch->fClipPlane = true;
706 batch->fClipPlaneIsect = false; 752 batch->fClipPlaneIsect = false;
707 batch->fClipPlaneUnion = false; 753 batch->fClipPlaneUnion = false;
708 } 754 }
709 } else { 755 } else {
710 batch->fGeoData.emplace_back(Geometry { 756 batch->fGeoData.emplace_back(Geometry {
711 color, 757 color,
712 innerRadius, 758 innerRadius,
713 outerRadius, 759 outerRadius,
714 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2 ]}, 760 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2 ]},
715 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2 ]}, 761 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2 ]},
716 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2 ]}, 762 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2 ]},
717 devBounds 763 devBounds,
764 stroked
718 }); 765 });
719 batch->fClipPlane = false; 766 batch->fClipPlane = false;
720 batch->fClipPlaneIsect = false; 767 batch->fClipPlaneIsect = false;
721 batch->fClipPlaneUnion = false; 768 batch->fClipPlaneUnion = false;
722 } 769 }
723 // Use the original radius and stroke radius for the bounds so that it d oes not include the 770 // Use the original radius and stroke radius for the bounds so that it d oes not include the
724 // AA bloat. 771 // AA bloat.
725 radius += halfWidth; 772 radius += halfWidth;
726 batch->setBounds({center.fX - radius, center.fY - radius, 773 batch->setBounds({center.fX - radius, center.fY - radius,
727 center.fX + radius, center.fY + radius}, 774 center.fX + radius, center.fY + radius},
728 HasAABloat::kYes, IsZeroArea::kNo); 775 HasAABloat::kYes, IsZeroArea::kNo);
729 batch->fStroked = isStrokeOnly && innerRadius > 0; 776 batch->fVertCount = circle_type_to_vert_count(stroked);
777 batch->fIndexCount = circle_type_to_index_count(stroked);
778 batch->fAllFill = !stroked;
730 return batch; 779 return batch;
731 } 780 }
732 781
733 const char* name() const override { return "CircleBatch"; } 782 const char* name() const override { return "CircleBatch"; }
734 783
735 SkString dumpInfo() const override { 784 SkString dumpInfo() const override {
736 SkString string; 785 SkString string;
737 for (int i = 0; i < fGeoData.count(); ++i) { 786 for (int i = 0; i < fGeoData.count(); ++i) {
738 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f]," 787 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f],"
739 "InnerRad: %.2f, OuterRad: %.2f\n", 788 "InnerRad: %.2f, OuterRad: %.2f\n",
(...skipping 25 matching lines...) Expand all
765 } 814 }
766 } 815 }
767 816
768 void onPrepareDraws(Target* target) const override { 817 void onPrepareDraws(Target* target) const override {
769 SkMatrix localMatrix; 818 SkMatrix localMatrix;
770 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 819 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) {
771 return; 820 return;
772 } 821 }
773 822
774 // Setup geometry processor 823 // Setup geometry processor
775 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fStroke d, fClipPlane, 824 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(!fAllFi ll, fClipPlane,
776 fClipPl aneIsect, 825 fClipPl aneIsect,
777 fClipPl aneUnion, 826 fClipPl aneUnion,
778 localMa trix)); 827 localMa trix));
779 828
780 struct CircleVertex { 829 struct CircleVertex {
781 SkPoint fPos; 830 SkPoint fPos;
782 GrColor fColor; 831 GrColor fColor;
783 SkPoint fOffset; 832 SkPoint fOffset;
784 SkScalar fOuterRadius; 833 SkScalar fOuterRadius;
785 SkScalar fInnerRadius; 834 SkScalar fInnerRadius;
786 // These planes may or may not be present in the vertex buffer. 835 // These planes may or may not be present in the vertex buffer.
787 SkScalar fHalfPlanes[3][3]; 836 SkScalar fHalfPlanes[3][3];
788 }; 837 };
789 838
790 int instanceCount = fGeoData.count(); 839 int instanceCount = fGeoData.count();
791 size_t vertexStride = gp->getVertexStride(); 840 size_t vertexStride = gp->getVertexStride();
792 SkASSERT(vertexStride == sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * si zeof(SkScalar)) 841 SkASSERT(vertexStride == sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * si zeof(SkScalar))
793 - (fClipPlaneIsect? 0 : 3 * sizeof(SkScalar)) 842 - (fClipPlaneIsect? 0 : 3 * sizeof(SkScalar))
794 - (fClipPlaneUnion? 0 : 3 * sizeof(SkScalar))); 843 - (fClipPlaneUnion? 0 : 3 * sizeof(SkScalar)));
795 QuadHelper helper; 844
796 char* vertices = reinterpret_cast<char*>(helper.init(target, vertexStrid e, instanceCount)); 845 const GrBuffer* vertexBuffer;
846 int firstVertex;
847 char* vertices = (char*)target->makeVertexSpace(vertexStride, fVertCount ,
848 &vertexBuffer, &firstVer tex);
797 if (!vertices) { 849 if (!vertices) {
850 SkDebugf("Could not allocate vertices\n");
798 return; 851 return;
799 } 852 }
800 853
854 const GrBuffer* indexBuffer = nullptr;
855 int firstIndex = 0;
856 uint16_t* indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &f irstIndex);
857 if (!indices) {
858 SkDebugf("Could not allocate indices\n");
859 return;
860 }
861
862 int currStartVertex = 0;
801 for (int i = 0; i < instanceCount; i++) { 863 for (int i = 0; i < instanceCount; i++) {
802 const Geometry& geom = fGeoData[i]; 864 const Geometry& geom = fGeoData[i];
803 865
804 GrColor color = geom.fColor; 866 GrColor color = geom.fColor;
805 SkScalar innerRadius = geom.fInnerRadius; 867 SkScalar innerRadius = geom.fInnerRadius;
806 SkScalar outerRadius = geom.fOuterRadius; 868 SkScalar outerRadius = geom.fOuterRadius;
807 869
808 const SkRect& bounds = geom.fDevBounds; 870 const SkRect& bounds = geom.fDevBounds;
809 CircleVertex* v0 = reinterpret_cast<CircleVertex*>(vertices + (4 * i + 0)*vertexStride); 871 CircleVertex* v0 = reinterpret_cast<CircleVertex*>(vertices + 0*vert exStride);
810 CircleVertex* v1 = reinterpret_cast<CircleVertex*>(vertices + (4 * i + 1)*vertexStride); 872 CircleVertex* v1 = reinterpret_cast<CircleVertex*>(vertices + 1*vert exStride);
811 CircleVertex* v2 = reinterpret_cast<CircleVertex*>(vertices + (4 * i + 2)*vertexStride); 873 CircleVertex* v2 = reinterpret_cast<CircleVertex*>(vertices + 2*vert exStride);
812 CircleVertex* v3 = reinterpret_cast<CircleVertex*>(vertices + (4 * i + 3)*vertexStride); 874 CircleVertex* v3 = reinterpret_cast<CircleVertex*>(vertices + 3*vert exStride);
875 CircleVertex* v4 = reinterpret_cast<CircleVertex*>(vertices + 4*vert exStride);
876 CircleVertex* v5 = reinterpret_cast<CircleVertex*>(vertices + 5*vert exStride);
877 CircleVertex* v6 = reinterpret_cast<CircleVertex*>(vertices + 6*vert exStride);
878 CircleVertex* v7 = reinterpret_cast<CircleVertex*>(vertices + 7*vert exStride);
813 879
814 // The inner radius in the vertex data must be specified in normaliz ed space. 880 // The inner radius in the vertex data must be specified in normaliz ed space.
815 innerRadius = innerRadius / outerRadius; 881 innerRadius = innerRadius / outerRadius;
816 v0->fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 882
883 SkPoint center = SkPoint::Make(bounds.centerX(), bounds.centerY());
884 SkScalar halfWidth = 0.5f*bounds.width();
885 SkScalar octOffset = 0.41421356237f; // sqrt(2) - 1
886
887 v0->fPos = center + SkPoint::Make(-octOffset*halfWidth, -halfWidth);
817 v0->fColor = color; 888 v0->fColor = color;
818 v0->fOffset = SkPoint::Make(-1, -1); 889 v0->fOffset = SkPoint::Make(-octOffset, -1);
819 v0->fOuterRadius = outerRadius; 890 v0->fOuterRadius = outerRadius;
820 v0->fInnerRadius = innerRadius; 891 v0->fInnerRadius = innerRadius;
821 892
822 v1->fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 893 v1->fPos = center + SkPoint::Make(octOffset*halfWidth, -halfWidth);
823 v1->fColor = color; 894 v1->fColor = color;
824 v1->fOffset = SkPoint::Make(-1, 1); 895 v1->fOffset = SkPoint::Make(octOffset, -1);
825 v1->fOuterRadius = outerRadius; 896 v1->fOuterRadius = outerRadius;
826 v1->fInnerRadius = innerRadius; 897 v1->fInnerRadius = innerRadius;
827 898
828 v2->fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 899 v2->fPos = center + SkPoint::Make(halfWidth, -octOffset*halfWidth);
829 v2->fColor = color; 900 v2->fColor = color;
830 v2->fOffset = SkPoint::Make(1, 1); 901 v2->fOffset = SkPoint::Make(1, -octOffset);
831 v2->fOuterRadius = outerRadius; 902 v2->fOuterRadius = outerRadius;
832 v2->fInnerRadius = innerRadius; 903 v2->fInnerRadius = innerRadius;
833 904
834 v3->fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 905 v3->fPos = center + SkPoint::Make(halfWidth, octOffset*halfWidth);
835 v3->fColor = color; 906 v3->fColor = color;
836 v3->fOffset = SkPoint::Make(1, -1); 907 v3->fOffset = SkPoint::Make(1, octOffset);
837 v3->fOuterRadius = outerRadius; 908 v3->fOuterRadius = outerRadius;
838 v3->fInnerRadius = innerRadius; 909 v3->fInnerRadius = innerRadius;
839 910
911 v4->fPos = center + SkPoint::Make(octOffset*halfWidth, halfWidth);
912 v4->fColor = color;
913 v4->fOffset = SkPoint::Make(octOffset, 1);
914 v4->fOuterRadius = outerRadius;
915 v4->fInnerRadius = innerRadius;
916
917 v5->fPos = center + SkPoint::Make(-octOffset*halfWidth, halfWidth);
918 v5->fColor = color;
919 v5->fOffset = SkPoint::Make(-octOffset, 1);
920 v5->fOuterRadius = outerRadius;
921 v5->fInnerRadius = innerRadius;
922
923 v6->fPos = center + SkPoint::Make(-halfWidth, octOffset*halfWidth);
924 v6->fColor = color;
925 v6->fOffset = SkPoint::Make(-1, octOffset);
926 v6->fOuterRadius = outerRadius;
927 v6->fInnerRadius = innerRadius;
928
929 v7->fPos = center + SkPoint::Make(-halfWidth, -octOffset*halfWidth);
930 v7->fColor = color;
931 v7->fOffset = SkPoint::Make(-1, -octOffset);
932 v7->fOuterRadius = outerRadius;
933 v7->fInnerRadius = innerRadius;
934
840 if (fClipPlane) { 935 if (fClipPlane) {
841 memcpy(v0->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) ); 936 memcpy(v0->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
842 memcpy(v1->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) ); 937 memcpy(v1->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
843 memcpy(v2->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) ); 938 memcpy(v2->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
844 memcpy(v3->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) ); 939 memcpy(v3->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
940 memcpy(v4->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
941 memcpy(v5->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
942 memcpy(v6->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
943 memcpy(v7->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkScalar) );
845 } 944 }
846 int unionIdx = 1; 945 int unionIdx = 1;
847 if (fClipPlaneIsect) { 946 if (fClipPlaneIsect) {
848 memcpy(v0->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar )); 947 memcpy(v0->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
849 memcpy(v1->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar )); 948 memcpy(v1->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
850 memcpy(v2->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar )); 949 memcpy(v2->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
851 memcpy(v3->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar )); 950 memcpy(v3->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
951 memcpy(v4->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
952 memcpy(v5->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
953 memcpy(v6->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
954 memcpy(v7->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkScalar ));
852 unionIdx = 2; 955 unionIdx = 2;
853 } 956 }
854 if (fClipPlaneUnion) { 957 if (fClipPlaneUnion) {
855 memcpy(v0->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar)); 958 memcpy(v0->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
856 memcpy(v1->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar)); 959 memcpy(v1->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
857 memcpy(v2->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar)); 960 memcpy(v2->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
858 memcpy(v3->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar)); 961 memcpy(v3->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
962 memcpy(v4->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
963 memcpy(v5->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
964 memcpy(v6->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
965 memcpy(v7->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * sizeof(S kScalar));
859 } 966 }
967
968 if (geom.fStroked) {
robertphillips 2016/10/06 20:09:56 Could this path share a "FillInOctVerts" subroutin
jvanverth1 2016/10/06 21:46:19 I tried that but got stymied -- I'll take another
robertphillips 2016/10/06 21:51:22 It should probably be a follow up CL.
969 // compute the inner ring
970 CircleVertex* v0 = reinterpret_cast<CircleVertex*>(vertices + 8 * vertexStride);
971 CircleVertex* v1 = reinterpret_cast<CircleVertex*>(vertices + 9 * vertexStride);
972 CircleVertex* v2 = reinterpret_cast<CircleVertex*>(vertices + 10 * vertexStride);
973 CircleVertex* v3 = reinterpret_cast<CircleVertex*>(vertices + 11 * vertexStride);
974 CircleVertex* v4 = reinterpret_cast<CircleVertex*>(vertices + 12 * vertexStride);
975 CircleVertex* v5 = reinterpret_cast<CircleVertex*>(vertices + 13 * vertexStride);
976 CircleVertex* v6 = reinterpret_cast<CircleVertex*>(vertices + 14 * vertexStride);
977 CircleVertex* v7 = reinterpret_cast<CircleVertex*>(vertices + 15 * vertexStride);
978
979 // cosine and sine of pi/8
980 SkScalar c = 0.923579533f;
981 SkScalar s = 0.382683432f;
982 SkScalar r = geom.fInnerRadius;
983
984 v0->fPos = center + SkPoint::Make(-s*r, -c*r);
985 v0->fColor = color;
986 v0->fOffset = SkPoint::Make(-s*innerRadius, -c*innerRadius);
987 v0->fOuterRadius = outerRadius;
988 v0->fInnerRadius = innerRadius;
989
990 v1->fPos = center + SkPoint::Make(s*r, -c*r);
991 v1->fColor = color;
992 v1->fOffset = SkPoint::Make(s*innerRadius, -c*innerRadius);
993 v1->fOuterRadius = outerRadius;
994 v1->fInnerRadius = innerRadius;
995
996 v2->fPos = center + SkPoint::Make(c*r, -s*r);
997 v2->fColor = color;
998 v2->fOffset = SkPoint::Make(c*innerRadius, -s*innerRadius);
999 v2->fOuterRadius = outerRadius;
1000 v2->fInnerRadius = innerRadius;
1001
1002 v3->fPos = center + SkPoint::Make(c*r, s*r);
1003 v3->fColor = color;
1004 v3->fOffset = SkPoint::Make(c*innerRadius, s*innerRadius);
1005 v3->fOuterRadius = outerRadius;
1006 v3->fInnerRadius = innerRadius;
1007
1008 v4->fPos = center + SkPoint::Make(s*r, c*r);
1009 v4->fColor = color;
1010 v4->fOffset = SkPoint::Make(s*innerRadius, c*innerRadius);
1011 v4->fOuterRadius = outerRadius;
1012 v4->fInnerRadius = innerRadius;
1013
1014 v5->fPos = center + SkPoint::Make(-s*r, c*r);
1015 v5->fColor = color;
1016 v5->fOffset = SkPoint::Make(-s*innerRadius, c*innerRadius);
1017 v5->fOuterRadius = outerRadius;
1018 v5->fInnerRadius = innerRadius;
1019
1020 v6->fPos = center + SkPoint::Make(-c*r, s*r);
1021 v6->fColor = color;
1022 v6->fOffset = SkPoint::Make(-c*innerRadius, s*innerRadius);
1023 v6->fOuterRadius = outerRadius;
1024 v6->fInnerRadius = innerRadius;
1025
1026 v7->fPos = center + SkPoint::Make(-c*r, -s*r);
1027 v7->fColor = color;
1028 v7->fOffset = SkPoint::Make(-c*innerRadius, -s*innerRadius);
1029 v7->fOuterRadius = outerRadius;
1030 v7->fInnerRadius = innerRadius;
1031
1032 if (fClipPlane) {
1033 memcpy(v0->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1034 memcpy(v1->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1035 memcpy(v2->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1036 memcpy(v3->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1037 memcpy(v4->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1038 memcpy(v5->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1039 memcpy(v6->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1040 memcpy(v7->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1041 }
1042 int unionIdx = 1;
1043 if (fClipPlaneIsect) {
1044 memcpy(v0->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1045 memcpy(v1->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1046 memcpy(v2->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1047 memcpy(v3->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1048 memcpy(v4->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1049 memcpy(v5->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1050 memcpy(v6->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1051 memcpy(v7->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1052 unionIdx = 2;
1053 }
1054 if (fClipPlaneUnion) {
1055 memcpy(v0->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1056 memcpy(v1->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1057 memcpy(v2->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1058 memcpy(v3->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1059 memcpy(v4->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1060 memcpy(v5->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1061 memcpy(v6->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1062 memcpy(v7->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1063 }
1064 } else {
1065 // filled
1066 CircleVertex* v8 = reinterpret_cast<CircleVertex*>(vertices + 8 * vertexStride);
1067 v8->fPos = center;
1068 v8->fColor = color;
1069 v8->fOffset = SkPoint::Make(0, 0);
1070 v8->fOuterRadius = outerRadius;
1071 v8->fInnerRadius = innerRadius;
1072 if (fClipPlane) {
1073 memcpy(v8->fHalfPlanes[0], geom.fClipPlane, 3 * sizeof(SkSca lar));
1074 }
1075 int unionIdx = 1;
1076 if (fClipPlaneIsect) {
1077 memcpy(v8->fHalfPlanes[1], geom.fIsectPlane, 3 * sizeof(SkSc alar));
1078 unionIdx = 2;
1079 }
1080 if (fClipPlaneUnion) {
1081 memcpy(v8->fHalfPlanes[unionIdx], geom.fUnionPlane, 3 * size of(SkScalar));
1082 }
1083 }
1084
1085 const uint16_t* primIndices = circle_type_to_indices(geom.fStroked);
1086 const int primIndexCount = circle_type_to_index_count(geom.fStroked) ;
1087 for (int i = 0; i < primIndexCount; ++i) {
1088 *indices++ = primIndices[i] + currStartVertex;
1089 }
1090
1091 currStartVertex += circle_type_to_vert_count(geom.fStroked);
1092 vertices += circle_type_to_vert_count(geom.fStroked)*vertexStride;
860 } 1093 }
861 helper.recordDraw(target, gp); 1094
1095 GrMesh mesh;
1096 mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
1097 firstIndex, fVertCount, fIndexCount);
1098 target->draw(gp.get(), mesh);
862 } 1099 }
863 1100
864 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1101 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
865 CircleBatch* that = t->cast<CircleBatch>(); 1102 CircleBatch* that = t->cast<CircleBatch>();
866 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), 1103 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(),
867 that->bounds(), caps)) { 1104 that->bounds(), caps)) {
868 return false; 1105 return false;
869 } 1106 }
870 1107
871 if (this->fStroked != that->fStroked) { 1108 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
872 return false; 1109 return false;
873 } 1110 }
874 1111
875 // Because we've set up the batches that don't use the planes with noop values 1112 // Because we've set up the batches that don't use the planes with noop values
876 // we can just accumulate used planes by later batches. 1113 // we can just accumulate used planes by later batches.
877 fClipPlane |= that->fClipPlane; 1114 fClipPlane |= that->fClipPlane;
878 fClipPlaneIsect |= that->fClipPlaneIsect; 1115 fClipPlaneIsect |= that->fClipPlaneIsect;
879 fClipPlaneUnion |= that->fClipPlaneUnion; 1116 fClipPlaneUnion |= that->fClipPlaneUnion;
880 1117
881 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
882 return false;
883 }
884
885 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 1118 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
886 this->joinBounds(*that); 1119 this->joinBounds(*that);
1120 fVertCount += that->fVertCount;
1121 fIndexCount += that->fIndexCount;
1122 fAllFill = fAllFill && that->fAllFill;
887 return true; 1123 return true;
888 } 1124 }
889 1125
890 struct Geometry { 1126 struct Geometry {
891 GrColor fColor; 1127 GrColor fColor;
892 SkScalar fInnerRadius; 1128 SkScalar fInnerRadius;
893 SkScalar fOuterRadius; 1129 SkScalar fOuterRadius;
894 SkScalar fClipPlane[3]; 1130 SkScalar fClipPlane[3];
895 SkScalar fIsectPlane[3]; 1131 SkScalar fIsectPlane[3];
896 SkScalar fUnionPlane[3]; 1132 SkScalar fUnionPlane[3];
897 SkRect fDevBounds; 1133 SkRect fDevBounds;
1134 bool fStroked;
898 }; 1135 };
899 1136
900 bool fStroked; 1137 SkSTArray<1, Geometry, true> fGeoData;
1138 SkMatrix fViewMatrixIfUsingLocalCoords;
1139 int fVertCount;
1140 int fIndexCount;
1141 bool fAllFill;
901 bool fClipPlane; 1142 bool fClipPlane;
902 bool fClipPlaneIsect; 1143 bool fClipPlaneIsect;
903 bool fClipPlaneUnion; 1144 bool fClipPlaneUnion;
904 SkMatrix fViewMatrixIfUsingLocalCoords;
905 SkSTArray<1, Geometry, true> fGeoData;
906 1145
907 typedef GrVertexBatch INHERITED; 1146 typedef GrVertexBatch INHERITED;
908 }; 1147 };
909 1148
910 /////////////////////////////////////////////////////////////////////////////// 1149 ///////////////////////////////////////////////////////////////////////////////
911 1150
912 class EllipseBatch : public GrVertexBatch { 1151 class EllipseBatch : public GrVertexBatch {
913 public: 1152 public:
914 DEFINE_BATCH_CLASS_ID 1153 DEFINE_BATCH_CLASS_ID
915 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& ellipse, 1154 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& ellipse,
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 } 2401 }
2163 2402
2164 DRAW_BATCH_TEST_DEFINE(RRectBatch) { 2403 DRAW_BATCH_TEST_DEFINE(RRectBatch) {
2165 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 2404 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
2166 GrColor color = GrRandomColor(random); 2405 GrColor color = GrRandomColor(random);
2167 const SkRRect& rrect = GrTest::TestRRectSimple(random); 2406 const SkRRect& rrect = GrTest::TestRRectSimple(random);
2168 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom)); 2407 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom));
2169 } 2408 }
2170 2409
2171 #endif 2410 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698