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/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "content/browser/renderer_host/input/gesture_event_filter.h" | 9 #include "content/browser/renderer_host/input/gesture_event_filter.h" |
10 #include "content/browser/renderer_host/input/input_ack_handler.h" | 10 #include "content/browser/renderer_host/input/input_ack_handler.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 using base::TimeTicks; | 29 using base::TimeTicks; |
30 using WebKit::WebGestureEvent; | 30 using WebKit::WebGestureEvent; |
31 using WebKit::WebInputEvent; | 31 using WebKit::WebInputEvent; |
32 using WebKit::WebKeyboardEvent; | 32 using WebKit::WebKeyboardEvent; |
33 using WebKit::WebMouseEvent; | 33 using WebKit::WebMouseEvent; |
34 using WebKit::WebMouseWheelEvent; | 34 using WebKit::WebMouseWheelEvent; |
35 | 35 |
36 namespace content { | 36 namespace content { |
37 namespace { | 37 namespace { |
38 | 38 |
39 // Returns |true| if the two wheel events should be coalesced. | |
40 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event, | |
41 const WebMouseWheelEvent& new_event) { | |
42 return last_event.modifiers == new_event.modifiers && | |
43 last_event.scrollByPage == new_event.scrollByPage && | |
44 last_event.hasPreciseScrollingDeltas | |
45 == new_event.hasPreciseScrollingDeltas && | |
46 last_event.phase == new_event.phase && | |
47 last_event.momentumPhase == new_event.momentumPhase; | |
48 } | |
49 | |
50 float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) { | |
51 return accelerated_delta * acceleration_ratio; | |
52 } | |
53 | |
54 float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) { | |
55 if (unaccelerated_delta == 0.f || accelerated_delta == 0.f) | |
56 return 1.f; | |
57 return unaccelerated_delta / accelerated_delta; | |
58 } | |
59 | |
60 const char* GetEventAckName(InputEventAckState ack_result) { | 39 const char* GetEventAckName(InputEventAckState ack_result) { |
61 switch(ack_result) { | 40 switch(ack_result) { |
62 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; | 41 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; |
63 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; | 42 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; |
64 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; | 43 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; |
65 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; | 44 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; |
66 default: | 45 default: |
67 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n"; | 46 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n"; |
68 break; | 47 break; |
69 } | 48 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 const MouseWheelEventWithLatencyInfo& wheel_event) { | 114 const MouseWheelEventWithLatencyInfo& wheel_event) { |
136 if (!client_->OnSendWheelEvent(wheel_event)) | 115 if (!client_->OnSendWheelEvent(wheel_event)) |
137 return; | 116 return; |
138 | 117 |
139 // If there's already a mouse wheel event waiting to be sent to the renderer, | 118 // If there's already a mouse wheel event waiting to be sent to the renderer, |
140 // add the new deltas to that event. Not doing so (e.g., by dropping the old | 119 // add the new deltas to that event. Not doing so (e.g., by dropping the old |
141 // event, as for mouse moves) results in very slow scrolling on the Mac (on | 120 // event, as for mouse moves) results in very slow scrolling on the Mac (on |
142 // which many, very small wheel events are sent). | 121 // which many, very small wheel events are sent). |
143 if (mouse_wheel_pending_) { | 122 if (mouse_wheel_pending_) { |
144 if (coalesced_mouse_wheel_events_.empty() || | 123 if (coalesced_mouse_wheel_events_.empty() || |
145 !ShouldCoalesceMouseWheelEvents( | 124 !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) { |
146 coalesced_mouse_wheel_events_.back().event, wheel_event.event)) { | |
147 coalesced_mouse_wheel_events_.push_back(wheel_event); | 125 coalesced_mouse_wheel_events_.push_back(wheel_event); |
148 } else { | 126 } else { |
149 MouseWheelEventWithLatencyInfo* last_wheel_event = | 127 coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event); |
150 &coalesced_mouse_wheel_events_.back(); | |
151 float unaccelerated_x = | |
152 GetUnacceleratedDelta(last_wheel_event->event.deltaX, | |
153 last_wheel_event->event.accelerationRatioX) + | |
154 GetUnacceleratedDelta(wheel_event.event.deltaX, | |
155 wheel_event.event.accelerationRatioX); | |
156 float unaccelerated_y = | |
157 GetUnacceleratedDelta(last_wheel_event->event.deltaY, | |
158 last_wheel_event->event.accelerationRatioY) + | |
159 GetUnacceleratedDelta(wheel_event.event.deltaY, | |
160 wheel_event.event.accelerationRatioY); | |
161 last_wheel_event->event.deltaX += wheel_event.event.deltaX; | |
162 last_wheel_event->event.deltaY += wheel_event.event.deltaY; | |
163 last_wheel_event->event.wheelTicksX += wheel_event.event.wheelTicksX; | |
164 last_wheel_event->event.wheelTicksY += wheel_event.event.wheelTicksY; | |
165 last_wheel_event->event.accelerationRatioX = | |
166 GetAccelerationRatio(last_wheel_event->event.deltaX, unaccelerated_x); | |
167 last_wheel_event->event.accelerationRatioY = | |
168 GetAccelerationRatio(last_wheel_event->event.deltaY, unaccelerated_y); | |
169 DCHECK_GE(wheel_event.event.timeStampSeconds, | |
170 last_wheel_event->event.timeStampSeconds); | |
171 last_wheel_event->event.timeStampSeconds = | |
172 wheel_event.event.timeStampSeconds; | |
173 last_wheel_event->latency.MergeWith(wheel_event.latency); | |
174 } | 128 } |
175 return; | 129 return; |
176 } | 130 } |
177 mouse_wheel_pending_ = true; | 131 mouse_wheel_pending_ = true; |
178 current_wheel_event_ = wheel_event; | 132 current_wheel_event_ = wheel_event; |
179 | 133 |
180 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", | 134 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", |
181 coalesced_mouse_wheel_events_.size()); | 135 coalesced_mouse_wheel_events_.size()); |
182 | 136 |
183 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); | 137 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 const MouseEventWithLatencyInfo& mouse_event) { | 177 const MouseEventWithLatencyInfo& mouse_event) { |
224 if (!client_->OnSendMouseEventImmediately(mouse_event)) | 178 if (!client_->OnSendMouseEventImmediately(mouse_event)) |
225 return; | 179 return; |
226 | 180 |
227 // Avoid spamming the renderer with mouse move events. It is important | 181 // Avoid spamming the renderer with mouse move events. It is important |
228 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our | 182 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our |
229 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way | 183 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way |
230 // more WM_MOUSEMOVE events than we wish to send to the renderer. | 184 // more WM_MOUSEMOVE events than we wish to send to the renderer. |
231 if (mouse_event.event.type == WebInputEvent::MouseMove) { | 185 if (mouse_event.event.type == WebInputEvent::MouseMove) { |
232 if (mouse_move_pending_) { | 186 if (mouse_move_pending_) { |
233 if (!next_mouse_move_) { | 187 if (!next_mouse_move_) |
234 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); | 188 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); |
235 } else { | 189 else |
236 // Accumulate movement deltas. | 190 next_mouse_move_->CoalesceWith(mouse_event); |
237 int x = next_mouse_move_->event.movementX; | |
238 int y = next_mouse_move_->event.movementY; | |
239 next_mouse_move_->event = mouse_event.event; | |
240 next_mouse_move_->event.movementX += x; | |
241 next_mouse_move_->event.movementY += y; | |
242 next_mouse_move_->latency.MergeWith(mouse_event.latency); | |
243 } | |
244 return; | 191 return; |
245 } | 192 } |
246 mouse_move_pending_ = true; | 193 mouse_move_pending_ = true; |
247 } | 194 } |
248 | 195 |
249 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); | 196 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); |
250 } | 197 } |
251 | 198 |
252 void ImmediateInputRouter::SendTouchEventImmediately( | 199 void ImmediateInputRouter::SendTouchEventImmediately( |
253 const TouchEventWithLatencyInfo& touch_event) { | 200 const TouchEventWithLatencyInfo& touch_event) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 507 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
561 touch_event_queue_->ProcessTouchAck(ack_result, latency); | 508 touch_event_queue_->ProcessTouchAck(ack_result, latency); |
562 } | 509 } |
563 | 510 |
564 void ImmediateInputRouter::HandleGestureScroll( | 511 void ImmediateInputRouter::HandleGestureScroll( |
565 const GestureEventWithLatencyInfo& gesture_event) { | 512 const GestureEventWithLatencyInfo& gesture_event) { |
566 touch_event_queue_->OnGestureScrollEvent(gesture_event); | 513 touch_event_queue_->OnGestureScrollEvent(gesture_event); |
567 } | 514 } |
568 | 515 |
569 } // namespace content | 516 } // namespace content |
OLD | NEW |