OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/renderer/input/main_thread_event_queue.h" | 5 #include "content/renderer/input/main_thread_event_queue.h" |
6 | 6 |
7 #include "base/metrics/field_trial.h" | 7 #include "base/metrics/field_trial.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "content/common/input/event_with_latency_info.h" | 10 #include "content/common/input/event_with_latency_info.h" |
11 #include "content/common/input_messages.h" | 11 #include "content/common/input_messages.h" |
12 | 12 |
13 namespace content { | 13 namespace content { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Time interval at which touchmove events will be skipped during rAF signal. | |
18 const double kAsyncTouchMoveIntervalSec = .2; | |
aelias_OOO_until_Jul13
2017/02/24 20:19:51
const base::TimeDelta kAsyncTouchMoveInterval = ba
dtapuska
2017/02/24 20:43:15
Done.
| |
19 | |
17 const size_t kTenSeconds = 10 * 1000 * 1000; | 20 const size_t kTenSeconds = 10 * 1000 * 1000; |
18 | 21 |
19 bool IsContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) { | 22 bool IsContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) { |
20 switch (event->event().type()) { | 23 switch (event->event().type()) { |
21 case blink::WebInputEvent::MouseMove: | 24 case blink::WebInputEvent::MouseMove: |
22 case blink::WebInputEvent::MouseWheel: | 25 case blink::WebInputEvent::MouseWheel: |
23 case blink::WebInputEvent::TouchMove: | 26 case blink::WebInputEvent::TouchMove: |
24 return true; | 27 return true; |
25 default: | 28 default: |
26 return false; | 29 return false; |
27 } | 30 } |
28 } | 31 } |
29 | 32 |
33 bool IsAsyncTouchMove(const std::unique_ptr<EventWithDispatchType>& event) { | |
34 if (event->event().type() != blink::WebInputEvent::TouchMove) | |
35 return false; | |
36 const blink::WebTouchEvent& touch_event = | |
37 static_cast<const blink::WebTouchEvent&>(event->event()); | |
38 return touch_event.movedBeyondSlopRegion && !event->originallyCancelable(); | |
39 } | |
40 | |
30 } // namespace | 41 } // namespace |
31 | 42 |
32 EventWithDispatchType::EventWithDispatchType( | 43 EventWithDispatchType::EventWithDispatchType( |
33 ui::WebScopedInputEvent event, | 44 ui::WebScopedInputEvent event, |
34 const ui::LatencyInfo& latency, | 45 const ui::LatencyInfo& latency, |
35 InputEventDispatchType dispatch_type) | 46 InputEventDispatchType dispatch_type, |
47 bool originally_cancelable) | |
36 : ScopedWebInputEventWithLatencyInfo(std::move(event), latency), | 48 : ScopedWebInputEventWithLatencyInfo(std::move(event), latency), |
37 dispatch_type_(dispatch_type), | 49 dispatch_type_(dispatch_type), |
38 non_blocking_coalesced_count_(0), | 50 non_blocking_coalesced_count_(0), |
39 creation_timestamp_(base::TimeTicks::Now()), | 51 creation_timestamp_(base::TimeTicks::Now()), |
40 last_coalesced_timestamp_(creation_timestamp_) {} | 52 last_coalesced_timestamp_(creation_timestamp_), |
53 originally_cancelable_(originally_cancelable) {} | |
41 | 54 |
42 EventWithDispatchType::~EventWithDispatchType() {} | 55 EventWithDispatchType::~EventWithDispatchType() {} |
43 | 56 |
44 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { | 57 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { |
45 // If this event was blocking push the event id to the blocking | 58 // If this event was blocking push the event id to the blocking |
46 // list before updating the dispatch_type of this event. | 59 // list before updating the dispatch_type of this event. |
47 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) { | 60 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) { |
48 blocking_coalesced_event_ids_.push_back( | 61 blocking_coalesced_event_ids_.push_back( |
49 ui::WebInputEventTraits::GetUniqueTouchEventId(event())); | 62 ui::WebInputEventTraits::GetUniqueTouchEventId(event())); |
50 } else { | 63 } else { |
51 non_blocking_coalesced_count_++; | 64 non_blocking_coalesced_count_++; |
52 } | 65 } |
53 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); | 66 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); |
54 dispatch_type_ = other.dispatch_type_; | 67 dispatch_type_ = other.dispatch_type_; |
55 last_coalesced_timestamp_ = base::TimeTicks::Now(); | 68 last_coalesced_timestamp_ = base::TimeTicks::Now(); |
69 originally_cancelable_ = other.originally_cancelable_; | |
56 } | 70 } |
57 | 71 |
58 MainThreadEventQueue::SharedState::SharedState() | 72 MainThreadEventQueue::SharedState::SharedState() |
59 : sent_main_frame_request_(false) {} | 73 : sent_main_frame_request_(false), last_async_touch_move_timestamp_(0) {} |
60 | 74 |
61 MainThreadEventQueue::SharedState::~SharedState() {} | 75 MainThreadEventQueue::SharedState::~SharedState() {} |
62 | 76 |
63 MainThreadEventQueue::MainThreadEventQueue( | 77 MainThreadEventQueue::MainThreadEventQueue( |
64 int routing_id, | 78 int routing_id, |
65 MainThreadEventQueueClient* client, | 79 MainThreadEventQueueClient* client, |
66 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, | 80 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, |
67 blink::scheduler::RendererScheduler* renderer_scheduler) | 81 blink::scheduler::RendererScheduler* renderer_scheduler) |
68 : routing_id_(routing_id), | 82 : routing_id_(routing_id), |
69 client_(client), | 83 client_(client), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || | 123 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || |
110 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); | 124 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); |
111 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || | 125 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || |
112 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING || | 126 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING || |
113 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 127 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
114 | 128 |
115 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || | 129 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || |
116 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; | 130 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; |
117 bool is_wheel = event->type() == blink::WebInputEvent::MouseWheel; | 131 bool is_wheel = event->type() == blink::WebInputEvent::MouseWheel; |
118 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type()); | 132 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type()); |
133 bool originally_cancelable = false; | |
119 | 134 |
120 if (is_touch) { | 135 if (is_touch) { |
121 blink::WebTouchEvent* touch_event = | 136 blink::WebTouchEvent* touch_event = |
122 static_cast<blink::WebTouchEvent*>(event.get()); | 137 static_cast<blink::WebTouchEvent*>(event.get()); |
123 | 138 |
139 originally_cancelable = | |
140 touch_event->dispatchType == blink::WebInputEvent::Blocking; | |
141 | |
124 // Adjust the |dispatchType| on the event since the compositor | 142 // Adjust the |dispatchType| on the event since the compositor |
125 // determined all event listeners are passive. | 143 // determined all event listeners are passive. |
126 if (non_blocking) { | 144 if (non_blocking) { |
127 touch_event->dispatchType = | 145 touch_event->dispatchType = |
128 blink::WebInputEvent::ListenersNonBlockingPassive; | 146 blink::WebInputEvent::ListenersNonBlockingPassive; |
129 } | 147 } |
130 if (touch_event->type() == blink::WebInputEvent::TouchStart) | 148 if (touch_event->type() == blink::WebInputEvent::TouchStart) |
131 last_touch_start_forced_nonblocking_due_to_fling_ = false; | 149 last_touch_start_forced_nonblocking_due_to_fling_ = false; |
132 | 150 |
133 if (enable_fling_passive_listener_flag_ && | 151 if (enable_fling_passive_listener_flag_ && |
(...skipping 20 matching lines...) Expand all Loading... | |
154 ListenersForcedNonBlockingDueToMainThreadResponsiveness; | 172 ListenersForcedNonBlockingDueToMainThreadResponsiveness; |
155 non_blocking = true; | 173 non_blocking = true; |
156 } | 174 } |
157 } | 175 } |
158 // If the event is non-cancelable ACK it right away. | 176 // If the event is non-cancelable ACK it right away. |
159 if (!non_blocking && | 177 if (!non_blocking && |
160 touch_event->dispatchType != blink::WebInputEvent::Blocking) | 178 touch_event->dispatchType != blink::WebInputEvent::Blocking) |
161 non_blocking = true; | 179 non_blocking = true; |
162 } | 180 } |
163 | 181 |
164 if (is_wheel && non_blocking) { | 182 if (is_wheel) { |
165 // Adjust the |dispatchType| on the event since the compositor | 183 blink::WebMouseWheelEvent* wheel_event = |
166 // determined all event listeners are passive. | 184 static_cast<blink::WebMouseWheelEvent*>(event.get()); |
167 static_cast<blink::WebMouseWheelEvent*>(event.get()) | 185 originally_cancelable = |
168 ->dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; | 186 wheel_event->dispatchType == blink::WebInputEvent::Blocking; |
187 if (non_blocking) { | |
188 // Adjust the |dispatchType| on the event since the compositor | |
189 // determined all event listeners are passive. | |
190 wheel_event->dispatchType = | |
191 blink::WebInputEvent::ListenersNonBlockingPassive; | |
192 } | |
169 } | 193 } |
170 | 194 |
171 InputEventDispatchType dispatch_type = | 195 InputEventDispatchType dispatch_type = |
172 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING; | 196 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING; |
173 | 197 |
174 std::unique_ptr<EventWithDispatchType> event_with_dispatch_type( | 198 std::unique_ptr<EventWithDispatchType> event_with_dispatch_type( |
175 new EventWithDispatchType(std::move(event), latency, dispatch_type)); | 199 new EventWithDispatchType(std::move(event), latency, dispatch_type, |
200 originally_cancelable)); | |
176 | 201 |
177 QueueEvent(std::move(event_with_dispatch_type)); | 202 QueueEvent(std::move(event_with_dispatch_type)); |
178 | 203 |
179 // send an ack when we are non-blocking. | 204 // send an ack when we are non-blocking. |
180 return non_blocking; | 205 return non_blocking; |
181 } | 206 } |
182 | 207 |
183 void MainThreadEventQueue::DispatchInFlightEvent() { | 208 void MainThreadEventQueue::DispatchInFlightEvent() { |
184 if (in_flight_event_) { | 209 if (in_flight_event_) { |
185 // Report the coalesced count only for continuous events; otherwise | 210 // Report the coalesced count only for continuous events; otherwise |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 for (const auto id : in_flight_event_->blockingCoalescedEventIds()) { | 287 for (const auto id : in_flight_event_->blockingCoalescedEventIds()) { |
263 client_->SendInputEventAck(routing_id_, type, ack_result, id); | 288 client_->SendInputEventAck(routing_id_, type, ack_result, id); |
264 if (renderer_scheduler_) { | 289 if (renderer_scheduler_) { |
265 renderer_scheduler_->DidHandleInputEventOnMainThread( | 290 renderer_scheduler_->DidHandleInputEventOnMainThread( |
266 in_flight_event_->event(), result); | 291 in_flight_event_->event(), result); |
267 } | 292 } |
268 } | 293 } |
269 } | 294 } |
270 } | 295 } |
271 | 296 |
272 void MainThreadEventQueue::DispatchRafAlignedInput() { | 297 void MainThreadEventQueue::DispatchRafAlignedInput(double frame_time_sec) { |
273 if (IsRafAlignedInputDisabled()) | 298 if (IsRafAlignedInputDisabled()) |
274 return; | 299 return; |
275 | 300 |
276 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process; | 301 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process; |
277 { | 302 { |
278 base::AutoLock lock(shared_state_lock_); | 303 base::AutoLock lock(shared_state_lock_); |
279 shared_state_.sent_main_frame_request_ = false; | 304 shared_state_.sent_main_frame_request_ = false; |
280 | 305 |
281 while(!shared_state_.events_.empty()) { | 306 // Throttle touchmoves that are async. |
282 if (!IsRafAlignedEvent(shared_state_.events_.front()->event())) | 307 if (handle_raf_aligned_touch_input_ && shared_state_.events_.size() == 1 && |
aelias_OOO_until_Jul13
2017/02/24 20:19:50
Could you explain the reasoning why this is only n
dtapuska
2017/02/24 20:23:35
Because it you have anything other than one then s
aelias_OOO_until_Jul13
2017/02/24 21:01:14
OK. Well, this control flow seems like it could b
dtapuska
2017/02/24 21:29:41
Done.
| |
283 break; | 308 IsAsyncTouchMove(shared_state_.events_.front())) { |
284 events_to_process.emplace_back(shared_state_.events_.Pop()); | 309 if (frame_time_sec >= shared_state_.last_async_touch_move_timestamp_ + |
310 kAsyncTouchMoveIntervalSec) { | |
311 shared_state_.last_async_touch_move_timestamp_ = frame_time_sec; | |
312 events_to_process.emplace_back(shared_state_.events_.Pop()); | |
313 } | |
314 } else { | |
315 while (!shared_state_.events_.empty()) { | |
316 if (!IsRafAlignedEvent(shared_state_.events_.front()->event())) | |
317 break; | |
318 events_to_process.emplace_back(shared_state_.events_.Pop()); | |
319 } | |
285 } | 320 } |
286 } | 321 } |
287 | 322 |
288 while(!events_to_process.empty()) { | 323 while(!events_to_process.empty()) { |
289 in_flight_event_ = std::move(events_to_process.front()); | 324 in_flight_event_ = std::move(events_to_process.front()); |
290 events_to_process.pop_front(); | 325 events_to_process.pop_front(); |
291 DispatchInFlightEvent(); | 326 DispatchInFlightEvent(); |
292 } | 327 } |
293 PossiblyScheduleMainFrame(); | 328 PossiblyScheduleMainFrame(); |
294 } | 329 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 case blink::WebInputEvent::MouseWheel: | 396 case blink::WebInputEvent::MouseWheel: |
362 return handle_raf_aligned_mouse_input_; | 397 return handle_raf_aligned_mouse_input_; |
363 case blink::WebInputEvent::TouchMove: | 398 case blink::WebInputEvent::TouchMove: |
364 return handle_raf_aligned_touch_input_; | 399 return handle_raf_aligned_touch_input_; |
365 default: | 400 default: |
366 return false; | 401 return false; |
367 } | 402 } |
368 } | 403 } |
369 | 404 |
370 } // namespace content | 405 } // namespace content |
OLD | NEW |