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 #include "content/renderer/render_widget.h" | 12 #include "content/renderer/render_widget.h" |
13 | 13 |
14 namespace content { | 14 namespace content { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 const size_t kTenSeconds = 10 * 1000 * 1000; | 18 const size_t kTenSeconds = 10 * 1000 * 1000; |
| 19 const base::TimeDelta kMaxRafDelay = |
| 20 base::TimeDelta::FromMilliseconds(5 * 1000); |
19 | 21 |
20 class QueuedClosure : public MainThreadEventQueueTask { | 22 class QueuedClosure : public MainThreadEventQueueTask { |
21 public: | 23 public: |
22 QueuedClosure(const base::Closure& closure) : closure_(closure) {} | 24 QueuedClosure(const base::Closure& closure) : closure_(closure) {} |
23 | 25 |
24 ~QueuedClosure() override {} | 26 ~QueuedClosure() override {} |
25 | 27 |
26 FilterResult FilterNewEvent( | 28 FilterResult FilterNewEvent( |
27 const MainThreadEventQueueTask& other_task) override { | 29 const MainThreadEventQueueTask& other_task) override { |
28 return other_task.IsWebInputEvent() ? FilterResult::KeepIterating | 30 return other_task.IsWebInputEvent() ? FilterResult::KeepIterating |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 enable_non_blocking_due_to_main_thread_responsiveness_flag_( | 212 enable_non_blocking_due_to_main_thread_responsiveness_flag_( |
211 base::FeatureList::IsEnabled( | 213 base::FeatureList::IsEnabled( |
212 features::kMainThreadBusyScrollIntervention)), | 214 features::kMainThreadBusyScrollIntervention)), |
213 handle_raf_aligned_touch_input_( | 215 handle_raf_aligned_touch_input_( |
214 allow_raf_aligned_input && | 216 allow_raf_aligned_input && |
215 base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)), | 217 base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)), |
216 handle_raf_aligned_mouse_input_( | 218 handle_raf_aligned_mouse_input_( |
217 allow_raf_aligned_input && | 219 allow_raf_aligned_input && |
218 base::FeatureList::IsEnabled(features::kRafAlignedMouseInputEvents)), | 220 base::FeatureList::IsEnabled(features::kRafAlignedMouseInputEvents)), |
219 main_task_runner_(main_task_runner), | 221 main_task_runner_(main_task_runner), |
220 renderer_scheduler_(renderer_scheduler) { | 222 renderer_scheduler_(renderer_scheduler), |
| 223 use_raf_fallback_timer_(true) { |
221 if (enable_non_blocking_due_to_main_thread_responsiveness_flag_) { | 224 if (enable_non_blocking_due_to_main_thread_responsiveness_flag_) { |
222 std::string group = base::FieldTrialList::FindFullName( | 225 std::string group = base::FieldTrialList::FindFullName( |
223 "MainThreadResponsivenessScrollIntervention"); | 226 "MainThreadResponsivenessScrollIntervention"); |
224 | 227 |
225 // The group name will be of the form Enabled$THRESHOLD_MS. Trim the prefix | 228 // The group name will be of the form Enabled$THRESHOLD_MS. Trim the prefix |
226 // "Enabled", and parse the threshold. | 229 // "Enabled", and parse the threshold. |
227 int threshold_ms = 0; | 230 int threshold_ms = 0; |
228 std::string prefix = "Enabled"; | 231 std::string prefix = "Enabled"; |
229 group.erase(0, prefix.length()); | 232 group.erase(0, prefix.length()); |
230 base::StringToInt(group, &threshold_ms); | 233 base::StringToInt(group, &threshold_ms); |
231 | 234 |
232 if (threshold_ms <= 0) { | 235 if (threshold_ms <= 0) { |
233 enable_non_blocking_due_to_main_thread_responsiveness_flag_ = false; | 236 enable_non_blocking_due_to_main_thread_responsiveness_flag_ = false; |
234 } else { | 237 } else { |
235 main_thread_responsiveness_threshold_ = | 238 main_thread_responsiveness_threshold_ = |
236 base::TimeDelta::FromMilliseconds(threshold_ms); | 239 base::TimeDelta::FromMilliseconds(threshold_ms); |
237 } | 240 } |
238 } | 241 } |
| 242 raf_fallback_timer_.SetTaskRunner(main_task_runner); |
239 } | 243 } |
240 | 244 |
241 MainThreadEventQueue::~MainThreadEventQueue() {} | 245 MainThreadEventQueue::~MainThreadEventQueue() {} |
242 | 246 |
243 bool MainThreadEventQueue::HandleEvent( | 247 bool MainThreadEventQueue::HandleEvent( |
244 ui::WebScopedInputEvent event, | 248 ui::WebScopedInputEvent event, |
245 const ui::LatencyInfo& latency, | 249 const ui::LatencyInfo& latency, |
246 InputEventDispatchType original_dispatch_type, | 250 InputEventDispatchType original_dispatch_type, |
247 InputEventAckState ack_result) { | 251 InputEventAckState ack_result) { |
248 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || | 252 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 return false; | 403 return false; |
400 const QueuedWebInputEvent* event = | 404 const QueuedWebInputEvent* event = |
401 static_cast<const QueuedWebInputEvent*>(queued_item.get()); | 405 static_cast<const QueuedWebInputEvent*>(queued_item.get()); |
402 if (event->event().GetType() != blink::WebInputEvent::kTouchMove) | 406 if (event->event().GetType() != blink::WebInputEvent::kTouchMove) |
403 return false; | 407 return false; |
404 const blink::WebTouchEvent& touch_event = | 408 const blink::WebTouchEvent& touch_event = |
405 static_cast<const blink::WebTouchEvent&>(event->event()); | 409 static_cast<const blink::WebTouchEvent&>(event->event()); |
406 return touch_event.moved_beyond_slop_region && !event->originallyCancelable(); | 410 return touch_event.moved_beyond_slop_region && !event->originallyCancelable(); |
407 } | 411 } |
408 | 412 |
| 413 void MainThreadEventQueue::RafFallbackTimerFired() { |
| 414 UMA_HISTOGRAM_BOOLEAN("Event.MainThreadEventQueue.FlushQueueNoBeginMainFrame", |
| 415 true); |
| 416 DispatchRafAlignedInput(base::TimeTicks::Now()); |
| 417 } |
| 418 |
409 void MainThreadEventQueue::DispatchRafAlignedInput(base::TimeTicks frame_time) { | 419 void MainThreadEventQueue::DispatchRafAlignedInput(base::TimeTicks frame_time) { |
410 if (IsRafAlignedInputDisabled()) | 420 if (IsRafAlignedInputDisabled()) |
411 return; | 421 return; |
412 | 422 |
| 423 raf_fallback_timer_.Stop(); |
413 size_t queue_size_at_start; | 424 size_t queue_size_at_start; |
414 | 425 |
415 // Record the queue size so that we only process | 426 // Record the queue size so that we only process |
416 // that maximum number of events. | 427 // that maximum number of events. |
417 { | 428 { |
418 base::AutoLock lock(shared_state_lock_); | 429 base::AutoLock lock(shared_state_lock_); |
419 shared_state_.sent_main_frame_request_ = false; | 430 shared_state_.sent_main_frame_request_ = false; |
420 queue_size_at_start = shared_state_.events_.size(); | 431 queue_size_at_start = shared_state_.events_.size(); |
421 } | 432 } |
422 | 433 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 if (renderer_scheduler_) { | 533 if (renderer_scheduler_) { |
523 renderer_scheduler_->DidHandleInputEventOnMainThread( | 534 renderer_scheduler_->DidHandleInputEventOnMainThread( |
524 event, ack_result == INPUT_EVENT_ACK_STATE_CONSUMED | 535 event, ack_result == INPUT_EVENT_ACK_STATE_CONSUMED |
525 ? blink::WebInputEventResult::kHandledApplication | 536 ? blink::WebInputEventResult::kHandledApplication |
526 : blink::WebInputEventResult::kNotHandled); | 537 : blink::WebInputEventResult::kNotHandled); |
527 } | 538 } |
528 } | 539 } |
529 | 540 |
530 void MainThreadEventQueue::SetNeedsMainFrame() { | 541 void MainThreadEventQueue::SetNeedsMainFrame() { |
531 if (main_task_runner_->BelongsToCurrentThread()) { | 542 if (main_task_runner_->BelongsToCurrentThread()) { |
| 543 if (use_raf_fallback_timer_) { |
| 544 raf_fallback_timer_.Start( |
| 545 FROM_HERE, kMaxRafDelay, |
| 546 base::Bind(&MainThreadEventQueue::RafFallbackTimerFired, this)); |
| 547 } |
532 if (client_) | 548 if (client_) |
533 client_->SetNeedsMainFrame(); | 549 client_->SetNeedsMainFrame(); |
534 return; | 550 return; |
535 } | 551 } |
536 | 552 |
537 main_task_runner_->PostTask( | 553 main_task_runner_->PostTask( |
538 FROM_HERE, base::Bind(&MainThreadEventQueue::SetNeedsMainFrame, this)); | 554 FROM_HERE, base::Bind(&MainThreadEventQueue::SetNeedsMainFrame, this)); |
539 } | 555 } |
540 | 556 |
541 void MainThreadEventQueue::ClearClient() { | 557 void MainThreadEventQueue::ClearClient() { |
542 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 558 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
543 client_ = nullptr; | 559 client_ = nullptr; |
544 } | 560 } |
545 | 561 |
546 } // namespace content | 562 } // namespace content |
OLD | NEW |