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

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 bug when directly hitting a drawn scrollbar 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 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)
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 if (!first_scrolling_layer_or_drawn_scrollbar)
2735 return true;
2736
2737 ScrollNode* closest_scroll_node = nullptr;
2738 auto& scroll_tree = active_tree_->property_trees()->scroll_tree;
2739 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index());
2740 for (; scroll_tree.parent(scroll_node);
2741 scroll_node = scroll_tree.parent(scroll_node)) {
2742 if (scroll_node->scrollable) {
2743 closest_scroll_node = scroll_node;
2744 break;
2745 }
2746 }
2747 if (!closest_scroll_node)
2748 return false;
2749
2750 // If |first_scrolling_layer_or_drawn_scrollbar| is scrollable, it will
2751 // create a scroll node. If this scroll node corresponds to first scrollable
2752 // ancestor along the scroll tree for |layer_impl|, the hit test has not
2753 // escaped to other areas of the scroll tree and is reliable.
2754 if (first_scrolling_layer_or_drawn_scrollbar->scrollable()) {
2755 return closest_scroll_node->id ==
2756 first_scrolling_layer_or_drawn_scrollbar->scroll_tree_index();
2757 }
2758
2759 // If |first_scrolling_layer_or_drawn_scrollbar| is not scrollable, it must
2760 // be a drawn scrollbar. These hit tests require falling back to main-thread
2761 // scrolling.
2762 DCHECK(first_scrolling_layer_or_drawn_scrollbar->IsDrawnScrollbar());
2763 return false;
2764 }
2765
2757 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( 2766 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
2758 const gfx::Point& viewport_point) { 2767 const gfx::Point& viewport_point) {
2759 InputHandler::ScrollStatus scroll_status; 2768 InputHandler::ScrollStatus scroll_status;
2760 scroll_status.main_thread_scrolling_reasons = 2769 scroll_status.main_thread_scrolling_reasons =
2761 MainThreadScrollingReason::kNotScrollingOnMain; 2770 MainThreadScrollingReason::kNotScrollingOnMain;
2762 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; 2771 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
2763 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); 2772 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
2764 if (scroll_node) { 2773 if (scroll_node) {
2765 gfx::Vector2dF delta; 2774 gfx::Vector2dF delta;
2766 2775
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 worker_context_visibility_ = 4149 worker_context_visibility_ =
4141 worker_context->CacheController()->ClientBecameVisible(); 4150 worker_context->CacheController()->ClientBecameVisible();
4142 } else { 4151 } else {
4143 worker_context->CacheController()->ClientBecameNotVisible( 4152 worker_context->CacheController()->ClientBecameNotVisible(
4144 std::move(worker_context_visibility_)); 4153 std::move(worker_context_visibility_));
4145 } 4154 }
4146 } 4155 }
4147 } 4156 }
4148 4157
4149 } // namespace cc 4158 } // 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