diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-20 05:11:17 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-20 05:11:17 +0000 |
commit | fd0b7f15f54de5eb43d4e6549c5040cae28e2049 (patch) | |
tree | 900d72ff37f0c6330fe7b1277d8feacc357e5cf9 /cc | |
parent | cc633e755ce252c7678cdedbeda80f3d11d9ee61 (diff) | |
download | chromium_src-fd0b7f15f54de5eb43d4e6549c5040cae28e2049.zip chromium_src-fd0b7f15f54de5eb43d4e6549c5040cae28e2049.tar.gz chromium_src-fd0b7f15f54de5eb43d4e6549c5040cae28e2049.tar.bz2 |
cc: Move scrolling tests to layer_tree_host_unittest_scroll.cc
I've implemented some TEST_P type macros for our LayerTreeHost tests, as we
cannot use the real TEST_P since the tests all inherit from the ThreadedTest
class.
I also rolled the ScrollChild vs ScrollRootLayer tests into a single TestCase
class, and used the TEST_P to instantiate it with various device scales for
each scrolling case. (Also our first non-integer device scale test I think!)
R=enne,jamesr
NOTRY=true
Review URL: https://codereview.chromium.org/11638029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174107 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/cc_tests.gyp | 1 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest.cc | 499 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest_scroll.cc | 476 | ||||
-rw-r--r-- | cc/test/layer_tree_test_common.cc | 5 | ||||
-rw-r--r-- | cc/test/layer_tree_test_common.h | 40 |
5 files changed, 521 insertions, 500 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index d0b70a77..b5b57e3 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -30,6 +30,7 @@ 'layer_tree_host_unittest.cc', 'layer_tree_host_unittest_animation.cc', 'layer_tree_host_unittest_occlusion.cc', + 'layer_tree_host_unittest_scroll.cc', 'layer_unittest.cc', 'math_util_unittest.cc', 'nine_patch_layer_impl_unittest.cc', diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc index fd94ca9..331de3b 100644 --- a/cc/layer_tree_host_unittest.cc +++ b/cc/layer_tree_host_unittest.cc @@ -22,7 +22,6 @@ #include "cc/test/occlusion_tracker_test_common.h" #include "cc/timing_function.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/WebKit/Source/Platform/chromium/public/WebLayerScrollClient.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" @@ -622,159 +621,6 @@ TEST_F(LayerTreeHostTestAbortFrameWhenInvisible, runMultiThread) runTest(true); } -class LayerTreeHostTestScrollSimple : public LayerTreeHostTest { -public: - LayerTreeHostTestScrollSimple() - : m_initialScroll(10, 20) - , m_secondScroll(40, 5) - , m_scrollAmount(2, -1) - , m_scrolls(0) - { - } - - virtual void beginTest() OVERRIDE - { - m_layerTreeHost->rootLayer()->setScrollable(true); - m_layerTreeHost->rootLayer()->setScrollOffset(m_initialScroll); - postSetNeedsCommitToMainThread(); - } - - virtual void layout() OVERRIDE - { - Layer* root = m_layerTreeHost->rootLayer(); - if (!m_layerTreeHost->commitNumber()) - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll); - else { - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount); - - // Pretend like Javascript updated the scroll position itself. - root->setScrollOffset(m_secondScroll); - } - } - - virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - LayerImpl* root = impl->rootLayer(); - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); - - root->setScrollable(true); - root->setMaxScrollOffset(gfx::Vector2d(100, 100)); - root->scrollBy(m_scrollAmount); - - if (!impl->activeTree()->source_frame_number()) { - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll); - EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount); - postSetNeedsCommitToMainThread(); - } else if (impl->activeTree()->source_frame_number() == 1) { - EXPECT_VECTOR_EQ(root->scrollOffset(), m_secondScroll); - EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount); - endTest(); - } - } - - virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE - { - gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); - m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta); - m_scrolls++; - } - - virtual void afterTest() OVERRIDE - { - EXPECT_EQ(1, m_scrolls); - } -private: - gfx::Vector2d m_initialScroll; - gfx::Vector2d m_secondScroll; - gfx::Vector2d m_scrollAmount; - int m_scrolls; -}; - -TEST_F(LayerTreeHostTestScrollSimple, runMultiThread) -{ - runTest(true); -} - -class LayerTreeHostTestScrollMultipleRedraw : public LayerTreeHostTest { -public: - LayerTreeHostTestScrollMultipleRedraw() - : m_initialScroll(40, 10) - , m_scrollAmount(-3, 17) - , m_scrolls(0) - { - } - - virtual void beginTest() OVERRIDE - { - m_layerTreeHost->rootLayer()->setScrollable(true); - m_layerTreeHost->rootLayer()->setScrollOffset(m_initialScroll); - postSetNeedsCommitToMainThread(); - } - - virtual void beginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - Layer* root = m_layerTreeHost->rootLayer(); - if (!m_layerTreeHost->commitNumber()) - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll); - else if (m_layerTreeHost->commitNumber() == 1) - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount); - else if (m_layerTreeHost->commitNumber() == 2) - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount); - } - - virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - LayerImpl* root = impl->rootLayer(); - root->setScrollable(true); - root->setMaxScrollOffset(gfx::Vector2d(100, 100)); - - if (!impl->activeTree()->source_frame_number() && impl->sourceAnimationFrameNumber() == 1) { - // First draw after first commit. - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); - root->scrollBy(m_scrollAmount); - EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount); - - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll); - postSetNeedsRedrawToMainThread(); - } else if (!impl->activeTree()->source_frame_number() && impl->sourceAnimationFrameNumber() == 2) { - // Second draw after first commit. - EXPECT_EQ(root->scrollDelta(), m_scrollAmount); - root->scrollBy(m_scrollAmount); - EXPECT_VECTOR_EQ(root->scrollDelta(), m_scrollAmount + m_scrollAmount); - - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll); - postSetNeedsCommitToMainThread(); - } else if (impl->activeTree()->source_frame_number() == 1) { - // Third or later draw after second commit. - EXPECT_GE(impl->sourceAnimationFrameNumber(), 3); - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); - EXPECT_VECTOR_EQ(root->scrollOffset(), m_initialScroll + m_scrollAmount + m_scrollAmount); - endTest(); - } - } - - virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE - { - gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); - m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta); - m_scrolls++; - } - - virtual void afterTest() OVERRIDE - { - EXPECT_EQ(1, m_scrolls); - } -private: - gfx::Vector2d m_initialScroll; - gfx::Vector2d m_scrollAmount; - int m_scrolls; -}; - -TEST_F(LayerTreeHostTestScrollMultipleRedraw, runMultiThread) -{ - runTest(true); -} - // This test verifies that properties on the layer tree host are commited to the impl side. class LayerTreeHostTestCommit : public LayerTreeHostTest { public: @@ -1457,59 +1303,6 @@ TEST_F(LayerTreeHostTestSetRepeatedLostContext, runMultiThread) runTest(true); } -class LayerTreeHostTestFractionalScroll : public LayerTreeHostTest { -public: - LayerTreeHostTestFractionalScroll() - : m_scrollAmount(1.75, 0) - { - } - - virtual void beginTest() OVERRIDE - { - m_layerTreeHost->rootLayer()->setScrollable(true); - postSetNeedsCommitToMainThread(); - } - - virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - LayerImpl* root = impl->rootLayer(); - root->setMaxScrollOffset(gfx::Vector2d(100, 100)); - - // Check that a fractional scroll delta is correctly accumulated over multiple commits. - if (!impl->activeTree()->source_frame_number()) { - EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::Vector2d(0, 0)); - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d(0, 0)); - postSetNeedsCommitToMainThread(); - } else if (impl->activeTree()->source_frame_number() == 1) { - EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::ToFlooredVector2d(m_scrollAmount)); - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2dF(fmod(m_scrollAmount.x(), 1), 0)); - postSetNeedsCommitToMainThread(); - } else if (impl->activeTree()->source_frame_number() == 2) { - EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::ToFlooredVector2d(m_scrollAmount + m_scrollAmount)); - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2dF(fmod(2 * m_scrollAmount.x(), 1), 0)); - endTest(); - } - root->scrollBy(m_scrollAmount); - } - - virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE - { - gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); - m_layerTreeHost->rootLayer()->setScrollOffset(offset + scrollDelta); - } - - virtual void afterTest() OVERRIDE - { - } -private: - gfx::Vector2dF m_scrollAmount; -}; - -TEST_F(LayerTreeHostTestFractionalScroll, runMultiThread) -{ - runTest(true); -} - class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest { public: LayerTreeHostTestFinishAllRendering() @@ -1561,298 +1354,6 @@ private: SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering) -class LayerTreeHostTestScrollChildLayer : public LayerTreeHostTest, public WebKit::WebLayerScrollClient { -public: - LayerTreeHostTestScrollChildLayer(float deviceScaleFactor) - : m_deviceScaleFactor(deviceScaleFactor) - , m_initialScroll(10, 20) - , m_secondScroll(40, 5) - , m_scrollAmount(2, -1) - , m_rootScrolls(0) - { - } - - virtual void beginTest() OVERRIDE - { - gfx::Size viewportSize(10, 10); - gfx::Size deviceViewportSize = gfx::ToCeiledSize(gfx::ScaleSize(viewportSize, m_deviceScaleFactor)); - m_layerTreeHost->setViewportSize(viewportSize, deviceViewportSize); - - m_layerTreeHost->setDeviceScaleFactor(m_deviceScaleFactor); - - m_rootScrollLayer = ContentLayer::create(&m_fakeDelegate); - m_rootScrollLayer->setBounds(gfx::Size(110, 110)); - - m_rootScrollLayer->setPosition(gfx::PointF(0, 0)); - m_rootScrollLayer->setAnchorPoint(gfx::PointF(0, 0)); - - m_rootScrollLayer->setIsDrawable(true); - m_rootScrollLayer->setScrollable(true); - m_rootScrollLayer->setMaxScrollOffset(gfx::Vector2d(100, 100)); - m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer); - - m_childLayer = ContentLayer::create(&m_fakeDelegate); - m_childLayer->setLayerScrollClient(this); - m_childLayer->setBounds(gfx::Size(110, 110)); - - // The scrolls will happen at 5, 5. If they are treated like device pixels, then - // they will be at 2.5, 2.5 in logical pixels, and will miss this layer. - m_childLayer->setPosition(gfx::PointF(5, 5)); - m_childLayer->setAnchorPoint(gfx::PointF(0, 0)); - - m_childLayer->setIsDrawable(true); - m_childLayer->setScrollable(true); - m_childLayer->setMaxScrollOffset(gfx::Vector2d(100, 100)); - m_rootScrollLayer->addChild(m_childLayer); - - m_childLayer->setScrollOffset(m_initialScroll); - - postSetNeedsCommitToMainThread(); - } - - virtual void didScroll() OVERRIDE - { - m_finalScrollOffset = m_childLayer->scrollOffset(); - } - - virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE - { - gfx::Vector2d offset = m_rootScrollLayer->scrollOffset(); - m_rootScrollLayer->setScrollOffset(offset + scrollDelta); - m_rootScrolls++; - } - - virtual void layout() OVERRIDE - { - EXPECT_VECTOR_EQ(gfx::Vector2d(), m_rootScrollLayer->scrollOffset()); - - switch (m_layerTreeHost->commitNumber()) { - case 0: - EXPECT_VECTOR_EQ(m_initialScroll, m_childLayer->scrollOffset()); - break; - case 1: - EXPECT_VECTOR_EQ(m_initialScroll + m_scrollAmount, m_childLayer->scrollOffset()); - - // Pretend like Javascript updated the scroll position itself. - m_childLayer->setScrollOffset(m_secondScroll); - break; - case 2: - EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_childLayer->scrollOffset()); - break; - } - } - - virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - LayerImpl* root = impl->rootLayer(); - LayerImpl* rootScrollLayer = root->children()[0]; - LayerImpl* childLayer = rootScrollLayer->children()[0]; - - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); - EXPECT_VECTOR_EQ(rootScrollLayer->scrollDelta(), gfx::Vector2d()); - EXPECT_EQ(rootScrollLayer->bounds().width() * m_deviceScaleFactor, rootScrollLayer->contentBounds().width()); - EXPECT_EQ(rootScrollLayer->bounds().height() * m_deviceScaleFactor, rootScrollLayer->contentBounds().height()); - EXPECT_EQ(childLayer->bounds().width() * m_deviceScaleFactor, childLayer->contentBounds().width()); - EXPECT_EQ(childLayer->bounds().height() * m_deviceScaleFactor, childLayer->contentBounds().height()); - - switch (impl->activeTree()->source_frame_number()) { - case 0: - // Gesture scroll on impl thread. - EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Gesture), InputHandlerClient::ScrollStarted); - impl->scrollBy(gfx::Point(), m_scrollAmount); - impl->scrollEnd(); - - EXPECT_VECTOR_EQ(m_initialScroll, childLayer->scrollOffset()); - EXPECT_VECTOR_EQ(m_scrollAmount, childLayer->scrollDelta()); - break; - case 1: - // Wheel scroll on impl thread. - EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Wheel), InputHandlerClient::ScrollStarted); - impl->scrollBy(gfx::Point(), m_scrollAmount); - impl->scrollEnd(); - - EXPECT_VECTOR_EQ(m_secondScroll, childLayer->scrollOffset()); - EXPECT_VECTOR_EQ(m_scrollAmount, childLayer->scrollDelta()); - break; - case 2: - EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, childLayer->scrollOffset()); - EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), childLayer->scrollDelta()); - - endTest(); - } - } - - virtual void afterTest() OVERRIDE - { - EXPECT_EQ(0, m_rootScrolls); - EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_finalScrollOffset); - } - -private: - float m_deviceScaleFactor; - gfx::Vector2d m_initialScroll; - gfx::Vector2d m_secondScroll; - gfx::Vector2d m_scrollAmount; - int m_rootScrolls; - gfx::Vector2d m_finalScrollOffset; - - FakeContentLayerClient m_fakeDelegate; - scoped_refptr<Layer> m_rootScrollLayer; - scoped_refptr<Layer> m_childLayer; -}; - -class LayerTreeHostTestScrollChildLayerNormalDpi : public LayerTreeHostTestScrollChildLayer { -public: - LayerTreeHostTestScrollChildLayerNormalDpi() : LayerTreeHostTestScrollChildLayer(1) { } -}; - -TEST_F(LayerTreeHostTestScrollChildLayerNormalDpi, runMultiThread) -{ - runTest(true); -} - -class LayerTreeHostTestScrollChildLayerHighDpi : public LayerTreeHostTestScrollChildLayer { -public: - LayerTreeHostTestScrollChildLayerHighDpi() : LayerTreeHostTestScrollChildLayer(2) { } -}; - -TEST_F(LayerTreeHostTestScrollChildLayerHighDpi, runMultiThread) -{ - runTest(true); -} - -class LayerTreeHostTestScrollRootScrollLayer : public LayerTreeHostTest { -public: - LayerTreeHostTestScrollRootScrollLayer(float deviceScaleFactor) - : m_deviceScaleFactor(deviceScaleFactor) - , m_initialScroll(10, 20) - , m_secondScroll(40, 5) - , m_scrollAmount(2, -1) - , m_rootScrolls(0) - { - } - - virtual void beginTest() OVERRIDE - { - gfx::Size viewportSize(10, 10); - gfx::Size deviceViewportSize = gfx::ToCeiledSize(gfx::ScaleSize(viewportSize, m_deviceScaleFactor)); - m_layerTreeHost->setViewportSize(viewportSize, deviceViewportSize); - - m_layerTreeHost->setDeviceScaleFactor(m_deviceScaleFactor); - - m_rootScrollLayer = ContentLayer::create(&m_fakeDelegate); - m_rootScrollLayer->setBounds(gfx::Size(110, 110)); - - m_rootScrollLayer->setPosition(gfx::PointF(0, 0)); - m_rootScrollLayer->setAnchorPoint(gfx::PointF(0, 0)); - - m_rootScrollLayer->setIsDrawable(true); - m_rootScrollLayer->setScrollable(true); - m_rootScrollLayer->setMaxScrollOffset(gfx::Vector2d(100, 100)); - m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer); - - m_rootScrollLayer->setScrollOffset(m_initialScroll); - - postSetNeedsCommitToMainThread(); - } - - virtual void applyScrollAndScale(gfx::Vector2d scrollDelta, float scale) OVERRIDE - { - gfx::Vector2d offset = m_rootScrollLayer->scrollOffset(); - m_rootScrollLayer->setScrollOffset(offset + scrollDelta); - m_rootScrolls++; - } - - virtual void layout() OVERRIDE - { - switch (m_layerTreeHost->commitNumber()) { - case 0: - EXPECT_VECTOR_EQ(m_initialScroll, m_rootScrollLayer->scrollOffset()); - break; - case 1: - EXPECT_VECTOR_EQ(m_initialScroll + m_scrollAmount, m_rootScrollLayer->scrollOffset()); - - // Pretend like Javascript updated the scroll position itself. - m_rootScrollLayer->setScrollOffset(m_secondScroll); - break; - case 2: - EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, m_rootScrollLayer->scrollOffset()); - break; - } - } - - virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE - { - LayerImpl* root = impl->rootLayer(); - LayerImpl* rootScrollLayer = root->children()[0]; - - EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); - EXPECT_EQ(rootScrollLayer->bounds().width() * m_deviceScaleFactor, rootScrollLayer->contentBounds().width()); - EXPECT_EQ(rootScrollLayer->bounds().height() * m_deviceScaleFactor, rootScrollLayer->contentBounds().height()); - - switch (impl->activeTree()->source_frame_number()) { - case 0: - // Gesture scroll on impl thread. - EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Gesture), InputHandlerClient::ScrollStarted); - impl->scrollBy(gfx::Point(), m_scrollAmount); - impl->scrollEnd(); - - EXPECT_VECTOR_EQ(m_initialScroll, rootScrollLayer->scrollOffset()); - EXPECT_VECTOR_EQ(m_scrollAmount, rootScrollLayer->scrollDelta()); - break; - case 1: - // Wheel scroll on impl thread. - EXPECT_EQ(impl->scrollBegin(gfx::Point(5, 5), InputHandlerClient::Wheel), InputHandlerClient::ScrollStarted); - impl->scrollBy(gfx::Point(), m_scrollAmount); - impl->scrollEnd(); - - EXPECT_VECTOR_EQ(m_secondScroll, rootScrollLayer->scrollOffset()); - EXPECT_VECTOR_EQ(m_scrollAmount, rootScrollLayer->scrollDelta()); - break; - case 2: - EXPECT_VECTOR_EQ(m_secondScroll + m_scrollAmount, rootScrollLayer->scrollOffset()); - EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), rootScrollLayer->scrollDelta()); - - endTest(); - } - } - - virtual void afterTest() OVERRIDE - { - EXPECT_EQ(2, m_rootScrolls); - } - -private: - float m_deviceScaleFactor; - gfx::Vector2d m_initialScroll; - gfx::Vector2d m_secondScroll; - gfx::Vector2d m_scrollAmount; - int m_rootScrolls; - - FakeContentLayerClient m_fakeDelegate; - scoped_refptr<Layer> m_rootScrollLayer; -}; - -class LayerTreeHostTestScrollRootScrollLayerNormalDpi : public LayerTreeHostTestScrollRootScrollLayer { -public: - LayerTreeHostTestScrollRootScrollLayerNormalDpi() : LayerTreeHostTestScrollRootScrollLayer(1) { } -}; - -TEST_F(LayerTreeHostTestScrollRootScrollLayerNormalDpi, runMultiThread) -{ - runTest(true); -} - -class LayerTreeHostTestScrollRootScrollLayerHighDpi : public LayerTreeHostTestScrollRootScrollLayer { -public: - LayerTreeHostTestScrollRootScrollLayerHighDpi() : LayerTreeHostTestScrollRootScrollLayer(2) { } -}; - -TEST_F(LayerTreeHostTestScrollRootScrollLayerHighDpi, runMultiThread) -{ - runTest(true); -} - class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest { public: LayerTreeHostTestCompositeAndReadbackCleanup() { } diff --git a/cc/layer_tree_host_unittest_scroll.cc b/cc/layer_tree_host_unittest_scroll.cc new file mode 100644 index 0000000..15ab63b --- /dev/null +++ b/cc/layer_tree_host_unittest_scroll.cc @@ -0,0 +1,476 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/layer_tree_host.h" + +#include "cc/content_layer.h" +#include "cc/layer.h" +#include "cc/layer_impl.h" +#include "cc/layer_tree_impl.h" +#include "cc/test/fake_content_layer_client.h" +#include "cc/test/geometry_test_utils.h" +#include "cc/test/layer_tree_test_common.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebLayerScrollClient.h" +#include "ui/gfx/point_conversions.h" +#include "ui/gfx/size_conversions.h" +#include "ui/gfx/vector2d_conversions.h" + +namespace cc { +namespace { + +class LayerTreeHostScrollTest : public ThreadedTest {}; + +class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestScrollSimple() + : initial_scroll_(10, 20), + second_scroll_(40, 5), + scroll_amount_(2, -1), + num_scrolls_(0) { + } + + virtual void beginTest() OVERRIDE { + m_layerTreeHost->rootLayer()->setScrollable(true); + m_layerTreeHost->rootLayer()->setScrollOffset(initial_scroll_); + postSetNeedsCommitToMainThread(); + } + + virtual void layout() OVERRIDE { + Layer* root = m_layerTreeHost->rootLayer(); + if (!m_layerTreeHost->commitNumber()) + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_); + else { + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_ + scroll_amount_); + + // Pretend like Javascript updated the scroll position itself. + root->setScrollOffset(second_scroll_); + } + } + + virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + LayerImpl* root = impl->rootLayer(); + EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); + + root->setScrollable(true); + root->setMaxScrollOffset(gfx::Vector2d(100, 100)); + root->scrollBy(scroll_amount_); + + switch (impl->activeTree()->source_frame_number()) { + case 0: + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_); + EXPECT_VECTOR_EQ(root->scrollDelta(), scroll_amount_); + postSetNeedsCommitToMainThread(); + break; + case 1: + EXPECT_VECTOR_EQ(root->scrollOffset(), second_scroll_); + EXPECT_VECTOR_EQ(root->scrollDelta(), scroll_amount_); + endTest(); + break; + } + } + + virtual void applyScrollAndScale( + gfx::Vector2d scroll_delta, float scale) OVERRIDE { + gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); + m_layerTreeHost->rootLayer()->setScrollOffset(offset + scroll_delta); + num_scrolls_++; + } + + virtual void afterTest() OVERRIDE { + EXPECT_EQ(1, num_scrolls_); + } + + private: + gfx::Vector2d initial_scroll_; + gfx::Vector2d second_scroll_; + gfx::Vector2d scroll_amount_; + int num_scrolls_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple) + +class LayerTreeHostScrollTestScrollMultipleRedraw : + public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestScrollMultipleRedraw() + : initial_scroll_(40, 10), + scroll_amount_(-3, 17), + num_scrolls_(0) { + } + + virtual void beginTest() OVERRIDE { + m_layerTreeHost->rootLayer()->setScrollable(true); + m_layerTreeHost->rootLayer()->setScrollOffset(initial_scroll_); + postSetNeedsCommitToMainThread(); + } + + virtual void beginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + Layer* root = m_layerTreeHost->rootLayer(); + switch (m_layerTreeHost->commitNumber()) { + case 0: + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_); + break; + case 1: + EXPECT_VECTOR_EQ( + root->scrollOffset(), + initial_scroll_ + scroll_amount_ + scroll_amount_); + case 2: + EXPECT_VECTOR_EQ( + root->scrollOffset(), + initial_scroll_ + scroll_amount_ + scroll_amount_); + break; + } + } + + virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + LayerImpl* root = impl->rootLayer(); + root->setScrollable(true); + root->setMaxScrollOffset(gfx::Vector2d(100, 100)); + + if (impl->activeTree()->source_frame_number() == 0 && + impl->sourceAnimationFrameNumber() == 1) { + // First draw after first commit. + EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); + root->scrollBy(scroll_amount_); + EXPECT_VECTOR_EQ(root->scrollDelta(), scroll_amount_); + + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_); + postSetNeedsRedrawToMainThread(); + } else if (impl->activeTree()->source_frame_number() == 0 && + impl->sourceAnimationFrameNumber() == 2) { + // Second draw after first commit. + EXPECT_EQ(root->scrollDelta(), scroll_amount_); + root->scrollBy(scroll_amount_); + EXPECT_VECTOR_EQ(root->scrollDelta(), scroll_amount_ + scroll_amount_); + + EXPECT_VECTOR_EQ(root->scrollOffset(), initial_scroll_); + postSetNeedsCommitToMainThread(); + } else if (impl->activeTree()->source_frame_number() == 1) { + // Third or later draw after second commit. + EXPECT_GE(impl->sourceAnimationFrameNumber(), 3); + EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d()); + EXPECT_VECTOR_EQ( + root->scrollOffset(), + initial_scroll_ + scroll_amount_ + scroll_amount_); + endTest(); + } + } + + virtual void applyScrollAndScale( + gfx::Vector2d scroll_delta, float scale) OVERRIDE { + gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); + m_layerTreeHost->rootLayer()->setScrollOffset(offset + scroll_delta); + num_scrolls_++; + } + + virtual void afterTest() OVERRIDE { + EXPECT_EQ(1, num_scrolls_); + } + private: + gfx::Vector2d initial_scroll_; + gfx::Vector2d scroll_amount_; + int num_scrolls_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw) + +class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestFractionalScroll() + : scroll_amount_(1.75, 0) { + } + + virtual void beginTest() OVERRIDE { + m_layerTreeHost->rootLayer()->setScrollable(true); + postSetNeedsCommitToMainThread(); + } + + virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + LayerImpl* root = impl->rootLayer(); + root->setMaxScrollOffset(gfx::Vector2d(100, 100)); + + // Check that a fractional scroll delta is correctly accumulated over + // multiple commits. + switch (impl->activeTree()->source_frame_number()) { + case 0: + EXPECT_VECTOR_EQ(root->scrollOffset(), gfx::Vector2d(0, 0)); + EXPECT_VECTOR_EQ(root->scrollDelta(), gfx::Vector2d(0, 0)); + postSetNeedsCommitToMainThread(); + break; + case 1: + EXPECT_VECTOR_EQ( + root->scrollOffset(), + gfx::ToFlooredVector2d(scroll_amount_)); + EXPECT_VECTOR_EQ( + root->scrollDelta(), + gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f)); + postSetNeedsCommitToMainThread(); + break; + case 2: + EXPECT_VECTOR_EQ( + root->scrollOffset(), + gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_)); + EXPECT_VECTOR_EQ( + root->scrollDelta(), + gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f)); + endTest(); + break; + } + root->scrollBy(scroll_amount_); + } + + virtual void applyScrollAndScale( + gfx::Vector2d scroll_delta, float scale) OVERRIDE { + gfx::Vector2d offset = m_layerTreeHost->rootLayer()->scrollOffset(); + m_layerTreeHost->rootLayer()->setScrollOffset(offset + scroll_delta); + } + + virtual void afterTest() OVERRIDE {} + + private: + gfx::Vector2dF scroll_amount_; +}; + +TEST_F(LayerTreeHostScrollTestFractionalScroll, runMultiThread) +{ + runTest(true); +} + +class LayerTreeHostScrollTestCaseWithChild : + public LayerTreeHostScrollTest, + public WebKit::WebLayerScrollClient { + public: + LayerTreeHostScrollTestCaseWithChild( + float device_scale_factor, bool scroll_child_layer) + : device_scale_factor_(device_scale_factor), + scroll_child_layer_(scroll_child_layer), + initial_offset_(10, 20), + javascript_scroll_(40, 5), + scroll_amount_(2, -1), + num_scrolls_(0) { + } + + virtual void setupTree() OVERRIDE { + m_layerTreeHost->setDeviceScaleFactor(device_scale_factor_); + + scoped_refptr<Layer> root_layer = Layer::create(); + root_layer->setBounds(gfx::Size(10, 10)); + + root_scroll_layer_ = ContentLayer::create(&fake_content_layer_client_); + root_scroll_layer_->setBounds(gfx::Size(110, 110)); + + root_scroll_layer_->setPosition(gfx::Point(0, 0)); + root_scroll_layer_->setAnchorPoint(gfx::PointF()); + + root_scroll_layer_->setIsDrawable(true); + root_scroll_layer_->setScrollable(true); + root_scroll_layer_->setMaxScrollOffset(gfx::Vector2d(100, 100)); + root_layer->addChild(root_scroll_layer_); + + child_layer_ = ContentLayer::create(&fake_content_layer_client_); + child_layer_->setLayerScrollClient(this); + child_layer_->setBounds(gfx::Size(110, 110)); + + // Scrolls on the child layer will happen at 5, 5. If they are treated + // like device pixels, and device scale factor is 2, then they will + // be considered at 2.5, 2.5 in logical pixels, and will miss this layer. + child_layer_->setPosition(gfx::Point(5, 5)); + child_layer_->setAnchorPoint(gfx::PointF()); + + child_layer_->setIsDrawable(true); + child_layer_->setScrollable(true); + child_layer_->setMaxScrollOffset(gfx::Vector2d(100, 100)); + root_scroll_layer_->addChild(child_layer_); + + if (scroll_child_layer_) { + expected_scroll_layer_ = child_layer_; + expected_no_scroll_layer_ = root_scroll_layer_; + } else { + expected_scroll_layer_ = root_scroll_layer_; + expected_no_scroll_layer_ = child_layer_; + } + + expected_scroll_layer_->setScrollOffset(initial_offset_); + + m_layerTreeHost->setRootLayer(root_layer); + LayerTreeHostScrollTest::setupTree(); + } + + virtual void beginTest() OVERRIDE { + postSetNeedsCommitToMainThread(); + } + + virtual void didScroll() OVERRIDE { + final_scroll_offset_ = expected_scroll_layer_->scrollOffset(); + } + + virtual void applyScrollAndScale( + gfx::Vector2d scroll_delta, float scale) OVERRIDE { + gfx::Vector2d offset = root_scroll_layer_->scrollOffset(); + root_scroll_layer_->setScrollOffset(offset + scroll_delta); + num_scrolls_++; + } + + virtual void layout() OVERRIDE { + EXPECT_VECTOR_EQ( + gfx::Vector2d(), expected_no_scroll_layer_->scrollOffset()); + + switch (m_layerTreeHost->commitNumber()) { + case 0: + EXPECT_VECTOR_EQ( + initial_offset_, + expected_scroll_layer_->scrollOffset()); + break; + case 1: + EXPECT_VECTOR_EQ( + initial_offset_ + scroll_amount_, + expected_scroll_layer_->scrollOffset()); + + // Pretend like Javascript updated the scroll position itself. + expected_scroll_layer_->setScrollOffset(javascript_scroll_); + break; + case 2: + EXPECT_VECTOR_EQ( + javascript_scroll_ + scroll_amount_, + expected_scroll_layer_->scrollOffset()); + break; + } + } + + virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + LayerImpl* root_impl = impl->rootLayer(); + LayerImpl* root_scroll_layer_impl = root_impl->children()[0]; + LayerImpl* child_layer_impl = root_scroll_layer_impl->children()[0]; + + LayerImpl* expected_scroll_layer_impl = NULL; + LayerImpl* expected_no_scroll_layer_impl = NULL; + if (scroll_child_layer_) { + expected_scroll_layer_impl = child_layer_impl; + expected_no_scroll_layer_impl = root_scroll_layer_impl; + } else { + expected_scroll_layer_impl = root_scroll_layer_impl; + expected_no_scroll_layer_impl = child_layer_impl; + } + + EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->scrollDelta()); + EXPECT_VECTOR_EQ( + gfx::Vector2d(), + expected_no_scroll_layer_impl->scrollDelta()); + + // Ensure device scale factor is affecting the layers. + gfx::Size expected_content_bounds = gfx::ToCeiledSize( + gfx::ScaleSize(root_scroll_layer_impl->bounds(), device_scale_factor_)); + EXPECT_SIZE_EQ( + expected_content_bounds, + root_scroll_layer_->contentBounds()); + + expected_content_bounds = gfx::ToCeiledSize( + gfx::ScaleSize(child_layer_impl->bounds(), device_scale_factor_)); + EXPECT_SIZE_EQ(expected_content_bounds, child_layer_->contentBounds()); + + switch (impl->activeTree()->source_frame_number()) { + case 0: { + // Gesture scroll on impl thread. + InputHandlerClient::ScrollStatus status = impl->scrollBegin( + gfx::ToCeiledPoint( + expected_scroll_layer_impl->position() + + gfx::Vector2dF(0.5f, 0.5f)), + InputHandlerClient::Gesture); + EXPECT_EQ(InputHandlerClient::ScrollStarted, status); + impl->scrollBy(gfx::Point(), scroll_amount_); + impl->scrollEnd(); + + // Check the scroll is applied as a delta. + EXPECT_VECTOR_EQ( + initial_offset_, + expected_scroll_layer_impl->scrollOffset()); + EXPECT_VECTOR_EQ( + scroll_amount_, + expected_scroll_layer_impl->scrollDelta()); + break; + } + case 1: { + // Wheel scroll on impl thread. + InputHandlerClient::ScrollStatus status = impl->scrollBegin( + gfx::ToCeiledPoint( + expected_scroll_layer_impl->position() + + gfx::Vector2dF(0.5f, 0.5f)), + InputHandlerClient::Wheel); + EXPECT_EQ(InputHandlerClient::ScrollStarted, status); + impl->scrollBy(gfx::Point(), scroll_amount_); + impl->scrollEnd(); + + // Check the scroll is applied as a delta. + EXPECT_VECTOR_EQ( + javascript_scroll_, + expected_scroll_layer_impl->scrollOffset()); + EXPECT_VECTOR_EQ( + scroll_amount_, + expected_scroll_layer_impl->scrollDelta()); + break; + } + case 2: + + EXPECT_VECTOR_EQ( + javascript_scroll_ + scroll_amount_, + expected_scroll_layer_impl->scrollOffset()); + EXPECT_VECTOR_EQ( + gfx::Vector2d(), + expected_scroll_layer_impl->scrollDelta()); + + endTest(); + break; + } + } + + virtual void afterTest() OVERRIDE { + if (scroll_child_layer_) { + EXPECT_EQ(0, num_scrolls_); + EXPECT_VECTOR_EQ( + javascript_scroll_ + scroll_amount_, + final_scroll_offset_); + } else { + EXPECT_EQ(2, num_scrolls_); + EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_); + } + } + + private: + float device_scale_factor_; + bool scroll_child_layer_; + gfx::Vector2d initial_offset_; + gfx::Vector2d javascript_scroll_; + gfx::Vector2d scroll_amount_; + int num_scrolls_; + gfx::Vector2d final_scroll_offset_; + + FakeContentLayerClient fake_content_layer_client_; + + scoped_refptr<Layer> root_scroll_layer_; + scoped_refptr<Layer> child_layer_; + scoped_refptr<Layer> expected_scroll_layer_; + scoped_refptr<Layer> expected_no_scroll_layer_; +}; + +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor1, 1.0f, + ScrollChild, true) +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor15, 1.5f, + ScrollChild, true) +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor2, 2.0f, + ScrollChild, true) +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor1, 1.0f, + ScrollRootScrollLayer, false) +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor15, 1.5f, + ScrollRootScrollLayer, false) +MULTI_THREAD_TEST_P2(LayerTreeHostScrollTestCaseWithChild, + DeviceScaleFactor2, 2.0f, + ScrollRootScrollLayer, false) + +} // namespace +} // namespace cc diff --git a/cc/test/layer_tree_test_common.cc b/cc/test/layer_tree_test_common.cc index 2a251ee..519cc94 100644 --- a/cc/test/layer_tree_test_common.cc +++ b/cc/test/layer_tree_test_common.cc @@ -24,6 +24,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h" +#include "ui/gfx/size_conversions.h" using namespace WebKit; @@ -318,7 +319,9 @@ void ThreadedTest::setupTree() } gfx::Size rootBounds = m_layerTreeHost->rootLayer()->bounds(); - m_layerTreeHost->setViewportSize(rootBounds, rootBounds); + gfx::Size deviceRootBounds = gfx::ToCeiledSize( + gfx::ScaleSize(rootBounds, m_layerTreeHost->deviceScaleFactor())); + m_layerTreeHost->setViewportSize(rootBounds, deviceRootBounds); } void ThreadedTest::timeout() diff --git a/cc/test/layer_tree_test_common.h b/cc/test/layer_tree_test_common.h index bdaac44..9be2059 100644 --- a/cc/test/layer_tree_test_common.h +++ b/cc/test/layer_tree_test_common.h @@ -179,4 +179,44 @@ private: SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME) \ MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) +#define MULTI_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1_NAME, P1) \ + class TEST_FIXTURE_NAME##_##P1_NAME : public TEST_FIXTURE_NAME { \ + public: \ + TEST_FIXTURE_NAME##_##P1_NAME() \ + : TEST_FIXTURE_NAME(P1) {} \ + }; \ + MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME##_##P1) + +#define SINGLE_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1_NAME, P1) \ + class TEST_FIXTURE_NAME##_##P1_NAME : public TEST_FIXTURE_NAME { \ + public: \ + TEST_FIXTURE_NAME##_##P1_NAME() \ + : TEST_FIXTURE_NAME(P1) {} \ + }; \ + SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME##_##P1_NAME) + +#define SINGLE_AND_MULTI_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1_NAME, P1) \ + SINGLE_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1) \ + MULTI_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1) + +#define MULTI_THREAD_TEST_P2(TEST_FIXTURE_NAME, P1_NAME, P1, P2_NAME, P2) \ + class TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME : public TEST_FIXTURE_NAME { \ + public: \ + TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME() \ + : TEST_FIXTURE_NAME(P1, P2) {} \ + }; \ + MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME) + +#define SINGLE_THREAD_TEST_P2(TEST_FIXTURE_NAME, P1_NAME, P1, P2_NAME, P2) \ + class TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME : public TEST_FIXTURE_NAME { \ + public: \ + TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME() \ + : TEST_FIXTURE_NAME(P1, P2) {} \ + }; \ + SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME##_##P1_NAME##_##P2_NAME) + +#define SINGLE_AND_MULTI_THREAD_TEST_P2(TEST_FIXTURE_NAME, P1_NAME, P1, P2_NAME, P2) \ + SINGLE_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1, P2) \ + MULTI_THREAD_TEST_P1(TEST_FIXTURE_NAME, P1, P2) + #endif // CC_TEST_LAYER_TREE_TEST_COMMON_H_ |