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

Side by Side Diff: cc/animation/scroll_offset_animation_curve.cc

Issue 2040543002: Take MT jank into account when animating the scroll offset on CC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix constant Created 4 years, 6 months 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "cc/animation/scroll_offset_animation_curve.h" 5 #include "cc/animation/scroll_offset_animation_curve.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 12 matching lines...) Expand all
23 const double kInverseDeltaMinDuration = 6.0; 23 const double kInverseDeltaMinDuration = 6.0;
24 const double kInverseDeltaMaxDuration = 12.0; 24 const double kInverseDeltaMaxDuration = 12.0;
25 25
26 const double kInverseDeltaSlope = 26 const double kInverseDeltaSlope =
27 (kInverseDeltaMinDuration - kInverseDeltaMaxDuration) / 27 (kInverseDeltaMinDuration - kInverseDeltaMaxDuration) /
28 (kInverseDeltaRampEndPx - kInverseDeltaRampStartPx); 28 (kInverseDeltaRampEndPx - kInverseDeltaRampStartPx);
29 29
30 const double kInverseDeltaOffset = 30 const double kInverseDeltaOffset =
31 kInverseDeltaMaxDuration - kInverseDeltaRampStartPx * kInverseDeltaSlope; 31 kInverseDeltaMaxDuration - kInverseDeltaRampStartPx * kInverseDeltaSlope;
32 32
33 const double kMinDuration = 5.0;
34
33 namespace cc { 35 namespace cc {
34 36
35 namespace { 37 namespace {
36 38
37 const double kEpsilon = 0.01f; 39 const double kEpsilon = 0.01f;
38 40
39 static float MaximumDimension(const gfx::Vector2dF& delta) { 41 static float MaximumDimension(const gfx::Vector2dF& delta) {
40 return std::abs(delta.x()) > std::abs(delta.y()) ? delta.x() : delta.y(); 42 return std::abs(delta.x()) > std::abs(delta.y()) ? delta.x() : delta.y();
41 } 43 }
42 44
43 static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta, 45 static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta,
44 DurationBehavior behavior) { 46 DurationBehavior behavior,
47 base::TimeDelta jank_adjustment) {
45 double duration = kConstantDuration; 48 double duration = kConstantDuration;
46 switch (behavior) { 49 switch (behavior) {
47 case DurationBehavior::CONSTANT: 50 case DurationBehavior::CONSTANT:
48 duration = kConstantDuration; 51 duration = kConstantDuration;
49 break; 52 break;
50 case DurationBehavior::DELTA_BASED: 53 case DurationBehavior::DELTA_BASED:
51 duration = std::sqrt(std::abs(MaximumDimension(delta))); 54 duration = std::sqrt(std::abs(MaximumDimension(delta)));
52 break; 55 break;
53 case DurationBehavior::INVERSE_DELTA: 56 case DurationBehavior::INVERSE_DELTA:
54 duration = std::min( 57 duration = std::min(
55 std::max(kInverseDeltaOffset + 58 std::max(kInverseDeltaOffset +
56 std::abs(MaximumDimension(delta)) * kInverseDeltaSlope, 59 std::abs(MaximumDimension(delta)) * kInverseDeltaSlope,
57 kInverseDeltaMinDuration), 60 kInverseDeltaMinDuration),
58 kInverseDeltaMaxDuration); 61 kInverseDeltaMaxDuration);
59 break; 62 break;
60 default: 63 default:
61 NOTREACHED(); 64 NOTREACHED();
62 } 65 }
63 return base::TimeDelta::FromMicroseconds(duration / kDurationDivisor * 66
64 base::Time::kMicrosecondsPerSecond); 67 base::TimeDelta td = base::TimeDelta::FromMicroseconds(
68 duration / kDurationDivisor * base::Time::kMicrosecondsPerSecond);
69 base::TimeDelta min_td = base::TimeDelta::FromMicroseconds(
70 kMinDuration / kDurationDivisor * base::Time::kMicrosecondsPerSecond);
71 // jank_adjustment is the time delay between now and when we were actually
72 // asked to scroll. If the delay is large, setting the duration to 0 will
73 // scroll to the target position instantly.
74 if (td - jank_adjustment > min_td)
75 return td - jank_adjustment;
76 return base::TimeDelta();
ymalik 2016/06/21 23:46:02 @skobes, If the animation duration is < 83ms, this
65 } 77 }
66 78
67 static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity( 79 static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity(
68 double velocity) { 80 double velocity) {
69 // Clamp velocity to a sane value. 81 // Clamp velocity to a sane value.
70 velocity = std::min(std::max(velocity, -1000.0), 1000.0); 82 velocity = std::min(std::max(velocity, -1000.0), 1000.0);
71 83
72 // Based on CubicBezierTimingFunction::EaseType::EASE_IN_OUT preset 84 // Based on CubicBezierTimingFunction::EaseType::EASE_IN_OUT preset
73 // with first control point scaled. 85 // with first control point scaled.
74 const double x1 = 0.42; 86 const double x1 = 0.42;
(...skipping 16 matching lines...) Expand all
91 std::unique_ptr<TimingFunction> timing_function, 103 std::unique_ptr<TimingFunction> timing_function,
92 DurationBehavior duration_behavior) 104 DurationBehavior duration_behavior)
93 : target_value_(target_value), 105 : target_value_(target_value),
94 timing_function_(std::move(timing_function)), 106 timing_function_(std::move(timing_function)),
95 duration_behavior_(duration_behavior), 107 duration_behavior_(duration_behavior),
96 has_set_initial_value_(false) {} 108 has_set_initial_value_(false) {}
97 109
98 ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() {} 110 ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() {}
99 111
100 void ScrollOffsetAnimationCurve::SetInitialValue( 112 void ScrollOffsetAnimationCurve::SetInitialValue(
101 const gfx::ScrollOffset& initial_value) { 113 const gfx::ScrollOffset& initial_value,
114 base::TimeDelta jank_adjustment) {
102 initial_value_ = initial_value; 115 initial_value_ = initial_value;
103 has_set_initial_value_ = true; 116 has_set_initial_value_ = true;
104 total_animation_duration_ = SegmentDuration( 117 total_animation_duration_ =
105 target_value_.DeltaFrom(initial_value_), duration_behavior_); 118 SegmentDuration(target_value_.DeltaFrom(initial_value_),
119 duration_behavior_, jank_adjustment);
106 } 120 }
107 121
108 bool ScrollOffsetAnimationCurve::HasSetInitialValue() const { 122 bool ScrollOffsetAnimationCurve::HasSetInitialValue() const {
109 return has_set_initial_value_; 123 return has_set_initial_value_;
110 } 124 }
111 125
112 void ScrollOffsetAnimationCurve::ApplyAdjustment( 126 void ScrollOffsetAnimationCurve::ApplyAdjustment(
113 const gfx::Vector2dF& adjustment) { 127 const gfx::Vector2dF& adjustment) {
114 initial_value_ = ScrollOffsetWithDelta(initial_value_, adjustment); 128 initial_value_ = ScrollOffsetWithDelta(initial_value_, adjustment);
115 target_value_ = ScrollOffsetWithDelta(target_value_, adjustment); 129 target_value_ = ScrollOffsetWithDelta(target_value_, adjustment);
116 } 130 }
117 131
118 gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue( 132 gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
119 base::TimeDelta t) const { 133 base::TimeDelta t) const {
120 base::TimeDelta duration = total_animation_duration_ - last_retarget_; 134 base::TimeDelta duration = total_animation_duration_ - last_retarget_;
121 t -= last_retarget_; 135 t -= last_retarget_;
122 136
137 if (t >= duration)
138 return target_value_;
139
123 if (t <= base::TimeDelta()) 140 if (t <= base::TimeDelta())
124 return initial_value_; 141 return initial_value_;
125 142
126 if (t >= duration)
127 return target_value_;
128
129 double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration)); 143 double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration));
130 return gfx::ScrollOffset( 144 return gfx::ScrollOffset(
131 gfx::Tween::FloatValueBetween( 145 gfx::Tween::FloatValueBetween(
132 progress, initial_value_.x(), target_value_.x()), 146 progress, initial_value_.x(), target_value_.x()),
133 gfx::Tween::FloatValueBetween( 147 gfx::Tween::FloatValueBetween(
134 progress, initial_value_.y(), target_value_.y())); 148 progress, initial_value_.y(), target_value_.y()));
135 } 149 }
136 150
137 base::TimeDelta ScrollOffsetAnimationCurve::Duration() const { 151 base::TimeDelta ScrollOffsetAnimationCurve::Duration() const {
138 return total_animation_duration_; 152 return total_animation_duration_;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 target_value_ = new_target; 208 target_value_ = new_target;
195 return; 209 return;
196 } 210 }
197 gfx::ScrollOffset current_position = 211 gfx::ScrollOffset current_position =
198 GetValue(base::TimeDelta::FromSecondsD(t)); 212 GetValue(base::TimeDelta::FromSecondsD(t));
199 gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_); 213 gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_);
200 gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position); 214 gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);
201 215
202 double old_duration = 216 double old_duration =
203 (total_animation_duration_ - last_retarget_).InSecondsF(); 217 (total_animation_duration_ - last_retarget_).InSecondsF();
218
219 if (old_duration < kEpsilon) {
220 // We had an almost instant animation previously, don't try to animate.
221 target_value_ = new_target;
222 return;
223 }
224
ymalik 2016/06/21 23:46:02 Reasoning: I think updating an animation which had
204 double old_normalized_velocity = timing_function_->Velocity( 225 double old_normalized_velocity = timing_function_->Velocity(
205 (t - last_retarget_.InSecondsF()) / old_duration); 226 (t - last_retarget_.InSecondsF()) / old_duration);
206 227
207 // Use the velocity-based duration bound when it is less than the constant 228 // Use the velocity-based duration bound when it is less than the constant
208 // segment duration. This minimizes the "rubber-band" bouncing effect when 229 // segment duration. This minimizes the "rubber-band" bouncing effect when
209 // old_normalized_velocity is large and new_delta is small. 230 // old_normalized_velocity is large and new_delta is small.
210 double new_duration = 231 double new_duration =
211 std::min(SegmentDuration(new_delta, duration_behavior_).InSecondsF(), 232 std::min(SegmentDuration(new_delta, duration_behavior_, base::TimeDelta())
233 .InSecondsF(),
212 VelocityBasedDurationBound(old_delta, old_normalized_velocity, 234 VelocityBasedDurationBound(old_delta, old_normalized_velocity,
213 old_duration, new_delta)); 235 old_duration, new_delta));
214 236
215 if (new_duration < kEpsilon) { 237 if (new_duration < kEpsilon) {
216 // We are already at or very close to the new target. Stop animating. 238 // We are already at or very close to the new target. Stop animating.
217 target_value_ = new_target; 239 target_value_ = new_target;
218 total_animation_duration_ = base::TimeDelta::FromSecondsD(t); 240 total_animation_duration_ = base::TimeDelta::FromSecondsD(t);
219 return; 241 return;
220 } 242 }
221 243
222 // TimingFunction::Velocity gives the slope of the curve from 0 to 1. 244 // TimingFunction::Velocity gives the slope of the curve from 0 to 1.
223 // To match the "true" velocity in px/sec we must adjust this slope for 245 // To match the "true" velocity in px/sec we must adjust this slope for
224 // differences in duration and scroll delta between old and new curves. 246 // differences in duration and scroll delta between old and new curves.
225 double new_normalized_velocity = 247 double new_normalized_velocity =
226 old_normalized_velocity * (new_duration / old_duration) * 248 old_normalized_velocity * (new_duration / old_duration) *
227 (MaximumDimension(old_delta) / MaximumDimension(new_delta)); 249 (MaximumDimension(old_delta) / MaximumDimension(new_delta));
228 250
229 initial_value_ = current_position; 251 initial_value_ = current_position;
230 target_value_ = new_target; 252 target_value_ = new_target;
231 total_animation_duration_ = base::TimeDelta::FromSecondsD(t + new_duration); 253 total_animation_duration_ = base::TimeDelta::FromSecondsD(t + new_duration);
232 last_retarget_ = base::TimeDelta::FromSecondsD(t); 254 last_retarget_ = base::TimeDelta::FromSecondsD(t);
233 timing_function_ = EaseOutWithInitialVelocity(new_normalized_velocity); 255 timing_function_ = EaseOutWithInitialVelocity(new_normalized_velocity);
234 } 256 }
235 257
236 } // namespace cc 258 } // namespace cc
OLDNEW
« no previous file with comments | « cc/animation/scroll_offset_animation_curve.h ('k') | cc/animation/scroll_offset_animations_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698