Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3010)

Unified Diff: cc/trees/layer_tree_host_impl.cc

Issue 23983047: Pinch/Zoom Infrastructure & Plumbing CL (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add fix for empty scroll-layer bounds. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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,

Powered by Google App Engine
This is Rietveld 408576698