summaryrefslogtreecommitdiffstats
path: root/cc/layers
diff options
context:
space:
mode:
authorymalik <ymalik@chromium.org>2016-02-24 18:44:24 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-25 02:45:18 +0000
commit002b8a254e34de53be24bea77e3e3ad3fd640f29 (patch)
tree601e208f9fa38fa11e67cc367dd84cd7487410c2 /cc/layers
parentd63bc982ba3444b1cbc9884cef9e20b2635c66ea (diff)
downloadchromium_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.cc17
-rw-r--r--cc/layers/layer.h3
-rw-r--r--cc/layers/layer_impl.h2
-rw-r--r--cc/layers/layer_unittest.cc51
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(