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

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

Issue 787763007: extract cubic classification from gpu into geometry (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix accidental change Created 6 years 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 | « src/core/SkGeometry.cpp ('k') | 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 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 "GrPathUtils.h" 8 #include "GrPathUtils.h"
9 9
10 #include "GrTypes.h" 10 #include "GrTypes.h"
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 540
541 for (int i = 0; i < count; ++i) { 541 for (int i = 0; i < count; ++i) {
542 SkPoint* cubic = chopped + 3*i; 542 SkPoint* cubic = chopped + 3*i;
543 convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents , dir, quads); 543 convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents , dir, quads);
544 } 544 }
545 545
546 } 546 }
547 547
548 //////////////////////////////////////////////////////////////////////////////// 548 ////////////////////////////////////////////////////////////////////////////////
549 549
550 enum CubicType {
551 kSerpentine_CubicType,
552 kCusp_CubicType,
553 kLoop_CubicType,
554 kQuadratic_CubicType,
555 kLine_CubicType,
556 kPoint_CubicType
557 };
558
559 // discr(I) = d0^2 * (3*d1^2 - 4*d0*d2)
560 // Classification:
561 // discr(I) > 0 Serpentine
562 // discr(I) = 0 Cusp
563 // discr(I) < 0 Loop
564 // d0 = d1 = 0 Quadratic
565 // d0 = d1 = d2 = 0 Line
566 // p0 = p1 = p2 = p3 Point
567 static CubicType classify_cubic(const SkPoint p[4], const SkScalar d[3]) {
568 if (p[0] == p[1] && p[0] == p[2] && p[0] == p[3]) {
569 return kPoint_CubicType;
570 }
571 const SkScalar discr = d[0] * d[0] * (3.f * d[1] * d[1] - 4.f * d[0] * d[2]) ;
572 if (discr > SK_ScalarNearlyZero) {
573 return kSerpentine_CubicType;
574 } else if (discr < -SK_ScalarNearlyZero) {
575 return kLoop_CubicType;
576 } else {
577 if (0.f == d[0] && 0.f == d[1]) {
578 return (0.f == d[2] ? kLine_CubicType : kQuadratic_CubicType);
579 } else {
580 return kCusp_CubicType;
581 }
582 }
583 }
584
585 // Assumes the third component of points is 1.
586 // Calcs p0 . (p1 x p2)
587 static SkScalar calc_dot_cross_cubic(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2) {
588 const SkScalar xComp = p0.fX * (p1.fY - p2.fY);
589 const SkScalar yComp = p0.fY * (p2.fX - p1.fX);
590 const SkScalar wComp = p1.fX * p2.fY - p1.fY * p2.fX;
591 return (xComp + yComp + wComp);
592 }
593
594 // Solves linear system to extract klm 550 // Solves linear system to extract klm
595 // P.K = k (similarly for l, m) 551 // P.K = k (similarly for l, m)
596 // Where P is matrix of control points 552 // Where P is matrix of control points
597 // K is coefficients for the line K 553 // K is coefficients for the line K
598 // k is vector of values of K evaluated at the control points 554 // k is vector of values of K evaluated at the control points
599 // Solving for K, thus K = P^(-1) . k 555 // Solving for K, thus K = P^(-1) . k
600 static void calc_cubic_klm(const SkPoint p[4], const SkScalar controlK[4], 556 static void calc_cubic_klm(const SkPoint p[4], const SkScalar controlK[4],
601 const SkScalar controlL[4], const SkScalar controlM[4 ], 557 const SkScalar controlL[4], const SkScalar controlM[4 ],
602 SkScalar k[3], SkScalar l[3], SkScalar m[3]) { 558 SkScalar k[3], SkScalar l[3], SkScalar m[3]) {
603 SkMatrix matrix; 559 SkMatrix matrix;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 // If d2 < 0 we need to flip the orientation of our curve 684 // If d2 < 0 we need to flip the orientation of our curve
729 // This is done by negating the k and l values 685 // This is done by negating the k and l values
730 if ( d[2] > 0) { 686 if ( d[2] > 0) {
731 for (int i = 0; i < 4; ++i) { 687 for (int i = 0; i < 4; ++i) {
732 k[i] = -k[i]; 688 k[i] = -k[i];
733 l[i] = -l[i]; 689 l[i] = -l[i];
734 } 690 }
735 } 691 }
736 } 692 }
737 693
738 // Calc coefficients of I(s,t) where roots of I are inflection points of curve
739 // I(s,t) = t*(3*d0*s^2 - 3*d1*s*t + d2*t^2)
740 // d0 = a1 - 2*a2+3*a3
741 // d1 = -a2 + 3*a3
742 // d2 = 3*a3
743 // a1 = p0 . (p3 x p2)
744 // a2 = p1 . (p0 x p3)
745 // a3 = p2 . (p1 x p0)
746 // Places the values of d1, d2, d3 in array d passed in
747 static void calc_cubic_inflection_func(const SkPoint p[4], SkScalar d[3]) {
748 SkScalar a1 = calc_dot_cross_cubic(p[0], p[3], p[2]);
749 SkScalar a2 = calc_dot_cross_cubic(p[1], p[0], p[3]);
750 SkScalar a3 = calc_dot_cross_cubic(p[2], p[1], p[0]);
751
752 // need to scale a's or values in later calculations will grow to high
753 SkScalar max = SkScalarAbs(a1);
754 max = SkMaxScalar(max, SkScalarAbs(a2));
755 max = SkMaxScalar(max, SkScalarAbs(a3));
756 max = 1.f/max;
757 a1 = a1 * max;
758 a2 = a2 * max;
759 a3 = a3 * max;
760
761 d[2] = 3.f * a3;
762 d[1] = d[2] - a2;
763 d[0] = d[1] - a2 + a1;
764 }
765
766 int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1 0], SkScalar klm[9], 694 int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1 0], SkScalar klm[9],
767 SkScalar klm_rev[3]) { 695 SkScalar klm_rev[3]) {
768 // Variable to store the two parametric values at the loop double point 696 // Variable to store the two parametric values at the loop double point
769 SkScalar smallS = 0.f; 697 SkScalar smallS = 0.f;
770 SkScalar largeS = 0.f; 698 SkScalar largeS = 0.f;
771 699
772 SkScalar d[3]; 700 SkScalar d[3];
773 calc_cubic_inflection_func(src, d); 701 SkCubicType cType = SkClassifyCubic(src, d);
774
775 CubicType cType = classify_cubic(src, d);
776 702
777 int chop_count = 0; 703 int chop_count = 0;
778 if (kLoop_CubicType == cType) { 704 if (kLoop_SkCubicType == cType) {
779 SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]); 705 SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]);
780 SkScalar ls = d[1] - tempSqrt; 706 SkScalar ls = d[1] - tempSqrt;
781 SkScalar lt = 2.f * d[0]; 707 SkScalar lt = 2.f * d[0];
782 SkScalar ms = d[1] + tempSqrt; 708 SkScalar ms = d[1] + tempSqrt;
783 SkScalar mt = 2.f * d[0]; 709 SkScalar mt = 2.f * d[0];
784 ls = ls / lt; 710 ls = ls / lt;
785 ms = ms / mt; 711 ms = ms / mt;
786 // need to have t values sorted since this is what is expected by SkChop CubicAt 712 // need to have t values sorted since this is what is expected by SkChop CubicAt
787 if (ls <= ms) { 713 if (ls <= ms) {
788 smallS = ls; 714 smallS = ls;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 if (smallS < 0.f && largeS > 1.f) { 753 if (smallS < 0.f && largeS > 1.f) {
828 klm_rev[0] = -1.f; 754 klm_rev[0] = -1.f;
829 } else { 755 } else {
830 klm_rev[0] = 1.f; 756 klm_rev[0] = 1.f;
831 } 757 }
832 } 758 }
833 SkScalar controlK[4]; 759 SkScalar controlK[4];
834 SkScalar controlL[4]; 760 SkScalar controlL[4];
835 SkScalar controlM[4]; 761 SkScalar controlM[4];
836 762
837 if (kSerpentine_CubicType == cType || (kCusp_CubicType == cType && 0.f ! = d[0])) { 763 if (kSerpentine_SkCubicType == cType || (kCusp_SkCubicType == cType && 0 .f != d[0])) {
838 set_serp_klm(d, controlK, controlL, controlM); 764 set_serp_klm(d, controlK, controlL, controlM);
839 } else if (kLoop_CubicType == cType) { 765 } else if (kLoop_SkCubicType == cType) {
840 set_loop_klm(d, controlK, controlL, controlM); 766 set_loop_klm(d, controlK, controlL, controlM);
841 } else if (kCusp_CubicType == cType) { 767 } else if (kCusp_SkCubicType == cType) {
842 SkASSERT(0.f == d[0]); 768 SkASSERT(0.f == d[0]);
843 set_cusp_klm(d, controlK, controlL, controlM); 769 set_cusp_klm(d, controlK, controlL, controlM);
844 } else if (kQuadratic_CubicType == cType) { 770 } else if (kQuadratic_SkCubicType == cType) {
845 set_quadratic_klm(d, controlK, controlL, controlM); 771 set_quadratic_klm(d, controlK, controlL, controlM);
846 } 772 }
847 773
848 calc_cubic_klm(src, controlK, controlL, controlM, klm, &klm[3], &klm[6]) ; 774 calc_cubic_klm(src, controlK, controlL, controlM, klm, &klm[3], &klm[6]) ;
849 } 775 }
850 return chop_count + 1; 776 return chop_count + 1;
851 } 777 }
852 778
853 void GrPathUtils::getCubicKLM(const SkPoint p[4], SkScalar klm[9]) { 779 void GrPathUtils::getCubicKLM(const SkPoint p[4], SkScalar klm[9]) {
854 SkScalar d[3]; 780 SkScalar d[3];
855 calc_cubic_inflection_func(p, d); 781 SkCubicType cType = SkClassifyCubic(p, d);
856
857 CubicType cType = classify_cubic(p, d);
858 782
859 SkScalar controlK[4]; 783 SkScalar controlK[4];
860 SkScalar controlL[4]; 784 SkScalar controlL[4];
861 SkScalar controlM[4]; 785 SkScalar controlM[4];
862 786
863 if (kSerpentine_CubicType == cType || (kCusp_CubicType == cType && 0.f != d[ 0])) { 787 if (kSerpentine_SkCubicType == cType || (kCusp_SkCubicType == cType && 0.f ! = d[0])) {
864 set_serp_klm(d, controlK, controlL, controlM); 788 set_serp_klm(d, controlK, controlL, controlM);
865 } else if (kLoop_CubicType == cType) { 789 } else if (kLoop_SkCubicType == cType) {
866 set_loop_klm(d, controlK, controlL, controlM); 790 set_loop_klm(d, controlK, controlL, controlM);
867 } else if (kCusp_CubicType == cType) { 791 } else if (kCusp_SkCubicType == cType) {
868 SkASSERT(0.f == d[0]); 792 SkASSERT(0.f == d[0]);
869 set_cusp_klm(d, controlK, controlL, controlM); 793 set_cusp_klm(d, controlK, controlL, controlM);
870 } else if (kQuadratic_CubicType == cType) { 794 } else if (kQuadratic_SkCubicType == cType) {
871 set_quadratic_klm(d, controlK, controlL, controlM); 795 set_quadratic_klm(d, controlK, controlL, controlM);
872 } 796 }
873 797
874 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]); 798 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]);
875 } 799 }
OLDNEW
« no previous file with comments | « src/core/SkGeometry.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698