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 "ui/events/blink/input_handler_proxy.h" | 5 #include "ui/events/blink/input_handler_proxy.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
17 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
18 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
| 19 #include "cc/input/main_thread_scrolling_reason.h" |
19 #include "third_party/WebKit/public/web/WebInputEvent.h" | 20 #include "third_party/WebKit/public/web/WebInputEvent.h" |
20 #include "ui/events/blink/input_handler_proxy_client.h" | 21 #include "ui/events/blink/input_handler_proxy_client.h" |
21 #include "ui/events/blink/input_scroll_elasticity_controller.h" | 22 #include "ui/events/blink/input_scroll_elasticity_controller.h" |
22 #include "ui/events/latency_info.h" | 23 #include "ui/events/latency_info.h" |
23 #include "ui/gfx/geometry/point_conversions.h" | 24 #include "ui/gfx/geometry/point_conversions.h" |
24 | 25 |
25 using blink::WebFloatPoint; | 26 using blink::WebFloatPoint; |
26 using blink::WebFloatSize; | 27 using blink::WebFloatSize; |
27 using blink::WebGestureEvent; | 28 using blink::WebGestureEvent; |
28 using blink::WebInputEvent; | 29 using blink::WebInputEvent; |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 // otherwise disrupt an in-progress touch scroll. | 353 // otherwise disrupt an in-progress touch scroll. |
353 if (fling_curve_) | 354 if (fling_curve_) |
354 CancelCurrentFling(); | 355 CancelCurrentFling(); |
355 } | 356 } |
356 break; | 357 break; |
357 } | 358 } |
358 | 359 |
359 return DID_NOT_HANDLE; | 360 return DID_NOT_HANDLE; |
360 } | 361 } |
361 | 362 |
362 void RecordMainThreadScrollingReasons( | 363 void RecordMainThreadScrollingReasons(WebInputEvent::Type type, |
363 WebInputEvent::Type type, | 364 uint32_t reasons) { |
364 cc::InputHandler::MainThreadScrollingReason reasons) { | |
365 static const char* kGestureHistogramName = | 365 static const char* kGestureHistogramName = |
366 "Renderer4.MainThreadGestureScrollReason"; | 366 "Renderer4.MainThreadGestureScrollReason"; |
367 static const char* kWheelHistogramName = | 367 static const char* kWheelHistogramName = |
368 "Renderer4.MainThreadWheelScrollReason"; | 368 "Renderer4.MainThreadWheelScrollReason"; |
369 | 369 |
370 DCHECK(type == WebInputEvent::GestureScrollBegin || | 370 DCHECK(type == WebInputEvent::GestureScrollBegin || |
371 type == WebInputEvent::MouseWheel); | 371 type == WebInputEvent::MouseWheel); |
372 | 372 |
373 if (type != WebInputEvent::GestureScrollBegin && | 373 if (type != WebInputEvent::GestureScrollBegin && |
374 type != WebInputEvent::MouseWheel) { | 374 type != WebInputEvent::MouseWheel) { |
375 return; | 375 return; |
376 } | 376 } |
377 | 377 |
378 if (reasons == cc::InputHandler::NOT_SCROLLING_ON_MAIN) { | 378 if (reasons == cc::MainThreadScrollingReason::kNotScrollingOnMain) { |
379 if (type == WebInputEvent::GestureScrollBegin) { | 379 if (type == WebInputEvent::GestureScrollBegin) { |
380 UMA_HISTOGRAM_ENUMERATION( | 380 UMA_HISTOGRAM_ENUMERATION( |
381 kGestureHistogramName, cc::InputHandler::NOT_SCROLLING_ON_MAIN, | 381 kGestureHistogramName, |
382 cc::InputHandler::MainThreadScrollingReasonCount); | 382 cc::MainThreadScrollingReason::kNotScrollingOnMain, |
| 383 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
383 } else { | 384 } else { |
384 UMA_HISTOGRAM_ENUMERATION( | 385 UMA_HISTOGRAM_ENUMERATION( |
385 kWheelHistogramName, cc::InputHandler::NOT_SCROLLING_ON_MAIN, | 386 kWheelHistogramName, |
386 cc::InputHandler::MainThreadScrollingReasonCount); | 387 cc::MainThreadScrollingReason::kNotScrollingOnMain, |
| 388 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
387 } | 389 } |
388 } | 390 } |
389 | 391 |
390 for (int i = 0; i < cc::InputHandler::MainThreadScrollingReasonCount - 1; | 392 for (uint32_t i = 0; |
| 393 i < cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount - 1; |
391 ++i) { | 394 ++i) { |
392 unsigned val = 1 << i; | 395 unsigned val = 1 << i; |
393 if (reasons & val) { | 396 if (reasons & val) { |
394 if (type == WebInputEvent::GestureScrollBegin) { | 397 if (type == WebInputEvent::GestureScrollBegin) { |
395 UMA_HISTOGRAM_ENUMERATION( | 398 UMA_HISTOGRAM_ENUMERATION( |
396 kGestureHistogramName, i + 1, | 399 kGestureHistogramName, i + 1, |
397 cc::InputHandler::MainThreadScrollingReasonCount); | 400 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
398 } else { | 401 } else { |
399 UMA_HISTOGRAM_ENUMERATION( | 402 UMA_HISTOGRAM_ENUMERATION( |
400 kWheelHistogramName, i + 1, | 403 kWheelHistogramName, i + 1, |
401 cc::InputHandler::MainThreadScrollingReasonCount); | 404 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
402 } | 405 } |
403 } | 406 } |
404 } | 407 } |
405 } | 408 } |
406 | 409 |
407 bool InputHandlerProxy::ShouldAnimate( | 410 bool InputHandlerProxy::ShouldAnimate( |
408 const blink::WebMouseWheelEvent& event) const { | 411 const blink::WebMouseWheelEvent& event) const { |
409 #if defined(OS_MACOSX) | 412 #if defined(OS_MACOSX) |
410 // Mac does not smooth scroll wheel events (crbug.com/574283). | 413 // Mac does not smooth scroll wheel events (crbug.com/574283). |
411 return false; | 414 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
426 ? -wheel_event.deltaX | 429 ? -wheel_event.deltaX |
427 : 0, | 430 : 0, |
428 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal | 431 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal |
429 ? -wheel_event.deltaY | 432 ? -wheel_event.deltaY |
430 : 0); | 433 : 0); |
431 | 434 |
432 if (wheel_event.scrollByPage) { | 435 if (wheel_event.scrollByPage) { |
433 // TODO(jamesr): We don't properly handle scroll by page in the compositor | 436 // TODO(jamesr): We don't properly handle scroll by page in the compositor |
434 // thread, so punt it to the main thread. http://crbug.com/236639 | 437 // thread, so punt it to the main thread. http://crbug.com/236639 |
435 result = DID_NOT_HANDLE; | 438 result = DID_NOT_HANDLE; |
436 RecordMainThreadScrollingReasons(wheel_event.type, | 439 RecordMainThreadScrollingReasons( |
437 cc::InputHandler::PAGE_BASED_SCROLLING); | 440 wheel_event.type, cc::MainThreadScrollingReason::kPageBasedScrolling); |
438 | 441 |
439 } else if (!wheel_event.canScroll) { | 442 } else if (!wheel_event.canScroll) { |
440 // Wheel events with |canScroll| == false will not trigger scrolling, | 443 // Wheel events with |canScroll| == false will not trigger scrolling, |
441 // only event handlers. Forward to the main thread. | 444 // only event handlers. Forward to the main thread. |
442 result = DID_NOT_HANDLE; | 445 result = DID_NOT_HANDLE; |
443 } else if (ShouldAnimate(wheel_event)) { | 446 } else if (ShouldAnimate(wheel_event)) { |
444 cc::InputHandler::ScrollStatus scroll_status = | 447 cc::InputHandler::ScrollStatus scroll_status = |
445 input_handler_->ScrollAnimated(gfx::Point(wheel_event.x, wheel_event.y), | 448 input_handler_->ScrollAnimated(gfx::Point(wheel_event.x, wheel_event.y), |
446 scroll_delta); | 449 scroll_delta); |
447 | 450 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail | 496 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail |
494 // to properly sync scrollability it's safer to send the event to the | 497 // to properly sync scrollability it's safer to send the event to the |
495 // main thread. Change back to DROP_EVENT once we have synchronization | 498 // main thread. Change back to DROP_EVENT once we have synchronization |
496 // bugs sorted out. | 499 // bugs sorted out. |
497 result = DID_NOT_HANDLE; | 500 result = DID_NOT_HANDLE; |
498 break; | 501 break; |
499 case cc::InputHandler::SCROLL_UNKNOWN: | 502 case cc::InputHandler::SCROLL_UNKNOWN: |
500 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: | 503 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: |
501 result = DID_NOT_HANDLE; | 504 result = DID_NOT_HANDLE; |
502 break; | 505 break; |
503 case cc::InputHandler::ScrollStatusCount: | |
504 NOTREACHED(); | |
505 break; | |
506 } | 506 } |
507 } | 507 } |
508 | 508 |
509 // Send the event and its disposition to the elasticity controller to update | 509 // Send the event and its disposition to the elasticity controller to update |
510 // the over-scroll animation. If the event is to be handled on the main | 510 // the over-scroll animation. If the event is to be handled on the main |
511 // thread, the event and its disposition will be sent to the elasticity | 511 // thread, the event and its disposition will be sent to the elasticity |
512 // controller after being handled on the main thread. | 512 // controller after being handled on the main thread. |
513 if (scroll_elasticity_controller_ && result != DID_NOT_HANDLE) { | 513 if (scroll_elasticity_controller_ && result != DID_NOT_HANDLE) { |
514 // Note that the call to the elasticity controller is made asynchronously, | 514 // Note that the call to the elasticity controller is made asynchronously, |
515 // to minimize divergence between main thread and impl thread event | 515 // to minimize divergence between main thread and impl thread event |
(...skipping 15 matching lines...) Expand all Loading... |
531 #ifndef NDEBUG | 531 #ifndef NDEBUG |
532 DCHECK(!expect_scroll_update_end_); | 532 DCHECK(!expect_scroll_update_end_); |
533 expect_scroll_update_end_ = true; | 533 expect_scroll_update_end_ = true; |
534 #endif | 534 #endif |
535 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 535 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); |
536 cc::InputHandler::ScrollStatus scroll_status; | 536 cc::InputHandler::ScrollStatus scroll_status; |
537 if (gesture_event.data.scrollBegin.deltaHintUnits == | 537 if (gesture_event.data.scrollBegin.deltaHintUnits == |
538 blink::WebGestureEvent::ScrollUnits::Page) { | 538 blink::WebGestureEvent::ScrollUnits::Page) { |
539 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; | 539 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; |
540 scroll_status.main_thread_scrolling_reasons = | 540 scroll_status.main_thread_scrolling_reasons = |
541 cc::InputHandler::CONTINUING_MAIN_THREAD_SCROLL; | 541 cc::MainThreadScrollingReason::kContinuingMainThreadScroll; |
542 } else if (gesture_event.data.scrollBegin.targetViewport) { | 542 } else if (gesture_event.data.scrollBegin.targetViewport) { |
543 scroll_status = input_handler_->RootScrollBegin(&scroll_state, | 543 scroll_status = input_handler_->RootScrollBegin(&scroll_state, |
544 cc::InputHandler::GESTURE); | 544 cc::InputHandler::GESTURE); |
545 } else if (smooth_scroll_enabled_ && | 545 } else if (smooth_scroll_enabled_ && |
546 gesture_event.data.scrollBegin.deltaHintUnits == | 546 gesture_event.data.scrollBegin.deltaHintUnits == |
547 blink::WebGestureEvent::ScrollUnits::Pixels) { | 547 blink::WebGestureEvent::ScrollUnits::Pixels) { |
548 gfx::Vector2dF scroll_delta(-gesture_event.data.scrollBegin.deltaXHint, | 548 gfx::Vector2dF scroll_delta(-gesture_event.data.scrollBegin.deltaXHint, |
549 -gesture_event.data.scrollBegin.deltaYHint); | 549 -gesture_event.data.scrollBegin.deltaYHint); |
550 scroll_status = input_handler_->ScrollAnimated( | 550 scroll_status = input_handler_->ScrollAnimated( |
551 gfx::Point(gesture_event.x, gesture_event.y), scroll_delta); | 551 gfx::Point(gesture_event.x, gesture_event.y), scroll_delta); |
552 } else { | 552 } else { |
553 scroll_status = | 553 scroll_status = |
554 input_handler_->ScrollBegin(&scroll_state, cc::InputHandler::GESTURE); | 554 input_handler_->ScrollBegin(&scroll_state, cc::InputHandler::GESTURE); |
555 } | 555 } |
556 UMA_HISTOGRAM_ENUMERATION("Renderer4.CompositorScrollHitTestResult", | 556 UMA_HISTOGRAM_ENUMERATION("Renderer4.CompositorScrollHitTestResult", |
557 scroll_status.thread, | 557 scroll_status.thread, |
558 cc::InputHandler::ScrollStatusCount); | 558 cc::InputHandler::LAST_SCROLL_STATUS + 1); |
559 | 559 |
560 RecordMainThreadScrollingReasons(gesture_event.type, | 560 RecordMainThreadScrollingReasons(gesture_event.type, |
561 scroll_status.main_thread_scrolling_reasons); | 561 scroll_status.main_thread_scrolling_reasons); |
562 | 562 |
563 switch (scroll_status.thread) { | 563 switch (scroll_status.thread) { |
564 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: | 564 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: |
565 TRACE_EVENT_INSTANT0("input", | 565 TRACE_EVENT_INSTANT0("input", |
566 "InputHandlerProxy::handle_input gesture scroll", | 566 "InputHandlerProxy::handle_input gesture scroll", |
567 TRACE_EVENT_SCOPE_THREAD); | 567 TRACE_EVENT_SCOPE_THREAD); |
568 gesture_scroll_on_impl_thread_ = true; | 568 gesture_scroll_on_impl_thread_ = true; |
569 return DID_HANDLE; | 569 return DID_HANDLE; |
570 case cc::InputHandler::SCROLL_UNKNOWN: | 570 case cc::InputHandler::SCROLL_UNKNOWN: |
571 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: | 571 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: |
572 return DID_NOT_HANDLE; | 572 return DID_NOT_HANDLE; |
573 case cc::InputHandler::SCROLL_IGNORED: | 573 case cc::InputHandler::SCROLL_IGNORED: |
574 return DROP_EVENT; | 574 return DROP_EVENT; |
575 case cc::InputHandler::ScrollStatusCount: | |
576 NOTREACHED(); | |
577 break; | |
578 } | 575 } |
579 return DID_NOT_HANDLE; | 576 return DID_NOT_HANDLE; |
580 } | 577 } |
581 | 578 |
582 InputHandlerProxy::EventDisposition | 579 InputHandlerProxy::EventDisposition |
583 InputHandlerProxy::HandleGestureScrollUpdate( | 580 InputHandlerProxy::HandleGestureScrollUpdate( |
584 const WebGestureEvent& gesture_event) { | 581 const WebGestureEvent& gesture_event) { |
585 #ifndef NDEBUG | 582 #ifndef NDEBUG |
586 DCHECK(expect_scroll_update_end_); | 583 DCHECK(expect_scroll_update_end_); |
587 #endif | 584 #endif |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 return DID_NOT_HANDLE; | 621 return DID_NOT_HANDLE; |
625 gesture_scroll_on_impl_thread_ = false; | 622 gesture_scroll_on_impl_thread_ = false; |
626 return DID_HANDLE; | 623 return DID_HANDLE; |
627 } | 624 } |
628 | 625 |
629 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( | 626 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( |
630 const WebGestureEvent& gesture_event) { | 627 const WebGestureEvent& gesture_event) { |
631 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 628 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); |
632 cc::InputHandler::ScrollStatus scroll_status; | 629 cc::InputHandler::ScrollStatus scroll_status; |
633 scroll_status.main_thread_scrolling_reasons = | 630 scroll_status.main_thread_scrolling_reasons = |
634 cc::InputHandler::NOT_SCROLLING_ON_MAIN; | 631 cc::MainThreadScrollingReason::kNotScrollingOnMain; |
635 switch (gesture_event.sourceDevice) { | 632 switch (gesture_event.sourceDevice) { |
636 case blink::WebGestureDeviceTouchpad: | 633 case blink::WebGestureDeviceTouchpad: |
637 if (gesture_event.data.flingStart.targetViewport) { | 634 if (gesture_event.data.flingStart.targetViewport) { |
638 scroll_status = input_handler_->RootScrollBegin( | 635 scroll_status = input_handler_->RootScrollBegin( |
639 &scroll_state, cc::InputHandler::NON_BUBBLING_GESTURE); | 636 &scroll_state, cc::InputHandler::NON_BUBBLING_GESTURE); |
640 } else { | 637 } else { |
641 scroll_status = input_handler_->ScrollBegin( | 638 scroll_status = input_handler_->ScrollBegin( |
642 &scroll_state, cc::InputHandler::NON_BUBBLING_GESTURE); | 639 &scroll_state, cc::InputHandler::NON_BUBBLING_GESTURE); |
643 } | 640 } |
644 break; | 641 break; |
645 case blink::WebGestureDeviceTouchscreen: | 642 case blink::WebGestureDeviceTouchscreen: |
646 if (!gesture_scroll_on_impl_thread_) { | 643 if (!gesture_scroll_on_impl_thread_) { |
647 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; | 644 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; |
648 scroll_status.main_thread_scrolling_reasons = | 645 scroll_status.main_thread_scrolling_reasons = |
649 cc::InputHandler::CONTINUING_MAIN_THREAD_SCROLL; | 646 cc::MainThreadScrollingReason::kContinuingMainThreadScroll; |
650 } else { | 647 } else { |
651 scroll_status = input_handler_->FlingScrollBegin(); | 648 scroll_status = input_handler_->FlingScrollBegin(); |
652 } | 649 } |
653 break; | 650 break; |
654 case blink::WebGestureDeviceUninitialized: | 651 case blink::WebGestureDeviceUninitialized: |
655 NOTREACHED(); | 652 NOTREACHED(); |
656 return DID_NOT_HANDLE; | 653 return DID_NOT_HANDLE; |
657 } | 654 } |
658 | 655 |
659 #ifndef NDEBUG | 656 #ifndef NDEBUG |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 TRACE_EVENT_SCOPE_THREAD); | 707 TRACE_EVENT_SCOPE_THREAD); |
711 gesture_scroll_on_impl_thread_ = false; | 708 gesture_scroll_on_impl_thread_ = false; |
712 if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad) { | 709 if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad) { |
713 // We still pass the curve to the main thread if there's nothing | 710 // We still pass the curve to the main thread if there's nothing |
714 // scrollable, in case something | 711 // scrollable, in case something |
715 // registers a handler before the curve is over. | 712 // registers a handler before the curve is over. |
716 return DID_NOT_HANDLE; | 713 return DID_NOT_HANDLE; |
717 } | 714 } |
718 return DROP_EVENT; | 715 return DROP_EVENT; |
719 } | 716 } |
720 case cc::InputHandler::ScrollStatusCount: | |
721 NOTREACHED(); | |
722 break; | |
723 } | 717 } |
724 return DID_NOT_HANDLE; | 718 return DID_NOT_HANDLE; |
725 } | 719 } |
726 | 720 |
727 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart( | 721 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart( |
728 const blink::WebTouchEvent& touch_event) { | 722 const blink::WebTouchEvent& touch_event) { |
729 for (size_t i = 0; i < touch_event.touchesLength; ++i) { | 723 for (size_t i = 0; i < touch_event.touchesLength; ++i) { |
730 if (touch_event.touches[i].state != WebTouchPoint::StatePressed) | 724 if (touch_event.touches[i].state != WebTouchPoint::StatePressed) |
731 continue; | 725 continue; |
732 if (input_handler_->DoTouchEventsBlockScrollAt( | 726 if (input_handler_->DoTouchEventsBlockScrollAt( |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 // trigger a scroll, e.g., with a trivial time delta between fling updates. | 1170 // trigger a scroll, e.g., with a trivial time delta between fling updates. |
1177 // Return true in this case to prevent early fling termination. | 1171 // Return true in this case to prevent early fling termination. |
1178 if (std::abs(clipped_increment.width) < kScrollEpsilon && | 1172 if (std::abs(clipped_increment.width) < kScrollEpsilon && |
1179 std::abs(clipped_increment.height) < kScrollEpsilon) | 1173 std::abs(clipped_increment.height) < kScrollEpsilon) |
1180 return true; | 1174 return true; |
1181 | 1175 |
1182 return did_scroll; | 1176 return did_scroll; |
1183 } | 1177 } |
1184 | 1178 |
1185 } // namespace ui | 1179 } // namespace ui |
OLD | NEW |