| 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 8b8ed9cf137fc0230a316305c58a1bbd05a19773..6fdd6b59ed8727686072236e367343f83e30d255 100644
|
| --- a/cc/trees/layer_tree_host_impl.cc
|
| +++ b/cc/trees/layer_tree_host_impl.cc
|
| @@ -289,8 +289,7 @@ LayerTreeHostImpl::~LayerTreeHostImpl() {
|
| input_handler_client_->WillShutdown();
|
| input_handler_client_ = NULL;
|
| }
|
| - if (scroll_elasticity_helper_)
|
| - scroll_elasticity_helper_.reset();
|
| + root_scroll_elasticity_helper_.reset();
|
|
|
| // The layer trees must be destroyed before the layer tree host. We've
|
| // made a contract with our animation controllers that the animation_host
|
| @@ -613,13 +612,33 @@ LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor(
|
| new LatencyInfoSwapPromiseMonitor(latency, NULL, this));
|
| }
|
|
|
| -ScrollElasticityHelper* LayerTreeHostImpl::CreateScrollElasticityHelper() {
|
| - DCHECK(!scroll_elasticity_helper_);
|
| +ScrollElasticityHelper* LayerTreeHostImpl::CreateRootScrollElasticityHelper() {
|
| + DCHECK(!root_scroll_elasticity_helper_);
|
| if (settings_.enable_elastic_overscroll) {
|
| - scroll_elasticity_helper_.reset(
|
| + root_scroll_elasticity_helper_.reset(
|
| ScrollElasticityHelper::CreateForLayerTreeHostImpl(this));
|
| }
|
| - return scroll_elasticity_helper_.get();
|
| + return root_scroll_elasticity_helper_.get();
|
| +}
|
| +
|
| +base::WeakPtr<ScrollElasticityHelper>
|
| +LayerTreeHostImpl::ScrollElasticityHelperForScrollingLayer() {
|
| + LayerImpl* scrolling_layer_impl = CurrentlyScrollingLayer();
|
| + if (!scrolling_layer_impl)
|
| + return nullptr;
|
| +
|
| + return ScrollElasticityHelperForId(scrolling_layer_impl->id())->GetWeakPtr();
|
| +}
|
| +
|
| +bool LayerTreeHostImpl::ScrollLayerTo(int layer_id,
|
| + const gfx::ScrollOffset& offset) {
|
| + LayerImpl* layer = active_tree()->FindActiveTreeLayerById(layer_id);
|
| + if (!layer)
|
| + return false;
|
| +
|
| + layer->ScrollBy(
|
| + ScrollOffsetToVector2dF(offset - layer->CurrentScrollOffset()));
|
| + return true;
|
| }
|
|
|
| void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate(
|
| @@ -2638,8 +2657,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
|
| // in input_handler_proxy instead.
|
| wheel_scrolling_ = IsWheelBasedScroll(type);
|
| scroll_state->set_is_direct_manipulation(!wheel_scrolling_);
|
| - // Invoke |DistributeScrollDelta| even with zero delta and velocity to ensure
|
| - // scroll customization callbacks are invoked.
|
| + // Invoke |DistributeScrollDelta| even with zero delta and velocity to process
|
| + // overscroll and ensure scroll customization callbacks are invoked.
|
| DistributeScrollDelta(scroll_state);
|
|
|
| client_->RenewTreePriority();
|
| @@ -2668,6 +2687,18 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
|
|
|
| ClearCurrentlyScrollingLayer();
|
|
|
| + if (!scroll_state->is_beginning()) {
|
| + DCHECK(scroll_state->is_in_inertial_phase());
|
| + // When transitioning into a "flick", try to find the layer that was
|
| + // already scrolling. Without this, a flick may begin after elastic
|
| + // overscroll moves the scrolling layer out from beneath the event, causing
|
| + // a failed hit test.
|
| + LayerImpl* scrolling_layer_impl =
|
| + active_tree_->LayerById(active_tree_->LastScrolledLayerId());
|
| + if (scrolling_layer_impl)
|
| + return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type);
|
| + }
|
| +
|
| gfx::Point viewport_point(scroll_state->position_x(),
|
| scroll_state->position_y());
|
|
|
| @@ -3548,6 +3579,38 @@ LayerTreeHostImpl::ScrollbarAnimationControllerForId(
|
| return i->second.get();
|
| }
|
|
|
| +void LayerTreeHostImpl::RegisterScrollElasticityHelper(int scroll_layer_id) {
|
| + DCHECK(!InnerViewportScrollLayer() ||
|
| + scroll_layer_id != InnerViewportScrollLayer()->id());
|
| + DCHECK(!OuterViewportScrollLayer() ||
|
| + scroll_layer_id != OuterViewportScrollLayer()->id());
|
| + DCHECK(settings().enable_elastic_overscroll);
|
| +
|
| + auto& helper = scroll_elasticity_helpers_[scroll_layer_id];
|
| + if (!helper)
|
| + helper = active_tree_->CreateScrollElasticityHelper(scroll_layer_id);
|
| +}
|
| +
|
| +void LayerTreeHostImpl::UnregisterScrollElasticityHelper(int scroll_layer_id) {
|
| + scroll_elasticity_helpers_.erase(scroll_layer_id);
|
| +}
|
| +
|
| +ScrollElasticityHelper* LayerTreeHostImpl::ScrollElasticityHelperForId(
|
| + int scroll_layer_id) {
|
| + if (!settings().enable_elastic_overscroll)
|
| + return nullptr;
|
| +
|
| + auto i = scroll_elasticity_helpers_.find(scroll_layer_id);
|
| + if (i != scroll_elasticity_helpers_.end())
|
| + return i->second.get();
|
| +
|
| + if (!root_scroll_elasticity_helper_) {
|
| + root_scroll_elasticity_helper_.reset(
|
| + ScrollElasticityHelper::CreateForLayerTreeHostImpl(this));
|
| + }
|
| + return root_scroll_elasticity_helper_.get();
|
| +}
|
| +
|
| void LayerTreeHostImpl::PostDelayedScrollbarAnimationTask(
|
| const base::Closure& task,
|
| base::TimeDelta delay) {
|
|
|