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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 #include "cc/trees/occlusion_tracker.h" | 68 #include "cc/trees/occlusion_tracker.h" |
69 #include "cc/trees/single_thread_proxy.h" | 69 #include "cc/trees/single_thread_proxy.h" |
70 #include "cc/trees/tree_synchronizer.h" | 70 #include "cc/trees/tree_synchronizer.h" |
71 #include "gpu/command_buffer/client/gles2_interface.h" | 71 #include "gpu/command_buffer/client/gles2_interface.h" |
72 #include "gpu/GLES2/gl2extchromium.h" | 72 #include "gpu/GLES2/gl2extchromium.h" |
73 #include "ui/gfx/frame_time.h" | 73 #include "ui/gfx/frame_time.h" |
74 #include "ui/gfx/geometry/rect_conversions.h" | 74 #include "ui/gfx/geometry/rect_conversions.h" |
75 #include "ui/gfx/size_conversions.h" | 75 #include "ui/gfx/size_conversions.h" |
76 #include "ui/gfx/vector2d_conversions.h" | 76 #include "ui/gfx/vector2d_conversions.h" |
77 | 77 |
78 namespace { | |
79 | |
80 // Small helper class that saves the current viewport location as the user sees | |
81 // it and resets to the same location on destruction. | |
82 class ViewportAnchor { | |
83 public: | |
84 ViewportAnchor(cc::LayerImpl* inner_scroll, cc::LayerImpl* outer_scroll) | |
85 : inner_(inner_scroll) | |
86 , outer_(outer_scroll) { | |
87 viewportInContentCoordinates_ = inner_->TotalScrollOffset(); | |
88 | |
89 if (outer_) | |
90 viewportInContentCoordinates_ += outer_->TotalScrollOffset(); | |
91 } | |
92 | |
93 ~ViewportAnchor() { | |
aelias_OOO_until_Jul13
2014/10/09 20:56:16
I'd prefer this to be an explicit method call rath
bokan
2014/10/09 21:51:37
Done.
| |
94 // No-op scroll to force clamp to maxScrollOffset. | |
95 inner_->ScrollBy(gfx::Vector2dF()); | |
aelias_OOO_until_Jul13
2014/10/09 20:55:13
Please call LayerImpl::ClampScrollToMaxScrollOffse
bokan
2014/10/09 21:51:37
Done.
| |
96 gfx::ScrollOffset viewport_location = inner_->TotalScrollOffset(); | |
97 | |
98 if (outer_) { | |
aelias_OOO_until_Jul13
2014/10/09 20:55:13
These if (outer_) statements are mainly what makes
bokan
2014/10/09 21:51:37
Done. Doesn't even need a guard since it's below t
| |
99 outer_->ScrollBy(gfx::Vector2dF()); | |
100 viewport_location += outer_->TotalScrollOffset(); | |
101 } | |
102 | |
103 gfx::Vector2dF delta = | |
104 viewportInContentCoordinates_.DeltaFrom(viewport_location); | |
105 | |
106 if (outer_) | |
107 delta = outer_->ScrollBy(delta); | |
108 | |
109 inner_->ScrollBy(delta); | |
110 } | |
111 | |
112 private: | |
113 cc::LayerImpl* inner_; | |
114 cc::LayerImpl* outer_; | |
115 gfx::ScrollOffset viewportInContentCoordinates_; | |
aelias_OOO_until_Jul13
2014/10/09 20:55:13
nit: camel-case not Chromium style
bokan
2014/10/09 21:51:37
Done.
| |
116 }; | |
117 | |
118 } // namespace | |
119 | |
78 namespace cc { | 120 namespace cc { |
79 namespace { | 121 namespace { |
80 | 122 |
81 void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { | 123 void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { |
82 if (visible) { | 124 if (visible) { |
83 TRACE_EVENT_ASYNC_BEGIN1("webkit", | 125 TRACE_EVENT_ASYNC_BEGIN1("webkit", |
84 "LayerTreeHostImpl::SetVisible", | 126 "LayerTreeHostImpl::SetVisible", |
85 id, | 127 id, |
86 "LayerTreeHostImpl", | 128 "LayerTreeHostImpl", |
87 id); | 129 id); |
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1646 } | 1688 } |
1647 | 1689 |
1648 void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { | 1690 void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { |
1649 // Sample the frame time now. This time will be used for updating animations | 1691 // Sample the frame time now. This time will be used for updating animations |
1650 // when we draw. | 1692 // when we draw. |
1651 UpdateCurrentBeginFrameArgs(args); | 1693 UpdateCurrentBeginFrameArgs(args); |
1652 // Cache the begin impl frame interval | 1694 // Cache the begin impl frame interval |
1653 begin_impl_frame_interval_ = args.interval; | 1695 begin_impl_frame_interval_ = args.interval; |
1654 } | 1696 } |
1655 | 1697 |
1656 void LayerTreeHostImpl::UpdateInnerViewportContainerSize() { | 1698 void LayerTreeHostImpl::UpdateViewportContainerSizes() { |
1657 LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer(); | 1699 LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer(); |
1658 if (!container_layer) | 1700 LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer(); |
1701 | |
1702 if (!inner_container || !top_controls_manager_) | |
1659 return; | 1703 return; |
1660 | 1704 |
1661 if (top_controls_manager_) { | 1705 { |
1662 container_layer->SetBoundsDelta( | 1706 ViewportAnchor anchor(InnerViewportScrollLayer(), |
aelias_OOO_until_Jul13
2014/10/09 03:51:36
Hmm, could you describe the clamping problem that
bokan
2014/10/09 13:30:13
These issues occur when the viewports are fully sc
aelias_OOO_until_Jul13
2014/10/09 20:55:13
OK, seems alright. Looks like an unavoidable cons
| |
1707 OuterViewportScrollLayer()); | |
1708 | |
1709 // Adjust the inner viewport by shrinking/expanding the container to account | |
1710 // for the change in top controls height since the last Resize from Blink. | |
1711 inner_container->SetBoundsDelta( | |
1663 gfx::Vector2dF(0, active_tree_->top_controls_layout_height() - | 1712 gfx::Vector2dF(0, active_tree_->top_controls_layout_height() - |
1664 active_tree_->total_top_controls_content_offset())); | 1713 active_tree_->total_top_controls_content_offset())); |
1714 | |
1715 if (!outer_container || outer_container->bounds().IsEmpty()) | |
1716 return; | |
1717 | |
1718 // Adjust the outer viewport container as well, since adjusting only the | |
1719 // inner may cause its bounds to exceed those of the outer, causing scroll | |
1720 // clamping. We adjust it so it maintains the same aspect ratio as the | |
1721 // inner viewport. | |
1722 float aspect_ratio = inner_container->bounds().width() / | |
1723 inner_container->bounds().height(); | |
1724 float target_height = outer_container->bounds().width() / aspect_ratio; | |
1725 float current_outer_height = outer_container->bounds().height() - | |
1726 outer_container->bounds_delta().y(); | |
1727 gfx::Vector2dF delta(0, target_height - current_outer_height); | |
1728 | |
1729 outer_container->SetBoundsDelta(delta); | |
1730 active_tree_->InnerViewportScrollLayer()->SetBoundsDelta(delta); | |
1665 } | 1731 } |
1666 } | 1732 } |
1667 | 1733 |
1668 void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) { | 1734 void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) { |
1669 if (active_tree_->top_controls_layout_height() == height) | 1735 if (active_tree_->top_controls_layout_height() == height) |
1670 return; | 1736 return; |
1671 | 1737 |
1672 active_tree_->set_top_controls_layout_height(height); | 1738 active_tree_->set_top_controls_layout_height(height); |
1673 UpdateInnerViewportContainerSize(); | 1739 UpdateViewportContainerSizes(); |
1674 SetFullRootLayerDamage(); | 1740 SetFullRootLayerDamage(); |
1675 } | 1741 } |
1676 | 1742 |
1677 void LayerTreeHostImpl::DidLoseOutputSurface() { | 1743 void LayerTreeHostImpl::DidLoseOutputSurface() { |
1678 if (resource_provider_) | 1744 if (resource_provider_) |
1679 resource_provider_->DidLoseOutputSurface(); | 1745 resource_provider_->DidLoseOutputSurface(); |
1680 client_->DidLoseOutputSurfaceOnImplThread(); | 1746 client_->DidLoseOutputSurfaceOnImplThread(); |
1681 } | 1747 } |
1682 | 1748 |
1683 bool LayerTreeHostImpl::HaveRootScrollLayer() const { | 1749 bool LayerTreeHostImpl::HaveRootScrollLayer() const { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1784 | 1850 |
1785 active_tree_->SetRootLayerScrollOffsetDelegate( | 1851 active_tree_->SetRootLayerScrollOffsetDelegate( |
1786 root_layer_scroll_offset_delegate_); | 1852 root_layer_scroll_offset_delegate_); |
1787 | 1853 |
1788 if (top_controls_manager_) { | 1854 if (top_controls_manager_) { |
1789 top_controls_manager_->SetControlsTopOffset( | 1855 top_controls_manager_->SetControlsTopOffset( |
1790 active_tree_->total_top_controls_content_offset() - | 1856 active_tree_->total_top_controls_content_offset() - |
1791 top_controls_manager_->top_controls_height()); | 1857 top_controls_manager_->top_controls_height()); |
1792 } | 1858 } |
1793 | 1859 |
1794 UpdateInnerViewportContainerSize(); | 1860 UpdateViewportContainerSizes(); |
1795 } else { | 1861 } else { |
1796 active_tree_->ProcessUIResourceRequestQueue(); | 1862 active_tree_->ProcessUIResourceRequestQueue(); |
1797 } | 1863 } |
1798 | 1864 |
1799 active_tree_->DidBecomeActive(); | 1865 active_tree_->DidBecomeActive(); |
1800 ActivateAnimations(); | 1866 ActivateAnimations(); |
1801 if (settings_.impl_side_painting) | 1867 if (settings_.impl_side_painting) |
1802 client_->RenewTreePriority(); | 1868 client_->RenewTreePriority(); |
1803 | 1869 |
1804 client_->OnCanDrawStateChanged(CanDraw()); | 1870 client_->OnCanDrawStateChanged(CanDraw()); |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2147 | 2213 |
2148 void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { | 2214 void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { |
2149 if (device_viewport_size == device_viewport_size_) | 2215 if (device_viewport_size == device_viewport_size_) |
2150 return; | 2216 return; |
2151 | 2217 |
2152 if (pending_tree_) | 2218 if (pending_tree_) |
2153 active_tree_->SetViewportSizeInvalid(); | 2219 active_tree_->SetViewportSizeInvalid(); |
2154 | 2220 |
2155 device_viewport_size_ = device_viewport_size; | 2221 device_viewport_size_ = device_viewport_size; |
2156 | 2222 |
2157 UpdateInnerViewportContainerSize(); | 2223 UpdateViewportContainerSizes(); |
2158 client_->OnCanDrawStateChanged(CanDraw()); | 2224 client_->OnCanDrawStateChanged(CanDraw()); |
2159 SetFullRootLayerDamage(); | 2225 SetFullRootLayerDamage(); |
2160 active_tree_->set_needs_update_draw_properties(); | 2226 active_tree_->set_needs_update_draw_properties(); |
2161 } | 2227 } |
2162 | 2228 |
2163 void LayerTreeHostImpl::SetOverhangUIResource( | 2229 void LayerTreeHostImpl::SetOverhangUIResource( |
2164 UIResourceId overhang_ui_resource_id, | 2230 UIResourceId overhang_ui_resource_id, |
2165 const gfx::Size& overhang_ui_resource_size) { | 2231 const gfx::Size& overhang_ui_resource_size) { |
2166 overhang_ui_resource_id_ = overhang_ui_resource_id; | 2232 overhang_ui_resource_id_ = overhang_ui_resource_id; |
2167 overhang_ui_resource_size_ = overhang_ui_resource_size; | 2233 overhang_ui_resource_size_ = overhang_ui_resource_size; |
(...skipping 30 matching lines...) Expand all Loading... | |
2198 return DeviceViewport(); | 2264 return DeviceViewport(); |
2199 | 2265 |
2200 return external_clip_; | 2266 return external_clip_; |
2201 } | 2267 } |
2202 | 2268 |
2203 const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { | 2269 const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { |
2204 return external_transform_; | 2270 return external_transform_; |
2205 } | 2271 } |
2206 | 2272 |
2207 void LayerTreeHostImpl::DidChangeTopControlsPosition() { | 2273 void LayerTreeHostImpl::DidChangeTopControlsPosition() { |
2208 UpdateInnerViewportContainerSize(); | 2274 UpdateViewportContainerSizes(); |
2209 SetNeedsRedraw(); | 2275 SetNeedsRedraw(); |
2210 SetNeedsAnimate(); | 2276 SetNeedsAnimate(); |
2211 active_tree_->set_needs_update_draw_properties(); | 2277 active_tree_->set_needs_update_draw_properties(); |
2212 SetFullRootLayerDamage(); | 2278 SetFullRootLayerDamage(); |
2213 } | 2279 } |
2214 | 2280 |
2215 void LayerTreeHostImpl::SetControlsTopOffset(float offset) { | 2281 void LayerTreeHostImpl::SetControlsTopOffset(float offset) { |
2216 float current_top_offset = active_tree_->top_controls_content_offset() - | 2282 float current_top_offset = active_tree_->top_controls_content_offset() - |
2217 top_controls_manager_->top_controls_height(); | 2283 top_controls_manager_->top_controls_height(); |
2218 active_tree_->set_top_controls_delta(offset - current_top_offset); | 2284 active_tree_->set_top_controls_delta(offset - current_top_offset); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2494 return actual_viewport_end_point - viewport_point; | 2560 return actual_viewport_end_point - viewport_point; |
2495 } | 2561 } |
2496 | 2562 |
2497 static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, | 2563 static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, |
2498 const gfx::Vector2dF& local_delta) { | 2564 const gfx::Vector2dF& local_delta) { |
2499 gfx::Vector2dF previous_delta(layer_impl->ScrollDelta()); | 2565 gfx::Vector2dF previous_delta(layer_impl->ScrollDelta()); |
2500 layer_impl->ScrollBy(local_delta); | 2566 layer_impl->ScrollBy(local_delta); |
2501 return layer_impl->ScrollDelta() - previous_delta; | 2567 return layer_impl->ScrollDelta() - previous_delta; |
2502 } | 2568 } |
2503 | 2569 |
2570 bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll( | |
2571 const gfx::Vector2dF& scroll_delta) const { | |
2572 if (!top_controls_manager_ || !CurrentlyScrollingLayer()) | |
aelias_OOO_until_Jul13
2014/10/09 20:55:13
!CurrentlyScrollingLayer() condition is unnecessar
bokan
2014/10/09 21:51:37
Done.
| |
2573 return false; | |
2574 | |
2575 // Always consume if it's in the direction to show the top controls. | |
2576 if (scroll_delta.y() < 0) | |
2577 return true; | |
2578 | |
2579 if (CurrentlyScrollingLayer() != InnerViewportScrollLayer() && | |
2580 CurrentlyScrollingLayer() != OuterViewportScrollLayer()) | |
2581 return false; | |
2582 | |
2583 if (InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) | |
2584 return true; | |
2585 | |
2586 if (OuterViewportScrollLayer() && | |
2587 OuterViewportScrollLayer()->MaxScrollOffset().y() > 0) | |
2588 return true; | |
2589 | |
2590 return false; | |
2591 } | |
2592 | |
2504 bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, | 2593 bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, |
2505 const gfx::Vector2dF& scroll_delta) { | 2594 const gfx::Vector2dF& scroll_delta) { |
2506 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); | 2595 TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); |
2507 if (!CurrentlyScrollingLayer()) | 2596 if (!CurrentlyScrollingLayer()) |
2508 return false; | 2597 return false; |
2509 | 2598 |
2510 gfx::Vector2dF pending_delta = scroll_delta; | 2599 gfx::Vector2dF pending_delta = scroll_delta; |
2511 gfx::Vector2dF unused_root_delta; | 2600 gfx::Vector2dF unused_root_delta; |
2512 bool did_scroll_x = false; | 2601 bool did_scroll_x = false; |
2513 bool did_scroll_y = false; | 2602 bool did_scroll_y = false; |
2514 bool did_scroll_top_controls = false; | 2603 bool did_scroll_top_controls = false; |
2515 // TODO(wjmaclean) Should we guard against CurrentlyScrollingLayer() == 0 | 2604 |
2516 // here? | 2605 bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta); |
2517 bool consume_by_top_controls = | |
2518 top_controls_manager_ && | |
2519 (((CurrentlyScrollingLayer() == InnerViewportScrollLayer() || | |
2520 CurrentlyScrollingLayer() == OuterViewportScrollLayer()) && | |
2521 InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) || | |
2522 scroll_delta.y() < 0); | |
2523 | 2606 |
2524 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); | 2607 for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); |
2525 layer_impl; | 2608 layer_impl; |
2526 layer_impl = layer_impl->parent()) { | 2609 layer_impl = layer_impl->parent()) { |
2527 if (!layer_impl->scrollable()) | 2610 if (!layer_impl->scrollable()) |
2528 continue; | 2611 continue; |
2529 | 2612 |
2530 if (layer_impl == InnerViewportScrollLayer()) { | 2613 if (layer_impl == InnerViewportScrollLayer() || |
2531 // Only allow bubble scrolling when the scroll is in the direction to make | 2614 layer_impl == OuterViewportScrollLayer()) { |
2532 // the top controls visible. | |
2533 gfx::Vector2dF applied_delta; | |
2534 gfx::Vector2dF excess_delta; | |
2535 if (consume_by_top_controls) { | 2615 if (consume_by_top_controls) { |
2536 excess_delta = top_controls_manager_->ScrollBy(pending_delta); | 2616 gfx::Vector2dF excess_delta = |
2537 applied_delta = pending_delta - excess_delta; | 2617 top_controls_manager_->ScrollBy(pending_delta); |
2618 gfx::Vector2dF applied_delta = pending_delta - excess_delta; | |
2538 pending_delta = excess_delta; | 2619 pending_delta = excess_delta; |
2539 // Force updating of vertical adjust values if needed. | 2620 // Force updating of vertical adjust values if needed. |
2540 if (applied_delta.y() != 0) { | 2621 if (applied_delta.y() != 0) |
2541 did_scroll_top_controls = true; | 2622 did_scroll_top_controls = true; |
2542 layer_impl->ScrollbarParametersDidChange(false); | |
bokan
2014/10/08 23:03:55
I think this is unneeded, it gets called when the
| |
2543 } | |
2544 } | 2623 } |
2545 // Track root layer deltas for reporting overscroll. | 2624 // Track root layer deltas for reporting overscroll. |
2546 unused_root_delta = pending_delta; | 2625 if (layer_impl == InnerViewportScrollLayer()) |
2626 unused_root_delta = pending_delta; | |
2547 } | 2627 } |
2548 | 2628 |
2549 gfx::Vector2dF applied_delta; | 2629 gfx::Vector2dF applied_delta; |
2550 // Gesture events need to be transformed from viewport coordinates to local | 2630 // Gesture events need to be transformed from viewport coordinates to local |
2551 // layer coordinates so that the scrolling contents exactly follow the | 2631 // layer coordinates so that the scrolling contents exactly follow the |
2552 // user's finger. In contrast, wheel events represent a fixed amount of | 2632 // user's finger. In contrast, wheel events represent a fixed amount of |
2553 // scrolling so we can just apply them directly. | 2633 // scrolling so we can just apply them directly. |
2554 if (!wheel_scrolling_) { | 2634 if (!wheel_scrolling_) { |
2555 float scale_from_viewport_to_screen_space = device_scale_factor_; | 2635 float scale_from_viewport_to_screen_space = device_scale_factor_; |
2556 applied_delta = | 2636 applied_delta = |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3380 } | 3460 } |
3381 | 3461 |
3382 void LayerTreeHostImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { | 3462 void LayerTreeHostImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { |
3383 std::vector<PictureLayerImpl*>::iterator it = | 3463 std::vector<PictureLayerImpl*>::iterator it = |
3384 std::find(picture_layers_.begin(), picture_layers_.end(), layer); | 3464 std::find(picture_layers_.begin(), picture_layers_.end(), layer); |
3385 DCHECK(it != picture_layers_.end()); | 3465 DCHECK(it != picture_layers_.end()); |
3386 picture_layers_.erase(it); | 3466 picture_layers_.erase(it); |
3387 } | 3467 } |
3388 | 3468 |
3389 } // namespace cc | 3469 } // namespace cc |
OLD | NEW |