Chromium Code Reviews| 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 74171b600c1524228fc6d331a4cd1c7843689d22..ed62b364577dba4d491c60a2a38bbe1f0daf1bc8 100644 |
| --- a/cc/trees/layer_tree_host_impl.cc |
| +++ b/cc/trees/layer_tree_host_impl.cc |
| @@ -430,11 +430,13 @@ void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset, |
| bool anchor_point, |
| float page_scale, |
| base::TimeDelta duration) { |
| - if (!RootScrollLayer()) |
| + if (!InnerViewportScrollLayer()) |
| return; |
| - gfx::Vector2dF scroll_total = |
| - RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta(); |
| + // Should we attempt to set to OuterViewportScrollingLayer if it's available? |
| + active_tree_->SetCurrentlyScrollingLayer(InnerViewportScrollLayer()); |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
I have a suggested change in AnimatePageScale() th
wjmaclean
2014/01/16 15:07:32
Done.
|
| + |
| + gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); |
| gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize(); |
| gfx::SizeF viewport_size = UnscaledScrollableViewportSize(); |
| @@ -1302,10 +1304,10 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { |
| metadata.overdraw_bottom_height = overdraw_bottom_height_; |
| } |
| - if (!RootScrollLayer()) |
| + if (!InnerViewportScrollLayer()) |
| return metadata; |
| - metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset(); |
| + metadata.root_scroll_offset = active_tree_->TotalScrollOffset(); |
| return metadata; |
| } |
| @@ -1507,15 +1509,19 @@ void LayerTreeHostImpl::Readback(void* pixels, |
| } |
| bool LayerTreeHostImpl::HaveRootScrollLayer() const { |
| - return !!RootScrollLayer(); |
| + return !!InnerViewportScrollLayer(); |
| } |
| LayerImpl* LayerTreeHostImpl::RootLayer() const { |
| return active_tree_->root_layer(); |
| } |
| -LayerImpl* LayerTreeHostImpl::RootScrollLayer() const { |
| - return active_tree_->RootScrollLayer(); |
| +LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { |
| + return active_tree_->InnerViewportScrollLayer(); |
| +} |
| + |
| +LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { |
| + return active_tree_->OuterViewportScrollLayer(); |
| } |
| LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { |
| @@ -1524,7 +1530,10 @@ LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { |
| bool LayerTreeHostImpl::IsCurrentlyScrolling() const { |
| return CurrentlyScrollingLayer() || |
| - (RootScrollLayer() && RootScrollLayer()->IsExternalFlingActive()); |
| + (InnerViewportScrollLayer() && |
| + InnerViewportScrollLayer()->IsExternalFlingActive()) || |
| + (OuterViewportScrollLayer() && |
| + OuterViewportScrollLayer()->IsExternalFlingActive()); |
| } |
| // Content layers can be either directly scrollable or contained in an outer |
| @@ -1901,8 +1910,6 @@ void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) { |
| device_viewport_size_ = device_viewport_size; |
| - UpdateMaxScrollOffset(); |
| - |
| client_->OnCanDrawStateChanged(CanDraw()); |
| SetFullRootLayerDamage(); |
| } |
| @@ -1912,7 +1919,6 @@ void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) { |
| return; |
| overdraw_bottom_height_ = overdraw_bottom_height; |
| - UpdateMaxScrollOffset(); |
| SetFullRootLayerDamage(); |
| } |
| @@ -1928,7 +1934,6 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { |
| return; |
| device_scale_factor_ = device_scale_factor; |
| - UpdateMaxScrollOffset(); |
| SetFullRootLayerDamage(); |
| } |
| @@ -1954,10 +1959,6 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { |
| return external_transform_; |
| } |
| -void LayerTreeHostImpl::UpdateMaxScrollOffset() { |
| - active_tree_->UpdateMaxScrollOffset(); |
| -} |
| - |
| void LayerTreeHostImpl::DidChangeTopControlsPosition() { |
| SetNeedsRedraw(); |
| active_tree_->set_needs_update_draw_properties(); |
| @@ -2042,8 +2043,11 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( |
| 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 = RootScrollLayer(); |
| + potentially_scrolling_layer_impl = |
| + OuterViewportScrollLayer() ? OuterViewportScrollLayer() |
| + : InnerViewportScrollLayer(); |
| if (potentially_scrolling_layer_impl) { |
| active_tree_->SetCurrentlyScrollingLayer( |
| @@ -2150,10 +2154,11 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
| gfx::Vector2dF unused_root_delta; |
| bool did_scroll_x = false; |
| bool did_scroll_y = false; |
| - bool consume_by_top_controls = top_controls_manager_ && |
| - (scroll_delta.y() < 0 || |
| - (RootScrollLayer() && CurrentlyScrollingLayer() == RootScrollLayer() && |
| - RootScrollLayer()->max_scroll_offset().y() > 0)); |
| + bool consume_by_top_controls = |
| + top_controls_manager_ && |
| + ((CurrentlyScrollingLayer() == InnerViewportScrollLayer() && |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
It looks like this should be also checking for Out
wjmaclean
2014/01/16 15:07:32
You mean not working with the flag turned on? Beca
|
| + InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) || |
| + scroll_delta.y() < 0); |
| for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); |
| layer_impl; |
| @@ -2161,12 +2166,18 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
| if (!layer_impl->scrollable()) |
| continue; |
| - if (layer_impl == RootScrollLayer()) { |
| + if (layer_impl == InnerViewportScrollLayer()) { |
| // 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) { |
| - pending_delta = top_controls_manager_->ScrollBy(pending_delta); |
| - UpdateMaxScrollOffset(); |
| + 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(); |
| } |
| // Track root layer deltas for reporting overscroll. |
| unused_root_delta = pending_delta; |
| @@ -2200,7 +2211,8 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
| break; |
| } |
| - if (layer_impl == RootScrollLayer()) |
| + if (layer_impl == InnerViewportScrollLayer() || |
| + layer_impl == OuterViewportScrollLayer()) |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
This looks incorrect, since unused outer-viewport
wjmaclean
2014/01/16 15:07:32
Thanks for pointing this out. I haven't had much c
|
| unused_root_delta.Subtract(applied_delta); |
| did_lock_scrolling_layer_ = true; |
| @@ -2267,10 +2279,10 @@ bool LayerTreeHostImpl::ScrollVerticallyByPage(gfx::Point viewport_point, |
| if (!layer_impl->scrollable()) |
| continue; |
| - if (!layer_impl->vertical_scrollbar_layer()) |
| + if (!layer_impl->HasScrollbar(VERTICAL)) |
| continue; |
| - float height = layer_impl->vertical_scrollbar_layer()->bounds().height(); |
| + float height = layer_impl->clip_height(); |
| // These magical values match WebKit and are designed to scroll nearly the |
| // entire visible content height but leave a bit of overlap. |
| @@ -2326,8 +2338,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { |
| return ScrollIgnored; |
| if (settings_.ignore_root_layer_flings && |
| - active_tree_->CurrentlyScrollingLayer() == |
| - active_tree_->RootScrollLayer()) { |
| + (active_tree_->CurrentlyScrollingLayer() == InnerViewportScrollLayer() || |
| + active_tree_->CurrentlyScrollingLayer() == OuterViewportScrollLayer())) { |
| ClearCurrentlyScrollingLayer(); |
| return ScrollIgnored; |
| } |
| @@ -2402,11 +2414,14 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) { |
| if (!animation_controller) |
| return; |
| - 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())); |
| + // 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)); |
| bool should_animate = animation_controller->DidMouseMoveNear( |
| CurrentPhysicalTimeTicks(), distance_to_scrollbar / device_scale_factor_); |
| @@ -2441,7 +2456,13 @@ void LayerTreeHostImpl::PinchGestureBegin() { |
| previous_pinch_anchor_ = gfx::Point(); |
| client_->RenewTreePriority(); |
| pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer(); |
| - active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer()); |
| + if (active_tree_->OuterViewportScrollLayer()) { |
| + active_tree_->SetCurrentlyScrollingLayer( |
| + active_tree_->OuterViewportScrollLayer()); |
| + } else { |
| + active_tree_->SetCurrentlyScrollingLayer( |
| + active_tree_->InnerViewportScrollLayer()); |
| + } |
| if (top_controls_manager_) |
| top_controls_manager_->PinchBegin(); |
| } |
| @@ -2450,7 +2471,11 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, |
| gfx::Point anchor) { |
| TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate"); |
| - if (!RootScrollLayer()) |
| + LayerImpl* pinch_scroll_layer = CurrentlyScrollingLayer(); |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
A pinch can never scroll sublayers, so this variab
wjmaclean
2014/01/16 15:07:32
Makes sense ... so default to OuterViewportScrollL
aelias_OOO_until_Jul13
2014/01/16 19:49:26
Right.
|
| + if (!pinch_scroll_layer) |
| + pinch_scroll_layer = InnerViewportScrollLayer(); |
| + |
| + if (!pinch_scroll_layer) |
| return; |
| // Keep the center-of-pinch anchor specified by (x, y) in a stable |
| @@ -2467,8 +2492,29 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, |
| previous_pinch_anchor_ = anchor; |
| move.Scale(1 / active_tree_->page_scale_factor()); |
| - |
| - RootScrollLayer()->ScrollBy(move); |
| + // When shrinking the page, the current scroll offset of the inner viewport |
| + // scroll layer may need to be adjusted so that it doesn't exceed its maximum |
| + // at the new page scale factor. |
| + if (magnify_delta < 1.f) { |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
This if statement isn't needed, just always call t
wjmaclean
2014/01/16 15:07:32
Done.
|
| + // 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 = pinch_scroll_layer->ScrollBy(move); |
| + |
| + if (!unused.IsZero() && pinch_scroll_layer == OuterViewportScrollLayer()) { |
| + InnerViewportScrollLayer()->ScrollBy(unused); |
| + InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset(); |
| + active_tree_->SetCurrentlyScrollingLayer( |
| + active_tree_->InnerViewportScrollLayer()); |
| + } |
| client_->SetNeedsCommitOnImplThread(); |
| SetNeedsRedraw(); |
| @@ -2520,12 +2566,11 @@ void LayerTreeHostImpl::SetFullRootLayerDamage() { |
| } |
| void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
| - if (!page_scale_animation_ || !RootScrollLayer()) |
| + if (!page_scale_animation_) |
| return; |
| double monotonic_time = (time - base::TimeTicks()).InSecondsF(); |
| - gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() + |
| - RootScrollLayer()->ScrollDelta(); |
| + gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); |
| if (!page_scale_animation_->IsAnimationStarted()) |
| page_scale_animation_->StartAnimation(monotonic_time); |
| @@ -2536,25 +2581,28 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
| gfx::Vector2dF next_scroll = |
| page_scale_animation_->ScrollOffsetAtTime(monotonic_time); |
| - RootScrollLayer()->ScrollBy(next_scroll - scroll_total); |
| + ScrollBy(gfx::Point(), next_scroll - scroll_total); |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
This doesn't look right. I'm not sure the scroll
wjmaclean
2014/01/16 15:07:32
Sure, seems reasonable. I'll investigate and modif
|
| SetNeedsRedraw(); |
| if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { |
| page_scale_animation_.reset(); |
| + // Make sure this is clear so subsequent ScrollBegin() calls don't hit |
| + // DCHECK(!CurrentlyScrollingLayer()). |
| + ClearCurrentlyScrollingLayer(); |
|
aelias_OOO_until_Jul13
2014/01/16 03:44:04
Not needed if you never set it.
wjmaclean
2014/01/16 15:07:32
Done.
|
| client_->SetNeedsCommitOnImplThread(); |
| client_->RenewTreePriority(); |
| } |
| } |
| void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { |
| - if (!top_controls_manager_ || !RootScrollLayer()) |
| + if (!top_controls_manager_) |
| return; |
| gfx::Vector2dF scroll = top_controls_manager_->Animate(time); |
| - UpdateMaxScrollOffset(); |
| - if (RootScrollLayer()->TotalScrollOffset().y() == 0.f) |
| + if (active_tree_->TotalScrollOffset().y() == 0.f) |
| return; |
| - RootScrollLayer()->ScrollBy(gfx::ScaleVector2d( |
| - scroll, 1.f / active_tree_->total_page_scale_factor())); |
| + ScrollBy(gfx::Point(), |
| + gfx::ScaleVector2d(scroll, |
| + 1.f / active_tree_->total_page_scale_factor())); |
| } |
| void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, |