| 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 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |