blob: 328116a7c64ac5d7d7346098b98228890b234cb3 [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)
[email protected]a30290142013-01-05 01:27:0020 , background_color_(0)
21 , has_transparent_background_(false)
[email protected]6f90b9e2013-01-17 23:42:0022 , scrolling_layer_id_from_previous_tree_(0)
23 , contents_textures_purged_(false) {
[email protected]3b31c6ac2012-12-06 21:27:2924}
25
26LayerTreeImpl::~LayerTreeImpl() {
[email protected]361bc00d2012-12-14 07:03:2427 // Need to explicitly clear the tree prior to destroying this so that
28 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
29 root_layer_.reset();
[email protected]3b31c6ac2012-12-06 21:27:2930}
31
32static LayerImpl* findRootScrollLayer(LayerImpl* layer)
33{
34 if (!layer)
35 return 0;
36
37 if (layer->scrollable())
38 return layer;
39
40 for (size_t i = 0; i < layer->children().size(); ++i) {
41 LayerImpl* found = findRootScrollLayer(layer->children()[i]);
42 if (found)
43 return found;
44 }
45
46 return 0;
47}
48
49void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
50 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:5351 root_scroll_layer_ = NULL;
52 currently_scrolling_layer_ = NULL;
53
54 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
55}
56
57void LayerTreeImpl::FindRootScrollLayer() {
[email protected]3b31c6ac2012-12-06 21:27:2958 root_scroll_layer_ = findRootScrollLayer(root_layer_.get());
[email protected]3b31c6ac2012-12-06 21:27:2959
60 if (root_layer_ && scrolling_layer_id_from_previous_tree_) {
61 currently_scrolling_layer_ = LayerTreeHostCommon::findLayerInSubtree(
62 root_layer_.get(),
63 scrolling_layer_id_from_previous_tree_);
64 }
65
66 scrolling_layer_id_from_previous_tree_ = 0;
[email protected]3b31c6ac2012-12-06 21:27:2967}
68
69scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
70 // Clear all data structures that have direct references to the layer tree.
71 scrolling_layer_id_from_previous_tree_ =
72 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
[email protected]69b50ec2013-01-19 04:58:0173 root_scroll_layer_ = NULL;
[email protected]3b31c6ac2012-12-06 21:27:2974 currently_scrolling_layer_ = NULL;
75
[email protected]76ffd9e2012-12-20 19:12:4776 render_surface_layer_list_.clear();
77 SetNeedsUpdateDrawProperties();
[email protected]3b31c6ac2012-12-06 21:27:2978 return root_layer_.Pass();
79}
80
[email protected]69b50ec2013-01-19 04:58:0181LayerImpl* LayerTreeImpl::RootScrollLayer() {
82 DCHECK(IsActiveTree());
83 return root_scroll_layer_;
84}
85
86LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() {
87 DCHECK(IsActiveTree());
88 return currently_scrolling_layer_;
89}
90
[email protected]3b31c6ac2012-12-06 21:27:2991void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
92 currently_scrolling_layer_ = NULL;
93 scrolling_layer_id_from_previous_tree_ = 0;
94}
95
[email protected]caa567d2012-12-20 07:56:1696void LayerTreeImpl::UpdateMaxScrollOffset() {
[email protected]69b50ec2013-01-19 04:58:0197 if (!root_scroll_layer_ || !root_scroll_layer_->children().size())
[email protected]caa567d2012-12-20 07:56:1698 return;
99
[email protected]42ccdbef2013-01-21 07:54:54100 gfx::SizeF view_bounds;
101 if (!settings().pageScalePinchZoomEnabled) {
102 view_bounds = device_viewport_size();
103 if (LayerImpl* clip_layer = root_scroll_layer_->parent()) {
104 // Compensate for non-overlay scrollbars.
105 if (clip_layer->masksToBounds())
106 view_bounds = gfx::ScaleSize(clip_layer->bounds(), device_scale_factor());
107 }
[email protected]a823df82013-01-10 02:38:17108 view_bounds.Scale(1 / pinch_zoom_viewport().page_scale_delta());
[email protected]42ccdbef2013-01-21 07:54:54109 } else {
110 view_bounds = layout_viewport_size();
[email protected]caa567d2012-12-20 07:56:16111 }
112
[email protected]42ccdbef2013-01-21 07:54:54113 gfx::Vector2dF max_scroll = gfx::Rect(ScrollableSize()).bottom_right() -
[email protected]caa567d2012-12-20 07:56:16114 gfx::RectF(view_bounds).bottom_right();
[email protected]caa567d2012-12-20 07:56:16115
116 // The viewport may be larger than the contents in some cases, such as
117 // having a vertical scrollbar but no horizontal overflow.
118 max_scroll.ClampToMin(gfx::Vector2dF());
119
[email protected]69b50ec2013-01-19 04:58:01120 root_scroll_layer_->setMaxScrollOffset(gfx::ToFlooredVector2d(max_scroll));
[email protected]caa567d2012-12-20 07:56:16121}
122
[email protected]76ffd9e2012-12-20 19:12:47123void LayerTreeImpl::UpdateDrawProperties() {
124 render_surface_layer_list_.clear();
125 if (!RootLayer())
126 return;
127
[email protected]69b50ec2013-01-19 04:58:01128 if (root_scroll_layer_) {
129 root_scroll_layer_->setImplTransform(
[email protected]76ffd9e2012-12-20 19:12:47130 layer_tree_host_impl_->implTransform());
131 }
132
133 {
134 TRACE_EVENT0("cc", "LayerTreeImpl::UpdateDrawProperties");
135 LayerTreeHostCommon::calculateDrawProperties(
136 RootLayer(),
137 device_viewport_size(),
138 device_scale_factor(),
[email protected]a823df82013-01-10 02:38:17139 pinch_zoom_viewport().page_scale_factor(),
[email protected]f6776532012-12-21 20:24:33140 MaxTextureSize(),
[email protected]76ffd9e2012-12-20 19:12:47141 settings().canUseLCDText,
142 render_surface_layer_list_);
143 }
144}
145
146static void ClearRenderSurfacesOnLayerImplRecursive(LayerImpl* current)
147{
148 DCHECK(current);
149 for (size_t i = 0; i < current->children().size(); ++i)
150 ClearRenderSurfacesOnLayerImplRecursive(current->children()[i]);
151 current->clearRenderSurface();
152}
153
154void LayerTreeImpl::ClearRenderSurfaces() {
155 ClearRenderSurfacesOnLayerImplRecursive(RootLayer());
156 render_surface_layer_list_.clear();
157 SetNeedsUpdateDrawProperties();
158}
159
[email protected]b0a917c8d2013-01-12 17:42:25160bool LayerTreeImpl::AreVisibleResourcesReady() const {
161 TRACE_EVENT0("cc", "LayerTreeImpl::AreVisibleResourcesReady");
162
163 typedef LayerIterator<LayerImpl,
164 std::vector<LayerImpl*>,
165 RenderSurfaceImpl,
166 LayerIteratorActions::BackToFront> LayerIteratorType;
167 LayerIteratorType end = LayerIteratorType::end(&render_surface_layer_list_);
168 for (LayerIteratorType it = LayerIteratorType::begin(
169 &render_surface_layer_list_); it != end; ++it) {
170 if (it.representsItself() && !(*it)->areVisibleResourcesReady())
171 return false;
172 }
173
174 return true;
175}
176
[email protected]76ffd9e2012-12-20 19:12:47177const LayerTreeImpl::LayerList& LayerTreeImpl::RenderSurfaceLayerList() const {
178 // If this assert triggers, then the list is dirty.
179 DCHECK(!layer_tree_host_impl_->needsUpdateDrawProperties());
180 return render_surface_layer_list_;
181}
182
[email protected]42ccdbef2013-01-21 07:54:54183gfx::Size LayerTreeImpl::ScrollableSize() const {
[email protected]c4d467a2013-01-21 03:21:01184 if (!root_scroll_layer_ || root_scroll_layer_->children().empty())
[email protected]caa567d2012-12-20 07:56:16185 return gfx::Size();
[email protected]c4d467a2013-01-21 03:21:01186 return root_scroll_layer_->children()[0]->bounds();
[email protected]caa567d2012-12-20 07:56:16187}
188
[email protected]361bc00d2012-12-14 07:03:24189LayerImpl* LayerTreeImpl::LayerById(int id) {
190 LayerIdMap::iterator iter = layer_id_map_.find(id);
191 return iter != layer_id_map_.end() ? iter->second : NULL;
192}
193
194void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
195 DCHECK(!LayerById(layer->id()));
196 layer_id_map_[layer->id()] = layer;
197}
198
199void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
200 DCHECK(LayerById(layer->id()));
201 layer_id_map_.erase(layer->id());
202}
203
[email protected]1e0f8d62013-01-09 07:41:35204void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pendingTree) {
205 int id = currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
206 pendingTree->set_currently_scrolling_layer(
207 LayerTreeHostCommon::findLayerInSubtree(pendingTree->RootLayer(), id));
208}
209
[email protected]37386f052013-01-13 00:42:22210static void DidBecomeActiveRecursive(LayerImpl* layer) {
211 layer->didBecomeActive();
212 for (size_t i = 0; i < layer->children().size(); ++i)
213 DidBecomeActiveRecursive(layer->children()[i]);
214}
215
216void LayerTreeImpl::DidBecomeActive() {
217 if (RootLayer())
218 DidBecomeActiveRecursive(RootLayer());
[email protected]69b50ec2013-01-19 04:58:01219 FindRootScrollLayer();
220 UpdateMaxScrollOffset();
[email protected]37386f052013-01-13 00:42:22221}
222
[email protected]6f90b9e2013-01-17 23:42:00223bool LayerTreeImpl::ContentsTexturesPurged() const {
224 return contents_textures_purged_;
225}
226
227void LayerTreeImpl::SetContentsTexturesPurged() {
228 contents_textures_purged_ = true;
229 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
230}
231
232void LayerTreeImpl::ResetContentsTexturesPurged() {
233 contents_textures_purged_ = false;
234 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
235}
236
[email protected]ff762fb2012-12-12 19:18:37237const LayerTreeSettings& LayerTreeImpl::settings() const {
238 return layer_tree_host_impl_->settings();
239}
240
241OutputSurface* LayerTreeImpl::output_surface() const {
242 return layer_tree_host_impl_->outputSurface();
243}
244
245ResourceProvider* LayerTreeImpl::resource_provider() const {
246 return layer_tree_host_impl_->resourceProvider();
247}
248
249TileManager* LayerTreeImpl::tile_manager() const {
250 return layer_tree_host_impl_->tileManager();
251}
252
253FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
254 return layer_tree_host_impl_->fpsCounter();
255}
256
[email protected]71691c22013-01-18 03:14:22257PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
258 return layer_tree_host_impl_->paintTimeCounter();
259}
260
[email protected]f117a4c2012-12-16 04:53:10261bool LayerTreeImpl::IsActiveTree() const {
262 return layer_tree_host_impl_->activeTree() == this;
263}
264
265bool LayerTreeImpl::IsPendingTree() const {
266 return layer_tree_host_impl_->pendingTree() == this;
267}
268
269LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
270 LayerTreeImpl* tree = layer_tree_host_impl_->activeTree();
271 if (!tree)
272 return NULL;
273 return tree->LayerById(id);
274}
275
276LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
277 LayerTreeImpl* tree = layer_tree_host_impl_->pendingTree();
278 if (!tree)
279 return NULL;
280 return tree->LayerById(id);
281}
282
[email protected]f6776532012-12-21 20:24:33283int LayerTreeImpl::MaxTextureSize() const {
284 return layer_tree_host_impl_->rendererCapabilities().maxTextureSize;
285}
286
[email protected]166db5c82013-01-09 23:54:31287bool LayerTreeImpl::PinchGestureActive() const {
288 return layer_tree_host_impl_->pinchGestureActive();
289}
290
[email protected]ff762fb2012-12-12 19:18:37291void LayerTreeImpl::SetNeedsRedraw() {
292 layer_tree_host_impl_->setNeedsRedraw();
293}
294
295void LayerTreeImpl::SetNeedsUpdateDrawProperties() {
296 layer_tree_host_impl_->setNeedsUpdateDrawProperties();
297}
298
299const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
300 return layer_tree_host_impl_->debugState();
301}
302
303float LayerTreeImpl::device_scale_factor() const {
304 return layer_tree_host_impl_->deviceScaleFactor();
305}
306
307const gfx::Size& LayerTreeImpl::device_viewport_size() const {
308 return layer_tree_host_impl_->deviceViewportSize();
309}
310
311const gfx::Size& LayerTreeImpl::layout_viewport_size() const {
312 return layer_tree_host_impl_->layoutViewportSize();
313}
314
315std::string LayerTreeImpl::layer_tree_as_text() const {
316 return layer_tree_host_impl_->layerTreeAsText();
317}
318
319DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
320 return layer_tree_host_impl_->debugRectHistory();
321}
322
[email protected]de4afb5e2012-12-20 00:11:34323AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
324 return layer_tree_host_impl_->animationRegistrar();
325}
[email protected]ff762fb2012-12-12 19:18:37326
[email protected]caa567d2012-12-20 07:56:16327const PinchZoomViewport& LayerTreeImpl::pinch_zoom_viewport() const {
328 return layer_tree_host_impl_->pinchZoomViewport();
329}
330
[email protected]3b31c6ac2012-12-06 21:27:29331} // namespace cc