OLD | NEW |
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 "content/browser/renderer_host/input/immediate_input_router.h" | 5 #include "content/browser/renderer_host/input/immediate_input_router.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "content/browser/renderer_host/input/gesture_event_filter.h" | 10 #include "content/browser/renderer_host/input/gesture_event_filter.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 using base::TimeTicks; | 31 using base::TimeTicks; |
32 using WebKit::WebGestureEvent; | 32 using WebKit::WebGestureEvent; |
33 using WebKit::WebInputEvent; | 33 using WebKit::WebInputEvent; |
34 using WebKit::WebKeyboardEvent; | 34 using WebKit::WebKeyboardEvent; |
35 using WebKit::WebMouseEvent; | 35 using WebKit::WebMouseEvent; |
36 using WebKit::WebMouseWheelEvent; | 36 using WebKit::WebMouseWheelEvent; |
37 | 37 |
38 namespace content { | 38 namespace content { |
39 namespace { | 39 namespace { |
40 | 40 |
41 // Returns |true| if the two wheel events should be coalesced. | |
42 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event, | |
43 const WebMouseWheelEvent& new_event) { | |
44 return last_event.modifiers == new_event.modifiers && | |
45 last_event.scrollByPage == new_event.scrollByPage && | |
46 last_event.hasPreciseScrollingDeltas | |
47 == new_event.hasPreciseScrollingDeltas && | |
48 last_event.phase == new_event.phase && | |
49 last_event.momentumPhase == new_event.momentumPhase; | |
50 } | |
51 | |
52 float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) { | |
53 return accelerated_delta * acceleration_ratio; | |
54 } | |
55 | |
56 float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) { | |
57 if (unaccelerated_delta == 0.f || accelerated_delta == 0.f) | |
58 return 1.f; | |
59 return unaccelerated_delta / accelerated_delta; | |
60 } | |
61 | |
62 GestureEventWithLatencyInfo MakeGestureEvent(WebInputEvent::Type type, | 41 GestureEventWithLatencyInfo MakeGestureEvent(WebInputEvent::Type type, |
63 double timestamp_seconds, | 42 double timestamp_seconds, |
64 int x, | 43 int x, |
65 int y, | 44 int y, |
66 int modifiers, | 45 int modifiers, |
67 const ui::LatencyInfo latency) { | 46 const ui::LatencyInfo latency) { |
68 WebGestureEvent result; | 47 WebGestureEvent result; |
69 | 48 |
70 result.type = type; | 49 result.type = type; |
71 result.x = x; | 50 result.x = x; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 138 } |
160 | 139 |
161 void ImmediateInputRouter::SendWheelEvent( | 140 void ImmediateInputRouter::SendWheelEvent( |
162 const MouseWheelEventWithLatencyInfo& wheel_event) { | 141 const MouseWheelEventWithLatencyInfo& wheel_event) { |
163 // If there's already a mouse wheel event waiting to be sent to the renderer, | 142 // If there's already a mouse wheel event waiting to be sent to the renderer, |
164 // add the new deltas to that event. Not doing so (e.g., by dropping the old | 143 // add the new deltas to that event. Not doing so (e.g., by dropping the old |
165 // event, as for mouse moves) results in very slow scrolling on the Mac (on | 144 // event, as for mouse moves) results in very slow scrolling on the Mac (on |
166 // which many, very small wheel events are sent). | 145 // which many, very small wheel events are sent). |
167 if (mouse_wheel_pending_) { | 146 if (mouse_wheel_pending_) { |
168 if (coalesced_mouse_wheel_events_.empty() || | 147 if (coalesced_mouse_wheel_events_.empty() || |
169 !ShouldCoalesceMouseWheelEvents( | 148 !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) { |
170 coalesced_mouse_wheel_events_.back().event, wheel_event.event)) { | |
171 coalesced_mouse_wheel_events_.push_back(wheel_event); | 149 coalesced_mouse_wheel_events_.push_back(wheel_event); |
172 } else { | 150 } else { |
173 MouseWheelEventWithLatencyInfo* last_wheel_event = | 151 coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event); |
174 &coalesced_mouse_wheel_events_.back(); | |
175 float unaccelerated_x = | |
176 GetUnacceleratedDelta(last_wheel_event->event.deltaX, | |
177 last_wheel_event->event.accelerationRatioX) + | |
178 GetUnacceleratedDelta(wheel_event.event.deltaX, | |
179 wheel_event.event.accelerationRatioX); | |
180 float unaccelerated_y = | |
181 GetUnacceleratedDelta(last_wheel_event->event.deltaY, | |
182 last_wheel_event->event.accelerationRatioY) + | |
183 GetUnacceleratedDelta(wheel_event.event.deltaY, | |
184 wheel_event.event.accelerationRatioY); | |
185 last_wheel_event->event.deltaX += wheel_event.event.deltaX; | |
186 last_wheel_event->event.deltaY += wheel_event.event.deltaY; | |
187 last_wheel_event->event.wheelTicksX += wheel_event.event.wheelTicksX; | |
188 last_wheel_event->event.wheelTicksY += wheel_event.event.wheelTicksY; | |
189 last_wheel_event->event.accelerationRatioX = | |
190 GetAccelerationRatio(last_wheel_event->event.deltaX, unaccelerated_x); | |
191 last_wheel_event->event.accelerationRatioY = | |
192 GetAccelerationRatio(last_wheel_event->event.deltaY, unaccelerated_y); | |
193 DCHECK_GE(wheel_event.event.timeStampSeconds, | |
194 last_wheel_event->event.timeStampSeconds); | |
195 last_wheel_event->event.timeStampSeconds = | |
196 wheel_event.event.timeStampSeconds; | |
197 last_wheel_event->latency.MergeWith(wheel_event.latency); | |
198 } | 152 } |
199 return; | 153 return; |
200 } | 154 } |
201 mouse_wheel_pending_ = true; | 155 mouse_wheel_pending_ = true; |
202 current_wheel_event_ = wheel_event; | 156 current_wheel_event_ = wheel_event; |
203 | 157 |
204 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", | 158 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", |
205 coalesced_mouse_wheel_events_.size()); | 159 coalesced_mouse_wheel_events_.size()); |
206 | 160 |
207 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); | 161 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // Forwards MouseEvent without passing it through | 200 // Forwards MouseEvent without passing it through |
247 // TouchpadTapSuppressionController. | 201 // TouchpadTapSuppressionController. |
248 void ImmediateInputRouter::SendMouseEventImmediately( | 202 void ImmediateInputRouter::SendMouseEventImmediately( |
249 const MouseEventWithLatencyInfo& mouse_event) { | 203 const MouseEventWithLatencyInfo& mouse_event) { |
250 // Avoid spamming the renderer with mouse move events. It is important | 204 // Avoid spamming the renderer with mouse move events. It is important |
251 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our | 205 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our |
252 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way | 206 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way |
253 // more WM_MOUSEMOVE events than we wish to send to the renderer. | 207 // more WM_MOUSEMOVE events than we wish to send to the renderer. |
254 if (mouse_event.event.type == WebInputEvent::MouseMove) { | 208 if (mouse_event.event.type == WebInputEvent::MouseMove) { |
255 if (mouse_move_pending_) { | 209 if (mouse_move_pending_) { |
256 if (!next_mouse_move_) { | 210 if (!next_mouse_move_) |
257 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); | 211 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); |
258 } else { | 212 else |
259 // Accumulate movement deltas. | 213 next_mouse_move_->CoalesceWith(mouse_event); |
260 int x = next_mouse_move_->event.movementX; | |
261 int y = next_mouse_move_->event.movementY; | |
262 next_mouse_move_->event = mouse_event.event; | |
263 next_mouse_move_->event.movementX += x; | |
264 next_mouse_move_->event.movementY += y; | |
265 next_mouse_move_->latency.MergeWith(mouse_event.latency); | |
266 } | |
267 return; | 214 return; |
268 } | 215 } |
269 mouse_move_pending_ = true; | 216 mouse_move_pending_ = true; |
270 } | 217 } |
271 | 218 |
272 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); | 219 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); |
273 } | 220 } |
274 | 221 |
275 void ImmediateInputRouter::SendTouchEventImmediately( | 222 void ImmediateInputRouter::SendTouchEventImmediately( |
276 const TouchEventWithLatencyInfo& touch_event) { | 223 const TouchEventWithLatencyInfo& touch_event) { |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 break; | 631 break; |
685 } | 632 } |
686 } | 633 } |
687 | 634 |
688 bool ImmediateInputRouter::IsInOverscrollGesture() const { | 635 bool ImmediateInputRouter::IsInOverscrollGesture() const { |
689 OverscrollController* controller = client_->GetOverscrollController(); | 636 OverscrollController* controller = client_->GetOverscrollController(); |
690 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | 637 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; |
691 } | 638 } |
692 | 639 |
693 } // namespace content | 640 } // namespace content |
OLD | NEW |