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

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

Issue 1215183004: Arrange compositor scrolling into scroll customization format (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nit. Created 5 years, 4 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_impl.h » ('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 <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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_impl.h ('k') | cc/trees/layer_tree_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698