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

Side by Side Diff: cc/trees/layer_tree_host_impl.cc

Issue 2718833002: Refactor unreliable hit test code to avoid owning_layers (Closed)
Patch Set: Fix mistake in HitTestVisibleScrollableOrTouchableFunctor, cleaup comments Created 3 years, 9 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 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698