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

Side by Side Diff: content/browser/renderer_host/input/fling/fling_curve_impl.cc

Issue 41703006: Move fling implementation from renderer to browser: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 7 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
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "content/browser/renderer_host/input/fling/fling_curve_impl.h"
6
7 #include <cmath>
8
9 #include "base/debug/trace_event.h"
10 #include "base/logging.h"
11 #include "content/browser/renderer_host/input/fling/fling_curve_configuration.h"
12 #include "content/public/common/renderer_preferences.h"
13
14 namespace {
15
16 const char* kCurveName = "FlingCurveImpl";
17
18 inline double Position(double t, float* p) {
19 return p[0] * exp(-p[2] * t) - p[1] * t - p[0];
20 }
21
22 inline double Velocity(double t, float* p) {
23 return -p[0] * p[2] * exp(-p[2] * t) - p[1];
24 }
25
26 inline double TimeAtVelocity(double v, float* p) {
27 DCHECK(p[0]);
28 DCHECK(p[2]);
29 return -log((v + p[1]) / (-p[0] * p[2])) / p[2];
30 }
31
32 } // namespace
33
34
35 namespace content {
36
37 // This curve implementation is based on the notion of a single, absolute
38 // curve, which starts at a large velocity and smoothly decreases to
39 // zero. For a given input velocity, we find where on the curve this
40 // velocity occurs, and start the animation at this point---denoted by
41 // (time_offset_, position_offset_).
42 //
43 // This has the effect of automatically determining an animation duration
44 // that scales with input velocity, as faster initial velocities start
45 // earlier on the curve and thus take longer to reach the end. No
46 // complicated time scaling is required.
47 //
48 // Since the starting velocity is implicitly determined by our starting
49 // point, we only store the relative magnitude and direction of both
50 // initial x- and y-velocities, and use this to scale the computed
51 // displacement at any point in time. This guarantees that fling
52 // trajectories are straight lines when viewed in x-y space. Initial
53 // velocities that lie outside the max velocity are constrained to start
54 // at zero (and thus are implicitly scaled).
55 //
56 // The curve is modelled as a 4th order polynomial, starting at t = 0,
57 // and ending at t = curve_duration_. Attempts to generate
58 // position/velocity estimates outside this range are undefined.
59
60 FlingCurve* FlingCurveImpl::Create(
61 const gfx::PointF& initial_velocity,
62 float p0,
63 float p1,
64 float p2,
65 const gfx::Point& cumulative_scroll) {
66 return new FlingCurveImpl(initial_velocity, p0, p1, p2,
67 cumulative_scroll);
68 }
69
70 FlingCurveImpl::FlingCurveImpl(
71 const gfx::PointF& initial_velocity,
72 float alpha,
73 float beta,
74 float gamma,
75 const gfx::Point& cumulative_scroll)
76 : cumulative_scroll_(gfx::PointF(cumulative_scroll.x(),
77 cumulative_scroll.y())) {
78 DCHECK(initial_velocity != gfx::PointF());
79
80 coefficients_[0] = alpha;
81 coefficients_[1] = beta;
82 coefficients_[2] = gamma;
83
84 // Curve ends when velocity reaches zero.
85 curve_duration_ = TimeAtVelocity(0, coefficients_);
86 DCHECK(curve_duration_ > 0);
87
88 float max_start_velocity = std::max(std::fabs(initial_velocity.x()),
89 std::fabs(initial_velocity.y()));
90
91 // Force max_start_velocity to lie in the range v(0) to v(curve_duration),
92 // and assume that the curve parameters define a monotonically decreasing
93 // velocity, or else bisection search may fail.
94 if (max_start_velocity > Velocity(0, coefficients_))
95 max_start_velocity = Velocity(0, coefficients_);
96
97 if (max_start_velocity < 0)
98 max_start_velocity = 0;
99
100 // We keep track of relative magnitudes and directions of the
101 // velocity/displacement components here.
102 displacement_ratio_ = gfx::PointF(initial_velocity.x() / max_start_velocity,
103 initial_velocity.y() / max_start_velocity);
104
105 // Compute time-offset for start velocity.
106 time_offset_ = TimeAtVelocity(max_start_velocity, coefficients_);
107
108 // Compute curve position at offset time
109 position_offset_ = Position(time_offset_, coefficients_);
110 TRACE_EVENT_ASYNC_BEGIN1("input", "GestureAnimation", this, "curve",
111 kCurveName);
112 }
113
114 FlingCurveImpl::~FlingCurveImpl() {
115 TRACE_EVENT_ASYNC_END0("input", "GestureAnimation", this);
116 }
117
118 bool FlingCurveImpl::Apply(double time_in_secs, FlingCurveTarget* target) {
119 float displacement;
120 float speed;
121 if (time_in_secs < 0) {
122 displacement = 0.f;
123 speed = 0.f;
124 } else if (time_in_secs + time_offset_ < curve_duration_) {
125 displacement =
126 Position(time_in_secs + time_offset_, coefficients_) - position_offset_;
127 speed = Velocity(time_in_secs + time_offset_, coefficients_);
128 } else {
129 displacement = Position(curve_duration_, coefficients_) - position_offset_;
130 speed = 0.f;
131 }
132
133 // Keep track of integer portion of scroll thus far, and prepare increment.
134 gfx::PointF scroll(displacement * displacement_ratio_.x(),
135 displacement * displacement_ratio_.y());
136 gfx::PointF scroll_increment(scroll.x() - cumulative_scroll_.x(),
137 scroll.y() - cumulative_scroll_.y());
138 gfx::PointF scroll_velocity(speed * displacement_ratio_.x(),
139 speed * displacement_ratio_.y());
140 cumulative_scroll_ = scroll;
141
142 if (time_in_secs + time_offset_ < curve_duration_ ||
143 scroll_increment != gfx::PointF()) {
144 target->NotifyCurrentFlingVelocity(scroll_velocity);
145 // scrollBy() could delete this curve if the animation is over, so don't
146 // touch any member variables after making that call.
147 target->ScrollBy(scroll_increment);
148 return true;
149 }
150
151 return false;
152 }
153
154 // static
155 FlingCurve* FlingCurve::Create(blink::WebGestureEvent::SourceDevice source,
156 const gfx::PointF& velocity,
157 const gfx::Point& cumulative_scroll) {
158 FlingCurveConfiguration config;
159 // TODO(varunjain): Set these parameters from actual preferences.
160 content::RendererPreferences def_prefs;
161 config.SetCurveParameters(def_prefs.touchpad_fling_profile,
162 def_prefs.touchscreen_fling_profile);
163 if (source == blink::WebGestureEvent::Touchscreen)
164 return config.CreateForTouchScreen(velocity, cumulative_scroll);
165 return config.CreateForTouchPad(velocity, cumulative_scroll);
166 }
167
168 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698