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

Unified 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 windows compile. Created 5 years, 5 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
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 da263e34a63ed8038f642223923945bb3045a590..9f867e5b654ac9ff7f834064d8b5c2ab71b3c7f5 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -34,6 +34,7 @@
#include "cc/debug/traced_value.h"
#include "cc/input/page_scale_animation.h"
#include "cc/input/scroll_elasticity_helper.h"
+#include "cc/input/scroll_state.h"
#include "cc/input/top_controls_manager.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/heads_up_display_layer_impl.h"
@@ -211,6 +212,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
should_bubble_scrolls_(false),
wheel_scrolling_(false),
scroll_affects_scroll_handler_(false),
+ in_inertial_scroll_(false),
scroll_layer_id_when_mouse_over_scrollbar_(0),
tile_priorities_dirty_(false),
root_layer_scroll_offset_delegate_(NULL),
@@ -2438,6 +2440,13 @@ static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) {
return false;
}
+static LayerImpl* nextLayerInScrollOrder(LayerImpl* layer) {
Ian Vollick 2015/07/09 14:03:55 This feels like it would be a function in the Scro
+ if (layer->scroll_parent())
+ return layer->scroll_parent();
+
+ return layer->parent();
+}
+
InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
LayerImpl* scrolling_layer_impl,
InputHandler::ScrollInputType type) {
@@ -2449,6 +2458,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl);
should_bubble_scrolls_ = (type != NON_BUBBLING_GESTURE);
wheel_scrolling_ = (type == WHEEL);
+ in_inertial_scroll_ = false;
+
client_->RenewTreePriority();
UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
return SCROLL_STARTED;
@@ -2557,7 +2568,7 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
gfx::Transform::kSkipInitialization);
bool did_invert = layer_impl->screen_space_transform().GetInverse(
&inverse_screen_space_transform);
- // TODO(shawnsingh): With the advent of impl-side crolling for non-root
+ // TODO(shawnsingh): With the advent of impl-side scrolling for non-root
// layers, we may need to explicitly handle uninvertible transforms here.
DCHECK(did_invert);
@@ -2644,11 +2655,54 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayer(LayerImpl* layer_impl,
return ScrollLayerWithLocalDelta(layer_impl, delta, scale_factor);
}
-static LayerImpl* nextLayerInScrollOrder(LayerImpl* layer) {
- if (layer->scroll_parent())
- return layer->scroll_parent();
+void LayerTreeHostImpl::ApplyScroll(LayerImpl* layer,
+ ScrollState* scroll_state) {
+ DCHECK(scroll_state);
+ gfx::Point viewport_point(scroll_state->start_position_x(),
+ scroll_state->start_position_y());
+ const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y());
+ gfx::Vector2dF applied_delta;
- return layer->parent();
+ if (layer == InnerViewportScrollLayer()) {
+ bool affect_top_controls = true;
+ applied_delta = viewport()->ScrollBy(delta, viewport_point,
+ scroll_state->is_direct_manipulation(),
+ affect_top_controls);
+ } else {
+ applied_delta = ScrollLayer(layer, delta, viewport_point,
+ scroll_state->is_direct_manipulation());
+ }
+
+ // If the layer wasn't able to move, try the next one in the hierarchy.
+ const float kEpsilon = 0.1f;
Ian Vollick 2015/07/09 14:03:55 Why this number? Should it not be one device pixel
tdresser 2015/07/09 16:07:45 I'm trying to avoid introducing any functional cha
Ian Vollick 2015/07/09 16:46:51 Yes, please file a bug for this, add a TODO and ex
tdresser 2015/07/16 14:04:50 Done.
+ bool scrolled = std::abs(applied_delta.x()) > kEpsilon;
+ scrolled = scrolled || std::abs(applied_delta.y()) > kEpsilon;
+
+ if (scrolled && layer != InnerViewportScrollLayer()) {
+ // 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, delta) <
+ angle_threshold) {
+ applied_delta = delta;
+ } else {
+ // Allow further movement only on an axis perpendicular to the direction
+ // in which the layer moved.
+ applied_delta = MathUtil::ProjectVector(delta, applied_delta);
+ }
+ }
+
+ scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y());
+
+ if (!scrolled)
+ return;
+ // 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 (!scroll_state->should_propagate())
+ scroll_state->set_current_native_scrolling_layer(layer);
}
InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
@@ -2658,81 +2712,45 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
if (!CurrentlyScrollingLayer())
return InputHandlerScrollResult();
- gfx::Vector2dF pending_delta = scroll_delta;
- gfx::Vector2dF unused_root_delta;
- bool did_scroll_x = false;
- bool did_scroll_y = false;
-
if (pinch_gesture_active_ && settings().invert_viewport_scroll_order) {
// Scrolls during a pinch gesture should pan the visual viewport, rather
// than a typical bubbling scroll.
- viewport()->Pan(pending_delta);
+ viewport()->Pan(scroll_delta);
return InputHandlerScrollResult();
}
- for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
- layer_impl;
+ ScrollState scroll_state(
+ scroll_delta.x(), scroll_delta.y(), viewport_point.x(),
+ viewport_point.y(), in_inertial_scroll_ /* in_inertial_phase*/,
+ should_bubble_scrolls_ /* should_propagate */,
+ did_lock_scrolling_layer_ /* delta_consumed_for_scroll_sequence */,
+ !wheel_scrolling_ /* is_direct_manipulation */);
+ scroll_state.set_current_native_scrolling_layer(
+ active_tree_->CurrentlyScrollingLayer());
+
+ std::list<LayerImpl*> current_scroll_chain;
+ for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl;
layer_impl = nextLayerInScrollOrder(layer_impl)) {
// 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;
+ current_scroll_chain.push_front(layer_impl);
+ }
+ scroll_state.set_scroll_chain(current_scroll_chain);
- gfx::Vector2dF applied_delta;
- if (layer_impl == InnerViewportScrollLayer()) {
- bool affect_top_controls = true;
- applied_delta =
- viewport()->ScrollBy(pending_delta, viewport_point, !wheel_scrolling_,
- affect_top_controls);
- unused_root_delta = pending_delta - applied_delta;
- } else {
- applied_delta = ScrollLayer(layer_impl, pending_delta, viewport_point,
- !wheel_scrolling_);
- }
-
- // If the layer wasn't able to move, try the next one in the hierarchy.
- const float kEpsilon = 0.1f;
- bool did_layer_consume_delta_x = std::abs(applied_delta.x()) > kEpsilon;
- bool did_layer_consume_delta_y = std::abs(applied_delta.y()) > kEpsilon;
-
- did_scroll_x |= did_layer_consume_delta_x;
- did_scroll_y |= did_layer_consume_delta_y;
-
- if (did_layer_consume_delta_x || did_layer_consume_delta_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);
- break;
- }
-
- // 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)
- break;
+ scroll_state.DistributeToScrollChainDescendant();
- // 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 (!should_bubble_scrolls_ && did_lock_scrolling_layer_)
- break;
- }
+ active_tree_->SetCurrentlyScrollingLayer(
+ scroll_state.current_native_scrolling_layer());
+ did_lock_scrolling_layer_ = scroll_state.delta_consumed_for_scroll_sequence();
+ const float kEpsilon = 0.1f;
+ bool did_scroll_x =
+ std::abs(scroll_state.delta_x() - scroll_delta.x()) > kEpsilon;
+ bool did_scroll_y =
+ std::abs(scroll_state.delta_y() - scroll_delta.y()) > kEpsilon;
bool did_scroll_content = did_scroll_x || did_scroll_y;
if (did_scroll_content) {
// If we are scrolling with an active scroll handler, forward latency
@@ -2750,6 +2768,8 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
accumulated_root_overscroll_.set_x(0);
if (did_scroll_y)
accumulated_root_overscroll_.set_y(0);
+ gfx::Vector2dF unused_root_delta(scroll_state.delta_x(),
+ scroll_state.delta_y());
accumulated_root_overscroll_ += unused_root_delta;
InputHandlerScrollResult scroll_result;
@@ -2843,6 +2863,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() {
should_bubble_scrolls_ = false;
}
+ in_inertial_scroll_ = true;
+
return SCROLL_STARTED;
}

Powered by Google App Engine
This is Rietveld 408576698