blob: 38a40f315cab2288e0fa14718754aad2427e8ec2 [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]c60279472013-01-30 12:10:518#include "cc/heads_up_display_layer_impl.h"
[email protected]3b31c6ac2012-12-06 21:27:299#include "cc/layer_tree_host_common.h"
10#include "cc/layer_tree_host_impl.h"
[email protected]caa567d2012-12-20 07:56:1611#include "ui/gfx/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2912
13namespace cc {
14
[email protected]8bef40572012-12-11 21:38:0815LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
[email protected]db8259f2013-02-01 05:25:0416 : layer_tree_host_impl_(layer_tree_host_impl),
17 source_frame_number_(-1),
18 hud_layer_(0),
19 root_scroll_layer_(0),
20 currently_scrolling_layer_(0),
21 background_color_(0),
22 has_transparent_background_(false),
23 page_scale_factor_(1),
24 page_scale_delta_(1),
25 sent_page_scale_delta_(1),
26 min_page_scale_factor_(0),
27 max_page_scale_factor_(0),
28 scrolling_layer_id_from_previous_tree_(0),
29 contents_textures_purged_(false),
30 needs_update_draw_properties_(true),
31 needs_full_tree_sync_(true) {
[email protected]3b31c6ac2012-12-06 21:27:2932}
33
34LayerTreeImpl::~LayerTreeImpl() {
[email protected]361bc00d2012-12-14 07:03:2435 // Need to explicitly clear the tree prior to destroying this so that
36 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
37 root_layer_.reset();
[email protected]3b31c6ac2012-12-06 21:27:2938}
39
40static LayerImpl* findRootScrollLayer(LayerImpl* layer)
41{
42 if (!layer)
43 return 0;
44
45 if (layer->scrollable())
46 return layer;
47
48 for (size_t i = 0; i < layer->children().size(); ++i) {
49 LayerImpl* found = findRootScrollLayer(layer->children()[i]);
50 if (found)
51 return found;
52 }
53
54 return 0;
55}
56
57void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
58 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:5359 root_scroll_layer_ = NULL;
60 currently_scrolling_layer_ = NULL;
61
62 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
63}
64
65void LayerTreeImpl::FindRootScrollLayer() {
[email protected]3b31c6ac2012-12-06 21:27:2966 root_scroll_layer_ = findRootScrollLayer(root_layer_.get());
[email protected]3b31c6ac2012-12-06 21:27:2967
68 if (root_layer_ && scrolling_layer_id_from_previous_tree_) {
69 currently_scrolling_layer_ = LayerTreeHostCommon::findLayerInSubtree(
70 root_layer_.get(),
71 scrolling_layer_id_from_previous_tree_);
72 }
73
74 scrolling_layer_id_from_previous_tree_ = 0;
[email protected]3b31c6ac2012-12-06 21:27:2975}
76
77scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
78 // Clear all data structures that have direct references to the layer tree.
79 scrolling_layer_id_from_previous_tree_ =
80 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
[email protected]69b50ec2013-01-19 04:58:0181 root_scroll_layer_ = NULL;
[email protected]3b31c6ac2012-12-06 21:27:2982 currently_scrolling_layer_ = NULL;
83
[email protected]76ffd9e2012-12-20 19:12:4784 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:1685 set_needs_update_draw_properties();
[email protected]3b31c6ac2012-12-06 21:27:2986 return root_layer_.Pass();
87}
88
[email protected]c60279472013-01-30 12:10:5189void LayerTreeImpl::pushPropertiesTo(LayerTreeImpl* target_tree) {
90 target_tree->SetPageScaleFactorAndLimits(
91 page_scale_factor(), min_page_scale_factor(), max_page_scale_factor());
92 target_tree->SetPageScaleDelta(
93 target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
94 target_tree->set_sent_page_scale_delta(1);
95
96 // This should match the property synchronization in
97 // LayerTreeHost::finishCommitOnImplThread().
98 target_tree->set_source_frame_number(source_frame_number());
99 target_tree->set_background_color(background_color());
100 target_tree->set_has_transparent_background(has_transparent_background());
101
102 if (ContentsTexturesPurged())
103 target_tree->SetContentsTexturesPurged();
104 else
105 target_tree->ResetContentsTexturesPurged();
106
107 if (hud_layer())
108 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
109 LayerTreeHostCommon::findLayerInSubtree(
110 target_tree->RootLayer(), hud_layer()->id())));
111 else
112 target_tree->set_hud_layer(NULL);
113}
114
[email protected]69b50ec2013-01-19 04:58:01115LayerImpl* LayerTreeImpl::RootScrollLayer() {
116 DCHECK(IsActiveTree());
117 return root_scroll_layer_;
118}
119
120LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() {
121 DCHECK(IsActiveTree());
122 return currently_scrolling_layer_;
123}
124
[email protected]3b31c6ac2012-12-06 21:27:29125void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
126 currently_scrolling_layer_ = NULL;
127 scrolling_layer_id_from_previous_tree_ = 0;
128}
129
[email protected]c60279472013-01-30 12:10:51130void LayerTreeImpl::SetPageScaleFactorAndLimits(float page_scale_factor,
131 float min_page_scale_factor, float max_page_scale_factor)
132{
133 if (!page_scale_factor)
134 return;
135
136 min_page_scale_factor_ = min_page_scale_factor;
137 max_page_scale_factor_ = max_page_scale_factor;
138 page_scale_factor_ = page_scale_factor;
139}
140
141void LayerTreeImpl::SetPageScaleDelta(float delta)
142{
143 // Clamp to the current min/max limits.
144 float total = page_scale_factor_ * delta;
145 if (min_page_scale_factor_ && total < min_page_scale_factor_)
146 delta = min_page_scale_factor_ / page_scale_factor_;
147 else if (max_page_scale_factor_ && total > max_page_scale_factor_)
148 delta = max_page_scale_factor_ / page_scale_factor_;
149
150 if (delta == page_scale_delta_)
151 return;
152
153 page_scale_delta_ = delta;
154
155 if (IsActiveTree()) {
156 LayerTreeImpl* pending_tree = layer_tree_host_impl_->pendingTree();
157 if (pending_tree) {
158 DCHECK_EQ(1, pending_tree->sent_page_scale_delta());
159 pending_tree->SetPageScaleDelta(page_scale_delta_ / sent_page_scale_delta_);
160 }
161 }
162
163 UpdateMaxScrollOffset();
164 set_needs_update_draw_properties();
165}
166
[email protected]257abfa82013-01-29 23:47:24167gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
168 gfx::SizeF view_bounds;
169 // The clip layer should be used for scrolling bounds if available since it
170 // adjusts for non-overlay scrollbars. Otherwise, fall back to our knowledge
171 // of the physical viewport size.
172 LayerImpl* clip_layer = NULL;
173 if (root_scroll_layer_)
174 clip_layer = root_scroll_layer_->parent();
175 if (clip_layer && clip_layer->masksToBounds()) {
176 view_bounds = clip_layer->bounds();
177 } else {
178 view_bounds = gfx::ScaleSize(device_viewport_size(),
179 1 / device_scale_factor());
180 }
[email protected]c60279472013-01-30 12:10:51181 view_bounds.Scale(1 / total_page_scale_factor());
[email protected]257abfa82013-01-29 23:47:24182
183 return view_bounds;
184}
185
[email protected]caa567d2012-12-20 07:56:16186void LayerTreeImpl::UpdateMaxScrollOffset() {
[email protected]69b50ec2013-01-19 04:58:01187 if (!root_scroll_layer_ || !root_scroll_layer_->children().size())
[email protected]caa567d2012-12-20 07:56:16188 return;
189
[email protected]42ccdbef2013-01-21 07:54:54190 gfx::Vector2dF max_scroll = gfx::Rect(ScrollableSize()).bottom_right() -
[email protected]257abfa82013-01-29 23:47:24191 gfx::RectF(ScrollableViewportSize()).bottom_right();
[email protected]caa567d2012-12-20 07:56:16192
193 // The viewport may be larger than the contents in some cases, such as
194 // having a vertical scrollbar but no horizontal overflow.
195 max_scroll.ClampToMin(gfx::Vector2dF());
196
[email protected]69b50ec2013-01-19 04:58:01197 root_scroll_layer_->setMaxScrollOffset(gfx::ToFlooredVector2d(max_scroll));
[email protected]caa567d2012-12-20 07:56:16198}
199
[email protected]c60279472013-01-30 12:10:51200gfx::Transform LayerTreeImpl::ImplTransform() const {
201 gfx::Transform transform;
202 transform.Scale(page_scale_delta_, page_scale_delta_);
203 if (settings().pageScalePinchZoomEnabled)
204 transform.Scale(page_scale_factor_, page_scale_factor_);
205 return transform;
206}
207
[email protected]4c9bb952013-01-27 05:41:18208struct UpdateTilePrioritiesForLayer {
209 void operator()(LayerImpl *layer) {
210 layer->updateTilePriorities();
211 }
212};
213
214void LayerTreeImpl::UpdateDrawProperties(UpdateDrawPropertiesReason reason) {
215 if (!needs_update_draw_properties_) {
216 if (reason == UPDATE_ACTIVE_TREE_FOR_DRAW && RootLayer())
217 LayerTreeHostCommon::callFunctionForSubtree<UpdateTilePrioritiesForLayer>(
218 RootLayer());
[email protected]615c78a2013-01-24 23:44:16219 return;
[email protected]4c9bb952013-01-27 05:41:18220 }
[email protected]615c78a2013-01-24 23:44:16221
222 needs_update_draw_properties_ = false;
[email protected]76ffd9e2012-12-20 19:12:47223 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16224
225 // For maxTextureSize.
226 if (!layer_tree_host_impl_->renderer())
227 return;
228
[email protected]76ffd9e2012-12-20 19:12:47229 if (!RootLayer())
230 return;
231
[email protected]69b50ec2013-01-19 04:58:01232 if (root_scroll_layer_) {
[email protected]c60279472013-01-30 12:10:51233 root_scroll_layer_->setImplTransform(ImplTransform());
[email protected]615c78a2013-01-24 23:44:16234 // Setting the impl transform re-sets this.
235 needs_update_draw_properties_ = false;
[email protected]76ffd9e2012-12-20 19:12:47236 }
237
238 {
[email protected]615c78a2013-01-24 23:44:16239 TRACE_EVENT1("cc", "LayerTreeImpl::UpdateDrawProperties", "IsActive", IsActiveTree());
[email protected]4c9bb952013-01-27 05:41:18240 bool update_tile_priorities =
241 reason == UPDATE_PENDING_TREE ||
242 reason == UPDATE_ACTIVE_TREE_FOR_DRAW;
[email protected]76ffd9e2012-12-20 19:12:47243 LayerTreeHostCommon::calculateDrawProperties(
244 RootLayer(),
245 device_viewport_size(),
246 device_scale_factor(),
[email protected]c60279472013-01-30 12:10:51247 total_page_scale_factor(),
[email protected]f6776532012-12-21 20:24:33248 MaxTextureSize(),
[email protected]76ffd9e2012-12-20 19:12:47249 settings().canUseLCDText,
[email protected]4c9bb952013-01-27 05:41:18250 render_surface_layer_list_,
251 update_tile_priorities);
[email protected]76ffd9e2012-12-20 19:12:47252 }
[email protected]615c78a2013-01-24 23:44:16253
254 DCHECK(!needs_update_draw_properties_) <<
255 "calcDrawProperties should not set_needs_update_draw_properties()";
[email protected]76ffd9e2012-12-20 19:12:47256}
257
258static void ClearRenderSurfacesOnLayerImplRecursive(LayerImpl* current)
259{
260 DCHECK(current);
261 for (size_t i = 0; i < current->children().size(); ++i)
262 ClearRenderSurfacesOnLayerImplRecursive(current->children()[i]);
263 current->clearRenderSurface();
264}
265
266void LayerTreeImpl::ClearRenderSurfaces() {
267 ClearRenderSurfacesOnLayerImplRecursive(RootLayer());
268 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16269 set_needs_update_draw_properties();
[email protected]76ffd9e2012-12-20 19:12:47270}
271
[email protected]b0a917c8d2013-01-12 17:42:25272bool LayerTreeImpl::AreVisibleResourcesReady() const {
273 TRACE_EVENT0("cc", "LayerTreeImpl::AreVisibleResourcesReady");
274
275 typedef LayerIterator<LayerImpl,
276 std::vector<LayerImpl*>,
277 RenderSurfaceImpl,
278 LayerIteratorActions::BackToFront> LayerIteratorType;
279 LayerIteratorType end = LayerIteratorType::end(&render_surface_layer_list_);
280 for (LayerIteratorType it = LayerIteratorType::begin(
281 &render_surface_layer_list_); it != end; ++it) {
282 if (it.representsItself() && !(*it)->areVisibleResourcesReady())
283 return false;
284 }
285
286 return true;
287}
288
[email protected]76ffd9e2012-12-20 19:12:47289const LayerTreeImpl::LayerList& LayerTreeImpl::RenderSurfaceLayerList() const {
290 // If this assert triggers, then the list is dirty.
[email protected]615c78a2013-01-24 23:44:16291 DCHECK(!needs_update_draw_properties_);
[email protected]76ffd9e2012-12-20 19:12:47292 return render_surface_layer_list_;
293}
294
[email protected]42ccdbef2013-01-21 07:54:54295gfx::Size LayerTreeImpl::ScrollableSize() const {
[email protected]c4d467a2013-01-21 03:21:01296 if (!root_scroll_layer_ || root_scroll_layer_->children().empty())
[email protected]caa567d2012-12-20 07:56:16297 return gfx::Size();
[email protected]c4d467a2013-01-21 03:21:01298 return root_scroll_layer_->children()[0]->bounds();
[email protected]caa567d2012-12-20 07:56:16299}
300
[email protected]361bc00d2012-12-14 07:03:24301LayerImpl* LayerTreeImpl::LayerById(int id) {
302 LayerIdMap::iterator iter = layer_id_map_.find(id);
303 return iter != layer_id_map_.end() ? iter->second : NULL;
304}
305
306void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
307 DCHECK(!LayerById(layer->id()));
308 layer_id_map_[layer->id()] = layer;
309}
310
311void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
312 DCHECK(LayerById(layer->id()));
313 layer_id_map_.erase(layer->id());
314}
315
[email protected]1e0f8d62013-01-09 07:41:35316void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pendingTree) {
317 int id = currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
318 pendingTree->set_currently_scrolling_layer(
319 LayerTreeHostCommon::findLayerInSubtree(pendingTree->RootLayer(), id));
320}
321
[email protected]37386f052013-01-13 00:42:22322static void DidBecomeActiveRecursive(LayerImpl* layer) {
323 layer->didBecomeActive();
324 for (size_t i = 0; i < layer->children().size(); ++i)
325 DidBecomeActiveRecursive(layer->children()[i]);
326}
327
328void LayerTreeImpl::DidBecomeActive() {
329 if (RootLayer())
330 DidBecomeActiveRecursive(RootLayer());
[email protected]69b50ec2013-01-19 04:58:01331 FindRootScrollLayer();
332 UpdateMaxScrollOffset();
[email protected]37386f052013-01-13 00:42:22333}
334
[email protected]6f90b9e2013-01-17 23:42:00335bool LayerTreeImpl::ContentsTexturesPurged() const {
336 return contents_textures_purged_;
337}
338
339void LayerTreeImpl::SetContentsTexturesPurged() {
340 contents_textures_purged_ = true;
341 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
342}
343
344void LayerTreeImpl::ResetContentsTexturesPurged() {
345 contents_textures_purged_ = false;
346 layer_tree_host_impl_->OnCanDrawStateChangedForTree(this);
347}
348
[email protected]48871fc2013-01-23 07:36:51349Proxy* LayerTreeImpl::proxy() const {
350 return layer_tree_host_impl_->proxy();
351}
352
[email protected]ff762fb2012-12-12 19:18:37353const LayerTreeSettings& LayerTreeImpl::settings() const {
354 return layer_tree_host_impl_->settings();
355}
356
357OutputSurface* LayerTreeImpl::output_surface() const {
358 return layer_tree_host_impl_->outputSurface();
359}
360
361ResourceProvider* LayerTreeImpl::resource_provider() const {
362 return layer_tree_host_impl_->resourceProvider();
363}
364
365TileManager* LayerTreeImpl::tile_manager() const {
366 return layer_tree_host_impl_->tileManager();
367}
368
369FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
370 return layer_tree_host_impl_->fpsCounter();
371}
372
[email protected]71691c22013-01-18 03:14:22373PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
374 return layer_tree_host_impl_->paintTimeCounter();
375}
376
[email protected]1191d9d2013-02-02 06:00:33377MemoryHistory* LayerTreeImpl::memory_history() const {
378 return layer_tree_host_impl_->memoryHistory();
379}
380
[email protected]f117a4c2012-12-16 04:53:10381bool LayerTreeImpl::IsActiveTree() const {
382 return layer_tree_host_impl_->activeTree() == this;
383}
384
385bool LayerTreeImpl::IsPendingTree() const {
386 return layer_tree_host_impl_->pendingTree() == this;
387}
388
[email protected]48871fc2013-01-23 07:36:51389bool LayerTreeImpl::IsRecycleTree() const {
390 return layer_tree_host_impl_->recycleTree() == this;
391}
392
[email protected]f117a4c2012-12-16 04:53:10393LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
394 LayerTreeImpl* tree = layer_tree_host_impl_->activeTree();
395 if (!tree)
396 return NULL;
397 return tree->LayerById(id);
398}
399
400LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
401 LayerTreeImpl* tree = layer_tree_host_impl_->pendingTree();
402 if (!tree)
403 return NULL;
404 return tree->LayerById(id);
405}
406
[email protected]f6776532012-12-21 20:24:33407int LayerTreeImpl::MaxTextureSize() const {
408 return layer_tree_host_impl_->rendererCapabilities().maxTextureSize;
409}
410
[email protected]166db5c82013-01-09 23:54:31411bool LayerTreeImpl::PinchGestureActive() const {
412 return layer_tree_host_impl_->pinchGestureActive();
413}
414
[email protected]829ad972013-01-28 23:36:10415base::TimeTicks LayerTreeImpl::CurrentFrameTime() const {
416 return layer_tree_host_impl_->currentFrameTime();
417}
418
[email protected]ff762fb2012-12-12 19:18:37419void LayerTreeImpl::SetNeedsRedraw() {
420 layer_tree_host_impl_->setNeedsRedraw();
421}
422
[email protected]ff762fb2012-12-12 19:18:37423const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
424 return layer_tree_host_impl_->debugState();
425}
426
427float LayerTreeImpl::device_scale_factor() const {
428 return layer_tree_host_impl_->deviceScaleFactor();
429}
430
431const gfx::Size& LayerTreeImpl::device_viewport_size() const {
432 return layer_tree_host_impl_->deviceViewportSize();
433}
434
435const gfx::Size& LayerTreeImpl::layout_viewport_size() const {
436 return layer_tree_host_impl_->layoutViewportSize();
437}
438
439std::string LayerTreeImpl::layer_tree_as_text() const {
440 return layer_tree_host_impl_->layerTreeAsText();
441}
442
443DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
444 return layer_tree_host_impl_->debugRectHistory();
445}
446
[email protected]de4afb5e2012-12-20 00:11:34447AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
448 return layer_tree_host_impl_->animationRegistrar();
449}
[email protected]ff762fb2012-12-12 19:18:37450
[email protected]3b31c6ac2012-12-06 21:27:29451} // namespace cc