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 |