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 "GrContext.h" | 10 #include "GrContext.h" |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 637 |
638 *vert += kLineSegNumVertices; | 638 *vert += kLineSegNumVertices; |
639 } | 639 } |
640 | 640 |
641 } | 641 } |
642 | 642 |
643 /////////////////////////////////////////////////////////////////////////////// | 643 /////////////////////////////////////////////////////////////////////////////// |
644 | 644 |
645 bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target, | 645 bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target, |
646 GrDrawState* drawState, | 646 GrDrawState* drawState, |
| 647 const SkMatrix& viewMatrix, |
647 uint8_t coverage, | 648 uint8_t coverage, |
648 size_t vertexStride, | 649 size_t vertexStride, |
649 GrDrawTarget::AutoReleaseGeometry*
arg, | 650 GrDrawTarget::AutoReleaseGeometry*
arg, |
650 SkRect* devBounds, | 651 SkRect* devBounds, |
651 const SkPath& path, | 652 const SkPath& path, |
652 const PtArray& lines, | 653 const PtArray& lines, |
653 int lineCnt) { | 654 int lineCnt) { |
654 const SkMatrix& viewM = drawState->getViewMatrix(); | |
655 | |
656 int vertCnt = kLineSegNumVertices * lineCnt; | 655 int vertCnt = kLineSegNumVertices * lineCnt; |
657 | 656 |
658 SkASSERT(vertexStride == sizeof(LineVertex)); | 657 SkASSERT(vertexStride == sizeof(LineVertex)); |
659 if (!arg->set(target, vertCnt, vertexStride, 0)) { | 658 if (!arg->set(target, vertCnt, vertexStride, 0)) { |
660 return false; | 659 return false; |
661 } | 660 } |
662 | 661 |
663 LineVertex* verts = reinterpret_cast<LineVertex*>(arg->vertices()); | 662 LineVertex* verts = reinterpret_cast<LineVertex*>(arg->vertices()); |
664 | 663 |
665 const SkMatrix* toSrc = NULL; | 664 const SkMatrix* toSrc = NULL; |
666 SkMatrix ivm; | 665 SkMatrix ivm; |
667 | 666 |
668 if (viewM.hasPerspective()) { | 667 if (viewMatrix.hasPerspective()) { |
669 if (viewM.invert(&ivm)) { | 668 if (viewMatrix.invert(&ivm)) { |
670 toSrc = &ivm; | 669 toSrc = &ivm; |
671 } | 670 } |
672 } | 671 } |
673 devBounds->set(lines.begin(), lines.count()); | 672 devBounds->set(lines.begin(), lines.count()); |
674 for (int i = 0; i < lineCnt; ++i) { | 673 for (int i = 0; i < lineCnt; ++i) { |
675 add_line(&lines[2*i], toSrc, coverage, &verts); | 674 add_line(&lines[2*i], toSrc, coverage, &verts); |
676 } | 675 } |
677 // All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the en
d points. | 676 // All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the en
d points. |
678 static const SkScalar kSqrtOfOneAndAQuarter = 1.118f; | 677 static const SkScalar kSqrtOfOneAndAQuarter = 1.118f; |
679 // Add a little extra to account for vector normalization precision. | 678 // Add a little extra to account for vector normalization precision. |
680 static const SkScalar kOutset = kSqrtOfOneAndAQuarter + SK_Scalar1 / 20; | 679 static const SkScalar kOutset = kSqrtOfOneAndAQuarter + SK_Scalar1 / 20; |
681 devBounds->outset(kOutset, kOutset); | 680 devBounds->outset(kOutset, kOutset); |
682 | 681 |
683 return true; | 682 return true; |
684 } | 683 } |
685 | 684 |
686 bool GrAAHairLinePathRenderer::createBezierGeom(GrDrawTarget* target, | 685 bool GrAAHairLinePathRenderer::createBezierGeom(GrDrawTarget* target, |
687 GrDrawState* drawState, | 686 GrDrawState* drawState, |
| 687 const SkMatrix& viewMatrix, |
688 GrDrawTarget::AutoReleaseGeometr
y* arg, | 688 GrDrawTarget::AutoReleaseGeometr
y* arg, |
689 SkRect* devBounds, | 689 SkRect* devBounds, |
690 const SkPath& path, | 690 const SkPath& path, |
691 const PtArray& quads, | 691 const PtArray& quads, |
692 int quadCnt, | 692 int quadCnt, |
693 const PtArray& conics, | 693 const PtArray& conics, |
694 int conicCnt, | 694 int conicCnt, |
695 const IntArray& qSubdivs, | 695 const IntArray& qSubdivs, |
696 const FloatArray& cWeights, | 696 const FloatArray& cWeights, |
697 size_t vertexStride) { | 697 size_t vertexStride) { |
698 const SkMatrix& viewM = drawState->getViewMatrix(); | |
699 | |
700 int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt; | 698 int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt; |
701 | 699 |
702 if (!arg->set(target, vertCnt, vertexStride, 0)) { | 700 if (!arg->set(target, vertCnt, vertexStride, 0)) { |
703 return false; | 701 return false; |
704 } | 702 } |
705 | 703 |
706 BezierVertex* verts = reinterpret_cast<BezierVertex*>(arg->vertices()); | 704 BezierVertex* verts = reinterpret_cast<BezierVertex*>(arg->vertices()); |
707 | 705 |
708 const SkMatrix* toDevice = NULL; | 706 const SkMatrix* toDevice = NULL; |
709 const SkMatrix* toSrc = NULL; | 707 const SkMatrix* toSrc = NULL; |
710 SkMatrix ivm; | 708 SkMatrix ivm; |
711 | 709 |
712 if (viewM.hasPerspective()) { | 710 if (viewMatrix.hasPerspective()) { |
713 if (viewM.invert(&ivm)) { | 711 if (viewMatrix.invert(&ivm)) { |
714 toDevice = &viewM; | 712 toDevice = &viewMatrix; |
715 toSrc = &ivm; | 713 toSrc = &ivm; |
716 } | 714 } |
717 } | 715 } |
718 | 716 |
719 // Seed the dev bounds with some pts known to be inside. Each quad and conic
grows the bounding | 717 // Seed the dev bounds with some pts known to be inside. Each quad and conic
grows the bounding |
720 // box to include its vertices. | 718 // box to include its vertices. |
721 SkPoint seedPts[2]; | 719 SkPoint seedPts[2]; |
722 if (quadCnt) { | 720 if (quadCnt) { |
723 seedPts[0] = quads[0]; | 721 seedPts[0] = quads[0]; |
724 seedPts[1] = quads[2]; | 722 seedPts[1] = quads[2]; |
(...skipping 14 matching lines...) Expand all Loading... |
739 | 737 |
740 // Start Conics | 738 // Start Conics |
741 for (int i = 0; i < conicCnt; ++i) { | 739 for (int i = 0; i < conicCnt; ++i) { |
742 add_conics(&conics[3*i], cWeights[i], toDevice, toSrc, &verts, devBounds
); | 740 add_conics(&conics[3*i], cWeights[i], toDevice, toSrc, &verts, devBounds
); |
743 } | 741 } |
744 return true; | 742 return true; |
745 } | 743 } |
746 | 744 |
747 bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target, | 745 bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target, |
748 const GrDrawState* drawState, | 746 const GrDrawState* drawState, |
| 747 const SkMatrix& viewMatrix, |
749 const SkPath& path, | 748 const SkPath& path, |
750 const SkStrokeRec& stroke, | 749 const SkStrokeRec& stroke, |
751 bool antiAlias) const { | 750 bool antiAlias) const { |
752 if (!antiAlias) { | 751 if (!antiAlias) { |
753 return false; | 752 return false; |
754 } | 753 } |
755 | 754 |
756 if (!IsStrokeHairlineOrEquivalent(stroke, | 755 if (!IsStrokeHairlineOrEquivalent(stroke, viewMatrix, NULL)) { |
757 drawState->getViewMatrix(), | |
758 NULL)) { | |
759 return false; | 756 return false; |
760 } | 757 } |
761 | 758 |
762 if (SkPath::kLine_SegmentMask == path.getSegmentMasks() || | 759 if (SkPath::kLine_SegmentMask == path.getSegmentMasks() || |
763 target->caps()->shaderDerivativeSupport()) { | 760 target->caps()->shaderDerivativeSupport()) { |
764 return true; | 761 return true; |
765 } | 762 } |
766 return false; | 763 return false; |
767 } | 764 } |
768 | 765 |
769 template <class VertexType> | 766 template <class VertexType> |
770 bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertice
s, int vCount) | 767 bool check_bounds(const SkMatrix& viewMatrix, const SkRect& devBounds, void* ver
tices, int vCount) |
771 { | 768 { |
772 SkRect tolDevBounds = devBounds; | 769 SkRect tolDevBounds = devBounds; |
773 // The bounds ought to be tight, but in perspective the below code runs the
verts | 770 // The bounds ought to be tight, but in perspective the below code runs the
verts |
774 // through the view matrix to get back to dev coords, which can introduce im
precision. | 771 // through the view matrix to get back to dev coords, which can introduce im
precision. |
775 if (drawState->getViewMatrix().hasPerspective()) { | 772 if (viewMatrix.hasPerspective()) { |
776 tolDevBounds.outset(SK_Scalar1 / 1000, SK_Scalar1 / 1000); | 773 tolDevBounds.outset(SK_Scalar1 / 1000, SK_Scalar1 / 1000); |
777 } else { | 774 } else { |
778 // Non-persp matrices cause this path renderer to draw in device space. | 775 // Non-persp matrices cause this path renderer to draw in device space. |
779 SkASSERT(drawState->getViewMatrix().isIdentity()); | 776 SkASSERT(viewMatrix.isIdentity()); |
780 } | 777 } |
781 SkRect actualBounds; | 778 SkRect actualBounds; |
782 | 779 |
783 VertexType* verts = reinterpret_cast<VertexType*>(vertices); | 780 VertexType* verts = reinterpret_cast<VertexType*>(vertices); |
784 bool first = true; | 781 bool first = true; |
785 for (int i = 0; i < vCount; ++i) { | 782 for (int i = 0; i < vCount; ++i) { |
786 SkPoint pos = verts[i].fPos; | 783 SkPoint pos = verts[i].fPos; |
787 // This is a hack to workaround the fact that we move some degenerate se
gments offscreen. | 784 // This is a hack to workaround the fact that we move some degenerate se
gments offscreen. |
788 if (SK_ScalarMax == pos.fX) { | 785 if (SK_ScalarMax == pos.fX) { |
789 continue; | 786 continue; |
790 } | 787 } |
791 drawState->getViewMatrix().mapPoints(&pos, 1); | 788 viewMatrix.mapPoints(&pos, 1); |
792 if (first) { | 789 if (first) { |
793 actualBounds.set(pos.fX, pos.fY, pos.fX, pos.fY); | 790 actualBounds.set(pos.fX, pos.fY, pos.fX, pos.fY); |
794 first = false; | 791 first = false; |
795 } else { | 792 } else { |
796 actualBounds.growToInclude(pos.fX, pos.fY); | 793 actualBounds.growToInclude(pos.fX, pos.fY); |
797 } | 794 } |
798 } | 795 } |
799 if (!first) { | 796 if (!first) { |
800 return tolDevBounds.contains(actualBounds); | 797 return tolDevBounds.contains(actualBounds); |
801 } | 798 } |
802 | 799 |
803 return true; | 800 return true; |
804 } | 801 } |
805 | 802 |
806 bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, | 803 bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, |
807 GrDrawState* drawState, | 804 GrDrawState* drawState, |
808 GrColor color, | 805 GrColor color, |
| 806 const SkMatrix& viewMatrix, |
809 const SkPath& path, | 807 const SkPath& path, |
810 const SkStrokeRec& stroke, | 808 const SkStrokeRec& stroke, |
811 bool antiAlias) { | 809 bool antiAlias) { |
812 SkScalar hairlineCoverage; | 810 SkScalar hairlineCoverage; |
813 uint8_t newCoverage = 0xff; | 811 uint8_t newCoverage = 0xff; |
814 if (IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(), | 812 if (IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) { |
815 &hairlineCoverage)) { | |
816 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); | 813 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); |
817 } | 814 } |
818 | 815 |
819 SkIRect devClipBounds; | 816 SkIRect devClipBounds; |
820 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), &devC
lipBounds); | 817 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), &devC
lipBounds); |
821 | 818 |
822 int lineCnt; | 819 int lineCnt; |
823 int quadCnt; | 820 int quadCnt; |
824 int conicCnt; | 821 int conicCnt; |
825 PREALLOC_PTARRAY(128) lines; | 822 PREALLOC_PTARRAY(128) lines; |
826 PREALLOC_PTARRAY(128) quads; | 823 PREALLOC_PTARRAY(128) quads; |
827 PREALLOC_PTARRAY(128) conics; | 824 PREALLOC_PTARRAY(128) conics; |
828 IntArray qSubdivs; | 825 IntArray qSubdivs; |
829 FloatArray cWeights; | 826 FloatArray cWeights; |
830 quadCnt = generate_lines_and_quads(path, drawState->getViewMatrix(), devClip
Bounds, | 827 quadCnt = generate_lines_and_quads(path, viewMatrix, devClipBounds, |
831 &lines, &quads, &conics, &qSubdivs, &cWei
ghts); | 828 &lines, &quads, &conics, &qSubdivs, &cWei
ghts); |
832 lineCnt = lines.count() / 2; | 829 lineCnt = lines.count() / 2; |
833 conicCnt = conics.count() / 3; | 830 conicCnt = conics.count() / 3; |
834 | 831 |
835 // createGeom transforms the geometry to device space when the matrix does n
ot have | 832 // createGeom transforms the geometry to device space when the matrix does n
ot have |
836 // perspective. | 833 // perspective. |
837 GrDrawState::AutoViewMatrixRestore avmr; | 834 SkMatrix vm = viewMatrix; |
838 SkMatrix invert = SkMatrix::I(); | 835 SkMatrix invert = SkMatrix::I(); |
839 if (!drawState->getViewMatrix().hasPerspective()) { | 836 if (!viewMatrix.hasPerspective()) { |
840 avmr.setIdentity(drawState); | 837 vm = SkMatrix::I(); |
841 if (!drawState->getViewMatrix().invert(&invert)) { | 838 if (!viewMatrix.invert(&invert)) { |
842 return false; | 839 return false; |
843 } | 840 } |
844 } | 841 } |
845 | 842 |
846 // do lines first | 843 // do lines first |
847 if (lineCnt) { | 844 if (lineCnt) { |
848 GrDrawTarget::AutoReleaseGeometry arg; | 845 GrDrawTarget::AutoReleaseGeometry arg; |
849 SkRect devBounds; | 846 SkRect devBounds; |
850 | 847 |
851 GrDrawState::AutoRestoreEffects are(drawState); | 848 GrDrawState::AutoRestoreEffects are(drawState); |
852 uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType | | 849 uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType | |
853 GrDefaultGeoProcFactory::kCoverage_GPType; | 850 GrDefaultGeoProcFactory::kCoverage_GPType; |
854 SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Crea
te(color, | 851 SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Crea
te(gpFlags, |
855
gpFlags, | 852
color, |
| 853
vm, |
| 854
invert, |
856
false, | 855
false, |
857
newCoverage, | 856
newCoverage)); |
858
invert)); | |
859 | 857 |
860 if (!this->createLineGeom(target, | 858 if (!this->createLineGeom(target, |
861 drawState, | 859 drawState, |
| 860 viewMatrix, |
862 newCoverage, | 861 newCoverage, |
863 gp->getVertexStride(), | 862 gp->getVertexStride(), |
864 &arg, | 863 &arg, |
865 &devBounds, | 864 &devBounds, |
866 path, | 865 path, |
867 lines, | 866 lines, |
868 lineCnt)) { | 867 lineCnt)) { |
869 return false; | 868 return false; |
870 } | 869 } |
871 | 870 |
872 // Check devBounds | 871 // Check devBounds |
873 SkASSERT(check_bounds<LineVertex>(drawState, devBounds, arg.vertices(), | 872 SkASSERT(check_bounds<LineVertex>(viewMatrix.hasPerspective() ? viewMatr
ix : SkMatrix::I(), |
| 873 devBounds, |
| 874 arg.vertices(), |
874 kLineSegNumVertices * lineCnt)); | 875 kLineSegNumVertices * lineCnt)); |
875 | 876 |
876 { | 877 { |
877 target->setIndexSourceToBuffer(fLinesIndexBuffer); | 878 target->setIndexSourceToBuffer(fLinesIndexBuffer); |
878 int lines = 0; | 879 int lines = 0; |
879 while (lines < lineCnt) { | 880 while (lines < lineCnt) { |
880 int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer); | 881 int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer); |
881 target->drawIndexed(drawState, | 882 target->drawIndexed(drawState, |
882 gp, | 883 gp, |
883 kTriangles_GrPrimitiveType, | 884 kTriangles_GrPrimitiveType, |
884 kLineSegNumVertices*lines, // startV | 885 kLineSegNumVertices*lines, // startV |
885 0, // startI | 886 0, // startI |
886 kLineSegNumVertices*n, // vCount | 887 kLineSegNumVertices*n, // vCount |
887 kIdxsPerLineSeg*n, // iCount | 888 kIdxsPerLineSeg*n, // iCount |
888 &devBounds); | 889 &devBounds); |
889 lines += n; | 890 lines += n; |
890 } | 891 } |
891 } | 892 } |
892 } | 893 } |
893 | 894 |
894 // then quadratics/conics | 895 // then quadratics/conics |
895 if (quadCnt || conicCnt) { | 896 if (quadCnt || conicCnt) { |
896 GrDrawTarget::AutoReleaseGeometry arg; | 897 GrDrawTarget::AutoReleaseGeometry arg; |
897 SkRect devBounds; | 898 SkRect devBounds; |
898 | 899 |
899 if (!this->createBezierGeom(target, | 900 if (!this->createBezierGeom(target, |
900 drawState, | 901 drawState, |
| 902 viewMatrix, |
901 &arg, | 903 &arg, |
902 &devBounds, | 904 &devBounds, |
903 path, | 905 path, |
904 quads, | 906 quads, |
905 quadCnt, | 907 quadCnt, |
906 conics, | 908 conics, |
907 conicCnt, | 909 conicCnt, |
908 qSubdivs, | 910 qSubdivs, |
909 cWeights, | 911 cWeights, |
910 sizeof(BezierVertex))) { | 912 sizeof(BezierVertex))) { |
911 return false; | 913 return false; |
912 } | 914 } |
913 | 915 |
914 // Check devBounds | 916 // Check devBounds |
915 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, | 917 SkASSERT(check_bounds<BezierVertex>(viewMatrix.hasPerspective() ? viewMa
trix : |
916 kQuadNumVertices * quadCnt + kQuadNu
mVertices * conicCnt)); | 918 SkMatr
ix::I(), |
| 919 devBounds, |
| 920 arg.vertices(), |
| 921 kQuadNumVertices * quadCnt + |
| 922 kQuadNumVertices * conicCnt)); |
917 | 923 |
918 if (quadCnt > 0) { | 924 if (quadCnt > 0) { |
919 SkAutoTUnref<GrGeometryProcessor> hairQuadProcessor( | 925 SkAutoTUnref<GrGeometryProcessor> hairQuadProcessor( |
920 GrQuadEffect::Create(color, | 926 GrQuadEffect::Create(color, |
| 927 vm, |
921 kHairlineAA_GrProcessorEdgeType, | 928 kHairlineAA_GrProcessorEdgeType, |
922 *target->caps(), | 929 *target->caps(), |
923 invert, | 930 invert, |
924 newCoverage)); | 931 newCoverage)); |
925 SkASSERT(hairQuadProcessor); | 932 SkASSERT(hairQuadProcessor); |
926 GrDrawState::AutoRestoreEffects are(drawState); | 933 GrDrawState::AutoRestoreEffects are(drawState); |
927 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 934 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
928 | 935 |
929 int quads = 0; | 936 int quads = 0; |
930 while (quads < quadCnt) { | 937 while (quads < quadCnt) { |
931 int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer); | 938 int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer); |
932 target->drawIndexed(drawState, | 939 target->drawIndexed(drawState, |
933 hairQuadProcessor, | 940 hairQuadProcessor, |
934 kTriangles_GrPrimitiveType, | 941 kTriangles_GrPrimitiveType, |
935 kQuadNumVertices*quads, // sta
rtV | 942 kQuadNumVertices*quads, // sta
rtV |
936 0, // sta
rtI | 943 0, // sta
rtI |
937 kQuadNumVertices*n, // vCo
unt | 944 kQuadNumVertices*n, // vCo
unt |
938 kIdxsPerQuad*n, // iCo
unt | 945 kIdxsPerQuad*n, // iCo
unt |
939 &devBounds); | 946 &devBounds); |
940 quads += n; | 947 quads += n; |
941 } | 948 } |
942 } | 949 } |
943 | 950 |
944 if (conicCnt > 0) { | 951 if (conicCnt > 0) { |
945 SkAutoTUnref<GrGeometryProcessor> hairConicProcessor( | 952 SkAutoTUnref<GrGeometryProcessor> hairConicProcessor( |
946 GrConicEffect::Create(color, kHairlineAA_GrProcessorEdgeType
, *target->caps(), | 953 GrConicEffect::Create(color, vm, kHairlineAA_GrProcessorEdge
Type, |
947 invert, newCoverage)); | 954 *target->caps(), invert, newCoverage))
; |
948 SkASSERT(hairConicProcessor); | 955 SkASSERT(hairConicProcessor); |
949 GrDrawState::AutoRestoreEffects are(drawState); | 956 GrDrawState::AutoRestoreEffects are(drawState); |
950 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 957 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
951 | 958 |
952 int conics = 0; | 959 int conics = 0; |
953 while (conics < conicCnt) { | 960 while (conics < conicCnt) { |
954 int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer); | 961 int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer); |
955 target->drawIndexed(drawState, | 962 target->drawIndexed(drawState, |
956 hairConicProcessor, | 963 hairConicProcessor, |
957 kTriangles_GrPrimitiveType, | 964 kTriangles_GrPrimitiveType, |
958 kQuadNumVertices*(quadCnt + conics), // sta
rtV | 965 kQuadNumVertices*(quadCnt + conics), // sta
rtV |
959 0, // sta
rtI | 966 0, // sta
rtI |
960 kQuadNumVertices*n, // vCo
unt | 967 kQuadNumVertices*n, // vCo
unt |
961 kIdxsPerQuad*n, // iCo
unt | 968 kIdxsPerQuad*n, // iCo
unt |
962 &devBounds); | 969 &devBounds); |
963 conics += n; | 970 conics += n; |
964 } | 971 } |
965 } | 972 } |
966 } | 973 } |
967 | 974 |
968 target->resetIndexSource(); | 975 target->resetIndexSource(); |
969 | 976 |
970 return true; | 977 return true; |
971 } | 978 } |
OLD | NEW |