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

Unified Diff: cc/trees/layer_tree_host_impl_unittest.cc

Issue 2243973002: Fix scroll chaining in CC for non-default RootScroller. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Tim's comments Created 4 years, 4 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
« no previous file with comments | « cc/trees/layer_tree_host_impl.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/layer_tree_host_impl_unittest.cc
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 9d1d79f205d53cd44bc88992e000cc39ba853841..3278cb7ab42827967acfd38d2699a276ab70227d 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -6389,6 +6389,138 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
.thread);
}
+// Test that scrolls chain correctly when a child scroller on the page (e.g. a
+// scrolling div) is set as the outer viewport. This happens in the
+// rootScroller proposal.
+TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
+ const gfx::Size content_size(200, 200);
+ const gfx::Size viewport_size(100, 100);
+
+ LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
+
+ LayerImpl* content_layer =
+ CreateBasicVirtualViewportLayers(viewport_size, content_size);
+ LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+
+ LayerImpl* scroll_layer = nullptr;
+ LayerImpl* child_scroll_layer = nullptr;
+
+ // Initialization: Add two nested scrolling layers, simulating a scrolling div
+ // with another scrolling div inside it. Set the outer "div" to be the outer
+ // viewport.
+ {
+ std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
+ clip->SetBounds(content_size);
+ clip->SetPosition(gfx::PointF());
+
+ std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
+ scroll->SetBounds(gfx::Size(400, 400));
+ scroll->SetScrollClipLayer(clip->id());
+ scroll->SetDrawsContent(true);
+
+ std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12);
+ clip2->SetBounds(gfx::Size(300, 300));
+ clip2->SetPosition(gfx::PointF());
+ clip2->SetDrawsContent(true);
+
+ std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13);
+ scroll2->SetBounds(gfx::Size(500, 500));
+ scroll2->SetScrollClipLayer(clip2->id());
+ scroll2->SetDrawsContent(true);
+
+ scroll_layer = scroll.get();
+ child_scroll_layer = scroll2.get();
+
+ clip2->test_properties()->AddChild(std::move(scroll2));
+ scroll->test_properties()->AddChild(std::move(clip2));
+
+ clip->test_properties()->AddChild(std::move(scroll));
+ content_layer->test_properties()->AddChild(std::move(clip));
+ layer_tree_impl->SetViewportLayersFromIds(
+ Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
+ inner_scroll_layer->id(), scroll_layer->id());
+ layer_tree_impl->BuildPropertyTreesForTesting();
+ }
+
+ // Scroll should target the nested scrolling layer in the content and then
+ // chain to the parent scrolling layer which is now set as the outer
+ // viewport. The original outer viewport layer shouldn't get any scroll here.
+ {
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ child_scroll_layer->CurrentScrollOffset());
+
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ outer_scroll_layer->CurrentScrollOffset());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ scroll_layer->CurrentScrollOffset());
+ }
+
+ // Now that the nested scrolling layers are fully scrolled, further scrolls
+ // would normally chain up to the "outer viewport" but since we've set the
+ // scrolling content as the outer viewport, it should stop chaining there.
+ {
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(),
+ outer_scroll_layer->CurrentScrollOffset());
+ }
+
+ // Zoom into the page by a 2X factor so that the inner viewport becomes
+ // scrollable.
+ float min_page_scale = 1.f, max_page_scale = 4.f;
+ float page_scale_factor = 2.f;
+ host_impl_->active_tree()->PushPageScaleFromMainThread(
+ page_scale_factor, min_page_scale, max_page_scale);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
+
+ // Reset the parent scrolling layer (i.e. the current outer viewport) so that
+ // we can ensure viewport scrolling works correctly.
+ scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0));
+
+ // Scrolling the content layer should now scroll the inner viewport first,
+ // and then chain up to the current outer viewport (i.e. the parent scroll
+ // layer).
+ {
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
+ inner_scroll_layer->CurrentScrollOffset());
+
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ outer_scroll_layer->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
+ scroll_layer->CurrentScrollOffset());
+ }
+}
+
TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) {
InputHandlerScrollResult scroll_result;
LayerTreeSettings settings = DefaultSettings();
@@ -9035,6 +9167,64 @@ TEST_F(LayerTreeHostImplWithTopControlsTest,
host_impl_->ScrollEnd(EndState().get());
}
+// Tests that when we set a child scroller (e.g. a scrolling div) as the outer
+// viewport, scrolling it controls the top controls.
+TEST_F(LayerTreeHostImplTopControlsTest,
+ ReplacedOuterViewportScrollsTopControls) {
+ const gfx::Size scroll_content_size(400, 400);
+ const gfx::Size root_layer_size(200, 200);
+ const gfx::Size viewport_size(100, 100);
+
+ SetupTopControlsAndScrollLayerWithVirtualViewport(
+ viewport_size, viewport_size, root_layer_size);
+
+ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
+ LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
+ LayerImpl* scroll_layer = nullptr;
+
+ // Initialization: Add a child scrolling layer to the outer scroll layer and
+ // set its scroll layer as the outer viewport. This simulates setting a
+ // scrolling element as the root scroller on the page.
+ {
+ std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
+ clip->SetBounds(root_layer_size);
+ clip->SetPosition(gfx::PointF());
+
+ std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
+ scroll->SetBounds(scroll_content_size);
+ scroll->SetScrollClipLayer(clip->id());
+ scroll->SetDrawsContent(true);
+
+ scroll_layer = scroll.get();
+
+ clip->test_properties()->AddChild(std::move(scroll));
+ outer_scroll->test_properties()->AddChild(std::move(clip));
+ layer_tree_impl->SetViewportLayersFromIds(
+ Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
+ inner_scroll->id(), scroll_layer->id());
+ layer_tree_impl->BuildPropertyTreesForTesting();
+ DrawFrame();
+ }
+
+ ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+
+ // Scrolling should scroll the child content and the top controls. The
+ // original outer viewport should get no scroll.
+ {
+ host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
+ InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
+ host_impl_->ScrollEnd(EndState().get());
+
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f),
+ scroll_layer->CurrentScrollOffset());
+ EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ }
+}
+
class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
public:
void SetupVirtualViewportLayers(const gfx::Size& content_size,
« no previous file with comments | « cc/trees/layer_tree_host_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698