aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar halcanary <halcanary@google.com>2016-08-10 11:40:37 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-10 11:40:37 -0700
commit69aaa5a49a10454d573cbd8c5d980029d78ae459 (patch)
tree18c8b0f90274114d3edb20424e8c540f6865787b /src
parent386ba540612defc7808edc28126b9b8afcf45b89 (diff)
Revert 386ba54 and 4ab47e0 : perf debug assert.
Revert "Refactor SkCurveMeasure to use existing eval code" This reverts commit 4ab47e087ecfc82f070cbbaef4d9eb562d3fd163. Revert "Fastpath lines in SkCurveMeasure" This reverts commit 386ba540612defc7808edc28126b9b8afcf45b89. TBR= NOTRY=true GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2233683004 Review-Url: https://codereview.chromium.org/2233683004
Diffstat (limited to 'src')
-rw-r--r--src/utils/SkCurveMeasure.cpp136
-rw-r--r--src/utils/SkCurveMeasure.h16
2 files changed, 63 insertions, 89 deletions
diff --git a/src/utils/SkCurveMeasure.cpp b/src/utils/SkCurveMeasure.cpp
index 2a74a49c22..fc2aa84faa 100644
--- a/src/utils/SkCurveMeasure.cpp
+++ b/src/utils/SkCurveMeasure.cpp
@@ -6,66 +6,10 @@
*/
#include "SkCurveMeasure.h"
-#include "SkGeometry.h"
// for abs
#include <cmath>
-#define UNIMPLEMENTED SkDEBUGF(("%s:%d unimplemented\n", __FILE__, __LINE__))
-
-/// Used inside SkCurveMeasure::getTime's Newton's iteration
-static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType,
- SkScalar t) {
- SkPoint pos;
- switch (segType) {
- case kQuad_SegType:
- pos = SkEvalQuadAt(pts, t);
- break;
- case kLine_SegType:
- pos = SkPoint::Make(SkScalarInterp(pts[0].x(), pts[1].x(), t),
- SkScalarInterp(pts[0].y(), pts[1].y(), t));
- break;
- case kCubic_SegType:
- SkEvalCubicAt(pts, t, &pos, nullptr, nullptr);
- break;
- case kConic_SegType: {
- SkConic conic(pts, pts[3].x());
- conic.evalAt(t, &pos);
- }
- break;
- default:
- UNIMPLEMENTED;
- }
-
- return pos;
-}
-
-/// Used inside SkCurveMeasure::getTime's Newton's iteration
-static inline SkVector evaluateDerivative(const SkPoint pts[4],
- SkSegType segType, SkScalar t) {
- SkVector tan;
- switch (segType) {
- case kQuad_SegType:
- tan = SkEvalQuadTangentAt(pts, t);
- break;
- case kLine_SegType:
- tan = pts[1] - pts[0];
- break;
- case kCubic_SegType:
- SkEvalCubicAt(pts, t, nullptr, &tan, nullptr);
- break;
- case kConic_SegType: {
- SkConic conic(pts, pts[3].x());
- conic.evalAt(t, nullptr, &tan);
- }
- break;
- default:
- UNIMPLEMENTED;
- }
-
- return tan;
-}
-/// Used in ArcLengthIntegrator::computeLength
static inline Sk8f evaluateDerivativeLength(const Sk8f& ts,
const Sk8f (&xCoeff)[3],
const Sk8f (&yCoeff)[3],
@@ -77,15 +21,18 @@ static inline Sk8f evaluateDerivativeLength(const Sk8f& ts,
x = xCoeff[0]*ts + xCoeff[1];
y = yCoeff[0]*ts + yCoeff[1];
break;
+ case kLine_SegType:
+ SkDebugf("Unimplemented");
+ break;
case kCubic_SegType:
x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2];
y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2];
break;
case kConic_SegType:
- UNIMPLEMENTED;
+ SkDebugf("Unimplemented");
break;
default:
- UNIMPLEMENTED;
+ SkDebugf("Unimplemented");
}
x = x * x;
@@ -93,7 +40,6 @@ static inline Sk8f evaluateDerivativeLength(const Sk8f& ts,
return (x + y).sqrt();
}
-
ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
: fSegType(segType) {
switch (fSegType) {
@@ -113,6 +59,9 @@ ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
yCoeff[1] = Sk8f(2.0f*(By - Ay));
}
break;
+ case kLine_SegType:
+ SkDEBUGF(("Unimplemented"));
+ break;
case kCubic_SegType:
{
float Ax = pts[0].x();
@@ -124,7 +73,6 @@ ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
float Cy = pts[2].y();
float Dy = pts[3].y();
- // precompute coefficients for derivative
xCoeff[0] = Sk8f(3.0f*(-Ax + 3.0f*(Bx - Cx) + Dx));
xCoeff[1] = Sk8f(3.0f*(2.0f*(Ax - 2.0f*Bx + Cx)));
xCoeff[2] = Sk8f(3.0f*(-Ax + Bx));
@@ -135,10 +83,10 @@ ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
}
break;
case kConic_SegType:
- UNIMPLEMENTED;
+ SkDEBUGF(("Unimplemented"));
break;
default:
- UNIMPLEMENTED;
+ SkDEBUGF(("Unimplemented"));
}
}
@@ -169,9 +117,7 @@ SkCurveMeasure::SkCurveMeasure(const SkPoint* pts, SkSegType segType)
}
break;
case SkSegType::kLine_SegType:
- fPts[0] = pts[0];
- fPts[1] = pts[1];
- fLength = (fPts[1] - fPts[0]).length();
+ SkDebugf("Unimplemented");
break;
case SkSegType::kCubic_SegType:
for (size_t i = 0; i < 4; i++) {
@@ -179,17 +125,13 @@ SkCurveMeasure::SkCurveMeasure(const SkPoint* pts, SkSegType segType)
}
break;
case SkSegType::kConic_SegType:
- for (size_t i = 0; i < 4; i++) {
- fPts[i] = pts[i];
- }
+ SkDebugf("Unimplemented");
break;
default:
- UNIMPLEMENTED;
+ SkDEBUGF(("Unimplemented"));
break;
}
- if (kLine_SegType != segType) {
- fIntegrator = ArcLengthIntegrator(fPts, fSegType);
- }
+ fIntegrator = ArcLengthIntegrator(fPts, fSegType);
}
SkScalar SkCurveMeasure::getLength() {
@@ -218,9 +160,6 @@ SkScalar SkCurveMeasure::getTime(SkScalar targetLength) {
if (SkScalarNearlyEqual(targetLength, currentLength)) {
return 1.0f;
}
- if (kLine_SegType == fSegType) {
- return targetLength / currentLength;
- }
// initial estimate of t is percentage of total length
SkScalar currentT = targetLength / currentLength;
@@ -260,8 +199,9 @@ SkScalar SkCurveMeasure::getTime(SkScalar targetLength) {
prevT = currentT;
if (iterations < kNewtonIters) {
+ // TODO(hstern) switch here on curve type.
// This is just newton's formula.
- SkScalar dt = evaluateDerivative(fPts, fSegType, currentT).length();
+ SkScalar dt = evaluateQuadDerivative(currentT).length();
newT = currentT - (lengthDiff / dt);
// If newT is out of bounds, bisect inside newton.
@@ -278,7 +218,7 @@ SkScalar SkCurveMeasure::getTime(SkScalar targetLength) {
newT = (minT + maxT) * 0.5f;
} else {
SkDEBUGF(("%.7f %.7f didn't get close enough after bisection.\n",
- currentT, currentLength));
+ currentT, currentLength));
break;
}
currentT = newT;
@@ -295,16 +235,52 @@ SkScalar SkCurveMeasure::getTime(SkScalar targetLength) {
}
void SkCurveMeasure::getPosTanTime(SkScalar targetLength, SkPoint* pos,
- SkVector* tan, SkScalar* time) {
+ SkVector* tan, SkScalar* time) {
SkScalar t = getTime(targetLength);
if (time) {
*time = t;
}
if (pos) {
- *pos = evaluate(fPts, fSegType, t);
+ // TODO(hstern) switch here on curve type.
+ *pos = evaluateQuad(t);
}
if (tan) {
- *tan = evaluateDerivative(fPts, fSegType, t);
+ // TODO(hstern) switch here on curve type.
+ *tan = evaluateQuadDerivative(t);
}
}
+
+// this is why I feel that the ArcLengthIntegrator should be combined
+// with some sort of evaluator that caches the constants computed from the
+// control points. this is basically the same code in ArcLengthIntegrator
+SkPoint SkCurveMeasure::evaluateQuad(SkScalar t) {
+ SkScalar ti = 1.0f - t;
+
+ SkScalar Ax = fPts[0].x();
+ SkScalar Bx = fPts[1].x();
+ SkScalar Cx = fPts[2].x();
+ SkScalar Ay = fPts[0].y();
+ SkScalar By = fPts[1].y();
+ SkScalar Cy = fPts[2].y();
+
+ SkScalar x = Ax*ti*ti + 2.0f*Bx*t*ti + Cx*t*t;
+ SkScalar y = Ay*ti*ti + 2.0f*By*t*ti + Cy*t*t;
+ return SkPoint::Make(x, y);
+}
+
+SkVector SkCurveMeasure::evaluateQuadDerivative(SkScalar t) {
+ SkScalar Ax = fPts[0].x();
+ SkScalar Bx = fPts[1].x();
+ SkScalar Cx = fPts[2].x();
+ SkScalar Ay = fPts[0].y();
+ SkScalar By = fPts[1].y();
+ SkScalar Cy = fPts[2].y();
+
+ SkScalar A2BCx = 2.0f*(Ax - 2*Bx + Cx);
+ SkScalar A2BCy = 2.0f*(Ay - 2*By + Cy);
+ SkScalar ABx = 2.0f*(Bx - Ax);
+ SkScalar ABy = 2.0f*(By - Ay);
+
+ return SkPoint::Make(A2BCx*t + ABx, A2BCy*t + ABy);
+}
diff --git a/src/utils/SkCurveMeasure.h b/src/utils/SkCurveMeasure.h
index 5807211236..2846103633 100644
--- a/src/utils/SkCurveMeasure.h
+++ b/src/utils/SkCurveMeasure.h
@@ -44,15 +44,6 @@ private:
class SkCurveMeasure {
public:
SkCurveMeasure() {}
-
- // Almost exactly the same as in SkPath::Iter:
- // kLine_SegType -> 2 points: start end
- // kQuad_SegType -> 3 points: start control end
- // kCubic_SegType -> 4 points: start control1 control2 end
- // kConic_SegType -> 4 points: start control end (w, w)
- //
- // i.e. the only difference is that the conic's last point is a point
- // consisting of the w value twice
SkCurveMeasure(const SkPoint* pts, SkSegType segType);
SkScalar getTime(SkScalar targetLength);
@@ -60,6 +51,13 @@ public:
SkScalar getLength();
private:
+ SkPoint evaluateQuad(SkScalar t);
+ SkVector evaluateQuadDerivative(SkScalar t);
+ //SkPoint evaluate_cubic(SkScalar t);
+ //SkVector evaluate_cubic_derivative(SkScalar t);
+ //SkPoint evaluate_conic(SkScalar t);
+ //SkVector evaluate_conic_derivative(SkScalar t);
+
const SkScalar kTolerance = 0.0001f;
const int kNewtonIters = 5;
const int kBisectIters = 5;