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

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

Issue 2720713004: Reland: Refactor unreliable hit test code to avoid owning_layers (Closed)
Patch Set: 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
« no previous file with comments | « cc/trees/layer_tree_host_impl.h ('k') | cc/trees/layer_tree_host_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2627 } 2622 }
2628 } 2623 }
2629 2624
2630 // TODO(pdr): Refactor this function to directly return |impl_scroll_node| 2625 // TODO(pdr): Refactor this function to directly return |impl_scroll_node|
2631 // instead of using ScrollNode's owning_layer_id to return a LayerImpl. 2626 // instead of using ScrollNode's owning_layer_id to return a LayerImpl.
2632 if (!impl_scroll_node) 2627 if (!impl_scroll_node)
2633 return nullptr; 2628 return nullptr;
2634 return active_tree_->LayerById(impl_scroll_node->owning_layer_id); 2629 return active_tree_->LayerById(impl_scroll_node->owning_layer_id);
2635 } 2630 }
2636 2631
2637 static bool IsClosestScrollAncestor(LayerImpl* child,
2638 LayerImpl* scroll_ancestor) {
2639 DCHECK(scroll_ancestor);
2640 if (!child)
2641 return false;
2642
2643 auto* property_trees = child->layer_tree_impl()->property_trees();
2644 auto ancestor_scroll_id =
2645 property_trees->layer_id_to_scroll_node_index.find(scroll_ancestor->id());
2646 if (ancestor_scroll_id == property_trees->layer_id_to_scroll_node_index.end())
2647 return false;
2648
2649 ScrollTree& scroll_tree = property_trees->scroll_tree;
2650 ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index());
2651 for (; scroll_tree.parent(scroll_node);
2652 scroll_node = scroll_tree.parent(scroll_node)) {
2653 if (scroll_node->scrollable)
2654 return scroll_node->id == ancestor_scroll_id->second;
2655 }
2656 return false;
2657 }
2658
2659 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( 2632 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
2660 ScrollState* scroll_state, 2633 ScrollState* scroll_state,
2661 LayerImpl* scrolling_layer_impl, 2634 LayerImpl* scrolling_layer_impl,
2662 InputHandler::ScrollInputType type) { 2635 InputHandler::ScrollInputType type) {
2663 DCHECK(scroll_state); 2636 DCHECK(scroll_state);
2664 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); 2637 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0);
2665 2638
2666 InputHandler::ScrollStatus scroll_status; 2639 InputHandler::ScrollStatus scroll_status;
2667 scroll_status.main_thread_scrolling_reasons = 2640 scroll_status.main_thread_scrolling_reasons =
2668 MainThreadScrollingReason::kNotScrollingOnMain; 2641 MainThreadScrollingReason::kNotScrollingOnMain;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2722 2695
2723 gfx::Point viewport_point(scroll_state->position_x(), 2696 gfx::Point viewport_point(scroll_state->position_x(),
2724 scroll_state->position_y()); 2697 scroll_state->position_y());
2725 2698
2726 gfx::PointF device_viewport_point = gfx::ScalePoint( 2699 gfx::PointF device_viewport_point = gfx::ScalePoint(
2727 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); 2700 gfx::PointF(viewport_point), active_tree_->device_scale_factor());
2728 LayerImpl* layer_impl = 2701 LayerImpl* layer_impl =
2729 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); 2702 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point);
2730 2703
2731 if (layer_impl) { 2704 if (layer_impl) {
2732 LayerImpl* scroll_layer_impl = 2705 if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) {
2733 active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint(
2734 device_viewport_point);
2735 if (scroll_layer_impl &&
2736 !IsClosestScrollAncestor(layer_impl, scroll_layer_impl)) {
2737 scroll_status.thread = SCROLL_UNKNOWN; 2706 scroll_status.thread = SCROLL_UNKNOWN;
2738 scroll_status.main_thread_scrolling_reasons = 2707 scroll_status.main_thread_scrolling_reasons =
2739 MainThreadScrollingReason::kFailedHitTest; 2708 MainThreadScrollingReason::kFailedHitTest;
2740 return scroll_status; 2709 return scroll_status;
2741 } 2710 }
2742 } 2711 }
2743 2712
2744 scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( 2713 scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint(
2745 device_viewport_point, type, layer_impl, &scroll_on_main_thread, 2714 device_viewport_point, type, layer_impl, &scroll_on_main_thread,
2746 &scroll_status.main_thread_scrolling_reasons); 2715 &scroll_status.main_thread_scrolling_reasons);
2747 } 2716 }
2748 2717
2749 if (scroll_on_main_thread) { 2718 if (scroll_on_main_thread) {
2750 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); 2719 RecordCompositorSlowScrollMetric(type, MAIN_THREAD);
2751 2720
2752 scroll_status.thread = SCROLL_ON_MAIN_THREAD; 2721 scroll_status.thread = SCROLL_ON_MAIN_THREAD;
2753 return scroll_status; 2722 return scroll_status;
2754 } else if (scrolling_layer_impl) { 2723 } else if (scrolling_layer_impl) {
2755 scroll_affects_scroll_handler_ = 2724 scroll_affects_scroll_handler_ =
2756 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); 2725 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers();
2757 } 2726 }
2758 2727
2759 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); 2728 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type);
2760 } 2729 }
2761 2730
2731 // Some initial scroll tests are known to be unreliable and require falling
2732 // back to main thread scrolling.
2733 bool LayerTreeHostImpl::IsInitialScrollHitTestReliable(
2734 LayerImpl* layer_impl,
2735 const gfx::PointF& device_viewport_point) {
2736 LayerImpl* first_scrolling_layer_or_drawn_scrollbar =
2737 active_tree_->FindFirstScrollingLayerOrDrawnScrollbarThatIsHitByPoint(
2738 device_viewport_point);
2739 if (!first_scrolling_layer_or_drawn_scrollbar)
2740 return true;
2741
2742 ScrollNode* closest_scroll_node = nullptr;
2743 auto& scroll_tree = active_tree_->property_trees()->scroll_tree;
2744 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index());
2745 for (; scroll_tree.parent(scroll_node);
2746 scroll_node = scroll_tree.parent(scroll_node)) {
2747 if (scroll_node->scrollable) {
2748 closest_scroll_node = scroll_node;
2749 break;
2750 }
2751 }
2752 if (!closest_scroll_node)
2753 return false;
2754
2755 // If |first_scrolling_layer_or_drawn_scrollbar| is scrollable, it will
2756 // create a scroll node. If this scroll node corresponds to first scrollable
2757 // ancestor along the scroll tree for |layer_impl|, the hit test has not
2758 // escaped to other areas of the scroll tree and is reliable.
2759 if (first_scrolling_layer_or_drawn_scrollbar->scrollable()) {
2760 return closest_scroll_node->id ==
2761 first_scrolling_layer_or_drawn_scrollbar->scroll_tree_index();
2762 }
2763
2764 // If |first_scrolling_layer_or_drawn_scrollbar| is not scrollable, it must
2765 // be a drawn scrollbar. These hit tests require falling back to main-thread
2766 // scrolling.
2767 DCHECK(first_scrolling_layer_or_drawn_scrollbar->IsDrawnScrollbar());
2768 return false;
2769 }
2770
2762 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( 2771 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
2763 const gfx::Point& viewport_point) { 2772 const gfx::Point& viewport_point) {
2764 InputHandler::ScrollStatus scroll_status; 2773 InputHandler::ScrollStatus scroll_status;
2765 scroll_status.main_thread_scrolling_reasons = 2774 scroll_status.main_thread_scrolling_reasons =
2766 MainThreadScrollingReason::kNotScrollingOnMain; 2775 MainThreadScrollingReason::kNotScrollingOnMain;
2767 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; 2776 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
2768 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); 2777 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
2769 if (scroll_node) { 2778 if (scroll_node) {
2770 gfx::Vector2dF delta; 2779 gfx::Vector2dF delta;
2771 2780
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after
4145 worker_context_visibility_ = 4154 worker_context_visibility_ =
4146 worker_context->CacheController()->ClientBecameVisible(); 4155 worker_context->CacheController()->ClientBecameVisible();
4147 } else { 4156 } else {
4148 worker_context->CacheController()->ClientBecameNotVisible( 4157 worker_context->CacheController()->ClientBecameNotVisible(
4149 std::move(worker_context_visibility_)); 4158 std::move(worker_context_visibility_));
4150 } 4159 }
4151 } 4160 }
4152 } 4161 }
4153 4162
4154 } // namespace cc 4163 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_impl.h ('k') | cc/trees/layer_tree_host_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698