OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "cc/trees/layer_tree_host_impl.h" | 5 #include "cc/trees/layer_tree_host_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 return false; | 568 return false; |
569 | 569 |
570 gfx::PointF device_viewport_point = gfx::ScalePoint( | 570 gfx::PointF device_viewport_point = gfx::ScalePoint( |
571 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); | 571 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
572 | 572 |
573 LayerImpl* layer_impl = | 573 LayerImpl* layer_impl = |
574 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); | 574 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
575 | 575 |
576 bool scroll_on_main_thread = false; | 576 bool scroll_on_main_thread = false; |
577 uint32_t main_thread_scrolling_reasons; | 577 uint32_t main_thread_scrolling_reasons; |
578 LayerImpl* test_layer_impl = FindScrollLayerForDeviceViewportPoint( | 578 auto* test_scroll_node = FindScrollNodeForDeviceViewportPoint( |
579 device_viewport_point, type, layer_impl, &scroll_on_main_thread, | 579 device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
580 &main_thread_scrolling_reasons); | 580 &main_thread_scrolling_reasons); |
581 | 581 |
582 if (scroll_on_main_thread) | 582 if (scroll_on_main_thread) |
583 return false; | 583 return false; |
584 | 584 |
585 int test_scroll_tree_index = test_layer_impl->scroll_tree_index(); | 585 if (scrolling_node == test_scroll_node) |
586 if (scrolling_node->id == test_scroll_tree_index) | |
587 return true; | 586 return true; |
588 | 587 |
589 // For active scrolling state treat the inner/outer viewports interchangeably. | 588 // For active scrolling state treat the inner/outer viewports interchangeably. |
590 if (scrolling_node->scrolls_inner_viewport || | 589 if (scrolling_node->scrolls_inner_viewport || |
591 scrolling_node->scrolls_outer_viewport) { | 590 scrolling_node->scrolls_outer_viewport) { |
592 return test_layer_impl == viewport()->MainScrollLayer(); | 591 return test_scroll_node == OuterViewportScrollNode(); |
593 } | 592 } |
594 | 593 |
595 return false; | 594 return false; |
596 } | 595 } |
597 | 596 |
598 EventListenerProperties LayerTreeHostImpl::GetEventListenerProperties( | 597 EventListenerProperties LayerTreeHostImpl::GetEventListenerProperties( |
599 EventListenerClass event_class) const { | 598 EventListenerClass event_class) const { |
600 return active_tree_->event_listener_properties(event_class); | 599 return active_tree_->event_listener_properties(event_class); |
601 } | 600 } |
602 | 601 |
(...skipping 2016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 status.main_thread_scrolling_reasons)); | 2618 status.main_thread_scrolling_reasons)); |
2620 } else { | 2619 } else { |
2621 DCHECK(MainThreadScrollingReason::CompositorCanSetScrollReasons( | 2620 DCHECK(MainThreadScrollingReason::CompositorCanSetScrollReasons( |
2622 status.main_thread_scrolling_reasons)); | 2621 status.main_thread_scrolling_reasons)); |
2623 } | 2622 } |
2624 return true; | 2623 return true; |
2625 } | 2624 } |
2626 return false; | 2625 return false; |
2627 } | 2626 } |
2628 | 2627 |
2629 LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( | 2628 ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint( |
2630 const gfx::PointF& device_viewport_point, | 2629 const gfx::PointF& device_viewport_point, |
2631 InputHandler::ScrollInputType type, | 2630 InputHandler::ScrollInputType type, |
2632 LayerImpl* layer_impl, | 2631 LayerImpl* layer_impl, |
2633 bool* scroll_on_main_thread, | 2632 bool* scroll_on_main_thread, |
2634 uint32_t* main_thread_scrolling_reasons) const { | 2633 uint32_t* main_thread_scrolling_reasons) const { |
2635 DCHECK(scroll_on_main_thread); | 2634 DCHECK(scroll_on_main_thread); |
2636 DCHECK(main_thread_scrolling_reasons); | 2635 DCHECK(main_thread_scrolling_reasons); |
2637 *main_thread_scrolling_reasons = | 2636 *main_thread_scrolling_reasons = |
2638 MainThreadScrollingReason::kNotScrollingOnMain; | 2637 MainThreadScrollingReason::kNotScrollingOnMain; |
2639 | 2638 |
2640 // Walk up the hierarchy and look for a scrollable layer. | 2639 // Walk up the hierarchy and look for a scrollable layer. |
2641 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; | 2640 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; |
2642 ScrollNode* impl_scroll_node = nullptr; | 2641 ScrollNode* impl_scroll_node = nullptr; |
2643 if (layer_impl) { | 2642 if (layer_impl) { |
2644 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); | 2643 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); |
2645 for (; scroll_tree.parent(scroll_node); | 2644 for (; scroll_tree.parent(scroll_node); |
2646 scroll_node = scroll_tree.parent(scroll_node)) { | 2645 scroll_node = scroll_tree.parent(scroll_node)) { |
2647 // The content layer can also block attempts to scroll outside the main | 2646 // The content layer can also block attempts to scroll outside the main |
2648 // thread. | 2647 // thread. |
2649 ScrollStatus status = | 2648 ScrollStatus status = |
2650 TryScroll(device_viewport_point, type, scroll_tree, scroll_node); | 2649 TryScroll(device_viewport_point, type, scroll_tree, scroll_node); |
2651 if (IsMainThreadScrolling(status, scroll_node)) { | 2650 if (IsMainThreadScrolling(status, scroll_node)) { |
2652 *scroll_on_main_thread = true; | 2651 *scroll_on_main_thread = true; |
2653 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; | 2652 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; |
2654 return active_tree_->LayerById(scroll_node->owning_layer_id); | 2653 return scroll_node; |
2655 } | 2654 } |
2656 | 2655 |
2657 if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && | 2656 if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && |
2658 !impl_scroll_node) { | 2657 !impl_scroll_node) { |
2659 impl_scroll_node = scroll_node; | 2658 impl_scroll_node = scroll_node; |
2660 } | 2659 } |
2661 } | 2660 } |
2662 } | 2661 } |
2663 | 2662 |
2664 // Falling back to the viewport layer ensures generation of root overscroll | 2663 // Falling back to the viewport layer ensures generation of root overscroll |
2665 // notifications. We use the viewport's main scroll layer to represent the | 2664 // notifications. We use the viewport's main scroll layer to represent the |
2666 // viewport in scrolling code. | 2665 // viewport in scrolling code. |
2667 bool scrolls_inner_viewport = | 2666 bool scrolls_inner_viewport = |
2668 impl_scroll_node && impl_scroll_node->scrolls_inner_viewport; | 2667 impl_scroll_node && impl_scroll_node->scrolls_inner_viewport; |
2669 bool scrolls_outer_viewport = | 2668 bool scrolls_outer_viewport = |
2670 impl_scroll_node && impl_scroll_node->scrolls_outer_viewport; | 2669 impl_scroll_node && impl_scroll_node->scrolls_outer_viewport; |
2671 if (!impl_scroll_node || scrolls_inner_viewport || scrolls_outer_viewport) | 2670 if (!impl_scroll_node || scrolls_inner_viewport || scrolls_outer_viewport) |
2672 impl_scroll_node = OuterViewportScrollNode(); | 2671 impl_scroll_node = OuterViewportScrollNode(); |
2673 | 2672 |
2674 if (impl_scroll_node) { | 2673 if (impl_scroll_node) { |
2675 // Ensure that final layer scrolls on impl thread (crbug.com/625100) | 2674 // Ensure that final layer scrolls on impl thread (crbug.com/625100) |
2676 ScrollStatus status = | 2675 ScrollStatus status = |
2677 TryScroll(device_viewport_point, type, scroll_tree, impl_scroll_node); | 2676 TryScroll(device_viewport_point, type, scroll_tree, impl_scroll_node); |
2678 if (IsMainThreadScrolling(status, impl_scroll_node)) { | 2677 if (IsMainThreadScrolling(status, impl_scroll_node)) { |
2679 *scroll_on_main_thread = true; | 2678 *scroll_on_main_thread = true; |
2680 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; | 2679 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; |
2681 } | 2680 } |
2682 } | 2681 } |
2683 | 2682 |
2684 // TODO(pdr): Refactor this function to directly return |impl_scroll_node| | 2683 return impl_scroll_node; |
2685 // instead of using ScrollNode's owning_layer_id to return a LayerImpl. | |
2686 if (!impl_scroll_node) | |
2687 return nullptr; | |
2688 return active_tree_->LayerById(impl_scroll_node->owning_layer_id); | |
2689 } | 2684 } |
2690 | 2685 |
2691 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( | 2686 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( |
2692 ScrollState* scroll_state, | 2687 ScrollState* scroll_state, |
2693 ScrollNode* scrolling_node, | 2688 ScrollNode* scrolling_node, |
2694 InputHandler::ScrollInputType type) { | 2689 InputHandler::ScrollInputType type) { |
2695 DCHECK(scroll_state); | 2690 DCHECK(scroll_state); |
2696 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); | 2691 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); |
2697 | 2692 |
2698 InputHandler::ScrollStatus scroll_status; | 2693 InputHandler::ScrollStatus scroll_status; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2763 | 2758 |
2764 if (layer_impl) { | 2759 if (layer_impl) { |
2765 if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) { | 2760 if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) { |
2766 scroll_status.thread = SCROLL_UNKNOWN; | 2761 scroll_status.thread = SCROLL_UNKNOWN; |
2767 scroll_status.main_thread_scrolling_reasons = | 2762 scroll_status.main_thread_scrolling_reasons = |
2768 MainThreadScrollingReason::kFailedHitTest; | 2763 MainThreadScrollingReason::kFailedHitTest; |
2769 return scroll_status; | 2764 return scroll_status; |
2770 } | 2765 } |
2771 } | 2766 } |
2772 | 2767 |
2773 auto* scrolling_layer = FindScrollLayerForDeviceViewportPoint( | 2768 scrolling_node = FindScrollNodeForDeviceViewportPoint( |
2774 device_viewport_point, type, layer_impl, &scroll_on_main_thread, | 2769 device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
2775 &scroll_status.main_thread_scrolling_reasons); | 2770 &scroll_status.main_thread_scrolling_reasons); |
2776 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; | |
2777 scrolling_node = | |
2778 scrolling_layer ? scroll_tree.Node(scrolling_layer->scroll_tree_index()) | |
2779 : nullptr; | |
2780 } | 2771 } |
2781 | 2772 |
2782 if (scroll_on_main_thread) { | 2773 if (scroll_on_main_thread) { |
2783 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); | 2774 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); |
2784 | 2775 |
2785 scroll_status.thread = SCROLL_ON_MAIN_THREAD; | 2776 scroll_status.thread = SCROLL_ON_MAIN_THREAD; |
2786 return scroll_status; | 2777 return scroll_status; |
2787 } else if (scrolling_node) { | 2778 } else if (scrolling_node) { |
2788 scroll_affects_scroll_handler_ = active_tree_->have_scroll_event_handlers(); | 2779 scroll_affects_scroll_handler_ = active_tree_->have_scroll_event_handlers(); |
2789 } | 2780 } |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3411 } | 3402 } |
3412 | 3403 |
3413 void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { | 3404 void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { |
3414 gfx::PointF device_viewport_point = gfx::ScalePoint( | 3405 gfx::PointF device_viewport_point = gfx::ScalePoint( |
3415 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); | 3406 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
3416 LayerImpl* layer_impl = | 3407 LayerImpl* layer_impl = |
3417 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); | 3408 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
3418 | 3409 |
3419 // Check if mouse is over a scrollbar or not. | 3410 // Check if mouse is over a scrollbar or not. |
3420 // TODO(sahel): get rid of this extera checking when | 3411 // TODO(sahel): get rid of this extera checking when |
3421 // FindScrollLayerForDeviceViewportPoint finds the proper layer for | 3412 // FindScrollNodeForDeviceViewportPoint finds the proper node for scrolling on |
3422 // scrolling on main thread when mouse is over scrollbar as well. | 3413 // the main thread when the mouse is over a scrollbar as well. |
3423 ElementId new_element_id; | 3414 ElementId scroll_element_id; |
3424 if (layer_impl && layer_impl->ToScrollbarLayer()) | 3415 if (layer_impl && layer_impl->ToScrollbarLayer()) |
3425 new_element_id = layer_impl->ToScrollbarLayer()->scroll_element_id(); | 3416 scroll_element_id = layer_impl->ToScrollbarLayer()->scroll_element_id(); |
3426 if (!new_element_id) { | 3417 if (!scroll_element_id) { |
3427 bool scroll_on_main_thread = false; | 3418 bool scroll_on_main_thread = false; |
3428 uint32_t main_thread_scrolling_reasons; | 3419 uint32_t main_thread_scrolling_reasons; |
3429 LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( | 3420 auto* scroll_node = FindScrollNodeForDeviceViewportPoint( |
3430 device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, | 3421 device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, |
3431 &scroll_on_main_thread, &main_thread_scrolling_reasons); | 3422 &scroll_on_main_thread, &main_thread_scrolling_reasons); |
| 3423 if (scroll_node) |
| 3424 scroll_element_id = scroll_node->element_id; |
3432 | 3425 |
3433 // Scrollbars for the viewport are registered with the outer viewport layer. | 3426 // Scrollbars for the viewport are registered with the outer viewport layer. |
3434 if (scroll_layer_impl == InnerViewportScrollLayer()) | 3427 if (InnerViewportScrollLayer() && OuterViewportScrollLayer() && |
3435 scroll_layer_impl = OuterViewportScrollLayer(); | 3428 scroll_element_id == InnerViewportScrollLayer()->element_id()) |
3436 | 3429 scroll_element_id = OuterViewportScrollLayer()->element_id(); |
3437 if (scroll_layer_impl) | |
3438 new_element_id = scroll_layer_impl->element_id(); | |
3439 } | 3430 } |
3440 | 3431 |
3441 if (new_element_id != scroll_element_id_mouse_currently_over_) { | 3432 if (scroll_element_id != scroll_element_id_mouse_currently_over_) { |
3442 ScrollbarAnimationController* old_animation_controller = | 3433 ScrollbarAnimationController* old_animation_controller = |
3443 ScrollbarAnimationControllerForElementId( | 3434 ScrollbarAnimationControllerForElementId( |
3444 scroll_element_id_mouse_currently_over_); | 3435 scroll_element_id_mouse_currently_over_); |
3445 if (old_animation_controller) { | 3436 if (old_animation_controller) { |
3446 old_animation_controller->DidMouseLeave(); | 3437 old_animation_controller->DidMouseLeave(); |
3447 } | 3438 } |
3448 scroll_element_id_mouse_currently_over_ = new_element_id; | 3439 scroll_element_id_mouse_currently_over_ = scroll_element_id; |
3449 } | 3440 } |
3450 | 3441 |
3451 ScrollbarAnimationController* new_animation_controller = | 3442 ScrollbarAnimationController* new_animation_controller = |
3452 ScrollbarAnimationControllerForElementId(new_element_id); | 3443 ScrollbarAnimationControllerForElementId(scroll_element_id); |
3453 if (!new_animation_controller) | 3444 if (!new_animation_controller) |
3454 return; | 3445 return; |
3455 | 3446 |
3456 int new_layer_id = active_tree_->LayerIdByElementId(new_element_id); | 3447 int scroll_layer_id = active_tree_->LayerIdByElementId(scroll_element_id); |
3457 for (ScrollbarLayerImplBase* scrollbar : | 3448 for (ScrollbarLayerImplBase* scrollbar : |
3458 active_tree_->ScrollbarsFor(new_layer_id)) { | 3449 active_tree_->ScrollbarsFor(scroll_layer_id)) { |
3459 new_animation_controller->DidMouseMoveNear( | 3450 new_animation_controller->DidMouseMoveNear( |
3460 scrollbar->orientation(), | 3451 scrollbar->orientation(), |
3461 DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar) / | 3452 DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar) / |
3462 active_tree_->device_scale_factor()); | 3453 active_tree_->device_scale_factor()); |
3463 } | 3454 } |
3464 } | 3455 } |
3465 | 3456 |
3466 void LayerTreeHostImpl::MouseLeave() { | 3457 void LayerTreeHostImpl::MouseLeave() { |
3467 for (auto& pair : scrollbar_animation_controllers_) | 3458 for (auto& pair : scrollbar_animation_controllers_) |
3468 pair.second->DidMouseLeave(); | 3459 pair.second->DidMouseLeave(); |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4286 } | 4277 } |
4287 | 4278 |
4288 void LayerTreeHostImpl::UpdateScrollSourceInfo(bool is_wheel_scroll) { | 4279 void LayerTreeHostImpl::UpdateScrollSourceInfo(bool is_wheel_scroll) { |
4289 if (is_wheel_scroll) | 4280 if (is_wheel_scroll) |
4290 has_scrolled_by_wheel_ = true; | 4281 has_scrolled_by_wheel_ = true; |
4291 else | 4282 else |
4292 has_scrolled_by_touch_ = true; | 4283 has_scrolled_by_touch_ = true; |
4293 } | 4284 } |
4294 | 4285 |
4295 } // namespace cc | 4286 } // namespace cc |
OLD | NEW |