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

Side by Side Diff: content/renderer/input/main_thread_event_queue.cc

Issue 2713093005: Teach MainThreadEventQueue about touchmove throttling. (Closed)
Patch Set: Roll if/else condition together Created 3 years, 10 months 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
OLDNEW
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 base::TimeDelta kAsyncTouchMoveInterval =
19 base::TimeDelta::FromMilliseconds(200);
20
17 const size_t kTenSeconds = 10 * 1000 * 1000; 21 const size_t kTenSeconds = 10 * 1000 * 1000;
18 22
19 bool IsContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) { 23 bool IsContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) {
20 switch (event->event().type()) { 24 switch (event->event().type()) {
21 case blink::WebInputEvent::MouseMove: 25 case blink::WebInputEvent::MouseMove:
22 case blink::WebInputEvent::MouseWheel: 26 case blink::WebInputEvent::MouseWheel:
23 case blink::WebInputEvent::TouchMove: 27 case blink::WebInputEvent::TouchMove:
24 return true; 28 return true;
25 default: 29 default:
26 return false; 30 return false;
27 } 31 }
28 } 32 }
29 33
34 bool IsAsyncTouchMove(const std::unique_ptr<EventWithDispatchType>& event) {
35 if (event->event().type() != blink::WebInputEvent::TouchMove)
36 return false;
37 const blink::WebTouchEvent& touch_event =
38 static_cast<const blink::WebTouchEvent&>(event->event());
39 return touch_event.movedBeyondSlopRegion && !event->originallyCancelable();
40 }
41
30 } // namespace 42 } // namespace
31 43
32 EventWithDispatchType::EventWithDispatchType( 44 EventWithDispatchType::EventWithDispatchType(
33 ui::WebScopedInputEvent event, 45 ui::WebScopedInputEvent event,
34 const ui::LatencyInfo& latency, 46 const ui::LatencyInfo& latency,
35 InputEventDispatchType dispatch_type) 47 InputEventDispatchType dispatch_type,
48 bool originally_cancelable)
36 : ScopedWebInputEventWithLatencyInfo(std::move(event), latency), 49 : ScopedWebInputEventWithLatencyInfo(std::move(event), latency),
37 dispatch_type_(dispatch_type), 50 dispatch_type_(dispatch_type),
38 non_blocking_coalesced_count_(0), 51 non_blocking_coalesced_count_(0),
39 creation_timestamp_(base::TimeTicks::Now()), 52 creation_timestamp_(base::TimeTicks::Now()),
40 last_coalesced_timestamp_(creation_timestamp_) {} 53 last_coalesced_timestamp_(creation_timestamp_),
54 originally_cancelable_(originally_cancelable) {}
41 55
42 EventWithDispatchType::~EventWithDispatchType() {} 56 EventWithDispatchType::~EventWithDispatchType() {}
43 57
44 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { 58 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) {
45 // If this event was blocking push the event id to the blocking 59 // If this event was blocking push the event id to the blocking
46 // list before updating the dispatch_type of this event. 60 // list before updating the dispatch_type of this event.
47 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) { 61 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) {
48 blocking_coalesced_event_ids_.push_back( 62 blocking_coalesced_event_ids_.push_back(
49 ui::WebInputEventTraits::GetUniqueTouchEventId(event())); 63 ui::WebInputEventTraits::GetUniqueTouchEventId(event()));
50 } else { 64 } else {
51 non_blocking_coalesced_count_++; 65 non_blocking_coalesced_count_++;
52 } 66 }
53 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); 67 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
54 dispatch_type_ = other.dispatch_type_; 68 dispatch_type_ = other.dispatch_type_;
55 last_coalesced_timestamp_ = base::TimeTicks::Now(); 69 last_coalesced_timestamp_ = base::TimeTicks::Now();
70 originally_cancelable_ = other.originally_cancelable_;
56 } 71 }
57 72
58 MainThreadEventQueue::SharedState::SharedState() 73 MainThreadEventQueue::SharedState::SharedState()
59 : sent_main_frame_request_(false) {} 74 : sent_main_frame_request_(false) {}
60 75
61 MainThreadEventQueue::SharedState::~SharedState() {} 76 MainThreadEventQueue::SharedState::~SharedState() {}
62 77
63 MainThreadEventQueue::MainThreadEventQueue( 78 MainThreadEventQueue::MainThreadEventQueue(
64 int routing_id, 79 int routing_id,
65 MainThreadEventQueueClient* client, 80 MainThreadEventQueueClient* client,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || 124 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING ||
110 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); 125 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
111 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || 126 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
112 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING || 127 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING ||
113 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 128 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
114 129
115 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || 130 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING ||
116 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; 131 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
117 bool is_wheel = event->type() == blink::WebInputEvent::MouseWheel; 132 bool is_wheel = event->type() == blink::WebInputEvent::MouseWheel;
118 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type()); 133 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type());
134 bool originally_cancelable = false;
119 135
120 if (is_touch) { 136 if (is_touch) {
121 blink::WebTouchEvent* touch_event = 137 blink::WebTouchEvent* touch_event =
122 static_cast<blink::WebTouchEvent*>(event.get()); 138 static_cast<blink::WebTouchEvent*>(event.get());
123 139
140 originally_cancelable =
141 touch_event->dispatchType == blink::WebInputEvent::Blocking;
142
124 // Adjust the |dispatchType| on the event since the compositor 143 // Adjust the |dispatchType| on the event since the compositor
125 // determined all event listeners are passive. 144 // determined all event listeners are passive.
126 if (non_blocking) { 145 if (non_blocking) {
127 touch_event->dispatchType = 146 touch_event->dispatchType =
128 blink::WebInputEvent::ListenersNonBlockingPassive; 147 blink::WebInputEvent::ListenersNonBlockingPassive;
129 } 148 }
130 if (touch_event->type() == blink::WebInputEvent::TouchStart) 149 if (touch_event->type() == blink::WebInputEvent::TouchStart)
131 last_touch_start_forced_nonblocking_due_to_fling_ = false; 150 last_touch_start_forced_nonblocking_due_to_fling_ = false;
132 151
133 if (enable_fling_passive_listener_flag_ && 152 if (enable_fling_passive_listener_flag_ &&
(...skipping 20 matching lines...) Expand all
154 ListenersForcedNonBlockingDueToMainThreadResponsiveness; 173 ListenersForcedNonBlockingDueToMainThreadResponsiveness;
155 non_blocking = true; 174 non_blocking = true;
156 } 175 }
157 } 176 }
158 // If the event is non-cancelable ACK it right away. 177 // If the event is non-cancelable ACK it right away.
159 if (!non_blocking && 178 if (!non_blocking &&
160 touch_event->dispatchType != blink::WebInputEvent::Blocking) 179 touch_event->dispatchType != blink::WebInputEvent::Blocking)
161 non_blocking = true; 180 non_blocking = true;
162 } 181 }
163 182
164 if (is_wheel && non_blocking) { 183 if (is_wheel) {
165 // Adjust the |dispatchType| on the event since the compositor 184 blink::WebMouseWheelEvent* wheel_event =
166 // determined all event listeners are passive. 185 static_cast<blink::WebMouseWheelEvent*>(event.get());
167 static_cast<blink::WebMouseWheelEvent*>(event.get()) 186 originally_cancelable =
168 ->dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; 187 wheel_event->dispatchType == blink::WebInputEvent::Blocking;
188 if (non_blocking) {
189 // Adjust the |dispatchType| on the event since the compositor
190 // determined all event listeners are passive.
191 wheel_event->dispatchType =
192 blink::WebInputEvent::ListenersNonBlockingPassive;
193 }
169 } 194 }
170 195
171 InputEventDispatchType dispatch_type = 196 InputEventDispatchType dispatch_type =
172 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING; 197 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
173 198
174 std::unique_ptr<EventWithDispatchType> event_with_dispatch_type( 199 std::unique_ptr<EventWithDispatchType> event_with_dispatch_type(
175 new EventWithDispatchType(std::move(event), latency, dispatch_type)); 200 new EventWithDispatchType(std::move(event), latency, dispatch_type,
201 originally_cancelable));
176 202
177 QueueEvent(std::move(event_with_dispatch_type)); 203 QueueEvent(std::move(event_with_dispatch_type));
178 204
179 // send an ack when we are non-blocking. 205 // send an ack when we are non-blocking.
180 return non_blocking; 206 return non_blocking;
181 } 207 }
182 208
183 void MainThreadEventQueue::DispatchInFlightEvent() { 209 void MainThreadEventQueue::DispatchInFlightEvent() {
184 if (in_flight_event_) { 210 if (in_flight_event_) {
185 // Report the coalesced count only for continuous events; otherwise 211 // Report the coalesced count only for continuous events; otherwise
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 for (const auto id : in_flight_event_->blockingCoalescedEventIds()) { 288 for (const auto id : in_flight_event_->blockingCoalescedEventIds()) {
263 client_->SendInputEventAck(routing_id_, type, ack_result, id); 289 client_->SendInputEventAck(routing_id_, type, ack_result, id);
264 if (renderer_scheduler_) { 290 if (renderer_scheduler_) {
265 renderer_scheduler_->DidHandleInputEventOnMainThread( 291 renderer_scheduler_->DidHandleInputEventOnMainThread(
266 in_flight_event_->event(), result); 292 in_flight_event_->event(), result);
267 } 293 }
268 } 294 }
269 } 295 }
270 } 296 }
271 297
272 void MainThreadEventQueue::DispatchRafAlignedInput() { 298 void MainThreadEventQueue::DispatchRafAlignedInput(base::TimeTicks frame_time) {
273 if (IsRafAlignedInputDisabled()) 299 if (IsRafAlignedInputDisabled())
274 return; 300 return;
275 301
276 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process; 302 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process;
277 { 303 {
278 base::AutoLock lock(shared_state_lock_); 304 base::AutoLock lock(shared_state_lock_);
279 shared_state_.sent_main_frame_request_ = false; 305 shared_state_.sent_main_frame_request_ = false;
280 306
281 while(!shared_state_.events_.empty()) { 307 while (!shared_state_.events_.empty()) {
282 if (!IsRafAlignedEvent(shared_state_.events_.front()->event())) 308 if (!IsRafAlignedEvent(shared_state_.events_.front()->event()))
283 break; 309 break;
310
311 // Throttle touchmoves that are async.
312 if (handle_raf_aligned_touch_input_ &&
313 IsAsyncTouchMove(shared_state_.events_.front())) {
314 if (shared_state_.events_.size() == 1 &&
315 frame_time < shared_state_.last_async_touch_move_timestamp_ +
316 kAsyncTouchMoveInterval) {
317 break;
318 }
319 shared_state_.last_async_touch_move_timestamp_ = frame_time;
320 }
284 events_to_process.emplace_back(shared_state_.events_.Pop()); 321 events_to_process.emplace_back(shared_state_.events_.Pop());
285 } 322 }
286 } 323 }
287 324
288 while(!events_to_process.empty()) { 325 while(!events_to_process.empty()) {
289 in_flight_event_ = std::move(events_to_process.front()); 326 in_flight_event_ = std::move(events_to_process.front());
290 events_to_process.pop_front(); 327 events_to_process.pop_front();
291 DispatchInFlightEvent(); 328 DispatchInFlightEvent();
292 } 329 }
293 PossiblyScheduleMainFrame(); 330 PossiblyScheduleMainFrame();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 case blink::WebInputEvent::MouseWheel: 398 case blink::WebInputEvent::MouseWheel:
362 return handle_raf_aligned_mouse_input_; 399 return handle_raf_aligned_mouse_input_;
363 case blink::WebInputEvent::TouchMove: 400 case blink::WebInputEvent::TouchMove:
364 return handle_raf_aligned_touch_input_; 401 return handle_raf_aligned_touch_input_;
365 default: 402 default:
366 return false; 403 return false;
367 } 404 }
368 } 405 }
369 406
370 } // namespace content 407 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/input/main_thread_event_queue.h ('k') | content/renderer/input/main_thread_event_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698