diff options
author | ymalik <ymalik@chromium.org> | 2016-02-24 18:44:24 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-25 02:45:18 +0000 |
commit | 002b8a254e34de53be24bea77e3e3ad3fd640f29 (patch) | |
tree | 601e208f9fa38fa11e67cc367dd84cd7487410c2 /cc/layers | |
parent | d63bc982ba3444b1cbc9884cef9e20b2635c66ea (diff) | |
download | chromium_src-002b8a254e34de53be24bea77e3e3ad3fd640f29.zip chromium_src-002b8a254e34de53be24bea77e3e3ad3fd640f29.tar.gz chromium_src-002b8a254e34de53be24bea77e3e3ad3fd640f29.tar.bz2 |
Fix smooth scroll jump when switching scroll handling from MT to CC
To simulate position:sticky, some websites have JS code that conditionally
attaches position:fixed depending on the scroll offset. This CL finishes the
the animations on MT before switching to compositor scrolling.
ScrollingCoordinator proxys the call to clear main thread scrolling reasons to
ScrollAnimator which calls weblayer->clearMTSReasons when the scroll offset
animation is finished. ScrollAnimator adds a temporary main thread scrolling
reason until the animation is finished.
BUG=581875
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1648293003
Cr-Commit-Position: refs/heads/master@{#377476}
Diffstat (limited to 'cc/layers')
-rw-r--r-- | cc/layers/layer.cc | 17 | ||||
-rw-r--r-- | cc/layers/layer.h | 3 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 2 | ||||
-rw-r--r-- | cc/layers/layer_unittest.cc | 51 |
4 files changed, 64 insertions, 9 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index a453f4f..e7053a8 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -966,18 +966,23 @@ void Layer::AddMainThreadScrollingReasons( uint32_t main_thread_scrolling_reasons) { DCHECK(IsPropertyChangeAllowed()); DCHECK(main_thread_scrolling_reasons); - if (main_thread_scrolling_reasons_ == main_thread_scrolling_reasons) + uint32_t new_reasons = + main_thread_scrolling_reasons_ | main_thread_scrolling_reasons; + if (main_thread_scrolling_reasons_ == new_reasons) return; - main_thread_scrolling_reasons_ |= main_thread_scrolling_reasons; + main_thread_scrolling_reasons_ = new_reasons; SetNeedsCommit(); } -void Layer::ClearMainThreadScrollingReasons() { +void Layer::ClearMainThreadScrollingReasons( + uint32_t main_thread_scrolling_reasons_to_clear) { DCHECK(IsPropertyChangeAllowed()); - if (!main_thread_scrolling_reasons_) + DCHECK(main_thread_scrolling_reasons_to_clear); + uint32_t new_reasons = + ~main_thread_scrolling_reasons_to_clear & main_thread_scrolling_reasons_; + if (new_reasons == main_thread_scrolling_reasons_) return; - main_thread_scrolling_reasons_ = - MainThreadScrollingReason::kNotScrollingOnMain; + main_thread_scrolling_reasons_ = new_reasons; SetNeedsCommit(); } diff --git a/cc/layers/layer.h b/cc/layers/layer.h index ff3e806..cdc0fee 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -280,7 +280,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, bool user_scrollable_vertical() const { return user_scrollable_vertical_; } void AddMainThreadScrollingReasons(uint32_t main_thread_scrolling_reasons); - void ClearMainThreadScrollingReasons(); + void ClearMainThreadScrollingReasons( + uint32_t main_thread_scrolling_reasons_to_clear); uint32_t main_thread_scrolling_reasons() const { return main_thread_scrolling_reasons_; } diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 3e23310b8..d4bf384 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -508,11 +508,9 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, uint32_t main_thread_scrolling_reasons) { main_thread_scrolling_reasons_ = main_thread_scrolling_reasons; } - uint32_t main_thread_scrolling_reasons() const { return main_thread_scrolling_reasons_; } - bool should_scroll_on_main_thread() const { return !!main_thread_scrolling_reasons_; } diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index a1d18ae6..1b10a91 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -1547,6 +1547,57 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) { EXPECT_TRUE(test_layer->NeedsDisplayForTesting()); } +TEST_F(LayerTest, TestSettingMainThreadScrollingReason) { + scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, + layer_tree_host_->SetRootLayer(test_layer)); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true)); + + // sanity check of initial test condition + EXPECT_FALSE(test_layer->NeedsDisplayForTesting()); + + uint32_t reasons = 0, reasons_to_clear = 0, reasons_after_clearing = 0; + reasons |= MainThreadScrollingReason::kEventHandlers; + reasons |= MainThreadScrollingReason::kContinuingMainThreadScroll; + reasons |= MainThreadScrollingReason::kScrollbarScrolling; + + reasons_to_clear |= MainThreadScrollingReason::kContinuingMainThreadScroll; + reasons_to_clear |= MainThreadScrollingReason::kThreadedScrollingDisabled; + + reasons_after_clearing |= MainThreadScrollingReason::kEventHandlers; + reasons_after_clearing |= MainThreadScrollingReason::kScrollbarScrolling; + + // Check that the reasons are added correctly. + EXPECT_SET_NEEDS_COMMIT(1, test_layer->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kEventHandlers)); + EXPECT_SET_NEEDS_COMMIT( + 1, test_layer->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kContinuingMainThreadScroll)); + EXPECT_SET_NEEDS_COMMIT(1, + test_layer->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kScrollbarScrolling)); + EXPECT_EQ(reasons, test_layer->main_thread_scrolling_reasons()); + + // Check that the reasons can be selectively cleared. + EXPECT_SET_NEEDS_COMMIT( + 1, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear)); + EXPECT_EQ(reasons_after_clearing, + test_layer->main_thread_scrolling_reasons()); + + // Check that clearing non-set reasons doesn't set needs commit. + reasons_to_clear = 0; + reasons_to_clear |= MainThreadScrollingReason::kThreadedScrollingDisabled; + reasons_to_clear |= MainThreadScrollingReason::kNoScrollingLayer; + EXPECT_SET_NEEDS_COMMIT( + 0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear)); + EXPECT_EQ(reasons_after_clearing, + test_layer->main_thread_scrolling_reasons()); + + // Check that adding an existing condition doesn't set needs commit. + EXPECT_SET_NEEDS_COMMIT(0, test_layer->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kEventHandlers)); +} + TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_); EXPECT_SET_NEEDS_FULL_TREE_SYNC( |