Chromium Code Reviews| 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 d47f504871741c890f5daf7280c13c7412cf7e2e..9854704dd6ef9b3a0500e2f3f4823068fe90a0c8 100644 |
| --- a/cc/trees/layer_tree_host_impl.cc |
| +++ b/cc/trees/layer_tree_host_impl.cc |
| @@ -156,6 +156,36 @@ void RecordCompositorSlowScrollMetric(InputHandler::ScrollInputType type, |
| } |
| } |
| +// Used to cache scroll related variables that get reset while clearing |
| +// the currently scrolling layer. Cached values are restored in case of a |
| +// scrollBegin in inertial phase (fling) to latch the fling to its |
| +// coresponding scroll event. |
|
tdresser
2016/10/19 15:28:04
corresponding
sahel
2016/10/25 15:34:14
Done.
|
| +class ScrollingVariablesState { |
| + public: |
| + ScrollingVariablesState() { |
| + ScrollingVariablesState(false, false, gfx::Vector2dF()); |
| + } |
| + ScrollingVariablesState(bool did_lock_scrolling_layer, |
| + bool scroll_affects_scroll_handler, |
| + gfx::Vector2dF accumulated_root_overscroll) |
| + : did_lock_scrolling_layer_(did_lock_scrolling_layer), |
| + scroll_affects_scroll_handler_(scroll_affects_scroll_handler), |
| + accumulated_root_overscroll_(accumulated_root_overscroll) {} |
| + |
| + bool didLockScrollingLayer() { return did_lock_scrolling_layer_; } |
| + bool scrollAffectsScrollHandler() { return scroll_affects_scroll_handler_; } |
| + gfx::Vector2dF accumulatedRootOverscroll() { |
| + return accumulated_root_overscroll_; |
| + } |
| + |
| + private: |
| + bool did_lock_scrolling_layer_; |
| + bool scroll_affects_scroll_handler_; |
| + gfx::Vector2dF accumulated_root_overscroll_; |
| +}; |
| + |
| +ScrollingVariablesState CashedScrollingVariablesState; |
|
tdresser
2016/10/19 15:28:04
Variable name should be cached_scrolling_variables
bokan
2016/10/20 15:35:10
Is there a reason for this variable to be a local
sahel
2016/10/25 15:34:14
Done.
sahel
2016/10/25 15:34:14
Acknowledged.
|
| + |
| } // namespace |
| DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer, |
| @@ -265,6 +295,9 @@ LayerTreeHostImpl::LayerTreeHostImpl( |
| top_controls_manager_ = |
| TopControlsManager::Create(this, settings.top_controls_show_threshold, |
| settings.top_controls_hide_threshold); |
| + CashedScrollingVariablesState = ScrollingVariablesState( |
| + did_lock_scrolling_layer_, scroll_affects_scroll_handler_, |
| + accumulated_root_overscroll_); |
| } |
| LayerTreeHostImpl::~LayerTreeHostImpl() { |
| @@ -2643,49 +2676,55 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( |
| scroll_status.main_thread_scrolling_reasons = |
| MainThreadScrollingReason::kNotScrollingOnMain; |
| TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); |
| - |
| + LayerImpl* scrolling_layer_impl = nullptr; |
| // On Mac a scroll begin with |inertial_phase| = true happens to handle a |
| - // fling. |
| - if (scroll_state->is_in_inertial_phase()) |
| - return FlingScrollBegin(); |
| - |
| - ClearCurrentlyScrollingLayer(); |
| + // fling. Also, touchpad fling starts are handled by calling ScrollBegin |
| + // instead of FlingScrollBegin. |
| + if (scroll_state->is_in_inertial_phase()) { |
| + scrolling_layer_impl = |
| + active_tree_->LayerById(active_tree_->LastScrolledLayerId()); |
| + RestoreCachedScrollingVariablesState(); |
| + } |
| - gfx::Point viewport_point(scroll_state->position_x(), |
| - scroll_state->position_y()); |
| + if (!scrolling_layer_impl) { |
| + ClearCurrentlyScrollingLayer(); |
| - gfx::PointF device_viewport_point = gfx::ScalePoint( |
| - gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
| - LayerImpl* layer_impl = |
| - active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
| + gfx::Point viewport_point(scroll_state->position_x(), |
| + scroll_state->position_y()); |
| - if (layer_impl) { |
| - LayerImpl* scroll_layer_impl = |
| - active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( |
| - device_viewport_point); |
| - if (scroll_layer_impl && |
| - !HasScrollAncestor(layer_impl, scroll_layer_impl)) { |
| - scroll_status.thread = SCROLL_UNKNOWN; |
| - scroll_status.main_thread_scrolling_reasons = |
| - MainThreadScrollingReason::kFailedHitTest; |
| - return scroll_status; |
| + gfx::PointF device_viewport_point = gfx::ScalePoint( |
| + gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
| + LayerImpl* layer_impl = |
| + active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
| + |
| + if (layer_impl) { |
| + LayerImpl* scroll_layer_impl = |
| + active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( |
| + device_viewport_point); |
| + if (scroll_layer_impl && |
| + !HasScrollAncestor(layer_impl, scroll_layer_impl)) { |
| + scroll_status.thread = SCROLL_UNKNOWN; |
| + scroll_status.main_thread_scrolling_reasons = |
| + MainThreadScrollingReason::kFailedHitTest; |
| + return scroll_status; |
| + } |
| } |
| - } |
| - bool scroll_on_main_thread = false; |
| - LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( |
| - device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
| - &scroll_status.main_thread_scrolling_reasons); |
| + bool scroll_on_main_thread = false; |
| + scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( |
| + device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
| + &scroll_status.main_thread_scrolling_reasons); |
| - if (scrolling_layer_impl) |
| - scroll_affects_scroll_handler_ = |
| - scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); |
| + if (scrolling_layer_impl) |
| + scroll_affects_scroll_handler_ = |
| + scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); |
| - if (scroll_on_main_thread) { |
| - RecordCompositorSlowScrollMetric(type, MAIN_THREAD); |
| + if (scroll_on_main_thread) { |
| + RecordCompositorSlowScrollMetric(type, MAIN_THREAD); |
| - scroll_status.thread = SCROLL_ON_MAIN_THREAD; |
| - return scroll_status; |
| + scroll_status.thread = SCROLL_ON_MAIN_THREAD; |
| + return scroll_status; |
| + } |
| } |
| return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); |
| @@ -2725,11 +2764,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( |
| ScrollStateData scroll_state_end_data; |
| scroll_state_end_data.is_ending = true; |
| ScrollState scroll_state_end(scroll_state_end_data); |
| - // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is |
| - // implemented, the current scrolling layer should not get cleared after |
| - // each animation (crbug.com/526463). |
| ScrollEnd(&scroll_state_end); |
| - ClearCurrentlyScrollingLayer(); |
| } |
| return scroll_status; |
| } |
| @@ -2854,11 +2889,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( |
| } |
| } |
| scroll_state.set_is_ending(true); |
| - // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is |
| - // implemented, the current scrolling layer should not get cleared after |
| - // each animation (crbug.com/526463). |
| ScrollEnd(&scroll_state); |
| - ClearCurrentlyScrollingLayer(); |
| return scroll_status; |
| } |
| @@ -3166,6 +3197,11 @@ void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset( |
| void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { |
| active_tree_->ClearCurrentlyScrollingLayer(); |
| + // Cached scrolling variables state is restored in a ScrollBegin with |
| + // inertial phase (fling) to latch it to its corresponding scroll. When |
| + // reseting a variable here, update ScrollingVariablesState struct as well |
| + // to maintain the proper caching. |
| + CacheScrollingVariablesState(); |
| did_lock_scrolling_layer_ = false; |
| scroll_affects_scroll_handler_ = false; |
| accumulated_root_overscroll_ = gfx::Vector2dF(); |
| @@ -3178,11 +3214,7 @@ void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state) { |
| DistributeScrollDelta(scroll_state); |
| top_controls_manager_->ScrollEnd(); |
| - if (scroll_state->is_in_inertial_phase()) { |
| - // Only clear the currently scrolling layer if we know the scroll is done. |
| - // A non-inertial scroll end could be followed by an inertial scroll. |
| - ClearCurrentlyScrollingLayer(); |
| - } |
| + ClearCurrentlyScrollingLayer(); |
| } |
| InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { |
| @@ -4022,11 +4054,7 @@ void LayerTreeHostImpl::ScrollOffsetAnimationFinished() { |
| // TODO(majidvp): We should pass in the original starting scroll position here |
| ScrollStateData scroll_state_data; |
| ScrollState scroll_state(scroll_state_data); |
| - // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is |
| - // implemented, the current scrolling layer should not get cleared after |
| - // each animation (crbug.com/526463). |
| ScrollEnd(&scroll_state); |
| - ClearCurrentlyScrollingLayer(); |
| } |
| gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation( |
| @@ -4094,4 +4122,18 @@ void LayerTreeHostImpl::SetWorkerContextVisibility(bool is_visible) { |
| } |
| } |
| +void LayerTreeHostImpl::CacheScrollingVariablesState() { |
| + CashedScrollingVariablesState = ScrollingVariablesState( |
| + did_lock_scrolling_layer_, scroll_affects_scroll_handler_, |
| + accumulated_root_overscroll_); |
| +} |
| +void LayerTreeHostImpl::RestoreCachedScrollingVariablesState() { |
| + did_lock_scrolling_layer_ = |
| + CashedScrollingVariablesState.didLockScrollingLayer(); |
| + scroll_affects_scroll_handler_ = |
| + CashedScrollingVariablesState.scrollAffectsScrollHandler(); |
| + accumulated_root_overscroll_ = |
| + CashedScrollingVariablesState.accumulatedRootOverscroll(); |
| +} |
| + |
| } // namespace cc |