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

Unified Diff: cc/timing_function.cc

Issue 11359077: cc: Replace the WebCore::UnitBezier class with the SkUnitCubicInterp() method from Skia. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix web unittests Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/timing_function.h ('k') | cc/timing_function_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/timing_function.cc
diff --git a/cc/timing_function.cc b/cc/timing_function.cc
index 6588d36d9649c51aa57bce41f1832389a638ced5..7aef57ebb9cab0d00c2385f54bb1600ec1666eb8 100644
--- a/cc/timing_function.cc
+++ b/cc/timing_function.cc
@@ -5,10 +5,79 @@
#include "config.h"
#include "cc/timing_function.h"
+#include "third_party/skia/include/core/SkMath.h"
+// TODO(danakj) These methods come from SkInterpolator.cpp. When such a method
+// is available in the public Skia API, we should switch to using that.
+// http://crbug.com/159735
namespace {
-const double epsilon = 1e-6;
-} // namespace
+
+// Dot14 has 14 bits for decimal places, and the remainder for whole numbers.
+typedef int Dot14;
+#define DOT14_ONE (1 << 14)
+#define DOT14_HALF (1 << 13)
+
+#define Dot14ToFloat(x) ((x) / 16384.f)
+
+static inline Dot14 Dot14Mul(Dot14 a, Dot14 b)
+{
+ return (a * b + DOT14_HALF) >> 14;
+}
+
+static inline Dot14 EvalCubic(Dot14 t, Dot14 A, Dot14 B, Dot14 C)
+{
+ return Dot14Mul(Dot14Mul(Dot14Mul(C, t) + B, t) + A, t);
+}
+
+static inline Dot14 PinAndConvert(SkScalar x)
+{
+ if (x <= 0)
+ return 0;
+ if (x >= SK_Scalar1)
+ return DOT14_ONE;
+ return SkScalarToFixed(x) >> 2;
+}
+
+SkScalar SkUnitCubicInterp(SkScalar bx, SkScalar by, SkScalar cx, SkScalar cy, SkScalar value)
+{
+ Dot14 x = PinAndConvert(value);
+
+ if (x == 0) return 0;
+ if (x == DOT14_ONE) return SK_Scalar1;
+
+ Dot14 b = PinAndConvert(bx);
+ Dot14 c = PinAndConvert(cx);
+
+ // Now compute our coefficients from the control points.
+ // t -> 3b
+ // t^2 -> 3c - 6b
+ // t^3 -> 3b - 3c + 1
+ Dot14 A = 3 * b;
+ Dot14 B = 3 * (c - 2 * b);
+ Dot14 C = 3 * (b - c) + DOT14_ONE;
+
+ // Now search for a t value given x.
+ Dot14 t = DOT14_HALF;
+ Dot14 dt = DOT14_HALF;
+ for (int i = 0; i < 13; i++) {
+ dt >>= 1;
+ Dot14 guess = EvalCubic(t, A, B, C);
+ if (x < guess)
+ t -= dt;
+ else
+ t += dt;
+ }
+
+ // Now we have t, so compute the coefficient for Y and evaluate.
+ b = PinAndConvert(by);
+ c = PinAndConvert(cy);
+ A = 3 * b;
+ B = 3 * (c - 2 * b);
+ C = 3 * (b - c) + DOT14_ONE;
+ return SkFixedToScalar(EvalCubic(t, A, B, C) << 2);
+}
+
+} // anonymous namespace
namespace cc {
@@ -31,7 +100,10 @@ scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::create(double x
}
CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, double y1, double x2, double y2)
- : m_curve(x1, y1, x2, y2)
+ : m_x1(SkDoubleToScalar(x1))
+ , m_y1(SkDoubleToScalar(y1))
+ , m_x2(SkDoubleToScalar(x2))
+ , m_y2(SkDoubleToScalar(y2))
{
}
@@ -41,8 +113,8 @@ CubicBezierTimingFunction::~CubicBezierTimingFunction()
float CubicBezierTimingFunction::getValue(double x) const
{
- UnitBezier temp(m_curve);
- return static_cast<float>(temp.solve(x, epsilon));
+ SkScalar value = SkUnitCubicInterp(m_x1, m_y1, m_x2, m_y2, x);
+ return SkScalarToFloat(value);
}
scoped_ptr<AnimationCurve> CubicBezierTimingFunction::clone() const
« no previous file with comments | « cc/timing_function.h ('k') | cc/timing_function_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698