diff options
author | tdresser <tdresser@chromium.org> | 2015-07-31 06:15:07 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-31 13:15:39 +0000 |
commit | d9e20147dd5649be4c9b742d3e6984034853715c (patch) | |
tree | ee23091180f4ab0895946dc803ca1041b6ec67ee | |
parent | 582211ec456040fb553264c1d61129cfbbc52ddb (diff) | |
download | chromium_src-d9e20147dd5649be4c9b742d3e6984034853715c.zip chromium_src-d9e20147dd5649be4c9b742d3e6984034853715c.tar.gz chromium_src-d9e20147dd5649be4c9b742d3e6984034853715c.tar.bz2 |
Arrange compositor scrolling into scroll customization format (WIP)
This splits compositor driven scrolling into applyScroll and
distributeScroll methods. Future patches will allow JavaScript on
a CompositorWorker to override these methods.
BUG=505851
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1215183004
Cr-Commit-Position: refs/heads/master@{#341323}
-rw-r--r-- | cc/BUILD.gn | 3 | ||||
-rw-r--r-- | cc/cc.gyp | 2 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 1 | ||||
-rw-r--r-- | cc/input/scroll_state.cc | 46 | ||||
-rw-r--r-- | cc/input/scroll_state.h | 108 | ||||
-rw-r--r-- | cc/input/scroll_state_unittest.cc | 79 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 25 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 4 | ||||
-rw-r--r-- | cc/layers/viewport.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 156 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.h | 4 |
12 files changed, 361 insertions, 70 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index c4cdb2d..e421db1 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn @@ -108,6 +108,8 @@ component("cc") { "input/page_scale_animation.h", "input/scroll_elasticity_helper.cc", "input/scroll_elasticity_helper.h", + "input/scroll_state.cc", + "input/scroll_state.h", "input/selection.h", "input/selection_bound_type.h", "input/top_controls_manager.cc", @@ -733,6 +735,7 @@ test("cc_unittests") { "base/tiling_data_unittest.cc", "debug/frame_timing_tracker_unittest.cc", "debug/micro_benchmark_controller_unittest.cc", + "input/scroll_state_unittest.cc", "input/top_controls_manager_unittest.cc", "layers/delegated_frame_provider_unittest.cc", "layers/delegated_frame_resource_collection_unittest.cc", @@ -164,6 +164,8 @@ 'input/page_scale_animation.h', 'input/scroll_elasticity_helper.cc', 'input/scroll_elasticity_helper.h', + 'input/scroll_state.cc', + 'input/scroll_state.h', 'input/selection_bound_type.h', 'input/selection.h', 'input/top_controls_manager.cc', diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index c0be740..5dfd42a 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -32,6 +32,7 @@ 'debug/frame_timing_tracker_unittest.cc', 'debug/micro_benchmark_controller_unittest.cc', 'debug/rendering_stats_unittest.cc', + 'input/scroll_state_unittest.cc', 'input/top_controls_manager_unittest.cc', 'layers/delegated_frame_provider_unittest.cc', 'layers/delegated_frame_resource_collection_unittest.cc', diff --git a/cc/input/scroll_state.cc b/cc/input/scroll_state.cc new file mode 100644 index 0000000..52a0cca --- /dev/null +++ b/cc/input/scroll_state.cc @@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/input/scroll_state.h" + +#include "cc/layers/layer_impl.h" + +namespace cc { + +ScrollState::ScrollState(double delta_x, + double delta_y, + int start_position_x, + int start_position_y, + bool should_propagate, + bool delta_consumed_for_scroll_sequence, + bool is_direct_manipulation) + : delta_x_(delta_x), + delta_y_(delta_y), + start_position_x_(start_position_x), + start_position_y_(start_position_y), + should_propagate_(should_propagate), + delta_consumed_for_scroll_sequence_(delta_consumed_for_scroll_sequence), + is_direct_manipulation_(is_direct_manipulation), + caused_scroll_x_(false), + caused_scroll_y_(false) {} + +ScrollState::~ScrollState() {} + +void ScrollState::ConsumeDelta(double x, double y) { + delta_x_ -= x; + delta_y_ -= y; + + if (x || y) + delta_consumed_for_scroll_sequence_ = true; +} + +void ScrollState::DistributeToScrollChainDescendant() { + if (!scroll_chain_.empty()) { + LayerImpl* next = scroll_chain_.front(); + scroll_chain_.pop_front(); + next->DistributeScroll(this); + } +} + +} // namespace cc diff --git a/cc/input/scroll_state.h b/cc/input/scroll_state.h new file mode 100644 index 0000000..2cd437d --- /dev/null +++ b/cc/input/scroll_state.h @@ -0,0 +1,108 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_INPUT_SCROLL_STATE_H_ +#define CC_INPUT_SCROLL_STATE_H_ + +#include <list> + +#include "cc/base/cc_export.h" + +namespace cc { + +class LayerImpl; + +// ScrollState is based on the proposal for scroll customization in blink, found +// here: https://goo.gl/1ipTpP. +class CC_EXPORT ScrollState { + public: + ScrollState(double delta_x, + double delta_y, + int start_position_x, + int start_position_y, + bool should_propagate, + bool delta_consumed_for_scroll_sequence, + bool is_direct_manipulation); + ~ScrollState(); + + // Reduce deltas by x, y. + void ConsumeDelta(double x, double y); + // Pops the first layer off of |scroll_chain_| and calls + // |DistributeScroll| on it. + void DistributeToScrollChainDescendant(); + // Positive when scrolling left. + double delta_x() const { return delta_x_; } + // Positive when scrolling up. + double delta_y() const { return delta_y_; } + // The location the scroll started at. For touch, the starting + // position of the finger. For mouse, the location of the cursor. + int start_position_x() const { return start_position_x_; } + int start_position_y() const { return start_position_y_; } + + // True if this scroll is allowed to bubble upwards. + bool should_propagate() const { return should_propagate_; } + // True if the user interacts directly with the screen, e.g., via touch. + bool is_direct_manipulation() const { return is_direct_manipulation_; } + + void set_scroll_chain(const std::list<LayerImpl*>& scroll_chain) { + scroll_chain_ = scroll_chain; + } + + void set_current_native_scrolling_layer(LayerImpl* layer) { + current_native_scrolling_layer_ = layer; + } + + LayerImpl* current_native_scrolling_layer() const { + return current_native_scrolling_layer_; + } + + bool delta_consumed_for_scroll_sequence() const { + return delta_consumed_for_scroll_sequence_; + } + + bool FullyConsumed() const { return !delta_x_ && !delta_y_; } + + void set_caused_scroll(bool x, bool y) { + caused_scroll_x_ |= x; + caused_scroll_y_ |= y; + } + + bool caused_scroll_x() const { return caused_scroll_x_; } + bool caused_scroll_y() const { return caused_scroll_y_; } + + private: + ScrollState(); + double delta_x_; + double delta_y_; + double start_position_x_; + double start_position_y_; + + bool should_propagate_; + + // The last layer to respond to a scroll, or null if none exists. + LayerImpl* current_native_scrolling_layer_; + // Whether the scroll sequence has had any delta consumed, in the + // current frame, or any child frames. + bool delta_consumed_for_scroll_sequence_; + // True if the user interacts directly with the display, e.g., via + // touch. + bool is_direct_manipulation_; + // TODO(tdresser): ScrollState shouldn't need to keep track of whether or not + // this ScrollState object has caused a scroll. Ideally, any native scroller + // consuming delta has caused a scroll. Currently, there are some cases where + // we consume delta without scrolling, such as in + // |Viewport::AdjustOverscroll|. Once these cases are fixed, we should get rid + // of |caused_scroll_*_|. See crbug.com/510045 for details. + bool caused_scroll_x_; + bool caused_scroll_y_; + + // TODO(tdresser): Change LayerImpl* to an abstract scrollable type. See + // crbug.com/476553 for detail on the effort to unify impl and main thread + // scrolling, which will require an abstract scrollable type. + std::list<LayerImpl*> scroll_chain_; +}; + +} // namespace cc + +#endif // CC_INPUT_SCROLL_STATE_H_ diff --git a/cc/input/scroll_state_unittest.cc b/cc/input/scroll_state_unittest.cc new file mode 100644 index 0000000..5e091df --- /dev/null +++ b/cc/input/scroll_state_unittest.cc @@ -0,0 +1,79 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/input/scroll_state.h" + +#include "cc/layers/layer_impl.h" +#include "cc/test/fake_impl_proxy.h" +#include "cc/test/fake_layer_tree_host_impl.h" +#include "cc/test/test_shared_bitmap_manager.h" +#include "cc/test/test_task_graph_runner.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { + +class ScrollStateTest : public testing::Test {}; + +TEST_F(ScrollStateTest, ConsumeDeltaNative) { + const float delta_x = 12.3f; + const float delta_y = 3.9f; + + const float delta_x_to_consume = 1.2f; + const float delta_y_to_consume = 2.3f; + + ScrollState scrollState(delta_x, delta_y, 0, 0, false /* should_propagate */, + false /* delta_consumed_for_scroll_sequence */, + false /* is_direct_manipulation */); + EXPECT_FLOAT_EQ(delta_x, scrollState.delta_x()); + EXPECT_FLOAT_EQ(delta_y, scrollState.delta_y()); + EXPECT_FALSE(scrollState.delta_consumed_for_scroll_sequence()); + EXPECT_FALSE(scrollState.FullyConsumed()); + + scrollState.ConsumeDelta(0, 0); + EXPECT_FLOAT_EQ(delta_x, scrollState.delta_x()); + EXPECT_FLOAT_EQ(delta_y, scrollState.delta_y()); + EXPECT_FALSE(scrollState.delta_consumed_for_scroll_sequence()); + EXPECT_FALSE(scrollState.FullyConsumed()); + + scrollState.ConsumeDelta(delta_x_to_consume, 0); + EXPECT_FLOAT_EQ(delta_x - delta_x_to_consume, scrollState.delta_x()); + EXPECT_FLOAT_EQ(delta_y, scrollState.delta_y()); + EXPECT_TRUE(scrollState.delta_consumed_for_scroll_sequence()); + EXPECT_FALSE(scrollState.FullyConsumed()); + + scrollState.ConsumeDelta(0, delta_y_to_consume); + EXPECT_FLOAT_EQ(delta_x - delta_x_to_consume, scrollState.delta_x()); + EXPECT_FLOAT_EQ(delta_y - delta_y_to_consume, scrollState.delta_y()); + EXPECT_TRUE(scrollState.delta_consumed_for_scroll_sequence()); + EXPECT_FALSE(scrollState.FullyConsumed()); + + scrollState.ConsumeDelta(scrollState.delta_x(), scrollState.delta_y()); + EXPECT_TRUE(scrollState.delta_consumed_for_scroll_sequence()); + EXPECT_TRUE(scrollState.FullyConsumed()); +} + +TEST_F(ScrollStateTest, CurrentNativeScrollingScrollable) { + ScrollState scrollState(0, 0, 0, 0, false, false, false); + + FakeImplProxy proxy; + TestSharedBitmapManager shared_bitmap_manager; + TestTaskGraphRunner task_graph_runner; + FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, + &task_graph_runner); + + scoped_ptr<LayerImpl> layer_impl = + LayerImpl::Create(host_impl.active_tree(), 1); + scrollState.set_current_native_scrolling_layer(layer_impl.get()); + EXPECT_EQ(layer_impl, scrollState.current_native_scrolling_layer()); +} + +TEST_F(ScrollStateTest, FullyConsumed) { + ScrollState scrollState(1, 3, 0, 0, 0, false, false); + EXPECT_FALSE(scrollState.FullyConsumed()); + + scrollState.ConsumeDelta(1, 3); + EXPECT_TRUE(scrollState.FullyConsumed()); +} +} // namespace cc diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 5c20611..957bd2c 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -17,6 +17,7 @@ #include "cc/debug/layer_tree_debug_state.h" #include "cc/debug/micro_benchmark_impl.h" #include "cc/debug/traced_value.h" +#include "cc/input/scroll_state.h" #include "cc/layers/layer_utils.h" #include "cc/layers/painted_scrollbar_layer_impl.h" #include "cc/output/copy_output_request.h" @@ -197,6 +198,30 @@ void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { SetNeedsPushProperties(); } +void LayerImpl::DistributeScroll(ScrollState* scroll_state) { + DCHECK(scroll_state); + if (scroll_state->FullyConsumed()) + return; + + scroll_state->DistributeToScrollChainDescendant(); + + // If the scroll doesn't propagate, and we're currently scrolling + // a layer other than this one, prevent the scroll from + // propagating to this layer. + if (!scroll_state->should_propagate() && + scroll_state->delta_consumed_for_scroll_sequence() && + scroll_state->current_native_scrolling_layer() != this) { + return; + } + + ApplyScroll(scroll_state); +} + +void LayerImpl::ApplyScroll(ScrollState* scroll_state) { + DCHECK(scroll_state); + layer_tree_impl()->ApplyScroll(this, scroll_state); +} + void LayerImpl::SetNumDescendantsThatDrawContent(int num_descendants) { if (num_descendants_that_draw_content_ == num_descendants) return; diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index dce8d05..3fd6bc538 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -67,6 +67,7 @@ class ScrollbarLayerImplBase; class SimpleEnclosedRegion; class Tile; class TransformTree; +class ScrollState; struct AppendQuadsData; @@ -149,6 +150,9 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, return scroll_children_.get(); } + void DistributeScroll(ScrollState* scroll_state); + void ApplyScroll(ScrollState* scroll_state); + void set_property_tree_sequence_number(int sequence_number) {} void SetTransformTreeIndex(int index); diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc index d9ae5f4..e5e3053 100644 --- a/cc/layers/viewport.cc +++ b/cc/layers/viewport.cc @@ -148,6 +148,8 @@ bool Viewport::ShouldTopControlsConsumeScroll( } gfx::Vector2dF Viewport::AdjustOverscroll(const gfx::Vector2dF& delta) const { + // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for + // details. const float kEpsilon = 0.1f; gfx::Vector2dF adjusted = delta; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 9bded52..e5a7e41 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" @@ -2422,6 +2423,13 @@ static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) { return false; } +static LayerImpl* nextLayerInScrollOrder(LayerImpl* layer) { + if (layer->scroll_parent()) + return layer->scroll_parent(); + + return layer->parent(); +} + InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( LayerImpl* scrolling_layer_impl, InputHandler::ScrollInputType type) { @@ -2628,11 +2636,62 @@ 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; + // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for + // details. + const float kEpsilon = 0.1f; + + if (layer == InnerViewportScrollLayer()) { + bool affect_top_controls = !wheel_scrolling_; + Viewport::ScrollResult result = viewport()->ScrollBy( + delta, viewport_point, scroll_state->is_direct_manipulation(), + affect_top_controls); + applied_delta = result.consumed_delta; + scroll_state->set_caused_scroll( + std::abs(result.content_scrolled_delta.x()) > kEpsilon, + std::abs(result.content_scrolled_delta.y()) > kEpsilon); + scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); + } 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. + 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->set_caused_scroll(std::abs(applied_delta.x()) > kEpsilon, + std::abs(applied_delta.y()) > kEpsilon); + scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); + } - return layer->parent(); + 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( @@ -2642,86 +2701,41 @@ 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; - float initial_top_controls_offset = - top_controls_manager_->ControlsTopOffset(); - 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; + float initial_top_controls_offset = + top_controls_manager_->ControlsTopOffset(); + ScrollState scroll_state( + scroll_delta.x(), scroll_delta.y(), viewport_point.x(), + viewport_point.y(), 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(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; - - gfx::Vector2dF applied_delta; - if (layer_impl == InnerViewportScrollLayer()) { - // Each wheel event triggers a ScrollBegin/Update/End. This can interact - // poorly with the top controls animation, which is triggered after each - // call to ScrollEnd. - bool affect_top_controls = !wheel_scrolling_; - Viewport::ScrollResult result = - viewport()->ScrollBy(pending_delta, viewport_point, !wheel_scrolling_, - affect_top_controls); - applied_delta = result.content_scrolled_delta; - unused_root_delta = pending_delta - result.consumed_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_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) { - 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; - - // 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; + current_scroll_chain.push_front(layer_impl); } + scroll_state.set_scroll_chain(current_scroll_chain); + scroll_state.DistributeToScrollChainDescendant(); + + active_tree_->SetCurrentlyScrollingLayer( + scroll_state.current_native_scrolling_layer()); + did_lock_scrolling_layer_ = scroll_state.delta_consumed_for_scroll_sequence(); + bool did_scroll_x = scroll_state.caused_scroll_x(); + bool did_scroll_y = scroll_state.caused_scroll_y(); 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 @@ -2739,6 +2753,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; bool did_scroll_top_controls = diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 01f8792..077f904 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -168,6 +168,7 @@ class CC_EXPORT LayerTreeHostImpl InputHandler::ScrollStatus ScrollAnimated( const gfx::Point& viewport_point, const gfx::Vector2dF& scroll_delta) override; + void ApplyScroll(LayerImpl* layer, ScrollState* scroll_state); InputHandlerScrollResult ScrollBy( const gfx::Point& viewport_point, const gfx::Vector2dF& scroll_delta) override; diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index a3d3554..476d8aa 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h @@ -275,6 +275,10 @@ class CC_EXPORT LayerTreeImpl { // The outer viewport scroll layer scrolls first. void DistributeRootScrollOffset(); + void ApplyScroll(LayerImpl* layer, ScrollState* scroll_state) { + layer_tree_host_impl_->ApplyScroll(layer, scroll_state); + } + // Call this function when you expect there to be a swap buffer. // See swap_promise.h for how to use SwapPromise. void QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise); |