blob: 949cf84769e153cf8a8a7e90a0788041f2688817 [file] [log] [blame]
[email protected]3b31c6ac2012-12-06 21:27:291// Copyright 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/layer_tree_impl.h"
6
[email protected]76ffd9e2012-12-20 19:12:477#include "base/debug/trace_event.h"
[email protected]3b31c6ac2012-12-06 21:27:298#include "cc/layer_tree_host_common.h"
9#include "cc/layer_tree_host_impl.h"
[email protected]caa567d2012-12-20 07:56:1610#include "ui/gfx/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2911
12namespace cc {
13
[email protected]8bef40572012-12-11 21:38:0814LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
15 : layer_tree_host_impl_(layer_tree_host_impl)
[email protected]3b31c6ac2012-12-06 21:27:2916 , source_frame_number_(-1)
17 , hud_layer_(0)
18 , root_scroll_layer_(0)
19 , currently_scrolling_layer_(0)
20 , scrolling_layer_id_from_previous_tree_(0) {
21}
22
23LayerTreeImpl::~LayerTreeImpl() {
[email protected]361bc00d2012-12-14 07:03:2424 // Need to explicitly clear the tree prior to destroying this so that
25 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
26 root_layer_.reset();
[email protected]3b31c6ac2012-12-06 21:27:2927}
28
29static LayerImpl* findRootScrollLayer(LayerImpl* layer)
30{
31 if (!layer)
32 return 0;
33
34 if (layer->scrollable())
35 return layer;
36
37 for (size_t i = 0; i < layer->children().size(); ++i) {
38 LayerImpl* found = findRootScrollLayer(layer->children()[i]);
39 if (found)
40 return found;
41 }
42
43 return 0;
44}
45
46void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
47 root_layer_ = layer.Pass();
48 root_scroll_layer_ = findRootScrollLayer(root_layer_.get());
49 currently_scrolling_layer_ = 0;
50
51 if (root_layer_ && scrolling_layer_id_from_previous_tree_) {
52 currently_scrolling_layer_ = LayerTreeHostCommon::findLayerInSubtree(
53 root_layer_.get(),
54 scrolling_layer_id_from_previous_tree_);
55 }
56
57 scrolling_layer_id_from_previous_tree_ = 0;
58
[email protected]8bef40572012-12-11 21:38:0859 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
[email protected]3b31c6ac2012-12-06 21:27:2960}
61
62scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
63 // Clear all data structures that have direct references to the layer tree.
64 scrolling_layer_id_from_previous_tree_ =
65 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
66 currently_scrolling_layer_ = NULL;
67
[email protected]76ffd9e2012-12-20 19:12:4768 render_surface_layer_list_.clear();
69 SetNeedsUpdateDrawProperties();
[email protected]3b31c6ac2012-12-06 21:27:2970 return root_layer_.Pass();
71}
72
73void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
74 currently_scrolling_layer_ = NULL;
75 scrolling_layer_id_from_previous_tree_ = 0;
76}
77
[email protected]caa567d2012-12-20 07:56:1678void LayerTreeImpl::UpdateMaxScrollOffset() {
79 if (!root_scroll_layer() || !root_scroll_layer()->children().size())
80 return;
81
82 gfx::SizeF view_bounds = device_viewport_size();
83 if (LayerImpl* clip_layer = root_scroll_layer()->parent()) {
84 // Compensate for non-overlay scrollbars.
85 if (clip_layer->masksToBounds())
86 view_bounds = gfx::ScaleSize(clip_layer->bounds(), device_scale_factor());
87 }
88
89 gfx::Size content_bounds = ContentSize();
90 if (settings().pageScalePinchZoomEnabled) {
91 // Pinch with pageScale scrolls entirely in layout space. ContentSize
92 // returns the bounds including the page scale factor, so calculate the
93 // pre page-scale layout size here.
94 float page_scale_factor = pinch_zoom_viewport().pageScaleFactor();
95 content_bounds.set_width(content_bounds.width() / page_scale_factor);
96 content_bounds.set_height(content_bounds.height() / page_scale_factor);
97 } else {
98 view_bounds.Scale(1 / pinch_zoom_viewport().pageScaleDelta());
99 }
100
101 gfx::Vector2dF max_scroll = gfx::Rect(content_bounds).bottom_right() -
102 gfx::RectF(view_bounds).bottom_right();
103 max_scroll.Scale(1 / device_scale_factor());
104
105 // The viewport may be larger than the contents in some cases, such as
106 // having a vertical scrollbar but no horizontal overflow.
107 max_scroll.ClampToMin(gfx::Vector2dF());
108
109 root_scroll_layer()->setMaxScrollOffset(gfx::ToFlooredVector2d(max_scroll));
110}
111
[email protected]76ffd9e2012-12-20 19:12:47112void LayerTreeImpl::UpdateDrawProperties() {
113 render_surface_layer_list_.clear();
114 if (!RootLayer())
115 return;
116
117 if (root_scroll_layer()) {
118 root_scroll_layer()->setImplTransform(
119 layer_tree_host_impl_->implTransform());
120 }
121
122 {
123 TRACE_EVENT0("cc", "LayerTreeImpl::UpdateDrawProperties");
124 LayerTreeHostCommon::calculateDrawProperties(
125 RootLayer(),
126 device_viewport_size(),
127 device_scale_factor(),
128 pinch_zoom_viewport().pageScaleFactor(),
129 layer_tree_host_impl_->rendererCapabilities().maxTextureSize,
130 settings().canUseLCDText,
131 render_surface_layer_list_);
132 }
133}
134
135static void ClearRenderSurfacesOnLayerImplRecursive(LayerImpl* current)
136{
137 DCHECK(current);
138 for (size_t i = 0; i < current->children().size(); ++i)
139 ClearRenderSurfacesOnLayerImplRecursive(current->children()[i]);
140 current->clearRenderSurface();
141}
142
143void LayerTreeImpl::ClearRenderSurfaces() {
144 ClearRenderSurfacesOnLayerImplRecursive(RootLayer());
145 render_surface_layer_list_.clear();
146 SetNeedsUpdateDrawProperties();
147}
148
149const LayerTreeImpl::LayerList& LayerTreeImpl::RenderSurfaceLayerList() const {
150 // If this assert triggers, then the list is dirty.
151 DCHECK(!layer_tree_host_impl_->needsUpdateDrawProperties());
152 return render_surface_layer_list_;
153}
154
[email protected]caa567d2012-12-20 07:56:16155gfx::Size LayerTreeImpl::ContentSize() const {
156 // TODO(aelias): Hardcoding the first child here is weird. Think of
157 // a cleaner way to get the contentBounds on the Impl side.
158 if (!root_scroll_layer() || root_scroll_layer()->children().isEmpty())
159 return gfx::Size();
160 return root_scroll_layer()->children()[0]->contentBounds();
161}
162
[email protected]361bc00d2012-12-14 07:03:24163LayerImpl* LayerTreeImpl::LayerById(int id) {
164 LayerIdMap::iterator iter = layer_id_map_.find(id);
165 return iter != layer_id_map_.end() ? iter->second : NULL;
166}
167
168void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
169 DCHECK(!LayerById(layer->id()));
170 layer_id_map_[layer->id()] = layer;
171}
172
173void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
174 DCHECK(LayerById(layer->id()));
175 layer_id_map_.erase(layer->id());
176}
177
[email protected]ff762fb2012-12-12 19:18:37178const LayerTreeSettings& LayerTreeImpl::settings() const {
179 return layer_tree_host_impl_->settings();
180}
181
182OutputSurface* LayerTreeImpl::output_surface() const {
183 return layer_tree_host_impl_->outputSurface();
184}
185
186ResourceProvider* LayerTreeImpl::resource_provider() const {
187 return layer_tree_host_impl_->resourceProvider();
188}
189
190TileManager* LayerTreeImpl::tile_manager() const {
191 return layer_tree_host_impl_->tileManager();
192}
193
194FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
195 return layer_tree_host_impl_->fpsCounter();
196}
197
[email protected]f117a4c2012-12-16 04:53:10198bool LayerTreeImpl::IsActiveTree() const {
199 return layer_tree_host_impl_->activeTree() == this;
200}
201
202bool LayerTreeImpl::IsPendingTree() const {
203 return layer_tree_host_impl_->pendingTree() == this;
204}
205
206LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
207 LayerTreeImpl* tree = layer_tree_host_impl_->activeTree();
208 if (!tree)
209 return NULL;
210 return tree->LayerById(id);
211}
212
213LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
214 LayerTreeImpl* tree = layer_tree_host_impl_->pendingTree();
215 if (!tree)
216 return NULL;
217 return tree->LayerById(id);
218}
219
[email protected]ff762fb2012-12-12 19:18:37220void LayerTreeImpl::SetNeedsRedraw() {
221 layer_tree_host_impl_->setNeedsRedraw();
222}
223
224void LayerTreeImpl::SetNeedsUpdateDrawProperties() {
225 layer_tree_host_impl_->setNeedsUpdateDrawProperties();
226}
227
228const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
229 return layer_tree_host_impl_->debugState();
230}
231
232float LayerTreeImpl::device_scale_factor() const {
233 return layer_tree_host_impl_->deviceScaleFactor();
234}
235
236const gfx::Size& LayerTreeImpl::device_viewport_size() const {
237 return layer_tree_host_impl_->deviceViewportSize();
238}
239
240const gfx::Size& LayerTreeImpl::layout_viewport_size() const {
241 return layer_tree_host_impl_->layoutViewportSize();
242}
243
244std::string LayerTreeImpl::layer_tree_as_text() const {
245 return layer_tree_host_impl_->layerTreeAsText();
246}
247
248DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
249 return layer_tree_host_impl_->debugRectHistory();
250}
251
[email protected]de4afb5e2012-12-20 00:11:34252AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
253 return layer_tree_host_impl_->animationRegistrar();
254}
[email protected]ff762fb2012-12-12 19:18:37255
[email protected]caa567d2012-12-20 07:56:16256const PinchZoomViewport& LayerTreeImpl::pinch_zoom_viewport() const {
257 return layer_tree_host_impl_->pinchZoomViewport();
258}
259
[email protected]3b31c6ac2012-12-06 21:27:29260} // namespace cc