| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/layer_tree_host_impl.h" | 5 #include "cc/trees/layer_tree_host_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 animation_host_(std::move(animation_host)), | 233 animation_host_(std::move(animation_host)), |
| 234 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 234 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 235 micro_benchmark_controller_(this), | 235 micro_benchmark_controller_(this), |
| 236 shared_bitmap_manager_(shared_bitmap_manager), | 236 shared_bitmap_manager_(shared_bitmap_manager), |
| 237 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | 237 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
| 238 task_graph_runner_(task_graph_runner), | 238 task_graph_runner_(task_graph_runner), |
| 239 id_(id), | 239 id_(id), |
| 240 requires_high_res_to_draw_(false), | 240 requires_high_res_to_draw_(false), |
| 241 is_likely_to_require_a_draw_(false), | 241 is_likely_to_require_a_draw_(false), |
| 242 has_valid_compositor_frame_sink_(false), | 242 has_valid_compositor_frame_sink_(false), |
| 243 mutator_(nullptr) { | 243 mutator_(nullptr), |
| 244 cached_scroll_state_for_fling_(Layer::INVALID_ID, |
| 245 did_lock_scrolling_layer_, |
| 246 scroll_affects_scroll_handler_, |
| 247 accumulated_root_overscroll_) { |
| 244 DCHECK(animation_host_); | 248 DCHECK(animation_host_); |
| 245 animation_host_->SetMutatorHostClient(this); | 249 animation_host_->SetMutatorHostClient(this); |
| 246 | 250 |
| 247 DCHECK(task_runner_provider_->IsImplThread()); | 251 DCHECK(task_runner_provider_->IsImplThread()); |
| 248 DidVisibilityChange(this, visible_); | 252 DidVisibilityChange(this, visible_); |
| 249 | 253 |
| 250 SetDebugState(settings.initial_debug_state); | 254 SetDebugState(settings.initial_debug_state); |
| 251 | 255 |
| 252 // LTHI always has an active tree. | 256 // LTHI always has an active tree. |
| 253 active_tree_ = base::MakeUnique<LayerTreeImpl>( | 257 active_tree_ = base::MakeUnique<LayerTreeImpl>( |
| (...skipping 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 return ScrollBeginImpl(scroll_state, viewport()->MainScrollLayer(), type); | 2639 return ScrollBeginImpl(scroll_state, viewport()->MainScrollLayer(), type); |
| 2636 } | 2640 } |
| 2637 | 2641 |
| 2638 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( | 2642 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( |
| 2639 ScrollState* scroll_state, | 2643 ScrollState* scroll_state, |
| 2640 InputHandler::ScrollInputType type) { | 2644 InputHandler::ScrollInputType type) { |
| 2641 ScrollStatus scroll_status; | 2645 ScrollStatus scroll_status; |
| 2642 scroll_status.main_thread_scrolling_reasons = | 2646 scroll_status.main_thread_scrolling_reasons = |
| 2643 MainThreadScrollingReason::kNotScrollingOnMain; | 2647 MainThreadScrollingReason::kNotScrollingOnMain; |
| 2644 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); | 2648 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin"); |
| 2649 LayerImpl* scrolling_layer_impl = nullptr; |
| 2650 // On Mac a scroll begin with |inertial_phase| = true happens to handle a |
| 2651 // fling. Also, touchpad fling starts are handled by calling ScrollBegin |
| 2652 // instead of FlingScrollBegin. |
| 2653 if (scroll_state->is_in_inertial_phase()) { |
| 2654 RestoreScrollStateForFling(); |
| 2655 scrolling_layer_impl = active_tree_->CurrentlyScrollingLayer(); |
| 2656 } |
| 2645 | 2657 |
| 2646 // On Mac a scroll begin with |inertial_phase| = true happens to handle a | 2658 if (!scrolling_layer_impl) { |
| 2647 // fling. | 2659 ClearCurrentlyScrollingLayer(); |
| 2648 if (scroll_state->is_in_inertial_phase()) | |
| 2649 return FlingScrollBegin(); | |
| 2650 | 2660 |
| 2651 ClearCurrentlyScrollingLayer(); | 2661 gfx::Point viewport_point(scroll_state->position_x(), |
| 2662 scroll_state->position_y()); |
| 2652 | 2663 |
| 2653 gfx::Point viewport_point(scroll_state->position_x(), | 2664 gfx::PointF device_viewport_point = gfx::ScalePoint( |
| 2654 scroll_state->position_y()); | 2665 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); |
| 2666 LayerImpl* layer_impl = |
| 2667 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
| 2655 | 2668 |
| 2656 gfx::PointF device_viewport_point = gfx::ScalePoint( | 2669 if (layer_impl) { |
| 2657 gfx::PointF(viewport_point), active_tree_->device_scale_factor()); | 2670 LayerImpl* scroll_layer_impl = |
| 2658 LayerImpl* layer_impl = | 2671 active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( |
| 2659 active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); | 2672 device_viewport_point); |
| 2673 if (scroll_layer_impl && |
| 2674 !HasScrollAncestor(layer_impl, scroll_layer_impl)) { |
| 2675 scroll_status.thread = SCROLL_UNKNOWN; |
| 2676 scroll_status.main_thread_scrolling_reasons = |
| 2677 MainThreadScrollingReason::kFailedHitTest; |
| 2678 return scroll_status; |
| 2679 } |
| 2680 } |
| 2660 | 2681 |
| 2661 if (layer_impl) { | 2682 bool scroll_on_main_thread = false; |
| 2662 LayerImpl* scroll_layer_impl = | 2683 scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( |
| 2663 active_tree_->FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( | 2684 device_viewport_point, type, layer_impl, &scroll_on_main_thread, |
| 2664 device_viewport_point); | 2685 &scroll_status.main_thread_scrolling_reasons); |
| 2665 if (scroll_layer_impl && | 2686 |
| 2666 !HasScrollAncestor(layer_impl, scroll_layer_impl)) { | 2687 if (scrolling_layer_impl) { |
| 2667 scroll_status.thread = SCROLL_UNKNOWN; | 2688 scroll_affects_scroll_handler_ = |
| 2668 scroll_status.main_thread_scrolling_reasons = | 2689 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); |
| 2669 MainThreadScrollingReason::kFailedHitTest; | 2690 } |
| 2691 |
| 2692 if (scroll_on_main_thread) { |
| 2693 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); |
| 2694 |
| 2695 scroll_status.thread = SCROLL_ON_MAIN_THREAD; |
| 2670 return scroll_status; | 2696 return scroll_status; |
| 2671 } | 2697 } |
| 2672 } | 2698 } |
| 2673 | 2699 |
| 2674 bool scroll_on_main_thread = false; | |
| 2675 LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint( | |
| 2676 device_viewport_point, type, layer_impl, &scroll_on_main_thread, | |
| 2677 &scroll_status.main_thread_scrolling_reasons); | |
| 2678 | |
| 2679 if (scrolling_layer_impl) | |
| 2680 scroll_affects_scroll_handler_ = | |
| 2681 scrolling_layer_impl->layer_tree_impl()->have_scroll_event_handlers(); | |
| 2682 | |
| 2683 if (scroll_on_main_thread) { | |
| 2684 RecordCompositorSlowScrollMetric(type, MAIN_THREAD); | |
| 2685 | |
| 2686 scroll_status.thread = SCROLL_ON_MAIN_THREAD; | |
| 2687 return scroll_status; | |
| 2688 } | |
| 2689 | |
| 2690 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); | 2700 return ScrollBeginImpl(scroll_state, scrolling_layer_impl, type); |
| 2691 } | 2701 } |
| 2692 | 2702 |
| 2693 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( | 2703 InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( |
| 2694 const gfx::Point& viewport_point) { | 2704 const gfx::Point& viewport_point) { |
| 2695 InputHandler::ScrollStatus scroll_status; | 2705 InputHandler::ScrollStatus scroll_status; |
| 2696 scroll_status.main_thread_scrolling_reasons = | 2706 scroll_status.main_thread_scrolling_reasons = |
| 2697 MainThreadScrollingReason::kNotScrollingOnMain; | 2707 MainThreadScrollingReason::kNotScrollingOnMain; |
| 2698 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; | 2708 ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; |
| 2699 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); | 2709 ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2717 // ScrollAnimated is used for animated wheel scrolls. We find the first layer | 2727 // ScrollAnimated is used for animated wheel scrolls. We find the first layer |
| 2718 // that can scroll and set up an animation of its scroll offset. Note that | 2728 // that can scroll and set up an animation of its scroll offset. Note that |
| 2719 // this does not currently go through the scroll customization machinery | 2729 // this does not currently go through the scroll customization machinery |
| 2720 // that ScrollBy uses for non-animated wheel scrolls. | 2730 // that ScrollBy uses for non-animated wheel scrolls. |
| 2721 scroll_status = ScrollBegin(&scroll_state, WHEEL); | 2731 scroll_status = ScrollBegin(&scroll_state, WHEEL); |
| 2722 scroll_node = scroll_tree.CurrentlyScrollingNode(); | 2732 scroll_node = scroll_tree.CurrentlyScrollingNode(); |
| 2723 if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { | 2733 if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { |
| 2724 ScrollStateData scroll_state_end_data; | 2734 ScrollStateData scroll_state_end_data; |
| 2725 scroll_state_end_data.is_ending = true; | 2735 scroll_state_end_data.is_ending = true; |
| 2726 ScrollState scroll_state_end(scroll_state_end_data); | 2736 ScrollState scroll_state_end(scroll_state_end_data); |
| 2727 // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is | |
| 2728 // implemented, the current scrolling layer should not get cleared after | |
| 2729 // each animation (crbug.com/526463). | |
| 2730 ScrollEnd(&scroll_state_end); | 2737 ScrollEnd(&scroll_state_end); |
| 2731 ClearCurrentlyScrollingLayer(); | |
| 2732 } | 2738 } |
| 2733 return scroll_status; | 2739 return scroll_status; |
| 2734 } | 2740 } |
| 2735 | 2741 |
| 2736 gfx::Vector2dF LayerTreeHostImpl::ComputeScrollDelta( | 2742 gfx::Vector2dF LayerTreeHostImpl::ComputeScrollDelta( |
| 2737 ScrollNode* scroll_node, | 2743 ScrollNode* scroll_node, |
| 2738 const gfx::Vector2dF& delta) { | 2744 const gfx::Vector2dF& delta) { |
| 2739 ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree; | 2745 ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree; |
| 2740 float scale_factor = active_tree()->current_page_scale_factor(); | 2746 float scale_factor = active_tree()->current_page_scale_factor(); |
| 2741 | 2747 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2845 gfx::Vector2dF scroll_delta = | 2851 gfx::Vector2dF scroll_delta = |
| 2846 ComputeScrollDelta(scroll_node, pending_delta); | 2852 ComputeScrollDelta(scroll_node, pending_delta); |
| 2847 if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) | 2853 if (ScrollAnimationCreate(scroll_node, scroll_delta, delayed_by)) |
| 2848 return scroll_status; | 2854 return scroll_status; |
| 2849 | 2855 |
| 2850 pending_delta -= scroll_delta; | 2856 pending_delta -= scroll_delta; |
| 2851 } | 2857 } |
| 2852 } | 2858 } |
| 2853 } | 2859 } |
| 2854 scroll_state.set_is_ending(true); | 2860 scroll_state.set_is_ending(true); |
| 2855 // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is | |
| 2856 // implemented, the current scrolling layer should not get cleared after | |
| 2857 // each animation (crbug.com/526463). | |
| 2858 ScrollEnd(&scroll_state); | 2861 ScrollEnd(&scroll_state); |
| 2859 ClearCurrentlyScrollingLayer(); | |
| 2860 | 2862 |
| 2861 return scroll_status; | 2863 return scroll_status; |
| 2862 } | 2864 } |
| 2863 | 2865 |
| 2864 gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( | 2866 gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( |
| 2865 ScrollNode* scroll_node, | 2867 ScrollNode* scroll_node, |
| 2866 const gfx::PointF& viewport_point, | 2868 const gfx::PointF& viewport_point, |
| 2867 const gfx::Vector2dF& viewport_delta, | 2869 const gfx::Vector2dF& viewport_delta, |
| 2868 ScrollTree* scroll_tree) { | 2870 ScrollTree* scroll_tree) { |
| 2869 // Layers with non-invertible screen space transforms should not have passed | 2871 // Layers with non-invertible screen space transforms should not have passed |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3157 | 3159 |
| 3158 client_->SetNeedsCommitOnImplThread(); | 3160 client_->SetNeedsCommitOnImplThread(); |
| 3159 // After applying the synchronous input handler's scroll offset, tell it what | 3161 // After applying the synchronous input handler's scroll offset, tell it what |
| 3160 // we ended up with. | 3162 // we ended up with. |
| 3161 UpdateRootLayerStateForSynchronousInputHandler(); | 3163 UpdateRootLayerStateForSynchronousInputHandler(); |
| 3162 SetFullViewportDamage(); | 3164 SetFullViewportDamage(); |
| 3163 SetNeedsRedraw(); | 3165 SetNeedsRedraw(); |
| 3164 } | 3166 } |
| 3165 | 3167 |
| 3166 void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { | 3168 void LayerTreeHostImpl::ClearCurrentlyScrollingLayer() { |
| 3169 // Cached scrolling variables state is restored in a ScrollBegin with |
| 3170 // inertial phase (fling) to latch it to its corresponding scroll. When |
| 3171 // reseting a variable here, update ScrollStateForFling class as well |
| 3172 // to maintain the proper caching. |
| 3173 CacheScrollStateForFling(); |
| 3167 active_tree_->ClearCurrentlyScrollingLayer(); | 3174 active_tree_->ClearCurrentlyScrollingLayer(); |
| 3168 did_lock_scrolling_layer_ = false; | 3175 did_lock_scrolling_layer_ = false; |
| 3169 scroll_affects_scroll_handler_ = false; | 3176 scroll_affects_scroll_handler_ = false; |
| 3170 accumulated_root_overscroll_ = gfx::Vector2dF(); | 3177 accumulated_root_overscroll_ = gfx::Vector2dF(); |
| 3171 } | 3178 } |
| 3172 | 3179 |
| 3173 void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state) { | 3180 void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state) { |
| 3174 DCHECK(scroll_state); | 3181 DCHECK(scroll_state); |
| 3175 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); | 3182 DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); |
| 3176 | 3183 |
| 3177 DistributeScrollDelta(scroll_state); | 3184 DistributeScrollDelta(scroll_state); |
| 3178 top_controls_manager_->ScrollEnd(); | 3185 top_controls_manager_->ScrollEnd(); |
| 3179 | 3186 |
| 3180 if (scroll_state->is_in_inertial_phase()) { | 3187 ClearCurrentlyScrollingLayer(); |
| 3181 // Only clear the currently scrolling layer if we know the scroll is done. | |
| 3182 // A non-inertial scroll end could be followed by an inertial scroll. | |
| 3183 ClearCurrentlyScrollingLayer(); | |
| 3184 } | |
| 3185 } | 3188 } |
| 3186 | 3189 |
| 3187 InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { | 3190 InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { |
| 3188 InputHandler::ScrollStatus scroll_status; | 3191 InputHandler::ScrollStatus scroll_status; |
| 3189 scroll_status.main_thread_scrolling_reasons = | 3192 scroll_status.main_thread_scrolling_reasons = |
| 3190 MainThreadScrollingReason::kNotScrollingOnMain; | 3193 MainThreadScrollingReason::kNotScrollingOnMain; |
| 3191 if (!CurrentlyScrollingLayer()) { | 3194 if (!CurrentlyScrollingLayer()) { |
| 3192 scroll_status.thread = SCROLL_IGNORED; | 3195 scroll_status.thread = SCROLL_IGNORED; |
| 3193 scroll_status.main_thread_scrolling_reasons = | 3196 scroll_status.main_thread_scrolling_reasons = |
| 3194 MainThreadScrollingReason::kNoScrollingLayer; | 3197 MainThreadScrollingReason::kNoScrollingLayer; |
| (...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4011 return; | 4014 return; |
| 4012 LayerImpl* layer = tree->LayerByElementId(element_id); | 4015 LayerImpl* layer = tree->LayerByElementId(element_id); |
| 4013 if (layer) | 4016 if (layer) |
| 4014 layer->OnIsAnimatingChanged(mask, state); | 4017 layer->OnIsAnimatingChanged(mask, state); |
| 4015 } | 4018 } |
| 4016 | 4019 |
| 4017 void LayerTreeHostImpl::ScrollOffsetAnimationFinished() { | 4020 void LayerTreeHostImpl::ScrollOffsetAnimationFinished() { |
| 4018 // TODO(majidvp): We should pass in the original starting scroll position here | 4021 // TODO(majidvp): We should pass in the original starting scroll position here |
| 4019 ScrollStateData scroll_state_data; | 4022 ScrollStateData scroll_state_data; |
| 4020 ScrollState scroll_state(scroll_state_data); | 4023 ScrollState scroll_state(scroll_state_data); |
| 4021 // TODO(Sahel): Once the touchpad scroll latching for Non-mac devices is | |
| 4022 // implemented, the current scrolling layer should not get cleared after | |
| 4023 // each animation (crbug.com/526463). | |
| 4024 ScrollEnd(&scroll_state); | 4024 ScrollEnd(&scroll_state); |
| 4025 ClearCurrentlyScrollingLayer(); | |
| 4026 } | 4025 } |
| 4027 | 4026 |
| 4028 gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation( | 4027 gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation( |
| 4029 ElementId element_id) const { | 4028 ElementId element_id) const { |
| 4030 if (active_tree()) { | 4029 if (active_tree()) { |
| 4031 LayerImpl* layer = active_tree()->LayerByElementId(element_id); | 4030 LayerImpl* layer = active_tree()->LayerByElementId(element_id); |
| 4032 if (layer) | 4031 if (layer) |
| 4033 return layer->ScrollOffsetForAnimation(); | 4032 return layer->ScrollOffsetForAnimation(); |
| 4034 } | 4033 } |
| 4035 | 4034 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4083 ContextProvider::ScopedContextLock hold(worker_context); | 4082 ContextProvider::ScopedContextLock hold(worker_context); |
| 4084 if (is_visible) { | 4083 if (is_visible) { |
| 4085 worker_context_visibility_ = | 4084 worker_context_visibility_ = |
| 4086 worker_context->CacheController()->ClientBecameVisible(); | 4085 worker_context->CacheController()->ClientBecameVisible(); |
| 4087 } else { | 4086 } else { |
| 4088 worker_context->CacheController()->ClientBecameNotVisible( | 4087 worker_context->CacheController()->ClientBecameNotVisible( |
| 4089 std::move(worker_context_visibility_)); | 4088 std::move(worker_context_visibility_)); |
| 4090 } | 4089 } |
| 4091 } | 4090 } |
| 4092 | 4091 |
| 4092 void LayerTreeHostImpl::CacheScrollStateForFling() { |
| 4093 int scrolling_layer_id = active_tree_->CurrentlyScrollingLayer() |
| 4094 ? active_tree_->CurrentlyScrollingLayer()->id() |
| 4095 : Layer::INVALID_ID; |
| 4096 cached_scroll_state_for_fling_ = ScrollStateForFling( |
| 4097 scrolling_layer_id, did_lock_scrolling_layer_, |
| 4098 scroll_affects_scroll_handler_, accumulated_root_overscroll_); |
| 4099 } |
| 4100 void LayerTreeHostImpl::RestoreScrollStateForFling() { |
| 4101 active_tree_->SetCurrentlyScrollingLayer(active_tree_->LayerById( |
| 4102 cached_scroll_state_for_fling_.scrolling_layer_id())); |
| 4103 did_lock_scrolling_layer_ = |
| 4104 cached_scroll_state_for_fling_.did_lock_scrolling_layer(); |
| 4105 scroll_affects_scroll_handler_ = |
| 4106 cached_scroll_state_for_fling_.scroll_affects_scroll_handler(); |
| 4107 accumulated_root_overscroll_ = |
| 4108 cached_scroll_state_for_fling_.accumulated_root_overscroll(); |
| 4109 } |
| 4110 |
| 4093 } // namespace cc | 4111 } // namespace cc |
| OLD | NEW |