1 // Copyright 2018 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.
4
5 #include "third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h"
6 #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
7 #include "third_party/blink/renderer/core/animation/timing_calculations.h"
8
9 namespace blink {
10
WorkletAnimationEffect(base::Optional<base::TimeDelta> local_time,const Timing & specified_timing)11 WorkletAnimationEffect::WorkletAnimationEffect(
12 base::Optional<base::TimeDelta> local_time,
13 const Timing& specified_timing)
14 : local_time_(local_time),
15 specified_timing_(specified_timing),
16 calculated_() {
17 specified_timing_.AssertValid();
18 }
19
getTiming() const20 EffectTiming* WorkletAnimationEffect::getTiming() const {
21 return specified_timing_.ConvertToEffectTiming();
22 }
23
getComputedTiming() const24 ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const {
25 base::Optional<double> local_time;
26 if (local_time_)
27 local_time = base::Optional<double>(local_time_.value().InSecondsF());
28
29 bool needs_update = last_update_time_ != local_time;
30 last_update_time_ = local_time;
31
32 if (needs_update) {
33 // The playback rate is needed to calculate whether the effect is current or
34 // not (https://drafts.csswg.org/web-animations-1/#current). Since we only
35 // use this information to create a ComputedEffectTiming, which does not
36 // include that information, we do not need to supply one.
37 base::Optional<double> playback_rate = base::nullopt;
38 calculated_ = specified_timing_.CalculateTimings(
39 local_time, Timing::AnimationDirection::kForwards, false,
40 playback_rate);
41 }
42
43 return specified_timing_.getComputedTiming(calculated_,
44 /*is_keyframe_effect*/ false);
45 }
46
localTime() const47 base::Optional<double> WorkletAnimationEffect::localTime() const {
48 if (!local_time_)
49 return base::nullopt;
50 return local_time_.value().InMillisecondsF();
51 }
52
setLocalTime(base::Optional<double> time_ms)53 void WorkletAnimationEffect::setLocalTime(base::Optional<double> time_ms) {
54 if (!time_ms) {
55 local_time_.reset();
56 return;
57 }
58 DCHECK(!std::isnan(time_ms.value()));
59 // Convert double to base::TimeDelta because cc/animation expects
60 // base::TimeDelta.
61 //
62 // Note on precision loss: base::TimeDelta has microseconds precision which is
63 // also the precision recommended by the web animation specification as well
64 // [1]. If the input time value has a bigger precision then the conversion
65 // causes precision loss. Doing the conversion here ensures that reading the
66 // value back provides the actual value we use in further computation which
67 // is the least surprising path.
68 // [1] https://drafts.csswg.org/web-animations/#precision-of-time-values
69 local_time_ = base::TimeDelta::FromMillisecondsD(time_ms.value());
70 }
71
setLocalTime(double time_ms,bool is_null)72 void WorkletAnimationEffect::setLocalTime(double time_ms, bool is_null) {
73 if (is_null) {
74 local_time_.reset();
75 return;
76 }
77 DCHECK(!std::isnan(time_ms));
78 // Convert double to base::TimeDelta because cc/animation expects
79 // base::TimeDelta.
80 //
81 // Note on precision loss: base::TimeDelta has microseconds precision which is
82 // also the precision recommended by the web animation specification as well
83 // [1]. If the input time value has a bigger precision then the conversion
84 // causes precision loss. Doing the conversion here ensures that reading the
85 // value back provides the actual value we use in further computation which
86 // is the least surprising path.
87 // [1] https://drafts.csswg.org/web-animations/#precision-of-time-values
88 local_time_ = base::TimeDelta::FromMillisecondsD(time_ms);
89 }
90
localTime(bool & is_null) const91 double WorkletAnimationEffect::localTime(bool& is_null) const {
92 is_null = !local_time_.has_value();
93 return local_time_.value_or(base::TimeDelta()).InMillisecondsF();
94 }
95
local_time() const96 base::Optional<base::TimeDelta> WorkletAnimationEffect::local_time() const {
97 return local_time_;
98 }
99 } // namespace blink
100