Index: cc/trees/layer_tree_host_impl.cc |
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc |
index 8c4e7498c3110a67a0ec37387251717a43ad5e70..c4d71a2380b3801014c22c332bb8f1243667697e 100644 |
--- a/cc/trees/layer_tree_host_impl.cc |
+++ b/cc/trees/layer_tree_host_impl.cc |
@@ -2538,6 +2538,26 @@ InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll( |
return scroll_status; |
} |
+static bool IsMainThreadScrolling(const InputHandler::ScrollStatus& status, |
+ const ScrollNode* scroll_node, |
+ bool* scroll_on_main_thread, |
+ uint32_t* main_thread_scrolling_reasons) { |
+ if (status.thread == InputHandler::SCROLL_ON_MAIN_THREAD) { |
+ if (!!scroll_node->data.main_thread_scrolling_reasons) { |
+ DCHECK(MainThreadScrollingReason::MainThreadCanSetScrollReasons( |
+ status.main_thread_scrolling_reasons)); |
+ } else { |
+ DCHECK(MainThreadScrollingReason::CompositorCanSetScrollReasons( |
+ status.main_thread_scrolling_reasons)); |
+ } |
+ |
+ *scroll_on_main_thread = true; |
+ *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
const gfx::PointF& device_viewport_point, |
InputHandler::ScrollInputType type, |
@@ -2550,9 +2570,9 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
MainThreadScrollingReason::kNotScrollingOnMain; |
// Walk up the hierarchy and look for a scrollable layer. |
+ ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; |
LayerImpl* potentially_scrolling_layer_impl = NULL; |
if (layer_impl) { |
- ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; |
ScrollNode* scroll_node = scroll_tree.Node(layer_impl->scroll_tree_index()); |
for (; scroll_tree.parent(scroll_node); |
scroll_node = scroll_tree.parent(scroll_node)) { |
@@ -2560,19 +2580,9 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
// thread. |
ScrollStatus status = |
TryScroll(device_viewport_point, type, scroll_tree, scroll_node); |
- if (status.thread == SCROLL_ON_MAIN_THREAD) { |
- if (!!scroll_node->data.main_thread_scrolling_reasons) { |
- DCHECK(MainThreadScrollingReason::MainThreadCanSetScrollReasons( |
- status.main_thread_scrolling_reasons)); |
- } else { |
- DCHECK(MainThreadScrollingReason::CompositorCanSetScrollReasons( |
- status.main_thread_scrolling_reasons)); |
- } |
- |
- *scroll_on_main_thread = true; |
- *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; |
+ if (IsMainThreadScrolling(status, scroll_node, scroll_on_main_thread, |
+ main_thread_scrolling_reasons)) |
return NULL; |
- } |
if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && |
!potentially_scrolling_layer_impl) { |
@@ -2581,10 +2591,10 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
} |
} |
} |
+ |
// Falling back to the root scroll layer ensures generation of root overscroll |
- // notifications while preventing scroll updates from being unintentionally |
- // forwarded to the main thread. The inner viewport layer represents the |
- // viewport during scrolling. |
+ // notifications. The inner viewport layer represents the viewport during |
+ // scrolling. |
if (!potentially_scrolling_layer_impl) |
potentially_scrolling_layer_impl = InnerViewportScrollLayer(); |
@@ -2592,6 +2602,17 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
if (potentially_scrolling_layer_impl == OuterViewportScrollLayer()) |
potentially_scrolling_layer_impl = InnerViewportScrollLayer(); |
+ if (potentially_scrolling_layer_impl) { |
+ // Ensure that final layer scrolls on impl thread (crbug.com/625100) |
+ ScrollNode* scroll_node = |
+ scroll_tree.Node(potentially_scrolling_layer_impl->scroll_tree_index()); |
+ ScrollStatus status = |
+ TryScroll(device_viewport_point, type, scroll_tree, scroll_node); |
+ if (IsMainThreadScrolling(status, scroll_node, scroll_on_main_thread, |
+ main_thread_scrolling_reasons)) |
+ return NULL; |
+ } |
+ |
return potentially_scrolling_layer_impl; |
} |