Mailbox support for texture layers.
[chromium-blink-merge.git] / cc / timing_function.cc
blobf181a7b22e5a8a87ee19883be5dd74ec41525b22
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
3 // found in the LICENSE file.
5 #include "cc/timing_function.h"
7 #include "third_party/skia/include/core/SkMath.h"
9 // TODO(danakj) These methods come from SkInterpolator.cpp. When such a method
10 // is available in the public Skia API, we should switch to using that.
11 // http://crbug.com/159735
12 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)
19 #define Dot14ToFloat(x) ((x) / 16384.f)
21 static inline Dot14 Dot14Mul(Dot14 a, Dot14 b) {
22 return (a * b + DOT14_HALF) >> 14;
25 static inline Dot14 EvalCubic(Dot14 t, Dot14 A, Dot14 B, Dot14 C) {
26 return Dot14Mul(Dot14Mul(Dot14Mul(C, t) + B, t) + A, t);
29 static inline Dot14 PinAndConvert(SkScalar x) {
30 if (x <= 0)
31 return 0;
32 if (x >= SK_Scalar1)
33 return DOT14_ONE;
34 return SkScalarToFixed(x) >> 2;
37 SkScalar SkUnitCubicInterp(SkScalar bx, SkScalar by,
38 SkScalar cx, SkScalar cy,
39 SkScalar value) {
40 Dot14 x = PinAndConvert(value);
42 if (x == 0) return 0;
43 if (x == DOT14_ONE) return SK_Scalar1;
45 Dot14 b = PinAndConvert(bx);
46 Dot14 c = PinAndConvert(cx);
48 // Now compute our coefficients from the control points.
49 // t -> 3b
50 // t^2 -> 3c - 6b
51 // t^3 -> 3b - 3c + 1
52 Dot14 A = 3 * b;
53 Dot14 B = 3 * (c - 2 * b);
54 Dot14 C = 3 * (b - c) + DOT14_ONE;
56 // Now search for a t value given x.
57 Dot14 t = DOT14_HALF;
58 Dot14 dt = DOT14_HALF;
59 for (int i = 0; i < 13; i++) {
60 dt >>= 1;
61 Dot14 guess = EvalCubic(t, A, B, C);
62 if (x < guess)
63 t -= dt;
64 else
65 t += dt;
68 // Now we have t, so compute the coefficient for Y and evaluate.
69 b = PinAndConvert(by);
70 c = PinAndConvert(cy);
71 A = 3 * b;
72 B = 3 * (c - 2 * b);
73 C = 3 * (b - c) + DOT14_ONE;
74 return SkFixedToScalar(EvalCubic(t, A, B, C) << 2);
77 } // namespace
79 namespace cc {
81 TimingFunction::TimingFunction() {
84 TimingFunction::~TimingFunction() {
87 double TimingFunction::duration() const {
88 return 1.0;
91 scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::create(
92 double x1, double y1, double x2, double y2) {
93 return make_scoped_ptr(new CubicBezierTimingFunction(x1, y1, x2, y2));
96 CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, double y1,
97 double x2, double y2)
98 : x1_(SkDoubleToScalar(x1)),
99 y1_(SkDoubleToScalar(y1)),
100 x2_(SkDoubleToScalar(x2)),
101 y2_(SkDoubleToScalar(y2)) {
104 CubicBezierTimingFunction::~CubicBezierTimingFunction() {
107 float CubicBezierTimingFunction::getValue(double x) const {
108 SkScalar value = SkUnitCubicInterp(x1_, y1_, x2_, y2_, x);
109 return SkScalarToFloat(value);
112 scoped_ptr<AnimationCurve> CubicBezierTimingFunction::clone() const {
113 return make_scoped_ptr(
114 new CubicBezierTimingFunction(*this)).PassAs<AnimationCurve>();
117 // These numbers come from http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag.
118 scoped_ptr<TimingFunction> EaseTimingFunction::create() {
119 return CubicBezierTimingFunction::create(
120 0.25, 0.1, 0.25, 1).PassAs<TimingFunction>();
123 scoped_ptr<TimingFunction> EaseInTimingFunction::create() {
124 return CubicBezierTimingFunction::create(
125 0.42, 0, 1.0, 1).PassAs<TimingFunction>();
128 scoped_ptr<TimingFunction> EaseOutTimingFunction::create() {
129 return CubicBezierTimingFunction::create(
130 0, 0, 0.58, 1).PassAs<TimingFunction>();
133 scoped_ptr<TimingFunction> EaseInOutTimingFunction::create() {
134 return CubicBezierTimingFunction::create(
135 0.42, 0, 0.58, 1).PassAs<TimingFunction>();
138 } // namespace cc