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

Unified Diff: cc/trees/layer_tree_host_impl.cc

Issue 986443003: Move viewport scrolling logic into separate class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: aelias feedback Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/trees/layer_tree_host_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2c13fcbc861f58e298a6a9c073f3eca33c4574f4..5eddc8faf3e78348b422498fb01f535d6fe6888a 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -39,6 +39,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"
@@ -240,6 +241,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
LayerTreeImpl::create(this, new SyncedProperty<ScaleGroup>(),
new SyncedTopControls, new SyncedElasticOverscroll);
+ viewport_ = Viewport::Create(this);
+
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_);
@@ -2477,7 +2480,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
@@ -2491,6 +2493,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);
@@ -2565,19 +2568,25 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(
return gfx::Vector2dF(scrolled.x(), scrolled.y());
}
-bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll(
- const gfx::Vector2dF& scroll_delta) const {
- DCHECK(CurrentlyScrollingLayer());
-
- // 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;
+gfx::Vector2dF LayerTreeHostImpl::ScrollLayer(LayerImpl* layer_impl,
+ const gfx::Vector2dF& delta,
+ const gfx::Point& viewport_point,
+ bool is_wheel_scroll) {
+ // 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 (is_wheel_scroll) {
+ float scale_factor = active_tree()->current_page_scale_factor();
+ return ScrollLayerWithLocalDelta(layer_impl,
+ delta,
+ scale_factor);
+ }
- return false;
+ return ScrollLayerWithViewportSpaceDelta(layer_impl,
+ viewport_point,
+ delta);
}
InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
@@ -2593,127 +2602,68 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
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())
+ // Skip the outer viewport scroll layer so that we try to scroll the
+ // viewport only once. i.e. The inner viewport layer represents the
+ // viewport.
+ if (!layer_impl->scrollable() || layer_impl == OuterViewportScrollLayer())
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);
- }
+ Viewport::ScrollResult result = viewport()->ScrollBy(pending_delta,
+ viewport_point,
+ wheel_scrolling_);
+ applied_delta = result.applied_delta;
+ unused_root_delta = result.unused_scroll_delta;
+ did_scroll_top_controls = result.top_controls_applied_delta.y() != 0;
+ } else {
+ applied_delta = ScrollLayer(layer_impl,
+ pending_delta,
+ viewport_point,
+ wheel_scrolling_);
}
- // 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;
+ if (did_move_layer_x || did_move_layer_y) {
+ 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 (!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())
+ if (!should_bubble_scrolls_ && did_lock_scrolling_layer_)
break;
}
« no previous file with comments | « cc/trees/layer_tree_host_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698