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

Side by Side 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: rebase 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/timing_function.h ('k') | cc/timing_function_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 6
7 #include "cc/timing_function.h" 7 #include "cc/timing_function.h"
8 #include "third_party/skia/include/core/SkMath.h"
8 9
10 // TODO(danakj) These methods come from SkInterpolator.cpp. When such a method
11 // is available in the public Skia API, we should switch to using that.
jamesr 2012/11/06 23:21:19 can we have a bug for this?
danakj 2012/11/06 23:26:51 Ya, I had asked mike for one, but I'll just make o
9 namespace { 12 namespace {
10 const double epsilon = 1e-6; 13
11 } // namespace 14 // Dot14 has 14 bits for decimal places, and the remainder for whole numbers.
15 typedef int Dot14;
16 #define DOT14_ONE (1 << 14)
17 #define DOT14_HALF (1 << 13)
18
19 #define Dot14ToFloat(x) ((x) / 16384.f)
20
21 static inline Dot14 Dot14Mul(Dot14 a, Dot14 b)
22 {
23 return (a * b + DOT14_HALF) >> 14;
24 }
25
26 static inline Dot14 EvalCubic(Dot14 t, Dot14 A, Dot14 B, Dot14 C)
27 {
28 return Dot14Mul(Dot14Mul(Dot14Mul(C, t) + B, t) + A, t);
29 }
30
31 static inline Dot14 PinAndConvert(SkScalar x)
32 {
33 if (x <= 0)
34 return 0;
35 if (x >= SK_Scalar1)
36 return DOT14_ONE;
37 return SkScalarToFixed(x) >> 2;
38 }
39
40 SkScalar SkUnitCubicInterp(SkScalar bx, SkScalar by, SkScalar cx, SkScalar cy, S kScalar value)
41 {
42 Dot14 x = PinAndConvert(value);
43
44 if (x == 0) return 0;
45 if (x == DOT14_ONE) return SK_Scalar1;
46
47 Dot14 b = PinAndConvert(bx);
48 Dot14 c = PinAndConvert(cx);
49
50 // Now compute our coefficients from the control points.
51 // t -> 3b
52 // t^2 -> 3c - 6b
53 // t^3 -> 3b - 3c + 1
54 Dot14 A = 3 * b;
55 Dot14 B = 3 * (c - 2 * b);
56 Dot14 C = 3 * (b - c) + DOT14_ONE;
57
58 // Now search for a t value given x.
59 Dot14 t = DOT14_HALF;
60 Dot14 dt = DOT14_HALF;
61 for (int i = 0; i < 13; i++) {
62 dt >>= 1;
63 Dot14 guess = EvalCubic(t, A, B, C);
64 if (x < guess)
65 t -= dt;
66 else
67 t += dt;
68 }
69
70 // Now we have t, so compute the coefficient for Y and evaluate.
71 b = PinAndConvert(by);
72 c = PinAndConvert(cy);
73 A = 3 * b;
74 B = 3 * (c - 2 * b);
75 C = 3 * (b - c) + DOT14_ONE;
76 return SkFixedToScalar(EvalCubic(t, A, B, C) << 2);
77 }
78
79 } // anonymous namespace
12 80
13 namespace cc { 81 namespace cc {
14 82
15 TimingFunction::TimingFunction() 83 TimingFunction::TimingFunction()
16 { 84 {
17 } 85 }
18 86
19 TimingFunction::~TimingFunction() 87 TimingFunction::~TimingFunction()
20 { 88 {
21 } 89 }
22 90
23 double TimingFunction::duration() const 91 double TimingFunction::duration() const
24 { 92 {
25 return 1.0; 93 return 1.0;
26 } 94 }
27 95
28 scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::create(double x 1, double y1, double x2, double y2) 96 scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::create(double x 1, double y1, double x2, double y2)
29 { 97 {
30 return make_scoped_ptr(new CubicBezierTimingFunction(x1, y1, x2, y2)); 98 return make_scoped_ptr(new CubicBezierTimingFunction(x1, y1, x2, y2));
31 } 99 }
32 100
33 CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, double y1, doubl e x2, double y2) 101 CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, double y1, doubl e x2, double y2)
34 : m_curve(x1, y1, x2, y2) 102 : m_x1(SkDoubleToScalar(x1))
103 , m_y1(SkDoubleToScalar(y1))
104 , m_x2(SkDoubleToScalar(x2))
105 , m_y2(SkDoubleToScalar(y2))
35 { 106 {
36 } 107 }
37 108
38 CubicBezierTimingFunction::~CubicBezierTimingFunction() 109 CubicBezierTimingFunction::~CubicBezierTimingFunction()
39 { 110 {
40 } 111 }
41 112
42 float CubicBezierTimingFunction::getValue(double x) const 113 float CubicBezierTimingFunction::getValue(double x) const
43 { 114 {
44 UnitBezier temp(m_curve); 115 SkScalar value = SkUnitCubicInterp(m_x1, m_y1, m_x2, m_y2, x);
45 return static_cast<float>(temp.solve(x, epsilon)); 116 return SkScalarToFloat(value);
46 } 117 }
47 118
48 scoped_ptr<AnimationCurve> CubicBezierTimingFunction::clone() const 119 scoped_ptr<AnimationCurve> CubicBezierTimingFunction::clone() const
49 { 120 {
50 return make_scoped_ptr(new CubicBezierTimingFunction(*this)).PassAs<Animatio nCurve>(); 121 return make_scoped_ptr(new CubicBezierTimingFunction(*this)).PassAs<Animatio nCurve>();
51 } 122 }
52 123
53 // These numbers come from http://www.w3.org/TR/css3-transitions/#transition-tim ing-function_tag. 124 // These numbers come from http://www.w3.org/TR/css3-transitions/#transition-tim ing-function_tag.
54 scoped_ptr<TimingFunction> EaseTimingFunction::create() 125 scoped_ptr<TimingFunction> EaseTimingFunction::create()
55 { 126 {
56 return CubicBezierTimingFunction::create(0.25, 0.1, 0.25, 1).PassAs<TimingFu nction>(); 127 return CubicBezierTimingFunction::create(0.25, 0.1, 0.25, 1).PassAs<TimingFu nction>();
57 } 128 }
58 129
59 scoped_ptr<TimingFunction> EaseInTimingFunction::create() 130 scoped_ptr<TimingFunction> EaseInTimingFunction::create()
60 { 131 {
61 return CubicBezierTimingFunction::create(0.42, 0, 1.0, 1).PassAs<TimingFunct ion>(); 132 return CubicBezierTimingFunction::create(0.42, 0, 1.0, 1).PassAs<TimingFunct ion>();
62 } 133 }
63 134
64 scoped_ptr<TimingFunction> EaseOutTimingFunction::create() 135 scoped_ptr<TimingFunction> EaseOutTimingFunction::create()
65 { 136 {
66 return CubicBezierTimingFunction::create(0, 0, 0.58, 1).PassAs<TimingFunctio n>(); 137 return CubicBezierTimingFunction::create(0, 0, 0.58, 1).PassAs<TimingFunctio n>();
67 } 138 }
68 139
69 scoped_ptr<TimingFunction> EaseInOutTimingFunction::create() 140 scoped_ptr<TimingFunction> EaseInOutTimingFunction::create()
70 { 141 {
71 return CubicBezierTimingFunction::create(0.42, 0, 0.58, 1).PassAs<TimingFunc tion>(); 142 return CubicBezierTimingFunction::create(0.42, 0, 0.58, 1).PassAs<TimingFunc tion>();
72 } 143 }
73 144
74 } // namespace cc 145 } // namespace cc
OLDNEW
« 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