blob: 2c0efdd594f52f1e8fba4be3f1c8e3dbe806b661 [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
[email protected]556fd292013-03-18 08:03:045#include "cc/trees/layer_tree_impl.h"
[email protected]3b31c6ac2012-12-06 21:27:296
[email protected]28336d52014-05-12 19:07:287#include <limits>
8#include <set>
9
[email protected]76ffd9e2012-12-20 19:12:4710#include "base/debug/trace_event.h"
[email protected]95e4e1a02013-03-18 07:09:0911#include "cc/animation/keyframed_animation_curve.h"
12#include "cc/animation/scrollbar_animation_controller.h"
[email protected]930ff43b2014-05-02 05:24:0013#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
14#include "cc/animation/scrollbar_animation_controller_thinning.h"
[email protected]3744e27b2013-11-06 21:44:0815#include "cc/base/math_util.h"
16#include "cc/base/util.h"
[email protected]12a63da2014-06-13 06:06:2217#include "cc/debug/devtools_instrumentation.h"
[email protected]f6742f52013-05-08 23:52:2218#include "cc/debug/traced_value.h"
[email protected]cc3cfaa2013-03-18 09:05:5219#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]57ac9482013-09-17 21:13:3920#include "cc/layers/layer.h"
[email protected]34ba1ffb2014-03-05 06:55:0321#include "cc/layers/layer_iterator.h"
[email protected]50761e92013-03-29 20:51:2822#include "cc/layers/render_surface_impl.h"
[email protected]80413d72013-08-30 20:25:3323#include "cc/layers/scrollbar_layer_impl_base.h"
[email protected]e1042192013-11-08 05:44:2424#include "cc/resources/ui_resource_request.h"
[email protected]556fd292013-03-18 08:03:0425#include "cc/trees/layer_tree_host_common.h"
26#include "cc/trees/layer_tree_host_impl.h"
[email protected]562b7ad2014-06-23 22:17:1127#include "cc/trees/occlusion_tracker.h"
[email protected]28336d52014-05-12 19:07:2828#include "ui/gfx/point_conversions.h"
[email protected]ffb2720f2013-03-15 19:18:3729#include "ui/gfx/size_conversions.h"
[email protected]caa567d2012-12-20 07:56:1630#include "ui/gfx/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2931
32namespace cc {
33
[email protected]adeda572014-01-31 00:49:4734// This class exists to split the LayerScrollOffsetDelegate between the
35// InnerViewportScrollLayer and the OuterViewportScrollLayer in a manner
36// that never requires the embedder or LayerImpl to know about.
[email protected]ec2322e2014-05-15 16:32:0037class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
[email protected]adeda572014-01-31 00:49:4738 public:
39 LayerScrollOffsetDelegateProxy(LayerImpl* layer,
40 LayerScrollOffsetDelegate* delegate,
41 LayerTreeImpl* layer_tree)
42 : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {}
[email protected]ec2322e2014-05-15 16:32:0043 virtual ~LayerScrollOffsetDelegateProxy() {}
[email protected]adeda572014-01-31 00:49:4744
45 gfx::Vector2dF last_set_scroll_offset() const {
46 return last_set_scroll_offset_;
47 }
48
49 // LayerScrollOffsetDelegate implementation.
[email protected]adeda572014-01-31 00:49:4750 virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_offset) OVERRIDE {
51 last_set_scroll_offset_ = new_offset;
52 layer_tree_impl_->UpdateScrollOffsetDelegate();
53 }
54
55 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
56 return layer_tree_impl_->GetDelegatedScrollOffset(layer_);
57 }
58
59 virtual bool IsExternalFlingActive() const OVERRIDE {
60 return delegate_->IsExternalFlingActive();
61 }
62
[email protected]adeda572014-01-31 00:49:4763 private:
64 LayerImpl* layer_;
65 LayerScrollOffsetDelegate* delegate_;
66 LayerTreeImpl* layer_tree_impl_;
67 gfx::Vector2dF last_set_scroll_offset_;
68};
69
[email protected]8bef40572012-12-11 21:38:0870LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
[email protected]db8259f2013-02-01 05:25:0471 : layer_tree_host_impl_(layer_tree_host_impl),
72 source_frame_number_(-1),
73 hud_layer_(0),
[email protected]1960a712013-04-30 17:06:4774 currently_scrolling_layer_(NULL),
75 root_layer_scroll_offset_delegate_(NULL),
[email protected]db8259f2013-02-01 05:25:0476 background_color_(0),
77 has_transparent_background_(false),
[email protected]57ac9482013-09-17 21:13:3978 page_scale_layer_(NULL),
79 inner_viewport_scroll_layer_(NULL),
80 outer_viewport_scroll_layer_(NULL),
[email protected]db8259f2013-02-01 05:25:0481 page_scale_factor_(1),
82 page_scale_delta_(1),
83 sent_page_scale_delta_(1),
84 min_page_scale_factor_(0),
85 max_page_scale_factor_(0),
86 scrolling_layer_id_from_previous_tree_(0),
87 contents_textures_purged_(false),
[email protected]3d609bb2014-02-01 01:10:2388 requires_high_res_to_draw_(false),
[email protected]318822852013-02-14 00:54:2789 viewport_size_invalid_(false),
[email protected]db8259f2013-02-01 05:25:0490 needs_update_draw_properties_(true),
[email protected]7d08a9352013-10-15 08:24:5691 needs_full_tree_sync_(true),
[email protected]390bb1ff2014-05-09 17:14:4092 next_activation_forces_redraw_(false),
93 render_surface_layer_list_id_(0) {
94}
[email protected]3b31c6ac2012-12-06 21:27:2995
96LayerTreeImpl::~LayerTreeImpl() {
[email protected]361bc00d2012-12-14 07:03:2497 // Need to explicitly clear the tree prior to destroying this so that
98 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
[email protected]df17af52014-02-06 02:20:4099 DCHECK(!root_layer_);
100 DCHECK(layers_with_copy_output_request_.empty());
[email protected]3b31c6ac2012-12-06 21:27:29101}
102
[email protected]df17af52014-02-06 02:20:40103void LayerTreeImpl::Shutdown() { root_layer_.reset(); }
104
[email protected]aeef2f02014-05-10 12:15:48105void LayerTreeImpl::ReleaseResources() {
106 if (root_layer_)
107 ReleaseResourcesRecursive(root_layer_.get());
108}
109
[email protected]d35cd7b22014-01-29 14:32:46110void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
[email protected]adeda572014-01-31 00:49:47111 if (inner_viewport_scroll_layer_)
112 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
113 if (outer_viewport_scroll_layer_)
114 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
115 inner_viewport_scroll_delegate_proxy_.reset();
116 outer_viewport_scroll_delegate_proxy_.reset();
117
[email protected]3b31c6ac2012-12-06 21:27:29118 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:53119 currently_scrolling_layer_ = NULL;
[email protected]adeda572014-01-31 00:49:47120 inner_viewport_scroll_layer_ = NULL;
121 outer_viewport_scroll_layer_ = NULL;
122 page_scale_layer_ = NULL;
[email protected]5c4824e12013-01-12 16:34:53123
[email protected]c1bb5af2013-03-13 19:06:27124 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]5c4824e12013-01-12 16:34:53125}
126
[email protected]adeda572014-01-31 00:49:47127LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
128 return inner_viewport_scroll_layer_;
129}
[email protected]3b31c6ac2012-12-06 21:27:29130
[email protected]adeda572014-01-31 00:49:47131LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
132 return outer_viewport_scroll_layer_;
133}
[email protected]1960a712013-04-30 17:06:47134
[email protected]adeda572014-01-31 00:49:47135gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const {
136 gfx::Vector2dF offset;
[email protected]3b31c6ac2012-12-06 21:27:29137
[email protected]adeda572014-01-31 00:49:47138 if (inner_viewport_scroll_layer_)
139 offset += inner_viewport_scroll_layer_->TotalScrollOffset();
140
141 if (outer_viewport_scroll_layer_)
142 offset += outer_viewport_scroll_layer_->TotalScrollOffset();
143
144 return offset;
145}
146
147gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const {
148 gfx::Vector2dF offset;
149
150 if (inner_viewport_scroll_layer_)
151 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
152
153 if (outer_viewport_scroll_layer_)
154 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
155
156 return offset;
157}
158gfx::Vector2dF LayerTreeImpl::TotalScrollDelta() const {
159 DCHECK(inner_viewport_scroll_layer_);
160 gfx::Vector2dF delta = inner_viewport_scroll_layer_->ScrollDelta();
161
162 if (outer_viewport_scroll_layer_)
163 delta += outer_viewport_scroll_layer_->ScrollDelta();
164
165 return delta;
[email protected]3b31c6ac2012-12-06 21:27:29166}
167
168scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
169 // Clear all data structures that have direct references to the layer tree.
170 scrolling_layer_id_from_previous_tree_ =
171 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
[email protected]adeda572014-01-31 00:49:47172 if (inner_viewport_scroll_layer_)
173 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
174 if (outer_viewport_scroll_layer_)
175 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
176 inner_viewport_scroll_delegate_proxy_.reset();
177 outer_viewport_scroll_delegate_proxy_.reset();
178 inner_viewport_scroll_layer_ = NULL;
179 outer_viewport_scroll_layer_ = NULL;
180 page_scale_layer_ = NULL;
[email protected]3b31c6ac2012-12-06 21:27:29181 currently_scrolling_layer_ = NULL;
182
[email protected]76ffd9e2012-12-20 19:12:47183 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16184 set_needs_update_draw_properties();
[email protected]3b31c6ac2012-12-06 21:27:29185 return root_layer_.Pass();
186}
187
[email protected]7aba6662013-03-12 10:17:34188void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
[email protected]c9280762013-08-01 06:28:57189 // The request queue should have been processed and does not require a push.
190 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
191
[email protected]7d08a9352013-10-15 08:24:56192 if (next_activation_forces_redraw_) {
[email protected]12a63da2014-06-13 06:06:22193 target_tree->ForceRedrawNextActivation();
[email protected]7d08a9352013-10-15 08:24:56194 next_activation_forces_redraw_ = false;
195 }
196
[email protected]b69c1db2013-11-27 00:05:19197 target_tree->PassSwapPromises(&swap_promise_list_);
198
[email protected]d6021f6a2014-06-12 21:15:24199 target_tree->SetPageScaleValues(
200 page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(),
[email protected]c60279472013-01-30 12:10:51201 target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
202 target_tree->set_sent_page_scale_delta(1);
203
[email protected]adeda572014-01-31 00:49:47204 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
[email protected]57ac9482013-09-17 21:13:39205 target_tree->SetViewportLayersFromIds(
206 page_scale_layer_->id(),
207 inner_viewport_scroll_layer_->id(),
208 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
209 : Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47210 } else {
211 target_tree->ClearViewportLayers();
[email protected]57ac9482013-09-17 21:13:39212 }
[email protected]c60279472013-01-30 12:10:51213 // This should match the property synchronization in
214 // LayerTreeHost::finishCommitOnImplThread().
215 target_tree->set_source_frame_number(source_frame_number());
216 target_tree->set_background_color(background_color());
217 target_tree->set_has_transparent_background(has_transparent_background());
218
219 if (ContentsTexturesPurged())
220 target_tree->SetContentsTexturesPurged();
221 else
222 target_tree->ResetContentsTexturesPurged();
223
[email protected]318822852013-02-14 00:54:27224 if (ViewportSizeInvalid())
225 target_tree->SetViewportSizeInvalid();
226 else
227 target_tree->ResetViewportSizeInvalid();
228
[email protected]c60279472013-01-30 12:10:51229 if (hud_layer())
230 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
[email protected]6ba914122013-03-22 16:26:39231 LayerTreeHostCommon::FindLayerInSubtree(
[email protected]c1bb5af2013-03-13 19:06:27232 target_tree->root_layer(), hud_layer()->id())));
[email protected]c60279472013-01-30 12:10:51233 else
234 target_tree->set_hud_layer(NULL);
235}
236
[email protected]fef74fd2014-02-27 06:28:17237LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
238 return inner_viewport_scroll_layer_
239 ? inner_viewport_scroll_layer_->scroll_clip_layer()
240 : NULL;
[email protected]ffb2720f2013-03-15 19:18:37241}
242
243LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
[email protected]69b50ec2013-01-19 04:58:01244 DCHECK(IsActiveTree());
245 return currently_scrolling_layer_;
246}
247
[email protected]0fc818e2013-03-18 06:45:20248void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
249 if (currently_scrolling_layer_ == layer)
250 return;
251
252 if (currently_scrolling_layer_ &&
253 currently_scrolling_layer_->scrollbar_animation_controller())
[email protected]1dc06162014-03-26 22:54:45254 currently_scrolling_layer_->scrollbar_animation_controller()
[email protected]930ff43b2014-05-02 05:24:00255 ->DidScrollEnd();
[email protected]0fc818e2013-03-18 06:45:20256 currently_scrolling_layer_ = layer;
257 if (layer && layer->scrollbar_animation_controller())
[email protected]930ff43b2014-05-02 05:24:00258 layer->scrollbar_animation_controller()->DidScrollBegin();
[email protected]0fc818e2013-03-18 06:45:20259}
260
[email protected]3b31c6ac2012-12-06 21:27:29261void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
[email protected]0fc818e2013-03-18 06:45:20262 SetCurrentlyScrollingLayer(NULL);
[email protected]3b31c6ac2012-12-06 21:27:29263 scrolling_layer_id_from_previous_tree_ = 0;
264}
265
[email protected]1f15bed2014-03-11 02:50:44266float LayerTreeImpl::VerticalAdjust(const int clip_layer_id) const {
267 LayerImpl* container_layer = InnerViewportContainerLayer();
268 if (!container_layer || clip_layer_id != container_layer->id())
[email protected]adeda572014-01-31 00:49:47269 return 0.f;
270
[email protected]fef74fd2014-02-27 06:28:17271 return layer_tree_host_impl_->VerticalAdjust();
[email protected]adeda572014-01-31 00:49:47272}
273
274namespace {
275
276void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
277 if (!current_layer)
278 return;
279
280 while (current_layer) {
281 current_layer->ScrollbarParametersDidChange();
282 current_layer = current_layer->parent();
283 }
284}
285
286} // namespace
287
[email protected]c60279472013-01-30 12:10:51288void LayerTreeImpl::SetPageScaleFactorAndLimits(float page_scale_factor,
[email protected]3c0a3252013-03-18 04:24:36289 float min_page_scale_factor, float max_page_scale_factor) {
[email protected]d6021f6a2014-06-12 21:15:24290 SetPageScaleValues(page_scale_factor, min_page_scale_factor,
291 max_page_scale_factor, page_scale_delta_);
292}
[email protected]c60279472013-01-30 12:10:51293
[email protected]d6021f6a2014-06-12 21:15:24294void LayerTreeImpl::SetPageScaleDelta(float delta) {
295 SetPageScaleValues(page_scale_factor_, min_page_scale_factor_,
296 max_page_scale_factor_, delta);
297}
298
299void LayerTreeImpl::SetPageScaleValues(float page_scale_factor,
300 float min_page_scale_factor, float max_page_scale_factor,
301 float page_scale_delta) {
302 bool page_scale_changed =
303 min_page_scale_factor != min_page_scale_factor_ ||
304 max_page_scale_factor != max_page_scale_factor_ ||
305 page_scale_factor != page_scale_factor_;
[email protected]7265e74e2014-02-07 23:43:06306
[email protected]c60279472013-01-30 12:10:51307 min_page_scale_factor_ = min_page_scale_factor;
308 max_page_scale_factor_ = max_page_scale_factor;
309 page_scale_factor_ = page_scale_factor;
[email protected]20d2b742013-09-26 05:41:34310
[email protected]d6021f6a2014-06-12 21:15:24311 float total = page_scale_factor_ * page_scale_delta;
312 if (min_page_scale_factor_ && total < min_page_scale_factor_)
313 page_scale_delta = min_page_scale_factor_ / page_scale_factor_;
314 else if (max_page_scale_factor_ && total > max_page_scale_factor_)
315 page_scale_delta = max_page_scale_factor_ / page_scale_factor_;
316
317 if (page_scale_delta_ == page_scale_delta && !page_scale_changed)
318 return;
319
320 if (page_scale_delta_ != page_scale_delta) {
321 page_scale_delta_ = page_scale_delta;
322
323 if (IsActiveTree()) {
324 LayerTreeImpl* pending_tree = layer_tree_host_impl_->pending_tree();
325 if (pending_tree) {
326 DCHECK_EQ(1, pending_tree->sent_page_scale_delta());
327 pending_tree->SetPageScaleDelta(
328 page_scale_delta_ / sent_page_scale_delta_);
329 }
330 }
331
332 set_needs_update_draw_properties();
333 }
334
[email protected]22f200a2013-10-09 18:08:29335 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:00336 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
337 TotalScrollOffset(),
338 TotalMaxScrollOffset(),
339 ScrollableSize(),
[email protected]68fe60f2014-02-12 13:49:11340 total_page_scale_factor(),
[email protected]d6021f6a2014-06-12 21:15:24341 min_page_scale_factor_,
342 max_page_scale_factor_);
[email protected]22f200a2013-10-09 18:08:29343 }
[email protected]adeda572014-01-31 00:49:47344
345 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
[email protected]c60279472013-01-30 12:10:51346}
347
[email protected]257abfa82013-01-29 23:47:24348gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
[email protected]adeda572014-01-31 00:49:47349 if (outer_viewport_scroll_layer_)
350 return layer_tree_host_impl_->UnscaledScrollableViewportSize();
351 else
352 return gfx::ScaleSize(
353 layer_tree_host_impl_->UnscaledScrollableViewportSize(),
354 1.0f / total_page_scale_factor());
[email protected]257abfa82013-01-29 23:47:24355}
356
[email protected]3744e27b2013-11-06 21:44:08357gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
[email protected]adeda572014-01-31 00:49:47358 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
359 ? OuterViewportScrollLayer()
360 : InnerViewportScrollLayer();
361 if (!root_scroll_layer || root_scroll_layer->children().empty())
[email protected]3744e27b2013-11-06 21:44:08362 return gfx::Rect();
[email protected]adeda572014-01-31 00:49:47363 LayerImpl* layer = root_scroll_layer->children()[0];
[email protected]8a822692014-02-12 17:30:55364 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
365 gfx::Rect(layer->content_bounds()));
[email protected]3744e27b2013-11-06 21:44:08366}
367
[email protected]58241dc2013-08-20 01:39:25368static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) {
369 layer->ApplySentScrollDeltasFromAbortedCommit();
[email protected]3519b872013-07-30 07:17:50370}
371
[email protected]58241dc2013-08-20 01:39:25372void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
[email protected]3519b872013-07-30 07:17:50373 DCHECK(IsActiveTree());
374
375 page_scale_factor_ *= sent_page_scale_delta_;
376 page_scale_delta_ /= sent_page_scale_delta_;
377 sent_page_scale_delta_ = 1.f;
378
379 if (!root_layer())
380 return;
381
382 LayerTreeHostCommon::CallFunctionForSubtree(
[email protected]58241dc2013-08-20 01:39:25383 root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo));
384}
385
[email protected]daea3d42013-10-23 17:04:50386static void ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl* layer) {
387 layer->ApplyScrollDeltasSinceBeginMainFrame();
[email protected]58241dc2013-08-20 01:39:25388}
389
[email protected]daea3d42013-10-23 17:04:50390void LayerTreeImpl::ApplyScrollDeltasSinceBeginMainFrame() {
[email protected]58241dc2013-08-20 01:39:25391 DCHECK(IsPendingTree());
392 if (!root_layer())
393 return;
394
395 LayerTreeHostCommon::CallFunctionForSubtree(
[email protected]daea3d42013-10-23 17:04:50396 root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginMainFrameTo));
[email protected]3519b872013-07-30 07:17:50397}
398
[email protected]57ac9482013-09-17 21:13:39399void LayerTreeImpl::SetViewportLayersFromIds(
400 int page_scale_layer_id,
401 int inner_viewport_scroll_layer_id,
402 int outer_viewport_scroll_layer_id) {
403 page_scale_layer_ = LayerById(page_scale_layer_id);
404 DCHECK(page_scale_layer_);
405
406 inner_viewport_scroll_layer_ =
407 LayerById(inner_viewport_scroll_layer_id);
408 DCHECK(inner_viewport_scroll_layer_);
409
410 outer_viewport_scroll_layer_ =
411 LayerById(outer_viewport_scroll_layer_id);
412 DCHECK(outer_viewport_scroll_layer_ ||
413 outer_viewport_scroll_layer_id == Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47414
415 if (!root_layer_scroll_offset_delegate_)
416 return;
417
418 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
419 new LayerScrollOffsetDelegateProxy(inner_viewport_scroll_layer_,
420 root_layer_scroll_offset_delegate_,
421 this));
422
423 if (outer_viewport_scroll_layer_)
424 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
425 new LayerScrollOffsetDelegateProxy(outer_viewport_scroll_layer_,
426 root_layer_scroll_offset_delegate_,
427 this));
[email protected]57ac9482013-09-17 21:13:39428}
429
430void LayerTreeImpl::ClearViewportLayers() {
431 page_scale_layer_ = NULL;
432 inner_viewport_scroll_layer_ = NULL;
433 outer_viewport_scroll_layer_ = NULL;
434}
435
[email protected]8f7f298822014-06-13 00:23:32436bool LayerTreeImpl::UpdateDrawProperties() {
437 if (!needs_update_draw_properties_)
438 return true;
[email protected]615c78a2013-01-24 23:44:16439
[email protected]ed511b8d2013-03-25 03:29:29440 // For max_texture_size.
[email protected]615c78a2013-01-24 23:44:16441 if (!layer_tree_host_impl_->renderer())
[email protected]8f7f298822014-06-13 00:23:32442 return false;
[email protected]615c78a2013-01-24 23:44:16443
[email protected]c1bb5af2013-03-13 19:06:27444 if (!root_layer())
[email protected]8f7f298822014-06-13 00:23:32445 return false;
446
447 needs_update_draw_properties_ = false;
448 render_surface_layer_list_.clear();
[email protected]76ffd9e2012-12-20 19:12:47449
[email protected]76ffd9e2012-12-20 19:12:47450 {
[email protected]7a52f43e2013-07-10 01:58:47451 TRACE_EVENT2("cc",
[email protected]c1bb5af2013-03-13 19:06:27452 "LayerTreeImpl::UpdateDrawProperties",
453 "IsActive",
[email protected]7a52f43e2013-07-10 01:58:47454 IsActiveTree(),
455 "SourceFrameNumber",
456 source_frame_number_);
[email protected]57ac9482013-09-17 21:13:39457 LayerImpl* page_scale_layer =
[email protected]fef74fd2014-02-27 06:28:17458 page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
[email protected]45948712013-09-27 02:46:48459 bool can_render_to_separate_surface =
460 !output_surface()->ForcedDrawToSoftwareDevice();
[email protected]390bb1ff2014-05-09 17:14:40461
462 ++render_surface_layer_list_id_;
[email protected]7aad55f2013-07-26 11:25:53463 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
[email protected]c1bb5af2013-03-13 19:06:27464 root_layer(),
[email protected]54af03522013-09-05 00:43:28465 DrawViewportSize(),
466 layer_tree_host_impl_->DrawTransform(),
[email protected]76ffd9e2012-12-20 19:12:47467 device_scale_factor(),
[email protected]c60279472013-01-30 12:10:51468 total_page_scale_factor(),
[email protected]57ac9482013-09-17 21:13:39469 page_scale_layer,
[email protected]f6776532012-12-21 20:24:33470 MaxTextureSize(),
[email protected]8e0176d2013-03-21 03:14:52471 settings().can_use_lcd_text,
[email protected]45948712013-09-27 02:46:48472 can_render_to_separate_surface,
[email protected]35a99a12013-05-09 23:52:29473 settings().layer_transforms_should_scale_layer_contents,
[email protected]390bb1ff2014-05-09 17:14:40474 &render_surface_layer_list_,
475 render_surface_layer_list_id_);
[email protected]7aad55f2013-07-26 11:25:53476 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
[email protected]76ffd9e2012-12-20 19:12:47477 }
[email protected]615c78a2013-01-24 23:44:16478
[email protected]e4be0262013-10-19 16:54:28479 {
480 TRACE_EVENT2("cc",
481 "LayerTreeImpl::UpdateTilePriorities",
482 "IsActive",
483 IsActiveTree(),
484 "SourceFrameNumber",
485 source_frame_number_);
[email protected]562b7ad2014-06-23 22:17:11486 scoped_ptr<OcclusionTracker<LayerImpl> > occlusion_tracker;
487 if (settings().use_occlusion_for_tile_prioritization) {
488 occlusion_tracker.reset(new OcclusionTracker<LayerImpl>(
489 root_layer()->render_surface()->content_rect()));
490 occlusion_tracker->set_minimum_tracking_size(
491 settings().minimum_occlusion_tracking_size);
492 }
493
[email protected]e4be0262013-10-19 16:54:28494 // LayerIterator is used here instead of CallFunctionForSubtree to only
495 // UpdateTilePriorities on layers that will be visible (and thus have valid
496 // draw properties) and not because any ordering is required.
[email protected]ba1b33e2014-02-28 16:44:51497 typedef LayerIterator<LayerImpl> LayerIteratorType;
[email protected]e4be0262013-10-19 16:54:28498 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
499 for (LayerIteratorType it =
500 LayerIteratorType::Begin(&render_surface_layer_list_);
501 it != end;
502 ++it) {
[email protected]562b7ad2014-06-23 22:17:11503 if (occlusion_tracker)
504 occlusion_tracker->EnterLayer(it);
505
[email protected]e4be0262013-10-19 16:54:28506 LayerImpl* layer = *it;
[email protected]6355d2d2014-05-07 15:07:27507 if (it.represents_itself())
[email protected]562b7ad2014-06-23 22:17:11508 layer->UpdateTiles(occlusion_tracker.get());
[email protected]e4be0262013-10-19 16:54:28509
[email protected]562b7ad2014-06-23 22:17:11510 if (!it.represents_contributing_render_surface()) {
511 if (occlusion_tracker)
512 occlusion_tracker->LeaveLayer(it);
[email protected]6355d2d2014-05-07 15:07:27513 continue;
[email protected]562b7ad2014-06-23 22:17:11514 }
[email protected]6355d2d2014-05-07 15:07:27515
[email protected]e4be0262013-10-19 16:54:28516 if (layer->mask_layer())
[email protected]562b7ad2014-06-23 22:17:11517 layer->mask_layer()->UpdateTiles(occlusion_tracker.get());
[email protected]e4be0262013-10-19 16:54:28518 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
[email protected]562b7ad2014-06-23 22:17:11519 layer->replica_layer()->mask_layer()->UpdateTiles(
520 occlusion_tracker.get());
521
522 if (occlusion_tracker)
523 occlusion_tracker->LeaveLayer(it);
[email protected]e4be0262013-10-19 16:54:28524 }
525 }
526
[email protected]615c78a2013-01-24 23:44:16527 DCHECK(!needs_update_draw_properties_) <<
[email protected]7d19dc342013-05-02 22:02:04528 "CalcDrawProperties should not set_needs_update_draw_properties()";
[email protected]8f7f298822014-06-13 00:23:32529 return true;
[email protected]76ffd9e2012-12-20 19:12:47530}
531
[email protected]50761e92013-03-29 20:51:28532const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
[email protected]76ffd9e2012-12-20 19:12:47533 // If this assert triggers, then the list is dirty.
[email protected]615c78a2013-01-24 23:44:16534 DCHECK(!needs_update_draw_properties_);
[email protected]76ffd9e2012-12-20 19:12:47535 return render_surface_layer_list_;
536}
537
[email protected]42ccdbef2013-01-21 07:54:54538gfx::Size LayerTreeImpl::ScrollableSize() const {
[email protected]adeda572014-01-31 00:49:47539 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
540 ? OuterViewportScrollLayer()
541 : InnerViewportScrollLayer();
542 if (!root_scroll_layer || root_scroll_layer->children().empty())
[email protected]caa567d2012-12-20 07:56:16543 return gfx::Size();
[email protected]adeda572014-01-31 00:49:47544 return root_scroll_layer->children()[0]->bounds();
[email protected]caa567d2012-12-20 07:56:16545}
546
[email protected]361bc00d2012-12-14 07:03:24547LayerImpl* LayerTreeImpl::LayerById(int id) {
548 LayerIdMap::iterator iter = layer_id_map_.find(id);
549 return iter != layer_id_map_.end() ? iter->second : NULL;
550}
551
552void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
553 DCHECK(!LayerById(layer->id()));
554 layer_id_map_[layer->id()] = layer;
555}
556
557void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
558 DCHECK(LayerById(layer->id()));
559 layer_id_map_.erase(layer->id());
560}
561
[email protected]ed511b8d2013-03-25 03:29:29562void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
[email protected]a90fac72013-06-06 18:56:13563 pending_tree->SetCurrentlyScrollingLayer(
564 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
565 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
[email protected]1e0f8d62013-01-09 07:41:35566}
567
[email protected]ff1211d2013-06-07 01:58:35568static void DidBecomeActiveRecursive(LayerImpl* layer) {
[email protected]7aba6662013-03-12 10:17:34569 layer->DidBecomeActive();
[email protected]ff1211d2013-06-07 01:58:35570 for (size_t i = 0; i < layer->children().size(); ++i)
571 DidBecomeActiveRecursive(layer->children()[i]);
[email protected]37386f052013-01-13 00:42:22572}
573
574void LayerTreeImpl::DidBecomeActive() {
[email protected]12a63da2014-06-13 06:06:22575 if (next_activation_forces_redraw_) {
576 layer_tree_host_impl_->SetFullRootLayerDamage();
577 next_activation_forces_redraw_ = false;
578 }
579
[email protected]adeda572014-01-31 00:49:47580 if (scrolling_layer_id_from_previous_tree_) {
581 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
[email protected]7dcf5632014-06-25 01:11:55582 root_layer(), scrolling_layer_id_from_previous_tree_);
[email protected]adeda572014-01-31 00:49:47583 }
584
[email protected]7dcf5632014-06-25 01:11:55585 // Always reset this flag on activation, as we would only have activated
586 // if we were in a good state.
587 ResetRequiresHighResToDraw();
588
589 if (root_layer())
590 DidBecomeActiveRecursive(root_layer());
591
[email protected]12a63da2014-06-13 06:06:22592 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
593 source_frame_number_);
[email protected]37386f052013-01-13 00:42:22594}
595
[email protected]6f90b9e2013-01-17 23:42:00596bool LayerTreeImpl::ContentsTexturesPurged() const {
597 return contents_textures_purged_;
598}
599
600void LayerTreeImpl::SetContentsTexturesPurged() {
[email protected]94bf75c2013-06-12 13:20:04601 if (contents_textures_purged_)
602 return;
[email protected]6f90b9e2013-01-17 23:42:00603 contents_textures_purged_ = true;
[email protected]c1bb5af2013-03-13 19:06:27604 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]6f90b9e2013-01-17 23:42:00605}
606
607void LayerTreeImpl::ResetContentsTexturesPurged() {
[email protected]94bf75c2013-06-12 13:20:04608 if (!contents_textures_purged_)
609 return;
[email protected]6f90b9e2013-01-17 23:42:00610 contents_textures_purged_ = false;
[email protected]c1bb5af2013-03-13 19:06:27611 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]6f90b9e2013-01-17 23:42:00612}
613
[email protected]3d609bb2014-02-01 01:10:23614void LayerTreeImpl::SetRequiresHighResToDraw() {
615 requires_high_res_to_draw_ = true;
616}
617
618void LayerTreeImpl::ResetRequiresHighResToDraw() {
619 requires_high_res_to_draw_ = false;
620}
621
622bool LayerTreeImpl::RequiresHighResToDraw() const {
623 return requires_high_res_to_draw_;
624}
625
[email protected]318822852013-02-14 00:54:27626bool LayerTreeImpl::ViewportSizeInvalid() const {
627 return viewport_size_invalid_;
628}
629
630void LayerTreeImpl::SetViewportSizeInvalid() {
631 viewport_size_invalid_ = true;
[email protected]c1bb5af2013-03-13 19:06:27632 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27633}
634
635void LayerTreeImpl::ResetViewportSizeInvalid() {
636 viewport_size_invalid_ = false;
[email protected]c1bb5af2013-03-13 19:06:27637 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27638}
639
[email protected]48871fc2013-01-23 07:36:51640Proxy* LayerTreeImpl::proxy() const {
641 return layer_tree_host_impl_->proxy();
642}
643
[email protected]ff762fb2012-12-12 19:18:37644const LayerTreeSettings& LayerTreeImpl::settings() const {
[email protected]c1bb5af2013-03-13 19:06:27645 return layer_tree_host_impl_->settings();
[email protected]ff762fb2012-12-12 19:18:37646}
647
[email protected]7a8bcd262014-01-15 12:54:58648const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
[email protected]c1bb5af2013-03-13 19:06:27649 return layer_tree_host_impl_->GetRendererCapabilities();
[email protected]bf5b3a02013-02-13 02:02:52650}
651
[email protected]0634cdd42013-08-16 00:46:09652ContextProvider* LayerTreeImpl::context_provider() const {
653 return output_surface()->context_provider();
654}
655
[email protected]ff762fb2012-12-12 19:18:37656OutputSurface* LayerTreeImpl::output_surface() const {
[email protected]c1bb5af2013-03-13 19:06:27657 return layer_tree_host_impl_->output_surface();
[email protected]ff762fb2012-12-12 19:18:37658}
659
660ResourceProvider* LayerTreeImpl::resource_provider() const {
[email protected]c1bb5af2013-03-13 19:06:27661 return layer_tree_host_impl_->resource_provider();
[email protected]ff762fb2012-12-12 19:18:37662}
663
664TileManager* LayerTreeImpl::tile_manager() const {
[email protected]c1bb5af2013-03-13 19:06:27665 return layer_tree_host_impl_->tile_manager();
[email protected]ff762fb2012-12-12 19:18:37666}
667
668FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27669 return layer_tree_host_impl_->fps_counter();
[email protected]ff762fb2012-12-12 19:18:37670}
671
[email protected]71691c22013-01-18 03:14:22672PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27673 return layer_tree_host_impl_->paint_time_counter();
[email protected]71691c22013-01-18 03:14:22674}
675
[email protected]1191d9d2013-02-02 06:00:33676MemoryHistory* LayerTreeImpl::memory_history() const {
[email protected]c1bb5af2013-03-13 19:06:27677 return layer_tree_host_impl_->memory_history();
[email protected]1191d9d2013-02-02 06:00:33678}
679
[email protected]54af03522013-09-05 00:43:28680bool LayerTreeImpl::device_viewport_valid_for_tile_management() const {
681 return layer_tree_host_impl_->device_viewport_valid_for_tile_management();
682}
683
[email protected]4a6c091d2014-04-24 21:06:46684gfx::Size LayerTreeImpl::device_viewport_size() const {
685 return layer_tree_host_impl_->device_viewport_size();
686}
687
[email protected]f117a4c2012-12-16 04:53:10688bool LayerTreeImpl::IsActiveTree() const {
[email protected]c1bb5af2013-03-13 19:06:27689 return layer_tree_host_impl_->active_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10690}
691
692bool LayerTreeImpl::IsPendingTree() const {
[email protected]c1bb5af2013-03-13 19:06:27693 return layer_tree_host_impl_->pending_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10694}
695
[email protected]48871fc2013-01-23 07:36:51696bool LayerTreeImpl::IsRecycleTree() const {
[email protected]c1bb5af2013-03-13 19:06:27697 return layer_tree_host_impl_->recycle_tree() == this;
[email protected]48871fc2013-01-23 07:36:51698}
699
[email protected]f117a4c2012-12-16 04:53:10700LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27701 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
[email protected]f117a4c2012-12-16 04:53:10702 if (!tree)
703 return NULL;
704 return tree->LayerById(id);
705}
706
707LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27708 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
[email protected]f117a4c2012-12-16 04:53:10709 if (!tree)
710 return NULL;
711 return tree->LayerById(id);
712}
713
[email protected]f6776532012-12-21 20:24:33714int LayerTreeImpl::MaxTextureSize() const {
[email protected]c1bb5af2013-03-13 19:06:27715 return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size;
[email protected]f6776532012-12-21 20:24:33716}
717
[email protected]166db5c82013-01-09 23:54:31718bool LayerTreeImpl::PinchGestureActive() const {
[email protected]c1bb5af2013-03-13 19:06:27719 return layer_tree_host_impl_->pinch_gesture_active();
[email protected]166db5c82013-01-09 23:54:31720}
721
[email protected]fb7425a2013-04-22 16:28:55722base::TimeTicks LayerTreeImpl::CurrentFrameTimeTicks() const {
723 return layer_tree_host_impl_->CurrentFrameTimeTicks();
724}
725
[email protected]c92195e2014-05-07 18:18:49726base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
727 return layer_tree_host_impl_->begin_impl_frame_interval();
728}
729
[email protected]d7eb8c72013-03-23 22:57:13730void LayerTreeImpl::SetNeedsCommit() {
731 layer_tree_host_impl_->SetNeedsCommit();
732}
733
[email protected]54af03522013-09-05 00:43:28734gfx::Size LayerTreeImpl::DrawViewportSize() const {
735 return layer_tree_host_impl_->DrawViewportSize();
736}
737
[email protected]930ff43b2014-05-02 05:24:00738scoped_ptr<ScrollbarAnimationController>
739LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
740 DCHECK(settings().scrollbar_fade_delay_ms);
741 DCHECK(settings().scrollbar_fade_duration_ms);
742 base::TimeDelta delay =
743 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
744 base::TimeDelta duration =
745 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
746 switch (settings().scrollbar_animator) {
747 case LayerTreeSettings::LinearFade: {
748 return ScrollbarAnimationControllerLinearFade::Create(
749 scrolling_layer, layer_tree_host_impl_, delay, duration)
750 .PassAs<ScrollbarAnimationController>();
751 }
752 case LayerTreeSettings::Thinning: {
753 return ScrollbarAnimationControllerThinning::Create(
754 scrolling_layer, layer_tree_host_impl_, delay, duration)
755 .PassAs<ScrollbarAnimationController>();
756 }
757 case LayerTreeSettings::NoAnimator:
758 NOTREACHED();
759 break;
760 }
761 return scoped_ptr<ScrollbarAnimationController>();
[email protected]2ea5aba2013-09-11 14:26:56762}
763
[email protected]b8384e22013-12-03 02:20:48764void LayerTreeImpl::DidAnimateScrollOffset() {
765 layer_tree_host_impl_->DidAnimateScrollOffset();
766}
767
[email protected]13525d62014-05-20 21:22:04768bool LayerTreeImpl::use_gpu_rasterization() const {
769 return layer_tree_host_impl_->use_gpu_rasterization();
770}
771
[email protected]473f1f22014-05-22 08:19:17772bool LayerTreeImpl::create_low_res_tiling() const {
773 return layer_tree_host_impl_->create_low_res_tiling();
774}
775
[email protected]ff762fb2012-12-12 19:18:37776void LayerTreeImpl::SetNeedsRedraw() {
[email protected]59adb112013-04-09 04:48:44777 layer_tree_host_impl_->SetNeedsRedraw();
[email protected]ff762fb2012-12-12 19:18:37778}
779
[email protected]ff762fb2012-12-12 19:18:37780const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
[email protected]c1bb5af2013-03-13 19:06:27781 return layer_tree_host_impl_->debug_state();
[email protected]ff762fb2012-12-12 19:18:37782}
783
784float LayerTreeImpl::device_scale_factor() const {
[email protected]c1bb5af2013-03-13 19:06:27785 return layer_tree_host_impl_->device_scale_factor();
[email protected]ff762fb2012-12-12 19:18:37786}
787
[email protected]ff762fb2012-12-12 19:18:37788DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
[email protected]c1bb5af2013-03-13 19:06:27789 return layer_tree_host_impl_->debug_rect_history();
[email protected]ff762fb2012-12-12 19:18:37790}
791
[email protected]de4afb5e2012-12-20 00:11:34792AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
[email protected]c1bb5af2013-03-13 19:06:27793 return layer_tree_host_impl_->animation_registrar();
[email protected]de4afb5e2012-12-20 00:11:34794}
[email protected]ff762fb2012-12-12 19:18:37795
[email protected]8c5690222013-02-15 17:36:43796scoped_ptr<base::Value> LayerTreeImpl::AsValue() const {
[email protected]f6742f52013-05-08 23:52:22797 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
798 TracedValue::MakeDictIntoImplicitSnapshot(
799 state.get(), "cc::LayerTreeImpl", this);
800
801 state->Set("root_layer", root_layer_->AsValue().release());
802
803 scoped_ptr<base::ListValue> render_surface_layer_list(new base::ListValue());
[email protected]ba1b33e2014-02-28 16:44:51804 typedef LayerIterator<LayerImpl> LayerIteratorType;
[email protected]71dfcc72013-03-20 21:30:09805 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
806 for (LayerIteratorType it = LayerIteratorType::Begin(
[email protected]8c5690222013-02-15 17:36:43807 &render_surface_layer_list_); it != end; ++it) {
[email protected]71dfcc72013-03-20 21:30:09808 if (!it.represents_itself())
[email protected]8c5690222013-02-15 17:36:43809 continue;
[email protected]f6742f52013-05-08 23:52:22810 render_surface_layer_list->Append(TracedValue::CreateIDRef(*it).release());
[email protected]8c5690222013-02-15 17:36:43811 }
[email protected]f6742f52013-05-08 23:52:22812
813 state->Set("render_surface_layer_list",
814 render_surface_layer_list.release());
[email protected]8c5690222013-02-15 17:36:43815 return state.PassAs<base::Value>();
816}
817
[email protected]1960a712013-04-30 17:06:47818void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
[email protected]c9280762013-08-01 06:28:57819 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
[email protected]20d2b742013-09-26 05:41:34820 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
821 return;
822
[email protected]adeda572014-01-31 00:49:47823 if (!root_layer_scroll_offset_delegate) {
824 // Make sure we remove the proxies from their layers before
825 // releasing them.
826 if (InnerViewportScrollLayer())
827 InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
828 if (OuterViewportScrollLayer())
829 OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
830 inner_viewport_scroll_delegate_proxy_.reset();
831 outer_viewport_scroll_delegate_proxy_.reset();
[email protected]d35cd7b22014-01-29 14:32:46832 }
833
[email protected]adeda572014-01-31 00:49:47834 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
835
[email protected]20d2b742013-09-26 05:41:34836 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:00837 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
838 TotalScrollOffset(),
839 TotalMaxScrollOffset(),
840 ScrollableSize(),
[email protected]68fe60f2014-02-12 13:49:11841 total_page_scale_factor(),
842 min_page_scale_factor(),
843 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:47844
845 if (inner_viewport_scroll_layer_) {
846 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
847 new LayerScrollOffsetDelegateProxy(InnerViewportScrollLayer(),
848 root_layer_scroll_offset_delegate_,
849 this));
850 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(
851 inner_viewport_scroll_delegate_proxy_.get());
852 }
853
854 if (outer_viewport_scroll_layer_) {
855 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
856 new LayerScrollOffsetDelegateProxy(OuterViewportScrollLayer(),
857 root_layer_scroll_offset_delegate_,
858 this));
859 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(
860 outer_viewport_scroll_delegate_proxy_.get());
861 }
[email protected]20d2b742013-09-26 05:41:34862 }
[email protected]1960a712013-04-30 17:06:47863}
864
[email protected]adeda572014-01-31 00:49:47865void LayerTreeImpl::UpdateScrollOffsetDelegate() {
866 DCHECK(InnerViewportScrollLayer());
867 DCHECK(root_layer_scroll_offset_delegate_);
868
869 gfx::Vector2dF offset =
870 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
871
872 if (OuterViewportScrollLayer())
873 offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
874
[email protected]ec2322e2014-05-15 16:32:00875 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
876 offset,
877 TotalMaxScrollOffset(),
878 ScrollableSize(),
879 total_page_scale_factor(),
880 min_page_scale_factor(),
881 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:47882}
883
884gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) {
885 DCHECK(root_layer_scroll_offset_delegate_);
886 DCHECK(InnerViewportScrollLayer());
887 if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer())
888 return root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
889
890 // If we get here, we have both inner/outer viewports, and need to distribute
891 // the scroll offset between them.
892 DCHECK(inner_viewport_scroll_delegate_proxy_);
893 DCHECK(outer_viewport_scroll_delegate_proxy_);
894 gfx::Vector2dF inner_viewport_offset =
895 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
896 gfx::Vector2dF outer_viewport_offset =
897 outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
898
899 // It may be nothing has changed.
900 gfx::Vector2dF delegate_offset =
901 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
902 if (inner_viewport_offset + outer_viewport_offset == delegate_offset) {
903 if (layer == InnerViewportScrollLayer())
904 return inner_viewport_offset;
905 else
906 return outer_viewport_offset;
907 }
908
909 gfx::Vector2d max_outer_viewport_scroll_offset =
910 OuterViewportScrollLayer()->MaxScrollOffset();
911
912 outer_viewport_offset = delegate_offset - inner_viewport_offset;
913 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
914 outer_viewport_offset.SetToMax(gfx::Vector2d());
915
916 if (layer == OuterViewportScrollLayer())
917 return outer_viewport_offset;
918
919 inner_viewport_offset = delegate_offset - outer_viewport_offset;
920
921 return inner_viewport_offset;
922}
923
[email protected]b69c1db2013-11-27 00:05:19924void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
925 DCHECK(swap_promise);
926 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
927 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
928 swap_promise_list_.push_back(swap_promise.Pass());
929}
930
931void LayerTreeImpl::PassSwapPromises(
932 ScopedPtrVector<SwapPromise>* new_swap_promise) {
933 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
934 *new_swap_promise);
935 new_swap_promise->clear();
936}
937
[email protected]d359203a2013-11-29 06:16:55938void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
[email protected]b69c1db2013-11-27 00:05:19939 for (size_t i = 0; i < swap_promise_list_.size(); i++)
[email protected]d359203a2013-11-29 06:16:55940 swap_promise_list_[i]->DidSwap(metadata);
[email protected]b69c1db2013-11-27 00:05:19941 swap_promise_list_.clear();
942}
943
944void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
945 for (size_t i = 0; i < swap_promise_list_.size(); i++)
946 swap_promise_list_[i]->DidNotSwap(reason);
947 swap_promise_list_.clear();
948}
949
[email protected]c48536a52013-09-14 00:02:08950void LayerTreeImpl::DidModifyTilePriorities() {
951 layer_tree_host_impl_->DidModifyTilePriorities();
[email protected]fcb846d2013-05-22 01:42:36952}
953
[email protected]c9280762013-08-01 06:28:57954void LayerTreeImpl::set_ui_resource_request_queue(
955 const UIResourceRequestQueue& queue) {
956 ui_resource_request_queue_ = queue;
957}
958
959ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
960 UIResourceId uid) const {
961 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
962}
963
[email protected]709c9542013-10-26 01:43:51964bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
965 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
966}
967
[email protected]c9280762013-08-01 06:28:57968void LayerTreeImpl::ProcessUIResourceRequestQueue() {
969 while (ui_resource_request_queue_.size() > 0) {
970 UIResourceRequest req = ui_resource_request_queue_.front();
971 ui_resource_request_queue_.pop_front();
972
[email protected]741fba422013-09-20 03:34:14973 switch (req.GetType()) {
[email protected]c9280762013-08-01 06:28:57974 case UIResourceRequest::UIResourceCreate:
[email protected]741fba422013-09-20 03:34:14975 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
[email protected]c9280762013-08-01 06:28:57976 break;
977 case UIResourceRequest::UIResourceDelete:
[email protected]741fba422013-09-20 03:34:14978 layer_tree_host_impl_->DeleteUIResource(req.GetId());
[email protected]c9280762013-08-01 06:28:57979 break;
[email protected]f28d64d2013-08-27 04:17:45980 case UIResourceRequest::UIResourceInvalidRequest:
[email protected]c9280762013-08-01 06:28:57981 NOTREACHED();
982 break;
983 }
984 }
[email protected]127bdc1a2013-09-11 01:44:48985
986 // If all UI resource evictions were not recreated by processing this queue,
987 // then another commit is required.
988 if (layer_tree_host_impl_->EvictedUIResourcesExist())
989 layer_tree_host_impl_->SetNeedsCommit();
[email protected]c9280762013-08-01 06:28:57990}
991
[email protected]30fe19ff2013-07-04 00:54:45992void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
993 // Only the active tree needs to know about layers with copy requests, as
994 // they are aborted if not serviced during draw.
995 DCHECK(IsActiveTree());
996
[email protected]a4ee12812014-02-06 17:33:38997 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
998 // layers_with_copy_output_request_.end(),
999 // layer) == layers_with_copy_output_request_.end());
1000 // TODO(danakj): Remove this once crash is found crbug.com/309777
1001 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1002 CHECK(layers_with_copy_output_request_[i] != layer)
1003 << i << " of " << layers_with_copy_output_request_.size();
1004 }
[email protected]30fe19ff2013-07-04 00:54:451005 layers_with_copy_output_request_.push_back(layer);
1006}
1007
1008void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1009 // Only the active tree needs to know about layers with copy requests, as
1010 // they are aborted if not serviced during draw.
1011 DCHECK(IsActiveTree());
1012
1013 std::vector<LayerImpl*>::iterator it = std::find(
1014 layers_with_copy_output_request_.begin(),
1015 layers_with_copy_output_request_.end(),
1016 layer);
1017 DCHECK(it != layers_with_copy_output_request_.end());
[email protected]f5de9e5b2013-07-30 22:26:571018 layers_with_copy_output_request_.erase(it);
[email protected]a4ee12812014-02-06 17:33:381019
1020 // TODO(danakj): Remove this once crash is found crbug.com/309777
1021 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1022 CHECK(layers_with_copy_output_request_[i] != layer)
1023 << i << " of " << layers_with_copy_output_request_.size();
1024 }
[email protected]30fe19ff2013-07-04 00:54:451025}
1026
[email protected]53526372013-12-07 04:31:501027const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
[email protected]30fe19ff2013-07-04 00:54:451028 const {
1029 // Only the active tree needs to know about layers with copy requests, as
1030 // they are aborted if not serviced during draw.
1031 DCHECK(IsActiveTree());
1032
1033 return layers_with_copy_output_request_;
1034}
1035
[email protected]aeef2f02014-05-10 12:15:481036void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) {
1037 DCHECK(current);
1038 current->ReleaseResources();
1039 if (current->mask_layer())
1040 ReleaseResourcesRecursive(current->mask_layer());
1041 if (current->replica_layer())
1042 ReleaseResourcesRecursive(current->replica_layer());
1043 for (size_t i = 0; i < current->children().size(); ++i)
1044 ReleaseResourcesRecursive(current->children()[i]);
1045}
1046
[email protected]28336d52014-05-12 19:07:281047template <typename LayerType>
1048static inline bool LayerClipsSubtree(LayerType* layer) {
1049 return layer->masks_to_bounds() || layer->mask_layer();
1050}
1051
1052static bool PointHitsRect(
1053 const gfx::PointF& screen_space_point,
1054 const gfx::Transform& local_space_to_screen_space_transform,
1055 const gfx::RectF& local_space_rect,
1056 float* distance_to_camera) {
1057 // If the transform is not invertible, then assume that this point doesn't hit
1058 // this rect.
1059 gfx::Transform inverse_local_space_to_screen_space(
1060 gfx::Transform::kSkipInitialization);
1061 if (!local_space_to_screen_space_transform.GetInverse(
1062 &inverse_local_space_to_screen_space))
1063 return false;
1064
1065 // Transform the hit test point from screen space to the local space of the
1066 // given rect.
1067 bool clipped = false;
1068 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1069 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1070 gfx::PointF hit_test_point_in_local_space =
1071 gfx::PointF(planar_point.x(), planar_point.y());
1072
1073 // If ProjectPoint could not project to a valid value, then we assume that
1074 // this point doesn't hit this rect.
1075 if (clipped)
1076 return false;
1077
1078 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1079 return false;
1080
1081 if (distance_to_camera) {
1082 // To compute the distance to the camera, we have to take the planar point
1083 // and pull it back to world space and compute the displacement along the
1084 // z-axis.
1085 gfx::Point3F planar_point_in_screen_space(planar_point);
1086 local_space_to_screen_space_transform.TransformPoint(
1087 &planar_point_in_screen_space);
1088 *distance_to_camera = planar_point_in_screen_space.z();
1089 }
1090
1091 return true;
1092}
1093
1094static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1095 const gfx::Transform& screen_space_transform,
1096 const Region& layer_space_region,
1097 float layer_content_scale_x,
1098 float layer_content_scale_y) {
1099 // If the transform is not invertible, then assume that this point doesn't hit
1100 // this region.
1101 gfx::Transform inverse_screen_space_transform(
1102 gfx::Transform::kSkipInitialization);
1103 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1104 return false;
1105
1106 // Transform the hit test point from screen space to the local space of the
1107 // given region.
1108 bool clipped = false;
1109 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1110 inverse_screen_space_transform, screen_space_point, &clipped);
1111 gfx::PointF hit_test_point_in_layer_space =
1112 gfx::ScalePoint(hit_test_point_in_content_space,
1113 1.f / layer_content_scale_x,
1114 1.f / layer_content_scale_y);
1115
1116 // If ProjectPoint could not project to a valid value, then we assume that
1117 // this point doesn't hit this region.
1118 if (clipped)
1119 return false;
1120
1121 return layer_space_region.Contains(
1122 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1123}
1124
[email protected]0ec86f52014-06-12 20:54:031125static LayerImpl* GetNextClippingLayer(LayerImpl* layer) {
1126 if (layer->scroll_parent())
1127 return layer->scroll_parent();
1128 if (layer->clip_parent())
1129 return layer->clip_parent();
1130 return layer->parent();
1131}
1132
[email protected]28336d52014-05-12 19:07:281133static bool PointIsClippedBySurfaceOrClipRect(
1134 const gfx::PointF& screen_space_point,
1135 LayerImpl* layer) {
[email protected]28336d52014-05-12 19:07:281136 // Walk up the layer tree and hit-test any render_surfaces and any layer
1137 // clip rects that are active.
[email protected]0ec86f52014-06-12 20:54:031138 for (; layer; layer = GetNextClippingLayer(layer)) {
1139 if (layer->render_surface() &&
1140 !PointHitsRect(screen_space_point,
1141 layer->render_surface()->screen_space_transform(),
1142 layer->render_surface()->content_rect(),
1143 NULL))
[email protected]28336d52014-05-12 19:07:281144 return true;
1145
[email protected]0ec86f52014-06-12 20:54:031146 if (LayerClipsSubtree(layer) &&
1147 !PointHitsRect(screen_space_point,
1148 layer->screen_space_transform(),
1149 gfx::Rect(layer->content_bounds()),
1150 NULL))
[email protected]28336d52014-05-12 19:07:281151 return true;
[email protected]28336d52014-05-12 19:07:281152 }
1153
1154 // If we have finished walking all ancestors without having already exited,
1155 // then the point is not clipped by any ancestors.
1156 return false;
1157}
1158
1159static bool PointHitsLayer(LayerImpl* layer,
1160 const gfx::PointF& screen_space_point,
1161 float* distance_to_intersection) {
1162 gfx::RectF content_rect(layer->content_bounds());
1163 if (!PointHitsRect(screen_space_point,
1164 layer->screen_space_transform(),
1165 content_rect,
1166 distance_to_intersection))
1167 return false;
1168
1169 // At this point, we think the point does hit the layer, but we need to walk
1170 // up the parents to ensure that the layer was not clipped in such a way
1171 // that the hit point actually should not hit the layer.
1172 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1173 return false;
1174
1175 // Skip the HUD layer.
1176 if (layer == layer->layer_tree_impl()->hud_layer())
1177 return false;
1178
1179 return true;
1180}
1181
1182struct FindClosestMatchingLayerDataForRecursion {
1183 FindClosestMatchingLayerDataForRecursion()
1184 : closest_match(NULL),
1185 closest_distance(-std::numeric_limits<float>::infinity()) {}
1186 LayerImpl* closest_match;
1187 // Note that the positive z-axis points towards the camera, so bigger means
1188 // closer in this case, counterintuitively.
1189 float closest_distance;
1190};
1191
1192template <typename Functor>
1193static void FindClosestMatchingLayer(
1194 const gfx::PointF& screen_space_point,
1195 LayerImpl* layer,
1196 const Functor& func,
1197 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
1198 for (int i = layer->children().size() - 1; i >= 0; --i) {
1199 FindClosestMatchingLayer(
1200 screen_space_point, layer->children()[i], func, data_for_recursion);
1201 }
1202
1203 float distance_to_intersection = 0.f;
1204 if (func(layer) &&
1205 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1206 ((!data_for_recursion->closest_match ||
1207 distance_to_intersection > data_for_recursion->closest_distance))) {
1208 data_for_recursion->closest_distance = distance_to_intersection;
1209 data_for_recursion->closest_match = layer;
1210 }
1211}
1212
1213static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1214 if (!layer->scrollable())
1215 return false;
1216 if (layer->IsDrawnRenderSurfaceLayerListMember())
1217 return true;
1218 if (!layer->scroll_children())
1219 return false;
1220 for (std::set<LayerImpl*>::const_iterator it =
1221 layer->scroll_children()->begin();
1222 it != layer->scroll_children()->end();
1223 ++it) {
1224 if ((*it)->IsDrawnRenderSurfaceLayerListMember())
1225 return true;
1226 }
1227 return false;
1228}
1229
1230struct FindScrollingLayerFunctor {
1231 bool operator()(LayerImpl* layer) const {
1232 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1233 }
1234};
1235
1236LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1237 const gfx::PointF& screen_space_point) {
1238 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1239 FindClosestMatchingLayer(screen_space_point,
1240 root_layer(),
1241 FindScrollingLayerFunctor(),
1242 &data_for_recursion);
1243 return data_for_recursion.closest_match;
1244}
1245
1246struct HitTestVisibleScrollableOrTouchableFunctor {
1247 bool operator()(LayerImpl* layer) const {
1248 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1249 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1250 !layer->touch_event_handler_region().IsEmpty() ||
1251 layer->have_wheel_event_handlers();
1252 }
1253};
1254
1255LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1256 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321257 if (!root_layer())
1258 return NULL;
1259 if (!UpdateDrawProperties())
1260 return NULL;
[email protected]28336d52014-05-12 19:07:281261 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1262 FindClosestMatchingLayer(screen_space_point,
1263 root_layer(),
1264 HitTestVisibleScrollableOrTouchableFunctor(),
1265 &data_for_recursion);
1266 return data_for_recursion.closest_match;
1267}
1268
1269static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1270 LayerImpl* layer_impl) {
1271 if (layer_impl->touch_event_handler_region().IsEmpty())
1272 return false;
1273
1274 if (!PointHitsRegion(screen_space_point,
1275 layer_impl->screen_space_transform(),
1276 layer_impl->touch_event_handler_region(),
1277 layer_impl->contents_scale_x(),
1278 layer_impl->contents_scale_y()))
1279 return false;
1280
1281 // At this point, we think the point does hit the touch event handler region
1282 // on the layer, but we need to walk up the parents to ensure that the layer
1283 // was not clipped in such a way that the hit point actually should not hit
1284 // the layer.
1285 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1286 return false;
1287
1288 return true;
1289}
1290
1291struct FindTouchEventLayerFunctor {
1292 bool operator()(LayerImpl* layer) const {
1293 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1294 }
1295 const gfx::PointF screen_space_point;
1296};
1297
1298LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1299 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321300 if (!root_layer())
1301 return NULL;
1302 if (!UpdateDrawProperties())
1303 return NULL;
[email protected]28336d52014-05-12 19:07:281304 FindTouchEventLayerFunctor func = {screen_space_point};
1305 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1306 FindClosestMatchingLayer(
1307 screen_space_point, root_layer(), func, &data_for_recursion);
1308 return data_for_recursion.closest_match;
1309}
1310
[email protected]8aa39ecb2014-06-12 14:19:141311void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1312 layer_tree_host_impl_->RegisterPictureLayerImpl(layer);
1313}
1314
1315void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1316 layer_tree_host_impl_->UnregisterPictureLayerImpl(layer);
1317}
1318
[email protected]ca2902e92013-03-28 01:45:351319} // namespace cc