1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6  * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_TIMING_FUNCTION_H_
26 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_TIMING_FUNCTION_H_
27 
28 #include "base/memory/scoped_refptr.h"
29 #include "cc/animation/timing_function.h"
30 #include "third_party/blink/renderer/platform/platform_export.h"
31 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
32 #include "third_party/blink/renderer/platform/wtf/assertions.h"
33 #include "third_party/blink/renderer/platform/wtf/casting.h"
34 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
35 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
36 #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
37 
38 namespace blink {
39 
40 class PLATFORM_EXPORT TimingFunction
41     : public ThreadSafeRefCounted<TimingFunction> {
42  public:
43   using Type = cc::TimingFunction::Type;
44   using LimitDirection = cc::TimingFunction::LimitDirection;
45 
46   virtual ~TimingFunction() = default;
47 
GetType()48   Type GetType() const { return type_; }
49 
50   virtual String ToString() const = 0;
51 
52   // Evaluates the timing function at the given fraction. The limit direction
53   // applies when evaluating a function at a discontinuous boundary and
54   // indicates if the left or right limit should be applied.
Evaluate(double fraction,LimitDirection limit_direction)55   virtual double Evaluate(double fraction,
56                           LimitDirection limit_direction) const {
57     return Evaluate(fraction);
58   }
59 
60   // Evaluates the timing function at the given fraction.
61   virtual double Evaluate(double fraction) const = 0;
62 
63   // This function returns the minimum and maximum values obtainable when
64   // calling evaluate();
65   virtual void Range(double* min_value, double* max_value) const = 0;
66 
67   // Create CC instance.
68   virtual std::unique_ptr<cc::TimingFunction> CloneToCC() const = 0;
69 
70  protected:
TimingFunction(Type type)71   TimingFunction(Type type) : type_(type) {}
72 
73  private:
74   Type type_;
75 };
76 
77 class PLATFORM_EXPORT LinearTimingFunction final : public TimingFunction {
78  public:
Shared()79   static LinearTimingFunction* Shared() {
80     DEFINE_STATIC_REF(LinearTimingFunction, linear,
81                       (base::AdoptRef(new LinearTimingFunction())));
82     return linear;
83   }
84 
85   ~LinearTimingFunction() override = default;
86 
87   // TimingFunction implementation.
88   String ToString() const override;
89   double Evaluate(double fraction) const override;
90   void Range(double* min_value, double* max_value) const override;
91   std::unique_ptr<cc::TimingFunction> CloneToCC() const override;
92 
93  private:
LinearTimingFunction()94   LinearTimingFunction() : TimingFunction(Type::LINEAR) {}
95 };
96 
97 class PLATFORM_EXPORT CubicBezierTimingFunction final : public TimingFunction {
98  public:
99   using EaseType = cc::CubicBezierTimingFunction::EaseType;
100 
Create(double x1,double y1,double x2,double y2)101   static scoped_refptr<CubicBezierTimingFunction> Create(double x1,
102                                                          double y1,
103                                                          double x2,
104                                                          double y2) {
105     return base::AdoptRef(new CubicBezierTimingFunction(x1, y1, x2, y2));
106   }
107 
108   static CubicBezierTimingFunction* Preset(EaseType);
109 
110   ~CubicBezierTimingFunction() override = default;
111 
112   // TimingFunction implementation.
113   String ToString() const override;
114   double Evaluate(double fraction) const override;
115   void Range(double* min_value, double* max_value) const override;
116   std::unique_ptr<cc::TimingFunction> CloneToCC() const override;
117 
X1()118   double X1() const {
119     DCHECK_EQ(GetEaseType(), EaseType::CUSTOM);
120     return x1_;
121   }
Y1()122   double Y1() const {
123     DCHECK_EQ(GetEaseType(), EaseType::CUSTOM);
124     return y1_;
125   }
X2()126   double X2() const {
127     DCHECK_EQ(GetEaseType(), EaseType::CUSTOM);
128     return x2_;
129   }
Y2()130   double Y2() const {
131     DCHECK_EQ(GetEaseType(), EaseType::CUSTOM);
132     return y2_;
133   }
GetEaseType()134   EaseType GetEaseType() const { return bezier_->ease_type(); }
135 
136  private:
CubicBezierTimingFunction(EaseType ease_type)137   explicit CubicBezierTimingFunction(EaseType ease_type)
138       : TimingFunction(Type::CUBIC_BEZIER),
139         bezier_(cc::CubicBezierTimingFunction::CreatePreset(ease_type)),
140         x1_(),
141         y1_(),
142         x2_(),
143         y2_() {}
144 
CubicBezierTimingFunction(double x1,double y1,double x2,double y2)145   CubicBezierTimingFunction(double x1, double y1, double x2, double y2)
146       : TimingFunction(Type::CUBIC_BEZIER),
147         bezier_(cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)),
148         x1_(x1),
149         y1_(y1),
150         x2_(x2),
151         y2_(y2) {}
152 
153   std::unique_ptr<cc::CubicBezierTimingFunction> bezier_;
154 
155   // TODO(loyso): Get these values from m_bezier->bezier_ (gfx::CubicBezier)
156   const double x1_;
157   const double y1_;
158   const double x2_;
159   const double y2_;
160 };
161 
162 class PLATFORM_EXPORT StepsTimingFunction final : public TimingFunction {
163  public:
164   using StepPosition = cc::StepsTimingFunction::StepPosition;
165 
Create(int steps,StepPosition step_position)166   static scoped_refptr<StepsTimingFunction> Create(int steps,
167                                                    StepPosition step_position) {
168     return base::AdoptRef(new StepsTimingFunction(steps, step_position));
169   }
170 
Preset(StepPosition position)171   static StepsTimingFunction* Preset(StepPosition position) {
172     DEFINE_STATIC_REF(StepsTimingFunction, start,
173                       Create(1, StepPosition::START));
174     DEFINE_STATIC_REF(StepsTimingFunction, end, Create(1, StepPosition::END));
175     switch (position) {
176       case StepPosition::START:
177         return start;
178       case StepPosition::END:
179         return end;
180       default:
181         NOTREACHED();
182         return end;
183     }
184   }
185 
186   ~StepsTimingFunction() override = default;
187 
188   // TimingFunction implementation.
189   String ToString() const override;
190   double Evaluate(double fraction,
191                   LimitDirection limit_direction) const override;
192   double Evaluate(double fraction) const override;
193 
194   void Range(double* min_value, double* max_value) const override;
195   std::unique_ptr<cc::TimingFunction> CloneToCC() const override;
196 
NumberOfSteps()197   int NumberOfSteps() const { return steps_->steps(); }
GetStepPosition()198   StepPosition GetStepPosition() const { return steps_->step_position(); }
199 
200  private:
StepsTimingFunction(int steps,StepPosition step_position)201   StepsTimingFunction(int steps, StepPosition step_position)
202       : TimingFunction(Type::STEPS),
203         steps_(cc::StepsTimingFunction::Create(steps, step_position)) {}
204 
205   std::unique_ptr<cc::StepsTimingFunction> steps_;
206 };
207 
208 PLATFORM_EXPORT scoped_refptr<TimingFunction>
209 CreateCompositorTimingFunctionFromCC(const cc::TimingFunction*);
210 
211 PLATFORM_EXPORT bool operator==(const LinearTimingFunction&,
212                                 const TimingFunction&);
213 PLATFORM_EXPORT bool operator==(const CubicBezierTimingFunction&,
214                                 const TimingFunction&);
215 PLATFORM_EXPORT bool operator==(const StepsTimingFunction&,
216                                 const TimingFunction&);
217 
218 PLATFORM_EXPORT bool operator==(const TimingFunction&, const TimingFunction&);
219 PLATFORM_EXPORT bool operator!=(const TimingFunction&, const TimingFunction&);
220 
221 template <>
222 struct DowncastTraits<LinearTimingFunction> {
223   static bool AllowFrom(const TimingFunction& value) {
224     return value.GetType() == TimingFunction::Type::LINEAR;
225   }
226 };
227 template <>
228 struct DowncastTraits<CubicBezierTimingFunction> {
229   static bool AllowFrom(const TimingFunction& value) {
230     return value.GetType() == TimingFunction::Type::CUBIC_BEZIER;
231   }
232 };
233 template <>
234 struct DowncastTraits<StepsTimingFunction> {
235   static bool AllowFrom(const TimingFunction& value) {
236     return value.GetType() == TimingFunction::Type::STEPS;
237   }
238 };
239 
240 }  // namespace blink
241 
242 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_TIMING_FUNCTION_H_
243