| Index: cc/trees/layer_tree_host_impl.cc
|
| diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
| index c03f7f79528ed0ed244c2fd301763b2bdfe97f20..6cdef42568a83b0215ad6165e8e6a2305de3a34a 100644
|
| --- a/cc/trees/layer_tree_host_impl.cc
|
| +++ b/cc/trees/layer_tree_host_impl.cc
|
| @@ -38,6 +38,7 @@
|
| #include "cc/layers/painted_scrollbar_layer_impl.h"
|
| #include "cc/layers/render_surface_impl.h"
|
| #include "cc/layers/scrollbar_layer_impl_base.h"
|
| +#include "cc/layers/viewport.h"
|
| #include "cc/output/compositor_frame_metadata.h"
|
| #include "cc/output/copy_output_request.h"
|
| #include "cc/output/delegating_renderer.h"
|
| @@ -2476,7 +2477,6 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
|
|
|
| gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
|
| LayerImpl* layer_impl,
|
| - float scale_from_viewport_to_screen_space,
|
| const gfx::PointF& viewport_point,
|
| const gfx::Vector2dF& viewport_delta) {
|
| // Layers with non-invertible screen space transforms should not have passed
|
| @@ -2490,6 +2490,7 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
|
| // layers, we may need to explicitly handle uninvertible transforms here.
|
| DCHECK(did_invert);
|
|
|
| + float scale_from_viewport_to_screen_space = device_scale_factor_;
|
| gfx::PointF screen_space_point =
|
| gfx::ScalePoint(viewport_point, scale_from_viewport_to_screen_space);
|
|
|
| @@ -2551,10 +2552,10 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
|
| return actual_viewport_end_point - viewport_point;
|
| }
|
|
|
| -static gfx::Vector2dF ScrollLayerWithLocalDelta(
|
| +gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithLocalDelta(
|
| LayerImpl* layer_impl,
|
| const gfx::Vector2dF& local_delta,
|
| - float page_scale_factor) {
|
| + float page_scale_factor) const {
|
| gfx::ScrollOffset previous_offset = layer_impl->CurrentScrollOffset();
|
| gfx::Vector2dF delta = local_delta;
|
| delta.Scale(1.f / page_scale_factor);
|
| @@ -2564,24 +2565,6 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(
|
| return gfx::Vector2dF(scrolled.x(), scrolled.y());
|
| }
|
|
|
| -bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll(
|
| - const gfx::Vector2dF& scroll_delta) const {
|
| - DCHECK(CurrentlyScrollingLayer());
|
| -
|
| - if (!top_controls_manager_)
|
| - return false;
|
| -
|
| - // Always consume if it's in the direction to show the top controls.
|
| - if (scroll_delta.y() < 0)
|
| - return true;
|
| -
|
| - if (active_tree()->TotalScrollOffset().y() <
|
| - active_tree()->TotalMaxScrollOffset().y())
|
| - return true;
|
| -
|
| - return false;
|
| -}
|
| -
|
| InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
|
| const gfx::Point& viewport_point,
|
| const gfx::Vector2dF& scroll_delta) {
|
| @@ -2593,130 +2576,75 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
|
| gfx::Vector2dF unused_root_delta;
|
| bool did_scroll_x = false;
|
| bool did_scroll_y = false;
|
| - bool did_scroll_top_controls = false;
|
| -
|
| - bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta);
|
| -
|
| - // There's an edge case where the outer viewport isn't scrollable when the
|
| - // scroll starts, however, as the top controls show the outer viewport becomes
|
| - // scrollable. Therefore, always try scrolling the outer viewport before the
|
| - // inner.
|
| - // TODO(bokan): Move the top controls logic out of the loop since the scroll
|
| - // that causes the outer viewport to become scrollable will still be applied
|
| - // to the inner viewport.
|
| - LayerImpl* start_layer = CurrentlyScrollingLayer();
|
| - if (start_layer == InnerViewportScrollLayer() && OuterViewportScrollLayer())
|
| - start_layer = OuterViewportScrollLayer();
|
| -
|
| - for (LayerImpl* layer_impl = start_layer;
|
| +
|
| + for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
|
| layer_impl;
|
| layer_impl = layer_impl->parent()) {
|
| if (!layer_impl->scrollable())
|
| continue;
|
|
|
| - if (layer_impl == InnerViewportScrollLayer() ||
|
| - layer_impl == OuterViewportScrollLayer()) {
|
| - if (consume_by_top_controls) {
|
| - gfx::Vector2dF excess_delta =
|
| - top_controls_manager_->ScrollBy(pending_delta);
|
| - gfx::Vector2dF applied_delta = pending_delta - excess_delta;
|
| - pending_delta = excess_delta;
|
| - // Force updating of vertical adjust values if needed.
|
| - if (applied_delta.y() != 0)
|
| - did_scroll_top_controls = true;
|
| - }
|
| - // Track root layer deltas for reporting overscroll.
|
| - if (layer_impl == InnerViewportScrollLayer())
|
| - unused_root_delta = pending_delta;
|
| - }
|
| -
|
| gfx::Vector2dF applied_delta;
|
| - // Gesture events need to be transformed from viewport coordinates to local
|
| - // layer coordinates so that the scrolling contents exactly follow the
|
| - // user's finger. In contrast, wheel events represent a fixed amount of
|
| - // scrolling so we can just apply them directly, but the page scale factor
|
| - // is applied to the scroll delta.
|
| - if (!wheel_scrolling_) {
|
| - float scale_from_viewport_to_screen_space = device_scale_factor_;
|
| - applied_delta =
|
| - ScrollLayerWithViewportSpaceDelta(layer_impl,
|
| - scale_from_viewport_to_screen_space,
|
| - viewport_point, pending_delta);
|
| - } else {
|
| - applied_delta = ScrollLayerWithLocalDelta(
|
| - layer_impl, pending_delta, active_tree_->current_page_scale_factor());
|
| - }
|
| -
|
| - const float kEpsilon = 0.1f;
|
| - if (layer_impl == InnerViewportScrollLayer()) {
|
| - unused_root_delta.Subtract(applied_delta);
|
| - if (std::abs(unused_root_delta.x()) < kEpsilon)
|
| - unused_root_delta.set_x(0.0f);
|
| - if (std::abs(unused_root_delta.y()) < kEpsilon)
|
| - unused_root_delta.set_y(0.0f);
|
| - // Disable overscroll on axes which is impossible to scroll.
|
| - if (settings_.report_overscroll_only_for_scrollable_axes) {
|
| - if (std::abs(active_tree_->TotalMaxScrollOffset().x()) <= kEpsilon ||
|
| - !layer_impl->user_scrollable_horizontal())
|
| - unused_root_delta.set_x(0.0f);
|
| - if (std::abs(active_tree_->TotalMaxScrollOffset().y()) <= kEpsilon ||
|
| - !layer_impl->user_scrollable_vertical())
|
| - unused_root_delta.set_y(0.0f);
|
| + if (Viewport()->IsViewportScrollingLayer(layer_impl)) {
|
| + Viewport::ScrollResult result = Viewport()->ScrollBy(pending_delta,
|
| + viewport_point,
|
| + wheel_scrolling_);
|
| + applied_delta = result.applied_delta;
|
| + unused_root_delta = result.unused_scroll_delta;
|
| + } else if (!Viewport()->IsViewportLayer(layer_impl)) {
|
| + // Gesture events need to be transformed from viewport coordinates to
|
| + // local layer coordinates so that the scrolling contents exactly follow
|
| + // the user's finger. In contrast, wheel events represent a fixed amount
|
| + // of scrolling so we can just apply them directly, but the page scale
|
| + // factor is applied to the scroll delta.
|
| + if (!wheel_scrolling_) {
|
| + applied_delta =
|
| + ScrollLayerWithViewportSpaceDelta(layer_impl,
|
| + viewport_point,
|
| + pending_delta);
|
| + } else {
|
| + applied_delta = ScrollLayerWithLocalDelta(
|
| + layer_impl,
|
| + pending_delta,
|
| + active_tree_->current_page_scale_factor());
|
| }
|
| }
|
|
|
| - // Scrolls should bubble perfectly between the outer and inner viewports.
|
| - bool allow_unrestricted_bubbling_for_current_layer =
|
| - layer_impl == OuterViewportScrollLayer();
|
| - bool allow_bubbling_for_current_layer =
|
| - allow_unrestricted_bubbling_for_current_layer || should_bubble_scrolls_;
|
| -
|
| // If the layer wasn't able to move, try the next one in the hierarchy.
|
| + const float kEpsilon = 0.1f;
|
| bool did_move_layer_x = std::abs(applied_delta.x()) > kEpsilon;
|
| bool did_move_layer_y = std::abs(applied_delta.y()) > kEpsilon;
|
| did_scroll_x |= did_move_layer_x;
|
| did_scroll_y |= did_move_layer_y;
|
| - if (!did_move_layer_x && !did_move_layer_y) {
|
| - if (allow_bubbling_for_current_layer || !did_lock_scrolling_layer_)
|
| - continue;
|
| - else
|
| - break;
|
| - }
|
| -
|
| - did_lock_scrolling_layer_ = true;
|
|
|
| - // When scrolls are allowed to bubble, it's important that the original
|
| - // scrolling layer be preserved. This ensures that, after a scroll bubbles,
|
| - // the user can reverse scroll directions and immediately resume scrolling
|
| - // the original layer that scrolled.
|
| - if (!should_bubble_scrolls_)
|
| - active_tree_->SetCurrentlyScrollingLayer(layer_impl);
|
| + if (did_move_layer_x || did_move_layer_y) {
|
| + did_lock_scrolling_layer_ = true;
|
|
|
| - if (!allow_bubbling_for_current_layer)
|
| - break;
|
| + // When scrolls are allowed to bubble, it's important that the original
|
| + // scrolling layer be preserved. This ensures that, after a scroll
|
| + // bubbles, the user can reverse scroll directions and immediately resume
|
| + // scrolling the original layer that scrolled.
|
| + if (!should_bubble_scrolls_) {
|
| + active_tree_->SetCurrentlyScrollingLayer(layer_impl);
|
| + break;
|
| + }
|
|
|
| - if (allow_unrestricted_bubbling_for_current_layer) {
|
| - pending_delta -= applied_delta;
|
| - } else {
|
| // If the applied delta is within 45 degrees of the input delta, bail out
|
| // to make it easier to scroll just one layer in one direction without
|
| // affecting any of its parents.
|
| float angle_threshold = 45;
|
| if (MathUtil::SmallestAngleBetweenVectors(applied_delta, pending_delta) <
|
| - angle_threshold) {
|
| - pending_delta = gfx::Vector2dF();
|
| + angle_threshold)
|
| break;
|
| - }
|
|
|
| // Allow further movement only on an axis perpendicular to the direction
|
| // in which the layer moved.
|
| gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
|
| pending_delta =
|
| MathUtil::ProjectVector(pending_delta, perpendicular_axis);
|
| - }
|
|
|
| - if (gfx::ToRoundedVector2d(pending_delta).IsZero())
|
| - break;
|
| + if (gfx::ToRoundedVector2d(pending_delta).IsZero())
|
| + break;
|
| + }
|
| }
|
|
|
| bool did_scroll_content = did_scroll_x || did_scroll_y;
|
| @@ -2739,7 +2667,7 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
|
| accumulated_root_overscroll_ += unused_root_delta;
|
|
|
| InputHandlerScrollResult scroll_result;
|
| - scroll_result.did_scroll = did_scroll_content || did_scroll_top_controls;
|
| + scroll_result.did_scroll = did_scroll_content;
|
| scroll_result.did_overscroll_root = !unused_root_delta.IsZero();
|
| scroll_result.accumulated_root_overscroll = accumulated_root_overscroll_;
|
| scroll_result.unused_scroll_delta = unused_root_delta;
|
| @@ -3468,4 +3396,8 @@ void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfForwardingToMainThread() {
|
| (*it)->OnForwardScrollUpdateToMainThreadOnImpl();
|
| }
|
|
|
| +Viewport* LayerTreeHostImpl::Viewport() {
|
| + return active_tree_->viewport();
|
| +}
|
| +
|
| } // namespace cc
|
|
|