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

Unified Diff: cc/trees/layer_tree_host_impl.cc

Issue 641873003: Made top controls work with virtual viewport pinch-to-zoom. (Chromium) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updates from danakj@ and aelias@ Created 6 years, 2 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 542143cea7af64c6cfc63ed93ba67bb66b77e5e8..ff3f99f803543494ce5d9547a7939281c8d49d7e 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -78,6 +78,42 @@
namespace cc {
namespace {
+// Small helper class that saves the current viewport location as the user sees
+// it and resets to the same location.
+class ViewportAnchor {
+ public:
+ ViewportAnchor(LayerImpl* inner_scroll, LayerImpl* outer_scroll)
+ : inner_(inner_scroll),
+ outer_(outer_scroll) {
+ viewport_in_content_coordinates_ = inner_->TotalScrollOffset();
+
+ if (outer_)
+ viewport_in_content_coordinates_ += outer_->TotalScrollOffset();
+ }
+
+ void ResetViewportToAnchoredPosition() {
+ DCHECK(outer_);
+
+ inner_->ClampScrollToMaxScrollOffset();
+ outer_->ClampScrollToMaxScrollOffset();
+
+ gfx::ScrollOffset viewport_location = inner_->TotalScrollOffset() +
+ outer_->TotalScrollOffset();
+
+ gfx::Vector2dF delta =
+ viewport_in_content_coordinates_.DeltaFrom(viewport_location);
+
+ delta = outer_->ScrollBy(delta);
+ inner_->ScrollBy(delta);
+ }
+
+ private:
+ LayerImpl* inner_;
+ LayerImpl* outer_;
+ gfx::ScrollOffset viewport_in_content_coordinates_;
+};
+
+
void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) {
if (visible) {
TRACE_EVENT_ASYNC_BEGIN1("webkit",
@@ -1654,16 +1690,41 @@ void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
begin_impl_frame_interval_ = args.interval;
}
-void LayerTreeHostImpl::UpdateInnerViewportContainerSize() {
- LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer();
- if (!container_layer)
+void LayerTreeHostImpl::UpdateViewportContainerSizes() {
+ LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer();
+ LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer();
+
+ if (!inner_container || !top_controls_manager_)
return;
- if (top_controls_manager_) {
- container_layer->SetBoundsDelta(
- gfx::Vector2dF(0, active_tree_->top_controls_layout_height() -
- active_tree_->total_top_controls_content_offset()));
- }
+ ViewportAnchor anchor(InnerViewportScrollLayer(),
+ OuterViewportScrollLayer());
+
+ // Adjust the inner viewport by shrinking/expanding the container to account
+ // for the change in top controls height since the last Resize from Blink.
+ inner_container->SetBoundsDelta(
+ gfx::Vector2dF(0, active_tree_->top_controls_layout_height() -
+ active_tree_->total_top_controls_content_offset()));
+
+ if (!outer_container || outer_container->BoundsForScrolling().IsEmpty())
+ return;
+
+ // Adjust the outer viewport container as well, since adjusting only the
+ // inner may cause its bounds to exceed those of the outer, causing scroll
+ // clamping. We adjust it so it maintains the same aspect ratio as the
+ // inner viewport.
+ float aspect_ratio = inner_container->BoundsForScrolling().width() /
+ inner_container->BoundsForScrolling().height();
+ float target_height = outer_container->BoundsForScrolling().width() /
+ aspect_ratio;
+ float current_outer_height = outer_container->BoundsForScrolling().height() -
+ outer_container->bounds_delta().y();
+ gfx::Vector2dF delta(0, target_height - current_outer_height);
+
+ outer_container->SetBoundsDelta(delta);
+ active_tree_->InnerViewportScrollLayer()->SetBoundsDelta(delta);
+
+ anchor.ResetViewportToAnchoredPosition();
}
void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) {
@@ -1671,7 +1732,7 @@ void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) {
return;
active_tree_->set_top_controls_layout_height(height);
- UpdateInnerViewportContainerSize();
+ UpdateViewportContainerSizes();
SetFullRootLayerDamage();
}
@@ -1792,7 +1853,7 @@ void LayerTreeHostImpl::ActivateSyncTree() {
top_controls_manager_->top_controls_height());
}
- UpdateInnerViewportContainerSize();
+ UpdateViewportContainerSizes();
} else {
active_tree_->ProcessUIResourceRequestQueue();
}
@@ -2155,7 +2216,7 @@ void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) {
device_viewport_size_ = device_viewport_size;
- UpdateInnerViewportContainerSize();
+ UpdateViewportContainerSizes();
client_->OnCanDrawStateChanged(CanDraw());
SetFullRootLayerDamage();
active_tree_->set_needs_update_draw_properties();
@@ -2206,7 +2267,7 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
}
void LayerTreeHostImpl::DidChangeTopControlsPosition() {
- UpdateInnerViewportContainerSize();
+ UpdateViewportContainerSizes();
SetNeedsRedraw();
SetNeedsAnimate();
active_tree_->set_needs_update_draw_properties();
@@ -2502,6 +2563,31 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
return layer_impl->ScrollDelta() - previous_delta;
}
+bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll(
+ const gfx::Vector2dF& scroll_delta) const {
+ DCHECK(CurrentlyScrollingLayer());
+
+ if (!top_controls_manager_)
+ return false;
+
+ // Always consume if it's in the direction to show the top controls.
+ if (scroll_delta.y() < 0)
+ return true;
+
+ if (CurrentlyScrollingLayer() != InnerViewportScrollLayer() &&
+ CurrentlyScrollingLayer() != OuterViewportScrollLayer())
+ return false;
+
+ if (InnerViewportScrollLayer()->MaxScrollOffset().y() > 0)
+ return true;
+
+ if (OuterViewportScrollLayer() &&
+ OuterViewportScrollLayer()->MaxScrollOffset().y() > 0)
+ return true;
+
+ return false;
+}
+
bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
@@ -2513,14 +2599,8 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
bool did_scroll_x = false;
bool did_scroll_y = false;
bool did_scroll_top_controls = 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 = ShouldTopControlsConsumeScroll(scroll_delta);
for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
layer_impl;
@@ -2528,23 +2608,20 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
if (!layer_impl->scrollable())
continue;
- 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 (layer_impl == InnerViewportScrollLayer() ||
+ layer_impl == OuterViewportScrollLayer()) {
if (consume_by_top_controls) {
- excess_delta = top_controls_manager_->ScrollBy(pending_delta);
- applied_delta = pending_delta - excess_delta;
+ gfx::Vector2dF excess_delta =
+ top_controls_manager_->ScrollBy(pending_delta);
+ gfx::Vector2dF applied_delta = pending_delta - excess_delta;
pending_delta = excess_delta;
// Force updating of vertical adjust values if needed.
- if (applied_delta.y() != 0) {
+ if (applied_delta.y() != 0)
did_scroll_top_controls = true;
- layer_impl->ScrollbarParametersDidChange(false);
- }
}
// Track root layer deltas for reporting overscroll.
- unused_root_delta = pending_delta;
+ if (layer_impl == InnerViewportScrollLayer())
+ unused_root_delta = pending_delta;
}
gfx::Vector2dF applied_delta;

Powered by Google App Engine
This is Rietveld 408576698