Chromium Code Reviews| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Return true if scrollable node for 'ancestor' is the same as 'child' or an | 157 // Return true if scrollable node for 'ancestor' is the same as 'child' or an |
| 158 // ancestor along the scroll tree. | 158 // ancestor along the scroll tree. |
| 159 bool IsScrolledBy(LayerImpl* child, LayerImpl* ancestor) { | 159 bool IsScrolledBy(LayerImpl* child, LayerImpl* ancestor) { |
| 160 DCHECK(ancestor && ancestor->scrollable()); | 160 DCHECK(ancestor && ancestor->scrollable()); |
| 161 if (!child) | 161 if (!child) |
| 162 return false; | 162 return false; |
| 163 | 163 |
| 164 auto* property_trees = child->layer_tree_impl()->property_trees(); | 164 auto* property_trees = child->layer_tree_impl()->property_trees(); |
| 165 auto ancestor_scroll_id = | |
| 166 property_trees->layer_id_to_scroll_node_index.find(ancestor->id()); | |
| 167 if (ancestor_scroll_id == property_trees->layer_id_to_scroll_node_index.end()) | |
| 168 return false; | |
| 169 | |
| 170 ScrollTree& scroll_tree = property_trees->scroll_tree; | 165 ScrollTree& scroll_tree = property_trees->scroll_tree; |
| 171 for (ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index()); | 166 for (ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index()); |
| 172 scroll_node; scroll_node = scroll_tree.parent(scroll_node)) { | 167 scroll_node; scroll_node = scroll_tree.parent(scroll_node)) { |
| 173 if (scroll_node->id == ancestor_scroll_id->second) | 168 if (scroll_node->id == ancestor->scroll_tree_index()) |
| 174 return true; | 169 return true; |
| 175 } | 170 } |
| 176 return false; | 171 return false; |
| 177 } | 172 } |
| 178 | 173 |
| 179 } // namespace | 174 } // namespace |
| 180 | 175 |
| 181 DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer, | 176 DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer, |
| 182 "Scheduling.%s.PendingTreeDuration"); | 177 "Scheduling.%s.PendingTreeDuration"); |
| 183 | 178 |
| (...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2622 } | 2617 } |
| 2623 } | 2618 } |
| 2624 | 2619 |
| 2625 // TODO(pdr): Refactor this function to directly return |impl_scroll_node| | 2620 // TODO(pdr): Refactor this function to directly return |impl_scroll_node| |
| 2626 // instead of using ScrollNode's owning_layer_id to return a LayerImpl. | 2621 // instead of using ScrollNode's owning_layer_id to return a LayerImpl. |
| 2627 if (!impl_scroll_node) | 2622 if (!impl_scroll_node) |
| 2628 return nullptr; | 2623 return nullptr; |
| 2629 return active_tree_->LayerById(impl_scroll_node->owning_layer_id); | 2624 return active_tree_->LayerById(impl_scroll_node->owning_layer_id); |
| 2630 } | 2625 } |
| 2631 | 2626 |
| 2632 static bool IsClosestScrollAncestor(LayerImpl* child, | |
| 2633 LayerImpl* scroll_ancestor) { | |
| 2634 DCHECK(scroll_ancestor); | |
| 2635 if (!child) | |
| 2636 return false; | |
| 2637 | |
| 2638 auto* property_trees = child->layer_tree_impl()->property_trees(); | |
| 2639 auto ancestor_scroll_id = | |
| 2640 property_trees->layer_id_to_scroll_node_index.find(scroll_ancestor->id()); | |
| 2641 if (ancestor_scroll_id == property_trees->layer_id_to_scroll_node_index.end()) | |
| 2642 return false; | |
| 2643 | |
| 2644 ScrollTree& scroll_tree = property_trees->scroll_tree; | |
| 2645 ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index()); | |
| 2646 for (; scroll_tree.parent(scroll_node); | |
| 2647 scroll_node = scroll_tree.parent(scroll_node)) { | |
| 2648 if (scroll_node->scrollable) | |
|
pdr.
2017/02/27 21:40:05
The refactoring in this patch is possible because
| |
| 2649 return scroll_node->id == ancestor_scroll_id->second; | |
| 2650 } | |
| 2651 return false; | |
| 2652 } | |
| 2653 | |
| 2654 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( | 2627 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( |
| 2655 ScrollState* scroll_state, | 2628 ScrollState* scroll_state, |
| 2656 LayerImpl* scrolling_layer_impl, | 2629 LayerImpl* scrolling_layer_impl, |
| 2657 InputHandler::ScrollInputType type) { | 2630 InputHandler::ScrollInputType type) { |
| 2658 DCHECK(scroll_state); | 2631 DCHECK(scroll_state); |
| 2659 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); | 2632 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); |
| 2660 | 2633 |
| 2661 InputHandler::ScrollStatus scroll_status; | 2634 InputHandler::ScrollStatus scroll_status; |
| 2662 scroll_status.main_thread_scrolling_reasons = | 2635 scroll_status.main_thread_scrolling_reasons = |
| 2663 MainThreadScrollingReason::kNotScrollingOnMain; | 2636 MainThreadScrollingReason::kNotScrollingOnMain; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2717 | 2690 |
| 2718 gfx::Point viewport_point(scroll_state->position_x(), | 2691 gfx::Point viewport_point(scroll_state->position_x(), |
| 2719 scroll_state->position_y()); | 2692 scroll_state->position_y()); |
| 2720 | 2693 |
| 2721 gfx::PointF device_viewport_point = gfx::ScalePoint( | 2694 gfx::PointF device_viewport_point = gfx::ScalePoint( |
| 2722 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); | 2695 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
| 2723 LayerImpl* layer_impl = | 2696 LayerImpl* layer_impl = |
| 2724 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); | 2697 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
| 2725 | 2698 |
| 2726 if (layer_impl) { | 2699 if (layer_impl) { |
| 2727 LayerImpl* scroll_layer_impl = | 2700 if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) { |
| 2728 active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( | |
| 2729 device_viewport_point); | |
| 2730 if (scroll_layer_impl && | |
| 2731 !IsClosestScrollAncestor(layer_impl, scroll_layer_impl)) { | |
| 2732 scroll_status.thread = SCROLL_UNKNOWN; | 2701 scroll_status.thread = SCROLL_UNKNOWN; |
| 2733 scroll_status.main_thread_scrolling_reasons = | 2702 scroll_status.main_thread_scrolling_reasons = |
| 2734 MainThreadScrollingReason::kFailedHitTest; | 2703 MainThreadScrollingReason::kFailedHitTest; |
| 2735 return scroll_status; | 2704 return scroll_status; |
| 2736 } | 2705 } |
| 2737 } | 2706 } |
| 2738 | 2707 |
| 2739 scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( | 2708 scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( |
| 2740 device_viewport_point, type, layer_impl, &scroll_on_main_thread, | 2709 device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
| 2741 &scroll_status.main_thread_scrolling_reasons); | 2710 &scroll_status.main_thread_scrolling_reasons); |
| 2742 } | 2711 } |
| 2743 | 2712 |
| 2744 if (scroll_on_main_thread) { | 2713 if (scroll_on_main_thread) { |
| 2745 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); | 2714 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); |
| 2746 | 2715 |
| 2747 scroll_status.thread = SCROLL_ON_MAIN_THREAD; | 2716 scroll_status.thread = SCROLL_ON_MAIN_THREAD; |
| 2748 return scroll_status; | 2717 return scroll_status; |
| 2749 } else if (scrolling_layer_impl) { | 2718 } else if (scrolling_layer_impl) { |
| 2750 scroll_affects_scroll_handler_ = | 2719 scroll_affects_scroll_handler_ = |
| 2751 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); | 2720 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); |
| 2752 } | 2721 } |
| 2753 | 2722 |
| 2754 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); | 2723 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); |
| 2755 } | 2724 } |
| 2756 | 2725 |
| 2726 // Some initial scroll tests are known to be unreliable and require falling | |
| 2727 // back to main thread scrolling. | |
| 2728 bool LayerTreeHostImpl::IsInitialScrollHitTestReliable( | |
| 2729 LayerImpl* layer_impl, | |
| 2730 const gfx::PointF& device_viewport_point) { | |
| 2731 LayerImpl* first_scrolling_layer_or_drawn_scrollbar = | |
| 2732 active_tree_->FindFirstScrollingLayerOrDrawnScrollbarThatIsHitByPoint( | |
| 2733 device_viewport_point); | |
| 2734 | |
| 2735 // If |layer_impl| is hit, we can reliably return true. | |
| 2736 if (!first_scrolling_layer_or_drawn_scrollbar || | |
| 2737 first_scrolling_layer_or_drawn_scrollbar == layer_impl) | |
|
ajuma
2017/02/28 00:38:58
If layer_impl is itself a non-scrollable drawn scr
pdr.
2017/02/28 01:01:35
True, this should not check for equality. Updated
| |
| 2738 return true; | |
| 2739 | |
| 2740 ScrollNode* closest_scroll_node = nullptr; | |
| 2741 auto& scroll_tree = active_tree_->property_trees()->scroll_tree; | |
| 2742 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); | |
| 2743 for (; scroll_tree.parent(scroll_node); | |
| 2744 scroll_node = scroll_tree.parent(scroll_node)) { | |
| 2745 if (scroll_node->scrollable) { | |
| 2746 closest_scroll_node = scroll_node; | |
| 2747 break; | |
| 2748 } | |
| 2749 } | |
| 2750 if (!closest_scroll_node) | |
| 2751 return false; | |
| 2752 | |
| 2753 // If |first_scrolling_layer_or_drawn_scrollbar| is scrollable, it will | |
| 2754 // create a scroll node. If this scroll node corresponds to first scrollable | |
| 2755 // ancestor along the scroll tree for |layer_impl|, the hit test has not | |
| 2756 // escaped to other areas of the scroll tree and is reliable. | |
| 2757 if (first_scrolling_layer_or_drawn_scrollbar->scrollable()) { | |
| 2758 return closest_scroll_node->id == | |
| 2759 first_scrolling_layer_or_drawn_scrollbar->scroll_tree_index(); | |
| 2760 } | |
| 2761 | |
| 2762 // If |first_scrolling_layer_or_drawn_scrollbar| is not scrollable, it must | |
| 2763 // be a drawn scrollbar. These hit tests require falling back to main-thread | |
| 2764 // scrolling. | |
| 2765 DCHECK(first_scrolling_layer_or_drawn_scrollbar->IsDrawnScrollbar()); | |
| 2766 return false; | |
| 2767 } | |
| 2768 | |
| 2757 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( | 2769 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( |
| 2758 const gfx::Point& viewport_point) { | 2770 const gfx::Point& viewport_point) { |
| 2759 InputHandler::ScrollStatus scroll_status; | 2771 InputHandler::ScrollStatus scroll_status; |
| 2760 scroll_status.main_thread_scrolling_reasons = | 2772 scroll_status.main_thread_scrolling_reasons = |
| 2761 MainThreadScrollingReason::kNotScrollingOnMain; | 2773 MainThreadScrollingReason::kNotScrollingOnMain; |
| 2762 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; | 2774 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; |
| 2763 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); | 2775 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); |
| 2764 if (scroll_node) { | 2776 if (scroll_node) { |
| 2765 gfx::Vector2dF delta; | 2777 gfx::Vector2dF delta; |
| 2766 | 2778 |
| (...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4140 worker_context_visibility_ = | 4152 worker_context_visibility_ = |
| 4141 worker_context->CacheController()->ClientBecameVisible(); | 4153 worker_context->CacheController()->ClientBecameVisible(); |
| 4142 } else { | 4154 } else { |
| 4143 worker_context->CacheController()->ClientBecameNotVisible( | 4155 worker_context->CacheController()->ClientBecameNotVisible( |
| 4144 std::move(worker_context_visibility_)); | 4156 std::move(worker_context_visibility_)); |
| 4145 } | 4157 } |
| 4146 } | 4158 } |
| 4147 } | 4159 } |
| 4148 | 4160 |
| 4149 } // namespace cc | 4161 } // namespace cc |
| OLD | NEW |