summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-07 04:59:34 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-07 04:59:34 +0000
commit114e65d34c6f1a38bc447d70840e8ac2b30b953b (patch)
treeb810d0d9b81098d8cc8e720528fd01cd6bed8ade
parent84b8bd1002a2a50e22fbc57fca169ebcbba35928 (diff)
downloadchromium_src-114e65d34c6f1a38bc447d70840e8ac2b30b953b.zip
chromium_src-114e65d34c6f1a38bc447d70840e8ac2b30b953b.tar.gz
chromium_src-114e65d34c6f1a38bc447d70840e8ac2b30b953b.tar.bz2
cc: Replace the WebCore::UnitBezier class with the SkUnitCubicInterp() method from Skia.
This method exists in Skia, but is not publicly consumable/linkable with a component build. Skia will expose this (or a similar) method through a proper public API, and we should use it. But in the meantime, we make a copy of the method in timing_function.cc, and use it there in place of WebCore's UnitBezier class. Tests: cc_unittests:TimingFunctionTest.CubicBezierTimingFunction This test compares the output of the timing function against baseline values recorded with WebCore's UnitBezier class. If new methods are able to come closer to those values, we should decrease the epsilon used in the test accordingly. R=jamesr BUG=147395 Review URL: https://chromiumcodereview.appspot.com/11359077 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166362 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/DEPS3
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/keyframed_animation_curve_unittest.cc2
-rw-r--r--cc/stubs/UnitBezier.h6
-rw-r--r--cc/stubs/unit_bezier.h14
-rw-r--r--cc/timing_function.cc82
-rw-r--r--cc/timing_function.h7
-rw-r--r--cc/timing_function_unittest.cc41
-rw-r--r--webkit/compositor_bindings/web_float_animation_curve_unittest.cc2
-rw-r--r--webkit/compositor_bindings/web_transform_animation_curve_unittest.cc2
11 files changed, 127 insertions, 35 deletions
diff --git a/cc/DEPS b/cc/DEPS
index 56c6cf7..a669999 100644
--- a/cc/DEPS
+++ b/cc/DEPS
@@ -8,9 +8,6 @@ include_rules = [
# http://crbug.com/147395
"+third_party/WebKit/Source/WebCore/platform/graphics/Region.h",
"+Source/WebCore/platform/graphics/Region.h",
-# TODO(jamesr): Resolve these
- "+third_party/WebKit/Source/WebCore/platform/graphics/UnitBezier.h",
- "+Source/WebCore/platform/graphics/UnitBezier.h",
# http://crbug.com/154451
"+third_party/WebKit/Source/WTF/config.h",
"+Source/WTF/config.h",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 1261484..cbb598d 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -264,10 +264,8 @@
'sources': [
'<@(cc_source_files)',
'stubs/Region.h',
- 'stubs/UnitBezier.h',
'stubs/config.h',
- 'stubs/unit_bezier.h',
],
},
],
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index df98423..a20849b 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -52,6 +52,7 @@
'texture_uploader_unittest.cc',
'tiled_layer_unittest.cc',
'tree_synchronizer_unittest.cc',
+ 'timing_function_unittest.cc',
],
'cc_tests_support_files': [
'test/animation_test_common.cc',
diff --git a/cc/keyframed_animation_curve_unittest.cc b/cc/keyframed_animation_curve_unittest.cc
index 2adfede..a1a0cf9 100644
--- a/cc/keyframed_animation_curve_unittest.cc
+++ b/cc/keyframed_animation_curve_unittest.cc
@@ -197,7 +197,7 @@ TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction)
EXPECT_FLOAT_EQ(0, curve->getValue(0));
EXPECT_LT(0, curve->getValue(0.25));
EXPECT_GT(0.25, curve->getValue(0.25));
- EXPECT_FLOAT_EQ(0.5, curve->getValue(0.5));
+ EXPECT_NEAR(curve->getValue(0.5), 0.5, 0.00015);
EXPECT_LT(0.75, curve->getValue(0.75));
EXPECT_GT(1, curve->getValue(0.75));
EXPECT_FLOAT_EQ(1, curve->getValue(1));
diff --git a/cc/stubs/UnitBezier.h b/cc/stubs/UnitBezier.h
deleted file mode 100644
index d6a792d..0000000
--- a/cc/stubs/UnitBezier.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Temporary forwarding header
-#include "cc/stubs/unit_bezier.h"
diff --git a/cc/stubs/unit_bezier.h b/cc/stubs/unit_bezier.h
deleted file mode 100644
index 1ff5da9..0000000
--- a/cc/stubs/unit_bezier.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(jamesr): Remove or refactor this dependency.
-#if INSIDE_WEBKIT_BUILD
-#include "Source/WebCore/platform/graphics/UnitBezier.h"
-#else
-#include "third_party/WebKit/Source/WebCore/platform/graphics/UnitBezier.h"
-#endif
-
-namespace cc {
-typedef WebCore::UnitBezier UnitBezier;
-}
diff --git a/cc/timing_function.cc b/cc/timing_function.cc
index 6588d36..7aef57e 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
diff --git a/cc/timing_function.h b/cc/timing_function.h
index df9e7ef..1150eba 100644
--- a/cc/timing_function.h
+++ b/cc/timing_function.h
@@ -5,9 +5,9 @@
#ifndef CC_TIMING_FUNCTION_H_
#define CC_TIMING_FUNCTION_H_
-#include "UnitBezier.h"
#include "cc/animation_curve.h"
#include "cc/cc_export.h"
+#include "third_party/skia/include/core/SkScalar.h"
namespace cc {
@@ -35,7 +35,10 @@ public:
protected:
CubicBezierTimingFunction(double x1, double y1, double x2, double y2);
- UnitBezier m_curve;
+ SkScalar m_x1;
+ SkScalar m_y1;
+ SkScalar m_x2;
+ SkScalar m_y2;
};
class CC_EXPORT EaseTimingFunction {
diff --git a/cc/timing_function_unittest.cc b/cc/timing_function_unittest.cc
new file mode 100644
index 0000000..69b3267
--- /dev/null
+++ b/cc/timing_function_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "cc/timing_function.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace cc;
+
+namespace {
+
+TEST(TimingFunctionTest, CubicBezierTimingFunction) {
+ scoped_ptr<CubicBezierTimingFunction> function = CubicBezierTimingFunction::create(0.25, 0, 0.75, 1);
+
+ double epsilon = 0.00015;
+
+ EXPECT_NEAR(function->getValue(0), 0, epsilon);
+ EXPECT_NEAR(function->getValue(0.05), 0.01136, epsilon);
+ EXPECT_NEAR(function->getValue(0.1), 0.03978, epsilon);
+ EXPECT_NEAR(function->getValue(0.15), 0.079780, epsilon);
+ EXPECT_NEAR(function->getValue(0.2), 0.12803, epsilon);
+ EXPECT_NEAR(function->getValue(0.25), 0.18235, epsilon);
+ EXPECT_NEAR(function->getValue(0.3), 0.24115, epsilon);
+ EXPECT_NEAR(function->getValue(0.35), 0.30323, epsilon);
+ EXPECT_NEAR(function->getValue(0.4), 0.36761, epsilon);
+ EXPECT_NEAR(function->getValue(0.45), 0.43345, epsilon);
+ EXPECT_NEAR(function->getValue(0.5), 0.5, epsilon);
+ EXPECT_NEAR(function->getValue(0.6), 0.63238, epsilon);
+ EXPECT_NEAR(function->getValue(0.65), 0.69676, epsilon);
+ EXPECT_NEAR(function->getValue(0.7), 0.75884, epsilon);
+ EXPECT_NEAR(function->getValue(0.75), 0.81764, epsilon);
+ EXPECT_NEAR(function->getValue(0.8), 0.87196, epsilon);
+ EXPECT_NEAR(function->getValue(0.85), 0.92021, epsilon);
+ EXPECT_NEAR(function->getValue(0.9), 0.96021, epsilon);
+ EXPECT_NEAR(function->getValue(0.95), 0.98863, epsilon);
+ EXPECT_NEAR(function->getValue(1), 1, epsilon);
+}
+
+} // anonymous namespace
diff --git a/webkit/compositor_bindings/web_float_animation_curve_unittest.cc b/webkit/compositor_bindings/web_float_animation_curve_unittest.cc
index 449a892..ee1b74e 100644
--- a/webkit/compositor_bindings/web_float_animation_curve_unittest.cc
+++ b/webkit/compositor_bindings/web_float_animation_curve_unittest.cc
@@ -103,7 +103,7 @@ TEST(WebFloatAnimationCurveTest, CubicBezierTimingFunction)
EXPECT_FLOAT_EQ(0, curve->getValue(0));
EXPECT_LT(0, curve->getValue(0.25));
EXPECT_GT(0.25, curve->getValue(0.25));
- EXPECT_FLOAT_EQ(0.5, curve->getValue(0.5));
+ EXPECT_NEAR(curve->getValue(0.5), 0.5, 0.00015);
EXPECT_LT(0.75, curve->getValue(0.75));
EXPECT_GT(1, curve->getValue(0.75));
EXPECT_FLOAT_EQ(1, curve->getValue(1));
diff --git a/webkit/compositor_bindings/web_transform_animation_curve_unittest.cc b/webkit/compositor_bindings/web_transform_animation_curve_unittest.cc
index 2ca4e48..db9e467 100644
--- a/webkit/compositor_bindings/web_transform_animation_curve_unittest.cc
+++ b/webkit/compositor_bindings/web_transform_animation_curve_unittest.cc
@@ -136,7 +136,7 @@ TEST(WebTransformAnimationCurveTest, CubicBezierTimingFunction)
EXPECT_FLOAT_EQ(0, curve->getValue(0).m41());
EXPECT_LT(0, curve->getValue(0.25).m41());
EXPECT_GT(0.25, curve->getValue(0.25).m41());
- EXPECT_FLOAT_EQ(0.5, curve->getValue(0.5).m41());
+ EXPECT_NEAR(curve->getValue(0.5).m41(), 0.5, 0.00015);
EXPECT_LT(0.75, curve->getValue(0.75).m41());
EXPECT_GT(1, curve->getValue(0.75).m41());
EXPECT_FLOAT_EQ(1, curve->getValue(1).m41());