cc: Avoid prefer smoothness mode when scrolling with scroll handler
Avoid going into prefer smoothness mode when the scrolled layer has a
scroll handler. The presence of a scroll handler suggests that the main
thread wants to animate in response to scrolling. Avoiding smoothness
mode gives it a chance to do that while still having our deadline as a
fallback.
BUG=347366
Review URL: https://codereview.chromium.org/206523003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260859 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 072e8e7..5d40bb7f 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -221,6 +221,7 @@
did_lock_scrolling_layer_(false),
should_bubble_scrolls_(false),
wheel_scrolling_(false),
+ scroll_affects_scroll_handler_(false),
scroll_layer_id_when_mouse_over_scrollbar_(0),
tile_priorities_dirty_(false),
root_layer_scroll_offset_delegate_(NULL),
@@ -2030,7 +2031,9 @@
LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint(
const gfx::PointF& device_viewport_point,
InputHandler::ScrollInputType type,
- LayerImpl* layer_impl, bool* scroll_on_main_thread) const {
+ LayerImpl* layer_impl,
+ bool* scroll_on_main_thread,
+ bool* has_ancestor_scroll_handler) const {
DCHECK(scroll_on_main_thread);
// Walk up the hierarchy and look for a scrollable layer.
@@ -2055,6 +2058,10 @@
return NULL;
}
+ if (has_ancestor_scroll_handler &&
+ scroll_layer_impl->have_scroll_event_handlers())
+ *has_ancestor_scroll_handler = true;
+
if (status == ScrollStarted && !potentially_scrolling_layer_impl)
potentially_scrolling_layer_impl = scroll_layer_impl;
}
@@ -2083,8 +2090,11 @@
active_tree_->RenderSurfaceLayerList());
bool scroll_on_main_thread = false;
LayerImpl* potentially_scrolling_layer_impl =
- FindScrollLayerForDeviceViewportPoint(device_viewport_point, type,
- layer_impl, &scroll_on_main_thread);
+ FindScrollLayerForDeviceViewportPoint(device_viewport_point,
+ type,
+ layer_impl,
+ &scroll_on_main_thread,
+ &scroll_affects_scroll_handler_);
if (scroll_on_main_thread) {
UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
@@ -2383,6 +2393,7 @@
void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() {
active_tree_->ClearCurrentlyScrollingLayer();
did_lock_scrolling_layer_ = false;
+ scroll_affects_scroll_handler_ = false;
accumulated_root_overscroll_ = gfx::Vector2dF();
current_fling_velocity_ = gfx::Vector2dF();
}
@@ -2468,9 +2479,12 @@
}
bool scroll_on_main_thread = false;
- LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint(
- device_viewport_point, InputHandler::Gesture, layer_impl,
- &scroll_on_main_thread);
+ LayerImpl* scroll_layer_impl =
+ FindScrollLayerForDeviceViewportPoint(device_viewport_point,
+ InputHandler::Gesture,
+ layer_impl,
+ &scroll_on_main_thread,
+ NULL);
if (scroll_on_main_thread || !scroll_layer_impl)
return;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 10477dc2..2d64a3b 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -284,9 +284,12 @@
LayerImpl* OuterViewportScrollLayer() const;
LayerImpl* CurrentlyScrollingLayer() const;
- int scroll_layer_id_when_mouse_over_scrollbar() {
+ int scroll_layer_id_when_mouse_over_scrollbar() const {
return scroll_layer_id_when_mouse_over_scrollbar_;
}
+ bool scroll_affects_scroll_handler() const {
+ return scroll_affects_scroll_handler_;
+ }
bool IsCurrentlyScrolling() const;
@@ -508,7 +511,8 @@
const gfx::PointF& device_viewport_point,
InputHandler::ScrollInputType type,
LayerImpl* layer_hit_by_point,
- bool* scroll_on_main_thread) const;
+ bool* scroll_on_main_thread,
+ bool* has_ancestor_scroll_handler) const;
float DeviceSpaceDistanceToLayer(const gfx::PointF& device_viewport_point,
LayerImpl* layer_impl);
void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time);
@@ -557,6 +561,7 @@
bool did_lock_scrolling_layer_;
bool should_bubble_scrolls_;
bool wheel_scrolling_;
+ bool scroll_affects_scroll_handler_;
int scroll_layer_id_when_mouse_over_scrollbar_;
bool tile_priorities_dirty_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 351ec356..c20d08f 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -701,6 +701,32 @@
InputHandler::Wheel));
}
+TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) {
+ LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
+ EXPECT_FALSE(scroll_layer->have_scroll_event_handlers());
+ host_impl_->SetViewportSize(gfx::Size(50, 50));
+ DrawFrame();
+
+ EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
+ EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
+ host_impl_->ScrollEnd();
+ EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
+}
+
+TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) {
+ LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
+ scroll_layer->SetHaveScrollEventHandlers(true);
+ host_impl_->SetViewportSize(gfx::Size(50, 50));
+ DrawFrame();
+
+ EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
+ EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler());
+ host_impl_->ScrollEnd();
+ EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
+}
+
TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
SetupScrollAndContentsLayers(gfx::Size(200, 200));
host_impl_->SetViewportSize(gfx::Size(100, 100));
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 8a1547c3..0c0ff9a 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -1626,8 +1626,9 @@
DCHECK(IsImplThread());
bool smoothness_takes_priority =
impl().layer_tree_host_impl->pinch_gesture_active() ||
- impl().layer_tree_host_impl->IsCurrentlyScrolling() ||
- impl().layer_tree_host_impl->page_scale_animation_active();
+ impl().layer_tree_host_impl->page_scale_animation_active() ||
+ (impl().layer_tree_host_impl->IsCurrentlyScrolling() &&
+ !impl().layer_tree_host_impl->scroll_affects_scroll_handler());
base::TimeTicks now = impl().layer_tree_host_impl->CurrentFrameTimeTicks();