| Index: cc/layers/viewport.cc
|
| diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc
|
| index 1b3cfe574a8a724da38c3b2997fc525c80b77ea9..b54c9cce2d6ea3816093af4f259d6d429f508809 100644
|
| --- a/cc/layers/viewport.cc
|
| +++ b/cc/layers/viewport.cc
|
| @@ -64,6 +64,62 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
|
| return result;
|
| }
|
|
|
| +bool Viewport::ShouldAnimateViewport(const gfx::Vector2dF& viewport_delta,
|
| + const gfx::Vector2dF& pending_delta) {
|
| + float max_dim_viewport_delta =
|
| + std::max(std::abs(viewport_delta.x()), std::abs(viewport_delta.y()));
|
| + float max_dim_pending_delta =
|
| + std::max(std::abs(pending_delta.x()), std::abs(pending_delta.y()));
|
| + return max_dim_viewport_delta > max_dim_pending_delta;
|
| +}
|
| +
|
| +gfx::Vector2dF Viewport::ScrollAnimated(const gfx::Vector2dF& delta) {
|
| + ScrollTree& scroll_tree =
|
| + host_impl_->active_tree()->property_trees()->scroll_tree;
|
| +
|
| + float scale_factor = host_impl_->active_tree()->current_page_scale_factor();
|
| + gfx::Vector2dF scaled_delta = delta;
|
| + scaled_delta.Scale(1.f / scale_factor);
|
| +
|
| + ScrollNode* inner_node =
|
| + scroll_tree.Node(InnerScrollLayer()->scroll_tree_index());
|
| + gfx::Vector2dF inner_delta =
|
| + host_impl_->ComputeScrollDelta(inner_node, delta);
|
| +
|
| + gfx::Vector2dF pending_delta = scaled_delta - inner_delta;
|
| + pending_delta.Scale(scale_factor);
|
| +
|
| + ScrollNode* outer_node =
|
| + scroll_tree.Node(OuterScrollLayer()->scroll_tree_index());
|
| + gfx::Vector2dF outer_delta =
|
| + host_impl_->ComputeScrollDelta(outer_node, pending_delta);
|
| +
|
| + if (inner_delta.IsZero() && outer_delta.IsZero())
|
| + return gfx::Vector2dF(0, 0);
|
| +
|
| + // Animate the viewport to which the majority of scroll delta will be applied.
|
| + // The animation system only supports running one scroll offset animation.
|
| + // TODO(ymalik): Fix the visible jump seen by instant scrolling one of the
|
| + // viewports.
|
| + bool will_animate = false;
|
| + if (ShouldAnimateViewport(inner_delta, outer_delta)) {
|
| + scroll_tree.ScrollBy(outer_node, outer_delta, host_impl_->active_tree());
|
| + will_animate = host_impl_->ScrollAnimationCreate(inner_node, inner_delta);
|
| + } else {
|
| + scroll_tree.ScrollBy(inner_node, inner_delta, host_impl_->active_tree());
|
| + will_animate = host_impl_->ScrollAnimationCreate(outer_node, outer_delta);
|
| + }
|
| +
|
| + if (will_animate) {
|
| + // Consume entire scroll delta as long as we are starting an animation.
|
| + return delta;
|
| + }
|
| +
|
| + pending_delta = scaled_delta - inner_delta - outer_delta;
|
| + pending_delta.Scale(scale_factor);
|
| + return pending_delta;
|
| +}
|
| +
|
| void Viewport::SnapPinchAnchorIfWithinMargin(const gfx::Point& anchor) {
|
| gfx::SizeF viewport_size = gfx::SizeF(
|
| host_impl_->active_tree()->InnerViewportContainerLayer()->bounds());
|
|
|