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

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

Issue 2707783003: Refactor viewport scrolling decisions to use ScrollNodes over layer ids (Closed)
Patch Set: Created 3 years, 10 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 | « no previous file | no next file » | 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 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 LayerImpl* layer_impl, 2561 LayerImpl* layer_impl,
2562 bool* scroll_on_main_thread, 2562 bool* scroll_on_main_thread,
2563 uint32_t* main_thread_scrolling_reasons) const { 2563 uint32_t* main_thread_scrolling_reasons) const {
2564 DCHECK(scroll_on_main_thread); 2564 DCHECK(scroll_on_main_thread);
2565 DCHECK(main_thread_scrolling_reasons); 2565 DCHECK(main_thread_scrolling_reasons);
2566 *main_thread_scrolling_reasons = 2566 *main_thread_scrolling_reasons =
2567 MainThreadScrollingReason::kNotScrollingOnMain; 2567 MainThreadScrollingReason::kNotScrollingOnMain;
2568 2568
2569 // Walk up the hierarchy and look for a scrollable layer. 2569 // Walk up the hierarchy and look for a scrollable layer.
2570 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; 2570 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
2571 LayerImpl* potentially_scrolling_layer_impl = nullptr; 2571 ScrollNode* impl_scroll_node = nullptr;
2572 if (layer_impl) { 2572 if (layer_impl) {
2573 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); 2573 ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index());
2574 for (; scroll_tree.parent(scroll_node); 2574 for (; scroll_tree.parent(scroll_node);
2575 scroll_node = scroll_tree.parent(scroll_node)) { 2575 scroll_node = scroll_tree.parent(scroll_node)) {
2576 // The content layer can also block attempts to scroll outside the main 2576 // The content layer can also block attempts to scroll outside the main
2577 // thread. 2577 // thread.
2578 ScrollStatus status = 2578 ScrollStatus status =
2579 TryScroll(device_viewport_point, type, scroll_tree, scroll_node); 2579 TryScroll(device_viewport_point, type, scroll_tree, scroll_node);
2580 if (IsMainThreadScrolling(status, scroll_node)) { 2580 if (IsMainThreadScrolling(status, scroll_node)) {
2581 *scroll_on_main_thread = true; 2581 *scroll_on_main_thread = true;
2582 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; 2582 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons;
2583 return active_tree_->LayerById(scroll_node->owning_layer_id); 2583 return active_tree_->LayerById(scroll_node->owning_layer_id);
2584 } 2584 }
2585 2585
2586 if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && 2586 if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD &&
2587 !potentially_scrolling_layer_impl) { 2587 !impl_scroll_node) {
2588 potentially_scrolling_layer_impl = 2588 impl_scroll_node = scroll_node;
2589 active_tree_->LayerById(scroll_node->owning_layer_id);
2590 } 2589 }
2591 } 2590 }
2592 } 2591 }
2593 2592
2594 // Falling back to the viewport layer ensures generation of root overscroll 2593 // Falling back to the viewport layer ensures generation of root overscroll
2595 // notifications. We use the viewport's main scroll layer to represent the 2594 // notifications. We use the viewport's main scroll layer to represent the
2596 // viewport in scrolling code. 2595 // viewport in scrolling code.
2597 if (!potentially_scrolling_layer_impl || 2596 bool scrolls_inner_viewport =
2598 potentially_scrolling_layer_impl == OuterViewportScrollLayer() || 2597 impl_scroll_node && InnerViewportScrollLayer() &&
2599 potentially_scrolling_layer_impl == InnerViewportScrollLayer()) { 2598 InnerViewportScrollLayer()->scroll_tree_index() == impl_scroll_node->id;
2600 potentially_scrolling_layer_impl = viewport()->MainScrollLayer(); 2599 bool scrolls_outer_viewport =
2600 impl_scroll_node && OuterViewportScrollLayer() &&
2601 OuterViewportScrollLayer()->scroll_tree_index() == impl_scroll_node->id;
2602 if (!impl_scroll_node || scrolls_inner_viewport || scrolls_outer_viewport) {
2603 if (auto* mainScrollLayer = viewport()->MainScrollLayer())
2604 impl_scroll_node = scroll_tree.Node(mainScrollLayer->scroll_tree_index());
2605 else
2606 impl_scroll_node = nullptr;
2601 } 2607 }
2602 2608
2603 if (potentially_scrolling_layer_impl) { 2609 if (impl_scroll_node) {
2604 // Ensure that final layer scrolls on impl thread (crbug.com/625100) 2610 // Ensure that final layer scrolls on impl thread (crbug.com/625100)
2605 ScrollNode* scroll_node =
2606 scroll_tree.Node(potentially_scrolling_layer_impl->scroll_tree_index());
2607 ScrollStatus status = 2611 ScrollStatus status =
2608 TryScroll(device_viewport_point, type, scroll_tree, scroll_node); 2612 TryScroll(device_viewport_point, type, scroll_tree, impl_scroll_node);
2609 if (IsMainThreadScrolling(status, scroll_node)) { 2613 if (IsMainThreadScrolling(status, impl_scroll_node)) {
2610 *scroll_on_main_thread = true; 2614 *scroll_on_main_thread = true;
2611 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; 2615 *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons;
2612 } 2616 }
2613 } 2617 }
2614 2618
2615 return potentially_scrolling_layer_impl; 2619 // TODO(pdr): Refactor this function to directly return |impl_scroll_node|
2620 // instead of using ScrollNode's owning_layer_id to return a LayerImpl.
2621 if (!impl_scroll_node)
2622 return nullptr;
2623 return active_tree_->LayerById(impl_scroll_node->owning_layer_id);
2616 } 2624 }
2617 2625
2618 static bool IsClosestScrollAncestor(LayerImpl* child, 2626 static bool IsClosestScrollAncestor(LayerImpl* child,
2619 LayerImpl* scroll_ancestor) { 2627 LayerImpl* scroll_ancestor) {
2620 DCHECK(scroll_ancestor); 2628 DCHECK(scroll_ancestor);
2621 if (!child) 2629 if (!child)
2622 return false; 2630 return false;
2623 ScrollTree& scroll_tree = 2631 ScrollTree& scroll_tree =
2624 child->layer_tree_impl()->property_trees()->scroll_tree; 2632 child->layer_tree_impl()->property_trees()->scroll_tree;
2625 ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index()); 2633 ScrollNode* scroll_node = scroll_tree.Node(child->scroll_tree_index());
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 scroll_state_data.position_x = viewport_point.x(); 2865 scroll_state_data.position_x = viewport_point.x();
2858 scroll_state_data.position_y = viewport_point.y(); 2866 scroll_state_data.position_y = viewport_point.y();
2859 ScrollState scroll_state(scroll_state_data); 2867 ScrollState scroll_state(scroll_state_data);
2860 2868
2861 // ScrollAnimated is used for animated wheel scrolls. We find the first layer 2869 // ScrollAnimated is used for animated wheel scrolls. We find the first layer
2862 // that can scroll and set up an animation of its scroll offset. Note that 2870 // that can scroll and set up an animation of its scroll offset. Note that
2863 // this does not currently go through the scroll customization machinery 2871 // this does not currently go through the scroll customization machinery
2864 // that ScrollBy uses for non-animated wheel scrolls. 2872 // that ScrollBy uses for non-animated wheel scrolls.
2865 scroll_status = ScrollBegin(&scroll_state, WHEEL); 2873 scroll_status = ScrollBegin(&scroll_state, WHEEL);
2866 scroll_node = scroll_tree.CurrentlyScrollingNode(); 2874 scroll_node = scroll_tree.CurrentlyScrollingNode();
2867 if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { 2875 if (scroll_status.thread == SCROLL_ON_IMPL_THREAD && scroll_node) {
2868 gfx::Vector2dF pending_delta = scroll_delta; 2876 gfx::Vector2dF pending_delta = scroll_delta;
2869 if (scroll_node) { 2877 for (; scroll_tree.parent(scroll_node);
2870 for (; scroll_tree.parent(scroll_node); 2878 scroll_node = scroll_tree.parent(scroll_node)) {
2871 scroll_node = scroll_tree.parent(scroll_node)) { 2879 if (!scroll_node->scrollable)
2872 if (!scroll_node->scrollable) 2880 continue;
2873 continue;
2874 2881
2875 if (viewport()->MainScrollLayer() && 2882 bool scrolls_main_viewport_scroll_layer =
2876 scroll_node->owning_layer_id == 2883 viewport()->MainScrollLayer() &&
2877 viewport()->MainScrollLayer()->id()) { 2884 viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id;
2878 gfx::Vector2dF scrolled = 2885 if (scrolls_main_viewport_scroll_layer) {
2879 viewport()->ScrollAnimated(pending_delta, delayed_by); 2886 gfx::Vector2dF scrolled =
2880 // Viewport::ScrollAnimated returns pending_delta as long as it 2887 viewport()->ScrollAnimated(pending_delta, delayed_by);
2881 // starts an animation. 2888 // Viewport::ScrollAnimated returns pending_delta as long as it starts
2882 if (scrolled == pending_delta) 2889 // an animation.
2883 return scroll_status; 2890 if (scrolled == pending_delta)
2884 break; 2891 return scroll_status;
2885 } 2892 break;
2893 }
2886 2894
2887 gfx::Vector2dF scroll_delta = 2895 gfx::Vector2dF scroll_delta =
2888 ComputeScrollDelta(scroll_node, pending_delta); 2896 ComputeScrollDelta(scroll_node, pending_delta);
2889 if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) 2897 if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by))
2890 return scroll_status; 2898 return scroll_status;
2891 2899
2892 pending_delta -= scroll_delta; 2900 pending_delta -= scroll_delta;
2893 }
2894 } 2901 }
2895 } 2902 }
2896 scroll_state.set_is_ending(true); 2903 scroll_state.set_is_ending(true);
2897 ScrollEnd(&scroll_state); 2904 ScrollEnd(&scroll_state);
2898 return scroll_status; 2905 return scroll_status;
2899 } 2906 }
2900 2907
2901 gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( 2908 gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta(
2902 ScrollNode* scroll_node, 2909 ScrollNode* scroll_node,
2903 const gfx::PointF& viewport_point, 2910 const gfx::PointF& viewport_point,
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 DCHECK(scroll_state); 3020 DCHECK(scroll_state);
3014 gfx::Point viewport_point(scroll_state->position_x(), 3021 gfx::Point viewport_point(scroll_state->position_x(),
3015 scroll_state->position_y()); 3022 scroll_state->position_y());
3016 const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y()); 3023 const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y());
3017 gfx::Vector2dF applied_delta; 3024 gfx::Vector2dF applied_delta;
3018 gfx::Vector2dF delta_applied_to_content; 3025 gfx::Vector2dF delta_applied_to_content;
3019 // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for 3026 // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for
3020 // details. 3027 // details.
3021 const float kEpsilon = 0.1f; 3028 const float kEpsilon = 0.1f;
3022 3029
3023 bool is_viewport_scroll_layer = 3030 bool scrolls_main_viewport_scroll_layer =
3024 viewport()->MainScrollLayer() && 3031 viewport()->MainScrollLayer() &&
3025 scroll_node->owning_layer_id == viewport()->MainScrollLayer()->id(); 3032 viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id;
3026 3033
3027 // This is needed if the scroll chains up to the viewport without going 3034 // This is needed if the scroll chains up to the viewport without going
3028 // through the outer viewport scroll layer. This can happen if we scroll an 3035 // through the outer viewport scroll node. This can happen if we scroll an
3029 // element that's not a descendant of the document.rootScroller. In that case 3036 // element that's not a descendant of the document.rootScroller. In that case
3030 // we want to scroll the inner viewport -- to allow panning while zoomed -- 3037 // we want to scroll the inner viewport -- to allow panning while zoomed --
3031 // but also move browser controls if needed. 3038 // but also move browser controls if needed.
3032 bool is_inner_viewport_scroll_layer = 3039 bool scrolls_inner_viewport_layer =
3033 InnerViewportScrollLayer() && 3040 InnerViewportScrollLayer() &&
3034 scroll_node->owning_layer_id == InnerViewportScrollLayer()->id(); 3041 InnerViewportScrollLayer()->scroll_tree_index() == scroll_node->id;
3035 3042
3036 if (is_viewport_scroll_layer || is_inner_viewport_scroll_layer) { 3043 if (scrolls_main_viewport_scroll_layer || scrolls_inner_viewport_layer) {
3037 Viewport::ScrollResult result = viewport()->ScrollBy( 3044 Viewport::ScrollResult result = viewport()->ScrollBy(
3038 delta, viewport_point, scroll_state->is_direct_manipulation(), 3045 delta, viewport_point, scroll_state->is_direct_manipulation(),
3039 !wheel_scrolling_, is_viewport_scroll_layer); 3046 !wheel_scrolling_, scrolls_main_viewport_scroll_layer);
3040 3047
3041 applied_delta = result.consumed_delta; 3048 applied_delta = result.consumed_delta;
3042 delta_applied_to_content = result.content_scrolled_delta; 3049 delta_applied_to_content = result.content_scrolled_delta;
3043 } else { 3050 } else {
3044 applied_delta = ScrollSingleNode( 3051 applied_delta = ScrollSingleNode(
3045 scroll_node, delta, viewport_point, 3052 scroll_node, delta, viewport_point,
3046 scroll_state->is_direct_manipulation(), 3053 scroll_state->is_direct_manipulation(),
3047 &scroll_state->layer_tree_impl()->property_trees()->scroll_tree); 3054 &scroll_state->layer_tree_impl()->property_trees()->scroll_tree);
3048 } 3055 }
3049 3056
3050 // If the layer wasn't able to move, try the next one in the hierarchy. 3057 // If the layer wasn't able to move, try the next one in the hierarchy.
3051 bool scrolled = std::abs(applied_delta.x()) > kEpsilon; 3058 bool scrolled = std::abs(applied_delta.x()) > kEpsilon;
3052 scrolled = scrolled || std::abs(applied_delta.y()) > kEpsilon; 3059 scrolled = scrolled || std::abs(applied_delta.y()) > kEpsilon;
3053 if (!scrolled) { 3060 if (!scrolled) {
3054 // TODO(bokan): This preserves existing behavior by not allowing tiny 3061 // TODO(bokan): This preserves existing behavior by not allowing tiny
3055 // scrolls to produce overscroll but is inconsistent in how delta gets 3062 // scrolls to produce overscroll but is inconsistent in how delta gets
3056 // chained up. We need to clean this up. 3063 // chained up. We need to clean this up.
3057 if (is_viewport_scroll_layer) 3064 if (scrolls_main_viewport_scroll_layer)
3058 scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); 3065 scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y());
3059 return; 3066 return;
3060 } 3067 }
3061 3068
3062 if (!is_viewport_scroll_layer && !is_inner_viewport_scroll_layer) { 3069 if (!scrolls_main_viewport_scroll_layer && !scrolls_inner_viewport_layer) {
3063 // If the applied delta is within 45 degrees of the input 3070 // If the applied delta is within 45 degrees of the input
3064 // delta, bail out to make it easier to scroll just one layer 3071 // delta, bail out to make it easier to scroll just one layer
3065 // in one direction without affecting any of its parents. 3072 // in one direction without affecting any of its parents.
3066 float angle_threshold = 45; 3073 float angle_threshold = 45;
3067 if (MathUtil::SmallestAngleBetweenVectors(applied_delta, delta) < 3074 if (MathUtil::SmallestAngleBetweenVectors(applied_delta, delta) <
3068 angle_threshold) { 3075 angle_threshold) {
3069 applied_delta = delta; 3076 applied_delta = delta;
3070 } else { 3077 } else {
3071 // Allow further movement only on an axis perpendicular to the direction 3078 // Allow further movement only on an axis perpendicular to the direction
3072 // in which the layer moved. 3079 // in which the layer moved.
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
4116 worker_context_visibility_ = 4123 worker_context_visibility_ =
4117 worker_context->CacheController()->ClientBecameVisible(); 4124 worker_context->CacheController()->ClientBecameVisible();
4118 } else { 4125 } else {
4119 worker_context->CacheController()->ClientBecameNotVisible( 4126 worker_context->CacheController()->ClientBecameNotVisible(
4120 std::move(worker_context_visibility_)); 4127 std::move(worker_context_visibility_));
4121 } 4128 }
4122 } 4129 }
4123 } 4130 }
4124 4131
4125 } // namespace cc 4132 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698