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

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

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

Powered by Google App Engine
This is Rietveld 408576698