| 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 4cd7009829097470c74f45a33fb87e266db19899..9063caf66d67f57c2dad462ec1ec9320663c8369 100644
|
| --- a/cc/trees/layer_tree_host_impl.cc
|
| +++ b/cc/trees/layer_tree_host_impl.cc
|
| @@ -432,10 +432,11 @@
|
| bool anchor_point,
|
| float page_scale,
|
| base::TimeDelta duration) {
|
| - if (!InnerViewportScrollLayer())
|
| - return;
|
| -
|
| - gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset();
|
| + if (!RootScrollLayer())
|
| + return;
|
| +
|
| + gfx::Vector2dF scroll_total =
|
| + RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta();
|
| gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
|
| gfx::SizeF viewport_size = UnscaledScrollableViewportSize();
|
|
|
| @@ -1303,10 +1304,10 @@
|
| metadata.overdraw_bottom_height = overdraw_bottom_height_;
|
| }
|
|
|
| - if (!InnerViewportScrollLayer())
|
| + if (!RootScrollLayer())
|
| return metadata;
|
|
|
| - metadata.root_scroll_offset = active_tree_->TotalScrollOffset();
|
| + metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset();
|
|
|
| return metadata;
|
| }
|
| @@ -1509,19 +1510,15 @@
|
| }
|
|
|
| bool LayerTreeHostImpl::HaveRootScrollLayer() const {
|
| - return !!InnerViewportScrollLayer();
|
| + return !!RootScrollLayer();
|
| }
|
|
|
| LayerImpl* LayerTreeHostImpl::RootLayer() const {
|
| return active_tree_->root_layer();
|
| }
|
|
|
| -LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const {
|
| - return active_tree_->InnerViewportScrollLayer();
|
| -}
|
| -
|
| -LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const {
|
| - return active_tree_->OuterViewportScrollLayer();
|
| +LayerImpl* LayerTreeHostImpl::RootScrollLayer() const {
|
| + return active_tree_->RootScrollLayer();
|
| }
|
|
|
| LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
|
| @@ -1530,10 +1527,7 @@
|
|
|
| bool LayerTreeHostImpl::IsCurrentlyScrolling() const {
|
| return CurrentlyScrollingLayer() ||
|
| - (InnerViewportScrollLayer() &&
|
| - InnerViewportScrollLayer()->IsExternalFlingActive()) ||
|
| - (OuterViewportScrollLayer() &&
|
| - OuterViewportScrollLayer()->IsExternalFlingActive());
|
| + (RootScrollLayer() && RootScrollLayer()->IsExternalFlingActive());
|
| }
|
|
|
| // Content layers can be either directly scrollable or contained in an outer
|
| @@ -1914,6 +1908,8 @@
|
|
|
| device_viewport_size_ = device_viewport_size;
|
|
|
| + UpdateMaxScrollOffset();
|
| +
|
| client_->OnCanDrawStateChanged(CanDraw());
|
| SetFullRootLayerDamage();
|
| }
|
| @@ -1923,6 +1919,7 @@
|
| return;
|
| overdraw_bottom_height_ = overdraw_bottom_height;
|
|
|
| + UpdateMaxScrollOffset();
|
| SetFullRootLayerDamage();
|
| }
|
|
|
| @@ -1938,6 +1935,7 @@
|
| return;
|
| device_scale_factor_ = device_scale_factor;
|
|
|
| + UpdateMaxScrollOffset();
|
| SetFullRootLayerDamage();
|
| }
|
|
|
| @@ -1961,6 +1959,10 @@
|
|
|
| const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
|
| return external_transform_;
|
| +}
|
| +
|
| +void LayerTreeHostImpl::UpdateMaxScrollOffset() {
|
| + active_tree_->UpdateMaxScrollOffset();
|
| }
|
|
|
| void LayerTreeHostImpl::DidChangeTopControlsPosition() {
|
| @@ -2048,11 +2050,8 @@
|
| return ScrollOnMainThread;
|
| }
|
|
|
| - // If we want to send a DidOverscroll for this scroll it can't be ignored.
|
| if (!potentially_scrolling_layer_impl)
|
| - potentially_scrolling_layer_impl =
|
| - OuterViewportScrollLayer() ? OuterViewportScrollLayer()
|
| - : InnerViewportScrollLayer();
|
| + potentially_scrolling_layer_impl = RootScrollLayer();
|
|
|
| if (potentially_scrolling_layer_impl) {
|
| active_tree_->SetCurrentlyScrollingLayer(
|
| @@ -2159,14 +2158,10 @@
|
| gfx::Vector2dF unused_root_delta;
|
| bool did_scroll_x = false;
|
| bool did_scroll_y = false;
|
| - // TODO(wjmaclean) Should we guard against CurrentlyScrollingLayer() == 0
|
| - // here?
|
| - bool consume_by_top_controls =
|
| - top_controls_manager_ &&
|
| - (((CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
|
| - CurrentlyScrollingLayer() == OuterViewportScrollLayer()) &&
|
| - InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) ||
|
| - scroll_delta.y() < 0);
|
| + bool consume_by_top_controls = top_controls_manager_ &&
|
| + (scroll_delta.y() < 0 ||
|
| + (RootScrollLayer() && CurrentlyScrollingLayer() == RootScrollLayer() &&
|
| + RootScrollLayer()->max_scroll_offset().y() > 0));
|
|
|
| for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
|
| layer_impl;
|
| @@ -2174,18 +2169,12 @@
|
| if (!layer_impl->scrollable())
|
| continue;
|
|
|
| - if (layer_impl == InnerViewportScrollLayer()) {
|
| + if (layer_impl == RootScrollLayer()) {
|
| // Only allow bubble scrolling when the scroll is in the direction to make
|
| // the top controls visible.
|
| - gfx::Vector2dF applied_delta;
|
| - gfx::Vector2dF excess_delta;
|
| if (consume_by_top_controls) {
|
| - excess_delta = top_controls_manager_->ScrollBy(pending_delta);
|
| - applied_delta = pending_delta - excess_delta;
|
| - pending_delta = excess_delta;
|
| - // Force updating of vertical adjust values if needed.
|
| - if (applied_delta.y() != 0)
|
| - layer_impl->ScrollbarParametersDidChange();
|
| + pending_delta = top_controls_manager_->ScrollBy(pending_delta);
|
| + UpdateMaxScrollOffset();
|
| }
|
| // Track root layer deltas for reporting overscroll.
|
| unused_root_delta = pending_delta;
|
| @@ -2219,7 +2208,7 @@
|
| break;
|
| }
|
|
|
| - if (layer_impl == InnerViewportScrollLayer())
|
| + if (layer_impl == RootScrollLayer())
|
| unused_root_delta.Subtract(applied_delta);
|
|
|
| did_lock_scrolling_layer_ = true;
|
| @@ -2286,10 +2275,10 @@
|
| if (!layer_impl->scrollable())
|
| continue;
|
|
|
| - if (!layer_impl->HasScrollbar(VERTICAL))
|
| + if (!layer_impl->vertical_scrollbar_layer())
|
| continue;
|
|
|
| - float height = layer_impl->clip_height();
|
| + float height = layer_impl->vertical_scrollbar_layer()->bounds().height();
|
|
|
| // These magical values match WebKit and are designed to scroll nearly the
|
| // entire visible content height but leave a bit of overlap.
|
| @@ -2345,8 +2334,8 @@
|
| return ScrollIgnored;
|
|
|
| if (settings_.ignore_root_layer_flings &&
|
| - (active_tree_->CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
|
| - active_tree_->CurrentlyScrollingLayer() == OuterViewportScrollLayer())) {
|
| + active_tree_->CurrentlyScrollingLayer() ==
|
| + active_tree_->RootScrollLayer()) {
|
| ClearCurrentlyScrollingLayer();
|
| return ScrollIgnored;
|
| }
|
| @@ -2422,14 +2411,11 @@
|
| if (!animation_controller)
|
| return;
|
|
|
| - // TODO(wjmaclean) Is it ok to choose distance from more than two scrollbars?
|
| - float distance_to_scrollbar = std::numeric_limits<float>::max();
|
| - for (LayerImpl::ScrollbarSet::iterator it =
|
| - scroll_layer_impl->scrollbars()->begin();
|
| - it != scroll_layer_impl->scrollbars()->end();
|
| - ++it)
|
| - distance_to_scrollbar = std::min(distance_to_scrollbar,
|
| - DeviceSpaceDistanceToLayer(device_viewport_point, *it));
|
| + float distance_to_scrollbar = std::min(
|
| + DeviceSpaceDistanceToLayer(device_viewport_point,
|
| + scroll_layer_impl->horizontal_scrollbar_layer()),
|
| + DeviceSpaceDistanceToLayer(device_viewport_point,
|
| + scroll_layer_impl->vertical_scrollbar_layer()));
|
|
|
| bool should_animate = animation_controller->DidMouseMoveNear(
|
| CurrentPhysicalTimeTicks(), distance_to_scrollbar / device_scale_factor_);
|
| @@ -2464,13 +2450,7 @@
|
| previous_pinch_anchor_ = gfx::Point();
|
| client_->RenewTreePriority();
|
| pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer();
|
| - if (active_tree_->OuterViewportScrollLayer()) {
|
| - active_tree_->SetCurrentlyScrollingLayer(
|
| - active_tree_->OuterViewportScrollLayer());
|
| - } else {
|
| - active_tree_->SetCurrentlyScrollingLayer(
|
| - active_tree_->InnerViewportScrollLayer());
|
| - }
|
| + active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer());
|
| if (top_controls_manager_)
|
| top_controls_manager_->PinchBegin();
|
| }
|
| @@ -2479,7 +2459,8 @@
|
| gfx::Point anchor) {
|
| TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
|
|
|
| - DCHECK(InnerViewportScrollLayer());
|
| + if (!RootScrollLayer())
|
| + return;
|
|
|
| // Keep the center-of-pinch anchor specified by (x, y) in a stable
|
| // position over the course of the magnify.
|
| @@ -2495,24 +2476,8 @@
|
| previous_pinch_anchor_ = anchor;
|
|
|
| move.Scale(1 / active_tree_->page_scale_factor());
|
| - // If clamping the inner viewport scroll offset causes a change, it should
|
| - // be accounted for from the intended move.
|
| - move -= InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset();
|
| -
|
| - // We manually manage the bubbling behaviour here as it is different to that
|
| - // implemented in LayerTreeHostImpl::ScrollBy(). Specifically:
|
| - // 1) we want to explicit limit the bubbling to the outer/inner viewports,
|
| - // 2) we don't want the directional limitations on the unused parts that
|
| - // ScrollBy() implements, and
|
| - // 3) pinching should not engage the top controls manager.
|
| - gfx::Vector2dF unused =
|
| - OuterViewportScrollLayer() ? OuterViewportScrollLayer()->ScrollBy(move)
|
| - : move;
|
| -
|
| - if (!unused.IsZero()) {
|
| - InnerViewportScrollLayer()->ScrollBy(unused);
|
| - InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset();
|
| - }
|
| +
|
| + RootScrollLayer()->ScrollBy(move);
|
|
|
| client_->SetNeedsCommitOnImplThread();
|
| SetNeedsRedraw();
|
| @@ -2563,24 +2528,13 @@
|
| SetViewportDamage(gfx::Rect(DrawViewportSize()));
|
| }
|
|
|
| -void LayerTreeHostImpl::ScrollViewportBy(gfx::Vector2dF scroll_delta) {
|
| - DCHECK(InnerViewportScrollLayer());
|
| - LayerImpl* scroll_layer =
|
| - OuterViewportScrollLayer() ? OuterViewportScrollLayer()
|
| - : InnerViewportScrollLayer();
|
| -
|
| - gfx::Vector2dF unused_delta = scroll_layer->ScrollBy(scroll_delta);
|
| -
|
| - if (!unused_delta.IsZero() && (scroll_layer == OuterViewportScrollLayer()))
|
| - InnerViewportScrollLayer()->ScrollBy(unused_delta);
|
| -}
|
| -
|
| void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
|
| - if (!page_scale_animation_)
|
| + if (!page_scale_animation_ || !RootScrollLayer())
|
| return;
|
|
|
| double monotonic_time = (time - base::TimeTicks()).InSecondsF();
|
| - gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset();
|
| + gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() +
|
| + RootScrollLayer()->ScrollDelta();
|
|
|
| if (!page_scale_animation_->IsAnimationStarted())
|
| page_scale_animation_->StartAnimation(monotonic_time);
|
| @@ -2591,7 +2545,7 @@
|
| gfx::Vector2dF next_scroll =
|
| page_scale_animation_->ScrollOffsetAtTime(monotonic_time);
|
|
|
| - ScrollViewportBy(next_scroll - scroll_total);
|
| + RootScrollLayer()->ScrollBy(next_scroll - scroll_total);
|
| SetNeedsRedraw();
|
|
|
| if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
|
| @@ -2602,17 +2556,18 @@
|
| }
|
|
|
| void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
|
| - if (!top_controls_manager_)
|
| + if (!top_controls_manager_ || !RootScrollLayer())
|
| return;
|
| gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
|
| - if (active_tree_->TotalScrollOffset().y() == 0.f)
|
| + UpdateMaxScrollOffset();
|
| + if (RootScrollLayer()->TotalScrollOffset().y() == 0.f)
|
| return;
|
| if (scroll.IsZero()) {
|
| // This may happen on the first animation step. Force redraw otherwise
|
| // the animation would stop because of no new frames.
|
| SetNeedsRedraw();
|
| } else {
|
| - ScrollViewportBy(gfx::ScaleVector2d(
|
| + RootScrollLayer()->ScrollBy(gfx::ScaleVector2d(
|
| scroll, 1.f / active_tree_->total_page_scale_factor()));
|
| }
|
| }
|
|
|