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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "cc/debug/benchmark_instrumentation.h" | 27 #include "cc/debug/benchmark_instrumentation.h" |
28 #include "cc/debug/debug_rect_history.h" | 28 #include "cc/debug/debug_rect_history.h" |
29 #include "cc/debug/devtools_instrumentation.h" | 29 #include "cc/debug/devtools_instrumentation.h" |
30 #include "cc/debug/frame_rate_counter.h" | 30 #include "cc/debug/frame_rate_counter.h" |
31 #include "cc/debug/frame_viewer_instrumentation.h" | 31 #include "cc/debug/frame_viewer_instrumentation.h" |
32 #include "cc/debug/paint_time_counter.h" | 32 #include "cc/debug/paint_time_counter.h" |
33 #include "cc/debug/rendering_stats_instrumentation.h" | 33 #include "cc/debug/rendering_stats_instrumentation.h" |
34 #include "cc/debug/traced_value.h" | 34 #include "cc/debug/traced_value.h" |
35 #include "cc/input/page_scale_animation.h" | 35 #include "cc/input/page_scale_animation.h" |
36 #include "cc/input/scroll_elasticity_helper.h" | 36 #include "cc/input/scroll_elasticity_helper.h" |
| 37 #include "cc/input/scroll_state.h" |
37 #include "cc/input/top_controls_manager.h" | 38 #include "cc/input/top_controls_manager.h" |
38 #include "cc/layers/append_quads_data.h" | 39 #include "cc/layers/append_quads_data.h" |
39 #include "cc/layers/heads_up_display_layer_impl.h" | 40 #include "cc/layers/heads_up_display_layer_impl.h" |
40 #include "cc/layers/layer_impl.h" | 41 #include "cc/layers/layer_impl.h" |
41 #include "cc/layers/layer_iterator.h" | 42 #include "cc/layers/layer_iterator.h" |
42 #include "cc/layers/painted_scrollbar_layer_impl.h" | 43 #include "cc/layers/painted_scrollbar_layer_impl.h" |
43 #include "cc/layers/render_surface_impl.h" | 44 #include "cc/layers/render_surface_impl.h" |
44 #include "cc/layers/scrollbar_layer_impl_base.h" | 45 #include "cc/layers/scrollbar_layer_impl_base.h" |
45 #include "cc/layers/viewport.h" | 46 #include "cc/layers/viewport.h" |
46 #include "cc/output/compositor_frame_metadata.h" | 47 #include "cc/output/compositor_frame_metadata.h" |
(...skipping 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2433 static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) { | 2434 static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) { |
2434 DCHECK(scroll_ancestor); | 2435 DCHECK(scroll_ancestor); |
2435 for (LayerImpl* ancestor = child; ancestor; | 2436 for (LayerImpl* ancestor = child; ancestor; |
2436 ancestor = NextScrollLayer(ancestor)) { | 2437 ancestor = NextScrollLayer(ancestor)) { |
2437 if (ancestor->scrollable()) | 2438 if (ancestor->scrollable()) |
2438 return ancestor == scroll_ancestor; | 2439 return ancestor == scroll_ancestor; |
2439 } | 2440 } |
2440 return false; | 2441 return false; |
2441 } | 2442 } |
2442 | 2443 |
| 2444 static LayerImpl* nextLayerInScrollOrder(LayerImpl* layer) { |
| 2445 if (layer->scroll_parent()) |
| 2446 return layer->scroll_parent(); |
| 2447 |
| 2448 return layer->parent(); |
| 2449 } |
| 2450 |
2443 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( | 2451 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( |
2444 LayerImpl* scrolling_layer_impl, | 2452 LayerImpl* scrolling_layer_impl, |
2445 InputHandler::ScrollInputType type) { | 2453 InputHandler::ScrollInputType type) { |
2446 if (!scrolling_layer_impl) | 2454 if (!scrolling_layer_impl) |
2447 return SCROLL_IGNORED; | 2455 return SCROLL_IGNORED; |
2448 | 2456 |
2449 top_controls_manager_->ScrollBegin(); | 2457 top_controls_manager_->ScrollBegin(); |
2450 | 2458 |
2451 active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl); | 2459 active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl); |
2452 should_bubble_scrolls_ = (type != NON_BUBBLING_GESTURE); | 2460 should_bubble_scrolls_ = (type != NON_BUBBLING_GESTURE); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 // finger. In contrast, events not representing direct manipulation of the | 2647 // finger. In contrast, events not representing direct manipulation of the |
2640 // screen (such as wheel events) represent a fixed amount of scrolling so we | 2648 // screen (such as wheel events) represent a fixed amount of scrolling so we |
2641 // can just apply them directly, but the page scale factor is applied to the | 2649 // can just apply them directly, but the page scale factor is applied to the |
2642 // scroll delta. | 2650 // scroll delta. |
2643 if (is_direct_manipulation) | 2651 if (is_direct_manipulation) |
2644 return ScrollLayerWithViewportSpaceDelta(layer_impl, viewport_point, delta); | 2652 return ScrollLayerWithViewportSpaceDelta(layer_impl, viewport_point, delta); |
2645 float scale_factor = active_tree()->current_page_scale_factor(); | 2653 float scale_factor = active_tree()->current_page_scale_factor(); |
2646 return ScrollLayerWithLocalDelta(layer_impl, delta, scale_factor); | 2654 return ScrollLayerWithLocalDelta(layer_impl, delta, scale_factor); |
2647 } | 2655 } |
2648 | 2656 |
2649 static LayerImpl* nextLayerInScrollOrder(LayerImpl* layer) { | 2657 void LayerTreeHostImpl::ApplyScroll(LayerImpl* layer, |
2650 if (layer->scroll_parent()) | 2658 ScrollState* scroll_state) { |
2651 return layer->scroll_parent(); | 2659 DCHECK(scroll_state); |
| 2660 gfx::Point viewport_point(scroll_state->start_position_x(), |
| 2661 scroll_state->start_position_y()); |
| 2662 const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y()); |
| 2663 gfx::Vector2dF applied_delta; |
| 2664 // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for |
| 2665 // details. |
| 2666 const float kEpsilon = 0.1f; |
2652 | 2667 |
2653 return layer->parent(); | 2668 if (layer == InnerViewportScrollLayer()) { |
| 2669 bool affect_top_controls = !wheel_scrolling_; |
| 2670 Viewport::ScrollResult result = viewport()->ScrollBy( |
| 2671 delta, viewport_point, scroll_state->is_direct_manipulation(), |
| 2672 affect_top_controls); |
| 2673 applied_delta = result.consumed_delta; |
| 2674 scroll_state->set_caused_scroll( |
| 2675 std::abs(result.content_scrolled_delta.x()) > kEpsilon, |
| 2676 std::abs(result.content_scrolled_delta.y()) > kEpsilon); |
| 2677 scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); |
| 2678 } else { |
| 2679 applied_delta = ScrollLayer(layer, delta, viewport_point, |
| 2680 scroll_state->is_direct_manipulation()); |
| 2681 } |
| 2682 |
| 2683 // If the layer wasn't able to move, try the next one in the hierarchy. |
| 2684 bool scrolled = std::abs(applied_delta.x()) > kEpsilon; |
| 2685 scrolled = scrolled || std::abs(applied_delta.y()) > kEpsilon; |
| 2686 |
| 2687 if (scrolled && layer != InnerViewportScrollLayer()) { |
| 2688 // If the applied delta is within 45 degrees of the input |
| 2689 // delta, bail out to make it easier to scroll just one layer |
| 2690 // in one direction without affecting any of its parents. |
| 2691 float angle_threshold = 45; |
| 2692 if (MathUtil::SmallestAngleBetweenVectors(applied_delta, delta) < |
| 2693 angle_threshold) { |
| 2694 applied_delta = delta; |
| 2695 } else { |
| 2696 // Allow further movement only on an axis perpendicular to the direction |
| 2697 // in which the layer moved. |
| 2698 applied_delta = MathUtil::ProjectVector(delta, applied_delta); |
| 2699 } |
| 2700 scroll_state->set_caused_scroll(std::abs(applied_delta.x()) > kEpsilon, |
| 2701 std::abs(applied_delta.y()) > kEpsilon); |
| 2702 scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); |
| 2703 } |
| 2704 |
| 2705 if (!scrolled) |
| 2706 return; |
| 2707 // When scrolls are allowed to bubble, it's important that the original |
| 2708 // scrolling layer be preserved. This ensures that, after a scroll |
| 2709 // bubbles, the user can reverse scroll directions and immediately resume |
| 2710 // scrolling the original layer that scrolled. |
| 2711 if (!scroll_state->should_propagate()) |
| 2712 scroll_state->set_current_native_scrolling_layer(layer); |
2654 } | 2713 } |
2655 | 2714 |
2656 InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( | 2715 InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( |
2657 const gfx::Point& viewport_point, | 2716 const gfx::Point& viewport_point, |
2658 const gfx::Vector2dF& scroll_delta) { | 2717 const gfx::Vector2dF& scroll_delta) { |
2659 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); | 2718 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); |
2660 if (!CurrentlyScrollingLayer()) | 2719 if (!CurrentlyScrollingLayer()) |
2661 return InputHandlerScrollResult(); | 2720 return InputHandlerScrollResult(); |
2662 | 2721 |
2663 gfx::Vector2dF pending_delta = scroll_delta; | |
2664 gfx::Vector2dF unused_root_delta; | |
2665 bool did_scroll_x = false; | |
2666 bool did_scroll_y = false; | |
2667 float initial_top_controls_offset = | |
2668 top_controls_manager_->ControlsTopOffset(); | |
2669 | |
2670 if (pinch_gesture_active_ && settings().invert_viewport_scroll_order) { | 2722 if (pinch_gesture_active_ && settings().invert_viewport_scroll_order) { |
2671 // Scrolls during a pinch gesture should pan the visual viewport, rather | 2723 // Scrolls during a pinch gesture should pan the visual viewport, rather |
2672 // than a typical bubbling scroll. | 2724 // than a typical bubbling scroll. |
2673 viewport()->Pan(pending_delta); | 2725 viewport()->Pan(scroll_delta); |
2674 return InputHandlerScrollResult(); | 2726 return InputHandlerScrollResult(); |
2675 } | 2727 } |
2676 | 2728 |
2677 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); | 2729 float initial_top_controls_offset = |
2678 layer_impl; | 2730 top_controls_manager_->ControlsTopOffset(); |
| 2731 ScrollState scroll_state( |
| 2732 scroll_delta.x(), scroll_delta.y(), viewport_point.x(), |
| 2733 viewport_point.y(), should_bubble_scrolls_ /* should_propagate */, |
| 2734 did_lock_scrolling_layer_ /* delta_consumed_for_scroll_sequence */, |
| 2735 !wheel_scrolling_ /* is_direct_manipulation */); |
| 2736 scroll_state.set_current_native_scrolling_layer(CurrentlyScrollingLayer()); |
| 2737 |
| 2738 std::list<LayerImpl*> current_scroll_chain; |
| 2739 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl; |
2679 layer_impl = nextLayerInScrollOrder(layer_impl)) { | 2740 layer_impl = nextLayerInScrollOrder(layer_impl)) { |
2680 // Skip the outer viewport scroll layer so that we try to scroll the | 2741 // Skip the outer viewport scroll layer so that we try to scroll the |
2681 // viewport only once. i.e. The inner viewport layer represents the | 2742 // viewport only once. i.e. The inner viewport layer represents the |
2682 // viewport. | 2743 // viewport. |
2683 if (!layer_impl->scrollable() || layer_impl == OuterViewportScrollLayer()) | 2744 if (!layer_impl->scrollable() || layer_impl == OuterViewportScrollLayer()) |
2684 continue; | 2745 continue; |
| 2746 current_scroll_chain.push_front(layer_impl); |
| 2747 } |
| 2748 scroll_state.set_scroll_chain(current_scroll_chain); |
| 2749 scroll_state.DistributeToScrollChainDescendant(); |
2685 | 2750 |
2686 gfx::Vector2dF applied_delta; | 2751 active_tree_->SetCurrentlyScrollingLayer( |
2687 if (layer_impl == InnerViewportScrollLayer()) { | 2752 scroll_state.current_native_scrolling_layer()); |
2688 // Each wheel event triggers a ScrollBegin/Update/End. This can interact | 2753 did_lock_scrolling_layer_ = scroll_state.delta_consumed_for_scroll_sequence(); |
2689 // poorly with the top controls animation, which is triggered after each | |
2690 // call to ScrollEnd. | |
2691 bool affect_top_controls = !wheel_scrolling_; | |
2692 Viewport::ScrollResult result = | |
2693 viewport()->ScrollBy(pending_delta, viewport_point, !wheel_scrolling_, | |
2694 affect_top_controls); | |
2695 applied_delta = result.content_scrolled_delta; | |
2696 unused_root_delta = pending_delta - result.consumed_delta; | |
2697 } else { | |
2698 applied_delta = ScrollLayer(layer_impl, pending_delta, viewport_point, | |
2699 !wheel_scrolling_); | |
2700 } | |
2701 | 2754 |
2702 // If the layer wasn't able to move, try the next one in the hierarchy. | 2755 bool did_scroll_x = scroll_state.caused_scroll_x(); |
2703 const float kEpsilon = 0.1f; | 2756 bool did_scroll_y = scroll_state.caused_scroll_y(); |
2704 bool did_move_layer_x = std::abs(applied_delta.x()) > kEpsilon; | |
2705 bool did_move_layer_y = std::abs(applied_delta.y()) > kEpsilon; | |
2706 did_scroll_x |= did_move_layer_x; | |
2707 did_scroll_y |= did_move_layer_y; | |
2708 | |
2709 if (did_move_layer_x || did_move_layer_y) { | |
2710 did_lock_scrolling_layer_ = true; | |
2711 | |
2712 // When scrolls are allowed to bubble, it's important that the original | |
2713 // scrolling layer be preserved. This ensures that, after a scroll | |
2714 // bubbles, the user can reverse scroll directions and immediately resume | |
2715 // scrolling the original layer that scrolled. | |
2716 if (!should_bubble_scrolls_) { | |
2717 active_tree_->SetCurrentlyScrollingLayer(layer_impl); | |
2718 break; | |
2719 } | |
2720 | |
2721 // If the applied delta is within 45 degrees of the input delta, bail out | |
2722 // to make it easier to scroll just one layer in one direction without | |
2723 // affecting any of its parents. | |
2724 float angle_threshold = 45; | |
2725 if (MathUtil::SmallestAngleBetweenVectors(applied_delta, pending_delta) < | |
2726 angle_threshold) | |
2727 break; | |
2728 | |
2729 // Allow further movement only on an axis perpendicular to the direction | |
2730 // in which the layer moved. | |
2731 gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x()); | |
2732 pending_delta = | |
2733 MathUtil::ProjectVector(pending_delta, perpendicular_axis); | |
2734 | |
2735 if (gfx::ToRoundedVector2d(pending_delta).IsZero()) | |
2736 break; | |
2737 } | |
2738 | |
2739 if (!should_bubble_scrolls_ && did_lock_scrolling_layer_) | |
2740 break; | |
2741 } | |
2742 | |
2743 bool did_scroll_content = did_scroll_x || did_scroll_y; | 2757 bool did_scroll_content = did_scroll_x || did_scroll_y; |
2744 if (did_scroll_content) { | 2758 if (did_scroll_content) { |
2745 // If we are scrolling with an active scroll handler, forward latency | 2759 // If we are scrolling with an active scroll handler, forward latency |
2746 // tracking information to the main thread so the delay introduced by the | 2760 // tracking information to the main thread so the delay introduced by the |
2747 // handler is accounted for. | 2761 // handler is accounted for. |
2748 if (scroll_affects_scroll_handler()) | 2762 if (scroll_affects_scroll_handler()) |
2749 NotifySwapPromiseMonitorsOfForwardingToMainThread(); | 2763 NotifySwapPromiseMonitorsOfForwardingToMainThread(); |
2750 client_->SetNeedsCommitOnImplThread(); | 2764 client_->SetNeedsCommitOnImplThread(); |
2751 SetNeedsRedraw(); | 2765 SetNeedsRedraw(); |
2752 client_->RenewTreePriority(); | 2766 client_->RenewTreePriority(); |
2753 } | 2767 } |
2754 | 2768 |
2755 // Scrolling along an axis resets accumulated root overscroll for that axis. | 2769 // Scrolling along an axis resets accumulated root overscroll for that axis. |
2756 if (did_scroll_x) | 2770 if (did_scroll_x) |
2757 accumulated_root_overscroll_.set_x(0); | 2771 accumulated_root_overscroll_.set_x(0); |
2758 if (did_scroll_y) | 2772 if (did_scroll_y) |
2759 accumulated_root_overscroll_.set_y(0); | 2773 accumulated_root_overscroll_.set_y(0); |
| 2774 gfx::Vector2dF unused_root_delta(scroll_state.delta_x(), |
| 2775 scroll_state.delta_y()); |
2760 accumulated_root_overscroll_ += unused_root_delta; | 2776 accumulated_root_overscroll_ += unused_root_delta; |
2761 | 2777 |
2762 bool did_scroll_top_controls = | 2778 bool did_scroll_top_controls = |
2763 initial_top_controls_offset != top_controls_manager_->ControlsTopOffset(); | 2779 initial_top_controls_offset != top_controls_manager_->ControlsTopOffset(); |
2764 | 2780 |
2765 InputHandlerScrollResult scroll_result; | 2781 InputHandlerScrollResult scroll_result; |
2766 scroll_result.did_scroll = did_scroll_content || did_scroll_top_controls; | 2782 scroll_result.did_scroll = did_scroll_content || did_scroll_top_controls; |
2767 scroll_result.did_overscroll_root = !unused_root_delta.IsZero(); | 2783 scroll_result.did_overscroll_root = !unused_root_delta.IsZero(); |
2768 scroll_result.accumulated_root_overscroll = accumulated_root_overscroll_; | 2784 scroll_result.accumulated_root_overscroll = accumulated_root_overscroll_; |
2769 scroll_result.unused_scroll_delta = unused_root_delta; | 2785 scroll_result.unused_scroll_delta = unused_root_delta; |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3614 if (active_tree()) { | 3630 if (active_tree()) { |
3615 LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id); | 3631 LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id); |
3616 if (layer) | 3632 if (layer) |
3617 return layer->ScrollOffsetForAnimation(); | 3633 return layer->ScrollOffsetForAnimation(); |
3618 } | 3634 } |
3619 | 3635 |
3620 return gfx::ScrollOffset(); | 3636 return gfx::ScrollOffset(); |
3621 } | 3637 } |
3622 | 3638 |
3623 } // namespace cc | 3639 } // namespace cc |
OLD | NEW |