blob: 6b0c9fd2e0549a1bb3532a8695fb8ce872ac2865 [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
aelias6004fe02015-02-07 21:43:017#include <algorithm>
[email protected]28336d52014-05-12 19:07:288#include <limits>
9#include <set>
10
primianoc06e2382015-01-28 04:21:4911#include "base/trace_event/trace_event.h"
12#include "base/trace_event/trace_event_argument.h"
loysobb93bef2015-07-03 00:19:5013#include "cc/animation/animation_host.h"
[email protected]95e4e1a02013-03-18 07:09:0914#include "cc/animation/keyframed_animation_curve.h"
15#include "cc/animation/scrollbar_animation_controller.h"
[email protected]930ff43b2014-05-02 05:24:0016#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
17#include "cc/animation/scrollbar_animation_controller_thinning.h"
[email protected]3744e27b2013-11-06 21:44:0818#include "cc/base/math_util.h"
aelias58eec0812014-12-04 01:04:4019#include "cc/base/synced_property.h"
[email protected]12a63da2014-06-13 06:06:2220#include "cc/debug/devtools_instrumentation.h"
[email protected]f6742f52013-05-08 23:52:2221#include "cc/debug/traced_value.h"
bokan915bf352014-10-02 21:57:1422#include "cc/input/page_scale_animation.h"
[email protected]cc3cfaa2013-03-18 09:05:5223#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]57ac9482013-09-17 21:13:3924#include "cc/layers/layer.h"
[email protected]34ba1ffb2014-03-05 06:55:0325#include "cc/layers/layer_iterator.h"
[email protected]50761e92013-03-29 20:51:2826#include "cc/layers/render_surface_impl.h"
[email protected]80413d72013-08-30 20:25:3327#include "cc/layers/scrollbar_layer_impl_base.h"
[email protected]e1042192013-11-08 05:44:2428#include "cc/resources/ui_resource_request.h"
[email protected]556fd292013-03-18 08:03:0429#include "cc/trees/layer_tree_host_common.h"
30#include "cc/trees/layer_tree_host_impl.h"
[email protected]562b7ad2014-06-23 22:17:1131#include "cc/trees/occlusion_tracker.h"
ajuma6b46da22015-06-25 21:53:0232#include "cc/trees/property_tree.h"
enne7c733af2015-05-27 23:32:4833#include "cc/trees/property_tree_builder.h"
loysod71ece82015-07-03 13:48:5034#include "ui/gfx/geometry/box_f.h"
heejin.r.chungd28506ba2014-10-23 16:36:2035#include "ui/gfx/geometry/point_conversions.h"
36#include "ui/gfx/geometry/size_conversions.h"
37#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2938
39namespace cc {
[email protected]adeda572014-01-31 00:49:4740
aelias58eec0812014-12-04 01:04:4041LayerTreeImpl::LayerTreeImpl(
42 LayerTreeHostImpl* layer_tree_host_impl,
ccameronb9aec4502014-12-05 19:31:0043 scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
aelias6004fe02015-02-07 21:43:0144 scoped_refptr<SyncedTopControls> top_controls_shown_ratio,
ccameronb9aec4502014-12-05 19:31:0045 scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)
[email protected]db8259f2013-02-01 05:25:0446 : layer_tree_host_impl_(layer_tree_host_impl),
47 source_frame_number_(-1),
48 hud_layer_(0),
[email protected]db8259f2013-02-01 05:25:0449 background_color_(0),
50 has_transparent_background_(false),
aeliasc26b50b72015-07-14 20:18:2551 currently_scrolling_layer_id_(Layer::INVALID_ID),
52 overscroll_elasticity_layer_id_(Layer::INVALID_ID),
53 page_scale_layer_id_(Layer::INVALID_ID),
54 inner_viewport_scroll_layer_id_(Layer::INVALID_ID),
55 outer_viewport_scroll_layer_id_(Layer::INVALID_ID),
aelias58eec0812014-12-04 01:04:4056 page_scale_factor_(page_scale_factor),
[email protected]db8259f2013-02-01 05:25:0457 min_page_scale_factor_(0),
58 max_page_scale_factor_(0),
skobes93102bc2015-08-04 20:38:0559 hide_pinch_scrollbars_near_min_scale_(false),
ajuma1d48e012015-09-25 22:24:1660 device_scale_factor_(1.f),
ccameronb9aec4502014-12-05 19:31:0061 elastic_overscroll_(elastic_overscroll),
[email protected]318822852013-02-14 00:54:2762 viewport_size_invalid_(false),
[email protected]db8259f2013-02-01 05:25:0463 needs_update_draw_properties_(true),
[email protected]7d08a9352013-10-15 08:24:5664 needs_full_tree_sync_(true),
[email protected]390bb1ff2014-05-09 17:14:4065 next_activation_forces_redraw_(false),
[email protected]759dc9f2014-07-23 19:18:5166 has_ever_been_drawn_(false),
bokan88eae012014-09-09 20:40:4267 render_surface_layer_list_id_(0),
dtrainorcb7779b82014-12-04 01:08:0268 top_controls_shrink_blink_size_(false),
69 top_controls_height_(0),
ajuma1d48e012015-09-25 22:24:1670 top_controls_shown_ratio_(top_controls_shown_ratio) {}
[email protected]3b31c6ac2012-12-06 21:27:2971
72LayerTreeImpl::~LayerTreeImpl() {
tobiasjs93d464842015-05-15 17:52:4473 BreakSwapPromises(IsActiveTree() ? SwapPromise::SWAP_FAILS
74 : SwapPromise::ACTIVATION_FAILS);
[email protected]586871b2014-07-22 17:05:1175
[email protected]361bc00d2012-12-14 07:03:2476 // Need to explicitly clear the tree prior to destroying this so that
77 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
[email protected]df17af52014-02-06 02:20:4078 DCHECK(!root_layer_);
79 DCHECK(layers_with_copy_output_request_.empty());
[email protected]3b31c6ac2012-12-06 21:27:2980}
81
danakjf446a072014-09-27 21:55:4882void LayerTreeImpl::Shutdown() {
83 root_layer_ = nullptr;
84}
[email protected]df17af52014-02-06 02:20:4085
[email protected]aeef2f02014-05-10 12:15:4886void LayerTreeImpl::ReleaseResources() {
vmpstra73f18d2015-03-02 21:04:3987 if (root_layer_) {
88 LayerTreeHostCommon::CallFunctionForSubtree(
89 root_layer_.get(), [](LayerImpl* layer) { layer->ReleaseResources(); });
90 }
vmpstr9ce5c662015-02-05 23:29:2691}
92
93void LayerTreeImpl::RecreateResources() {
vmpstra73f18d2015-03-02 21:04:3994 if (root_layer_) {
95 LayerTreeHostCommon::CallFunctionForSubtree(
96 root_layer_.get(),
97 [](LayerImpl* layer) { layer->RecreateResources(); });
98 }
[email protected]aeef2f02014-05-10 12:15:4899}
100
vmpstrd704c872015-04-03 20:29:51101void LayerTreeImpl::GatherFrameTimingRequestIds(
102 std::vector<int64_t>* request_ids) {
103 if (!root_layer_)
104 return;
105
106 // TODO(vmpstr): Early out if there are no requests on any of the layers. For
107 // that, we need to inform LayerTreeImpl whenever there are requests when we
108 // get them.
109 LayerTreeHostCommon::CallFunctionForSubtree(
110 root_layer_.get(), [request_ids](LayerImpl* layer) {
111 layer->GatherFrameTimingRequestIds(request_ids);
112 });
113}
114
aeliasa57c40d122015-10-08 00:20:09115bool LayerTreeImpl::IsViewportLayerId(int id) const {
116 if (id == inner_viewport_scroll_layer_id_ ||
117 id == outer_viewport_scroll_layer_id_)
118 return true;
119 if (InnerViewportContainerLayer() &&
120 id == InnerViewportContainerLayer()->id())
121 return true;
122 if (OuterViewportContainerLayer() &&
123 id == OuterViewportContainerLayer()->id())
124 return true;
125
126 return false;
127}
128
129void LayerTreeImpl::DidUpdateScrollState(int layer_id) {
130 if (!IsActiveTree())
131 return;
132
133 if (layer_id == Layer::INVALID_ID)
134 return;
135
136 int scroll_layer_id, clip_layer_id;
137 if (IsViewportLayerId(layer_id)) {
138 if (!InnerViewportContainerLayer())
139 return;
140
141 // For scrollbar purposes, a change to any of the four viewport layers
142 // should affect the scrollbars tied to the outermost layers, which express
143 // the sum of the entire viewport.
144 scroll_layer_id = outer_viewport_scroll_layer_id_;
145 clip_layer_id = InnerViewportContainerLayer()->id();
146 } else {
147 // If the clip layer id was passed in, then look up the scroll layer, or
148 // vice versa.
149 auto i = clip_scroll_map_.find(layer_id);
150 if (i != clip_scroll_map_.end()) {
151 scroll_layer_id = i->second;
152 clip_layer_id = layer_id;
153 } else {
154 scroll_layer_id = layer_id;
155 clip_layer_id = LayerById(scroll_layer_id)->scroll_clip_layer_id();
156 }
157 }
158 UpdateScrollbars(scroll_layer_id, clip_layer_id);
159}
160
161void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) {
162 DCHECK(IsActiveTree());
163
164 LayerImpl* clip_layer = LayerById(clip_layer_id);
165 LayerImpl* scroll_layer = LayerById(scroll_layer_id);
166
167 if (!clip_layer || !scroll_layer)
168 return;
169
170 gfx::SizeF clip_size(clip_layer->BoundsForScrolling());
171 gfx::SizeF scroll_size(scroll_layer->BoundsForScrolling());
172
173 if (scroll_size.IsEmpty())
174 return;
175
176 gfx::ScrollOffset current_offset = scroll_layer->CurrentScrollOffset();
177 if (IsViewportLayerId(scroll_layer_id)) {
178 current_offset += InnerViewportScrollLayer()->CurrentScrollOffset();
179 clip_size.Scale(1 / current_page_scale_factor());
180 }
181
182 bool scrollbar_needs_animation = false;
183 bool scroll_layer_size_did_change = false;
184 bool y_offset_did_change = false;
185 for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(scroll_layer_id)) {
186 if (scrollbar->orientation() == HORIZONTAL) {
187 scrollbar_needs_animation |= scrollbar->SetCurrentPos(current_offset.x());
188 scrollbar_needs_animation |=
189 scrollbar->SetClipLayerLength(clip_size.width());
190 scrollbar_needs_animation |= scroll_layer_size_did_change |=
191 scrollbar->SetScrollLayerLength(scroll_size.width());
192 } else {
193 scrollbar_needs_animation |= y_offset_did_change |=
194 scrollbar->SetCurrentPos(current_offset.y());
195 scrollbar_needs_animation |=
196 scrollbar->SetClipLayerLength(clip_size.height());
197 scrollbar_needs_animation |= scroll_layer_size_did_change |=
198 scrollbar->SetScrollLayerLength(scroll_size.height());
199 }
200 scrollbar_needs_animation |=
201 scrollbar->SetVerticalAdjust(clip_layer->bounds_delta().y());
202 }
203
204 if (y_offset_did_change && IsViewportLayerId(scroll_layer_id))
205 TRACE_COUNTER_ID1("cc", "scroll_offset_y", scroll_layer->id(),
206 current_offset.y());
207
208 if (scrollbar_needs_animation) {
209 ScrollbarAnimationController* controller =
210 layer_tree_host_impl_->ScrollbarAnimationControllerForId(
211 scroll_layer_id);
212 if (controller)
213 controller->DidScrollUpdate(scroll_layer_size_did_change);
214 }
215}
216
hush33370e12015-04-07 03:49:50217void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
[email protected]3b31c6ac2012-12-06 21:27:29218 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:53219
[email protected]c1bb5af2013-03-13 19:06:27220 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]5c4824e12013-01-12 16:34:53221}
222
[email protected]adeda572014-01-31 00:49:47223LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
aeliasc26b50b72015-07-14 20:18:25224 return LayerById(inner_viewport_scroll_layer_id_);
[email protected]adeda572014-01-31 00:49:47225}
[email protected]3b31c6ac2012-12-06 21:27:29226
[email protected]adeda572014-01-31 00:49:47227LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
aeliasc26b50b72015-07-14 20:18:25228 return LayerById(outer_viewport_scroll_layer_id_);
[email protected]adeda572014-01-31 00:49:47229}
[email protected]1960a712013-04-30 17:06:47230
miletusf57925d2014-10-01 19:38:13231gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
232 gfx::ScrollOffset offset;
[email protected]3b31c6ac2012-12-06 21:27:29233
aeliasc26b50b72015-07-14 20:18:25234 if (InnerViewportScrollLayer())
235 offset += InnerViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47236
aeliasc26b50b72015-07-14 20:18:25237 if (OuterViewportScrollLayer())
238 offset += OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47239
240 return offset;
241}
242
miletusf57925d2014-10-01 19:38:13243gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const {
244 gfx::ScrollOffset offset;
[email protected]adeda572014-01-31 00:49:47245
aeliasc26b50b72015-07-14 20:18:25246 if (InnerViewportScrollLayer())
247 offset += InnerViewportScrollLayer()->MaxScrollOffset();
[email protected]adeda572014-01-31 00:49:47248
aeliasc26b50b72015-07-14 20:18:25249 if (OuterViewportScrollLayer())
250 offset += OuterViewportScrollLayer()->MaxScrollOffset();
[email protected]adeda572014-01-31 00:49:47251
252 return offset;
253}
[email protected]3b31c6ac2012-12-06 21:27:29254
255scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
[email protected]76ffd9e2012-12-20 19:12:47256 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16257 set_needs_update_draw_properties();
[email protected]3b31c6ac2012-12-06 21:27:29258 return root_layer_.Pass();
259}
260
ajuma6b46da22015-06-25 21:53:02261static void UpdateClipTreeForBoundsDeltaOnLayer(LayerImpl* layer,
262 ClipTree* clip_tree) {
263 if (layer && layer->masks_to_bounds()) {
264 ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index());
265 if (clip_node) {
266 DCHECK_EQ(layer->id(), clip_node->owner_id);
danakjddaec912015-09-25 19:38:40267 gfx::SizeF bounds = gfx::SizeF(layer->bounds());
ajuma6b46da22015-06-25 21:53:02268 if (clip_node->data.clip.size() != bounds) {
269 clip_node->data.clip.set_size(bounds);
270 clip_tree->set_needs_update(true);
271 }
272 }
273 }
274}
275
276void LayerTreeImpl::UpdatePropertyTreesForBoundsDelta() {
277 DCHECK(IsActiveTree());
278 LayerImpl* inner_container = InnerViewportContainerLayer();
279 LayerImpl* outer_container = OuterViewportContainerLayer();
280
281 UpdateClipTreeForBoundsDeltaOnLayer(inner_container,
282 &property_trees_.clip_tree);
283 UpdateClipTreeForBoundsDeltaOnLayer(InnerViewportScrollLayer(),
284 &property_trees_.clip_tree);
285 UpdateClipTreeForBoundsDeltaOnLayer(outer_container,
286 &property_trees_.clip_tree);
287
288 TransformTree& transform_tree = property_trees_.transform_tree;
ajumadd2802e72015-06-30 20:28:29289 if (inner_container)
290 transform_tree.SetInnerViewportBoundsDelta(inner_container->bounds_delta());
291 if (outer_container)
292 transform_tree.SetOuterViewportBoundsDelta(outer_container->bounds_delta());
ajuma6b46da22015-06-25 21:53:02293}
294
[email protected]7aba6662013-03-12 10:17:34295void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
[email protected]c9280762013-08-01 06:28:57296 // The request queue should have been processed and does not require a push.
297 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
298
ennee95b1542015-04-20 20:35:50299 target_tree->SetPropertyTrees(property_trees_);
300
[email protected]7d08a9352013-10-15 08:24:56301 if (next_activation_forces_redraw_) {
[email protected]12a63da2014-06-13 06:06:22302 target_tree->ForceRedrawNextActivation();
[email protected]7d08a9352013-10-15 08:24:56303 next_activation_forces_redraw_ = false;
304 }
305
[email protected]b69c1db2013-11-27 00:05:19306 target_tree->PassSwapPromises(&swap_promise_list_);
307
aelias6004fe02015-02-07 21:43:01308 target_tree->set_top_controls_shrink_blink_size(
309 top_controls_shrink_blink_size_);
310 target_tree->set_top_controls_height(top_controls_height_);
311 target_tree->PushTopControls(nullptr);
bokan88eae012014-09-09 20:40:42312
skobes93102bc2015-08-04 20:38:05313 target_tree->set_hide_pinch_scrollbars_near_min_scale(
314 hide_pinch_scrollbars_near_min_scale_);
315
aelias58eec0812014-12-04 01:04:40316 // Active tree already shares the page_scale_factor object with pending
317 // tree so only the limits need to be provided.
318 target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
319 max_page_scale_factor());
ajuma1d48e012015-09-25 22:24:16320 target_tree->SetDeviceScaleFactor(device_scale_factor());
ccameronb9aec4502014-12-05 19:31:00321 target_tree->elastic_overscroll()->PushPendingToActive();
[email protected]c60279472013-01-30 12:10:51322
bokanfcdbc182014-11-21 21:53:33323 target_tree->pending_page_scale_animation_ =
324 pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:14325
aeliasc26b50b72015-07-14 20:18:25326 target_tree->SetViewportLayersFromIds(
327 overscroll_elasticity_layer_id_, page_scale_layer_id_,
328 inner_viewport_scroll_layer_id_, outer_viewport_scroll_layer_id_);
[email protected]19aec372014-07-01 19:08:49329
jdduke449b5292015-04-23 19:36:44330 target_tree->RegisterSelection(selection_);
[email protected]19aec372014-07-01 19:08:49331
[email protected]c60279472013-01-30 12:10:51332 // This should match the property synchronization in
333 // LayerTreeHost::finishCommitOnImplThread().
334 target_tree->set_source_frame_number(source_frame_number());
335 target_tree->set_background_color(background_color());
336 target_tree->set_has_transparent_background(has_transparent_background());
337
[email protected]318822852013-02-14 00:54:27338 if (ViewportSizeInvalid())
339 target_tree->SetViewportSizeInvalid();
340 else
341 target_tree->ResetViewportSizeInvalid();
342
[email protected]c60279472013-01-30 12:10:51343 if (hud_layer())
344 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
[email protected]6ba914122013-03-22 16:26:39345 LayerTreeHostCommon::FindLayerInSubtree(
[email protected]c1bb5af2013-03-13 19:06:27346 target_tree->root_layer(), hud_layer()->id())));
[email protected]c60279472013-01-30 12:10:51347 else
348 target_tree->set_hud_layer(NULL);
[email protected]759dc9f2014-07-23 19:18:51349
350 target_tree->has_ever_been_drawn_ = false;
[email protected]c60279472013-01-30 12:10:51351}
352
[email protected]fef74fd2014-02-27 06:28:17353LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
aeliasc26b50b72015-07-14 20:18:25354 return InnerViewportScrollLayer()
355 ? InnerViewportScrollLayer()->scroll_clip_layer()
[email protected]fef74fd2014-02-27 06:28:17356 : NULL;
[email protected]ffb2720f2013-03-15 19:18:37357}
358
bokanef971462014-10-13 22:58:32359LayerImpl* LayerTreeImpl::OuterViewportContainerLayer() const {
aeliasc26b50b72015-07-14 20:18:25360 return OuterViewportScrollLayer()
361 ? OuterViewportScrollLayer()->scroll_clip_layer()
bokanef971462014-10-13 22:58:32362 : NULL;
363}
364
[email protected]ffb2720f2013-03-15 19:18:37365LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
[email protected]69b50ec2013-01-19 04:58:01366 DCHECK(IsActiveTree());
aeliasc26b50b72015-07-14 20:18:25367 return LayerById(currently_scrolling_layer_id_);
[email protected]69b50ec2013-01-19 04:58:01368}
369
[email protected]0fc818e2013-03-18 06:45:20370void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
tdressera3f3a942015-09-28 21:15:39371 DCHECK_IMPLIES(layer, layer != OuterViewportScrollLayer());
372
aeliasc26b50b72015-07-14 20:18:25373 int new_id = layer ? layer->id() : Layer::INVALID_ID;
374 if (currently_scrolling_layer_id_ == new_id)
[email protected]0fc818e2013-03-18 06:45:20375 return;
376
aeliasa57c40d122015-10-08 00:20:09377 ScrollbarAnimationController* old_animation_controller =
378 layer_tree_host_impl_->ScrollbarAnimationControllerForId(
379 currently_scrolling_layer_id_);
380 ScrollbarAnimationController* new_animation_controller =
381 layer_tree_host_impl_->ScrollbarAnimationControllerForId(new_id);
382
383 if (old_animation_controller)
384 old_animation_controller->DidScrollEnd();
aeliasc26b50b72015-07-14 20:18:25385 currently_scrolling_layer_id_ = new_id;
aeliasa57c40d122015-10-08 00:20:09386 if (new_animation_controller)
387 new_animation_controller->DidScrollBegin();
[email protected]0fc818e2013-03-18 06:45:20388}
389
[email protected]3b31c6ac2012-12-06 21:27:29390void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
[email protected]0fc818e2013-03-18 06:45:20391 SetCurrentlyScrollingLayer(NULL);
[email protected]3b31c6ac2012-12-06 21:27:29392}
393
aelias58eec0812014-12-04 01:04:40394float LayerTreeImpl::ClampPageScaleFactorToLimits(
395 float page_scale_factor) const {
396 if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_)
397 page_scale_factor = min_page_scale_factor_;
398 else if (max_page_scale_factor_ && page_scale_factor > max_page_scale_factor_)
399 page_scale_factor = max_page_scale_factor_;
400 return page_scale_factor;
[email protected]d6021f6a2014-06-12 21:15:24401}
[email protected]c60279472013-01-30 12:10:51402
ajuma9db24fb2015-06-29 20:15:07403void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() {
404 // TODO(enne): This should get replaced by pulling out scrolling and
405 // animations into their own trees. Then scrolls and animations would have
406 // their own ways of synchronizing across commits. This occurs to push
407 // updates from scrolling deltas on the compositor thread that have occurred
408 // after begin frame and updates from animations that have ticked since begin
409 // frame to a newly-committed property tree.
enne1eb3a922015-06-17 17:37:50410 if (!root_layer())
411 return;
412 LayerTreeHostCommon::CallFunctionForSubtree(
413 root_layer(), [](LayerImpl* layer) {
ajuma9db24fb2015-06-29 20:15:07414 layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
enne1eb3a922015-06-17 17:37:50415 });
416}
417
aelias58eec0812014-12-04 01:04:40418void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
419 DCHECK(IsActiveTree());
420 if (page_scale_factor()->SetCurrent(
421 ClampPageScaleFactorToLimits(active_page_scale)))
422 DidUpdatePageScale();
[email protected]d6021f6a2014-06-12 21:15:24423}
424
aelias58eec0812014-12-04 01:04:40425void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
426 float min_page_scale_factor,
427 float max_page_scale_factor) {
428 PushPageScaleFactorAndLimits(&page_scale_factor, min_page_scale_factor,
429 max_page_scale_factor);
430}
431
432void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
433 float min_page_scale_factor,
434 float max_page_scale_factor) {
435 DCHECK(page_scale_factor || IsActiveTree());
436 bool changed_page_scale = false;
437 if (page_scale_factor) {
438 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
enne1eb3a922015-06-17 17:37:50439 changed_page_scale |= page_scale_factor_->Delta() != 1.f;
440 // TODO(enne): Once CDP goes away, ignore this call below. The only time
441 // the property trees will differ is if there's been a page scale on the
442 // compositor thread after the begin frame, which is the delta check above.
aelias58eec0812014-12-04 01:04:40443 changed_page_scale |=
444 page_scale_factor_->PushFromMainThread(*page_scale_factor);
445 }
enne1eb3a922015-06-17 17:37:50446 if (IsActiveTree()) {
447 // TODO(enne): Pushing from pending to active should never require
448 // DidUpdatePageScale. The values should already be set by the fully
449 // computed property trees being synced from one tree to another. Remove
450 // this once CDP goes away.
aelias58eec0812014-12-04 01:04:40451 changed_page_scale |= page_scale_factor_->PushPendingToActive();
enne1eb3a922015-06-17 17:37:50452 }
453
aelias58eec0812014-12-04 01:04:40454 changed_page_scale |=
455 SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
456
457 if (changed_page_scale)
458 DidUpdatePageScale();
459}
460
aelias6004fe02015-02-07 21:43:01461void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) {
462 if (top_controls_shrink_blink_size_ == shrink)
463 return;
464
465 top_controls_shrink_blink_size_ = shrink;
466 if (IsActiveTree())
467 layer_tree_host_impl_->UpdateViewportContainerSizes();
468}
469
470void LayerTreeImpl::set_top_controls_height(float top_controls_height) {
471 if (top_controls_height_ == top_controls_height)
472 return;
473
474 top_controls_height_ = top_controls_height;
475 if (IsActiveTree())
476 layer_tree_host_impl_->UpdateViewportContainerSizes();
477}
478
479bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) {
480 ratio = std::max(ratio, 0.f);
481 ratio = std::min(ratio, 1.f);
482 return top_controls_shown_ratio_->SetCurrent(ratio);
483}
484
485void LayerTreeImpl::PushTopControlsFromMainThread(
486 float top_controls_shown_ratio) {
487 PushTopControls(&top_controls_shown_ratio);
488}
489
490void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) {
491 DCHECK(top_controls_shown_ratio || IsActiveTree());
492
493 if (top_controls_shown_ratio) {
494 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
495 top_controls_shown_ratio_->PushFromMainThread(*top_controls_shown_ratio);
496 }
497 if (IsActiveTree()) {
498 if (top_controls_shown_ratio_->PushPendingToActive())
499 layer_tree_host_impl_->DidChangeTopControlsPosition();
500 }
501}
502
aelias58eec0812014-12-04 01:04:40503bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
504 float max_page_scale_factor) {
505 if (min_page_scale_factor == min_page_scale_factor_ &&
506 max_page_scale_factor == max_page_scale_factor_)
507 return false;
[email protected]7265e74e2014-02-07 23:43:06508
[email protected]c60279472013-01-30 12:10:51509 min_page_scale_factor_ = min_page_scale_factor;
510 max_page_scale_factor_ = max_page_scale_factor;
[email protected]20d2b742013-09-26 05:41:34511
aelias58eec0812014-12-04 01:04:40512 return true;
513}
[email protected]d6021f6a2014-06-12 21:15:24514
aelias58eec0812014-12-04 01:04:40515void LayerTreeImpl::DidUpdatePageScale() {
516 if (IsActiveTree())
517 page_scale_factor()->SetCurrent(
518 ClampPageScaleFactorToLimits(current_page_scale_factor()));
[email protected]d6021f6a2014-06-12 21:15:24519
aelias58eec0812014-12-04 01:04:40520 set_needs_update_draw_properties();
aeliasa57c40d122015-10-08 00:20:09521 DidUpdateScrollState(inner_viewport_scroll_layer_id_);
skobes93102bc2015-08-04 20:38:05522 HideInnerViewportScrollbarsIfNeeded();
bokanc784a6f2015-01-28 04:11:50523}
524
ajuma1d48e012015-09-25 22:24:16525void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
526 if (device_scale_factor == device_scale_factor_)
527 return;
528 device_scale_factor_ = device_scale_factor;
529
530 if (IsActiveTree())
531 layer_tree_host_impl_->SetFullRootLayerDamage();
532}
533
skobes93102bc2015-08-04 20:38:05534void LayerTreeImpl::HideInnerViewportScrollbarsIfNeeded() {
skobes93102bc2015-08-04 20:38:05535 float minimum_scale_to_show_at = min_page_scale_factor() * 1.05f;
536 bool hide_scrollbars =
537 hide_pinch_scrollbars_near_min_scale_ &&
538 (current_page_scale_factor() < minimum_scale_to_show_at);
539
aeliasa57c40d122015-10-08 00:20:09540 for (ScrollbarLayerImplBase* scrollbar_layer :
541 ScrollbarsFor(outer_viewport_scroll_layer_id_))
542 scrollbar_layer->SetHideLayerAndSubtree(hide_scrollbars);
[email protected]c60279472013-01-30 12:10:51543}
544
aelias58eec0812014-12-04 01:04:40545SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
546 return page_scale_factor_.get();
547}
548
549const SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() const {
550 return page_scale_factor_.get();
551}
552
[email protected]257abfa82013-01-29 23:47:24553gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
[email protected]587941d2014-08-22 01:40:01554 if (!InnerViewportContainerLayer())
555 return gfx::SizeF();
556
bokanef971462014-10-13 22:58:32557 return gfx::ScaleSize(InnerViewportContainerLayer()->BoundsForScrolling(),
aelias58eec0812014-12-04 01:04:40558 1.0f / current_page_scale_factor());
[email protected]257abfa82013-01-29 23:47:24559}
560
[email protected]3744e27b2013-11-06 21:44:08561gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
[email protected]adeda572014-01-31 00:49:47562 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
563 ? OuterViewportScrollLayer()
564 : InnerViewportScrollLayer();
565 if (!root_scroll_layer || root_scroll_layer->children().empty())
[email protected]3744e27b2013-11-06 21:44:08566 return gfx::Rect();
[email protected]adeda572014-01-31 00:49:47567 LayerImpl* layer = root_scroll_layer->children()[0];
[email protected]8a822692014-02-12 17:30:55568 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
Dana Jansensc46d3742015-06-18 01:33:14569 gfx::Rect(layer->bounds()));
[email protected]3744e27b2013-11-06 21:44:08570}
571
[email protected]58241dc2013-08-20 01:39:25572void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
[email protected]3519b872013-07-30 07:17:50573 DCHECK(IsActiveTree());
574
aelias58eec0812014-12-04 01:04:40575 page_scale_factor()->AbortCommit();
aelias6004fe02015-02-07 21:43:01576 top_controls_shown_ratio()->AbortCommit();
ccameronb9aec4502014-12-05 19:31:00577 elastic_overscroll()->AbortCommit();
[email protected]3519b872013-07-30 07:17:50578
579 if (!root_layer())
580 return;
581
582 LayerTreeHostCommon::CallFunctionForSubtree(
vmpstra73f18d2015-03-02 21:04:39583 root_layer(), [](LayerImpl* layer) {
584 layer->ApplySentScrollDeltasFromAbortedCommit();
585 });
[email protected]58241dc2013-08-20 01:39:25586}
587
[email protected]57ac9482013-09-17 21:13:39588void LayerTreeImpl::SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18589 int overscroll_elasticity_layer_id,
[email protected]57ac9482013-09-17 21:13:39590 int page_scale_layer_id,
591 int inner_viewport_scroll_layer_id,
592 int outer_viewport_scroll_layer_id) {
aeliasc26b50b72015-07-14 20:18:25593 overscroll_elasticity_layer_id_ = overscroll_elasticity_layer_id;
594 page_scale_layer_id_ = page_scale_layer_id;
595 inner_viewport_scroll_layer_id_ = inner_viewport_scroll_layer_id;
596 outer_viewport_scroll_layer_id_ = outer_viewport_scroll_layer_id;
[email protected]adeda572014-01-31 00:49:47597
skobes93102bc2015-08-04 20:38:05598 HideInnerViewportScrollbarsIfNeeded();
[email protected]57ac9482013-09-17 21:13:39599}
600
601void LayerTreeImpl::ClearViewportLayers() {
aeliasc26b50b72015-07-14 20:18:25602 overscroll_elasticity_layer_id_ = Layer::INVALID_ID;
603 page_scale_layer_id_ = Layer::INVALID_ID;
604 inner_viewport_scroll_layer_id_ = Layer::INVALID_ID;
605 outer_viewport_scroll_layer_id_ = Layer::INVALID_ID;
[email protected]57ac9482013-09-17 21:13:39606}
607
enne25041932015-09-25 19:42:01608#if DCHECK_IS_ON()
609int SanityCheckCopyRequestCounts(LayerImpl* layer) {
610 int count = layer->HasCopyRequest() ? 1 : 0;
611 for (size_t i = 0; i < layer->children().size(); ++i) {
612 count += SanityCheckCopyRequestCounts(layer->child_at(i));
613 }
614 DCHECK_EQ(count, layer->num_layer_or_descendants_with_copy_request())
615 << ", id: " << layer->id();
616 return count;
617}
618#endif
619
enneaf5bda32015-02-19 01:27:36620bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
enne25041932015-09-25 19:42:01621#if DCHECK_IS_ON()
622 if (root_layer())
623 SanityCheckCopyRequestCounts(root_layer());
624#endif
625
[email protected]8f7f298822014-06-13 00:23:32626 if (!needs_update_draw_properties_)
627 return true;
[email protected]615c78a2013-01-24 23:44:16628
enne0acea6ae2015-02-19 20:01:51629 // Calling UpdateDrawProperties must clear this flag, so there can be no
630 // early outs before this.
631 needs_update_draw_properties_ = false;
632
633 // For max_texture_size. When the renderer is re-created in
634 // CreateAndSetRenderer, the needs update draw properties flag is set
635 // again.
[email protected]615c78a2013-01-24 23:44:16636 if (!layer_tree_host_impl_->renderer())
[email protected]8f7f298822014-06-13 00:23:32637 return false;
[email protected]615c78a2013-01-24 23:44:16638
enne0acea6ae2015-02-19 20:01:51639 // Clear this after the renderer early out, as it should still be
640 // possible to hit test even without a renderer.
641 render_surface_layer_list_.clear();
642
[email protected]c1bb5af2013-03-13 19:06:27643 if (!root_layer())
[email protected]8f7f298822014-06-13 00:23:32644 return false;
645
[email protected]76ffd9e2012-12-20 19:12:47646 {
danakj4902c302015-02-13 22:12:16647 TRACE_EVENT2(
648 "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties",
649 "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_);
hush367d7dd2014-08-29 23:56:01650 bool can_render_to_separate_surface =
651 (layer_tree_host_impl_->GetDrawMode() !=
652 DRAW_MODE_RESOURCELESS_SOFTWARE);
[email protected]390bb1ff2014-05-09 17:14:40653
654 ++render_surface_layer_list_id_;
ennec3011472015-04-09 01:27:25655
[email protected]7aad55f2013-07-26 11:25:53656 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
danakj3f76ace2014-11-18 16:56:00657 root_layer(), DrawViewportSize(),
658 layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
aeliasc26b50b72015-07-14 20:18:25659 current_page_scale_factor(), PageScaleLayer(),
660 InnerViewportScrollLayer(), OuterViewportScrollLayer(),
ccameronb9aec4502014-12-05 19:31:00661 elastic_overscroll()->Current(IsActiveTree()),
aeliasc26b50b72015-07-14 20:18:25662 OverscrollElasticityLayer(), resource_provider()->max_texture_size(),
ccameronb9aec4502014-12-05 19:31:00663 settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text,
[email protected]45948712013-09-27 02:46:48664 can_render_to_separate_surface,
[email protected]35a99a12013-05-09 23:52:29665 settings().layer_transforms_should_scale_layer_contents,
ennec3011472015-04-09 01:27:25666 settings().verify_property_trees, &render_surface_layer_list_,
ennee95b1542015-04-20 20:35:50667 render_surface_layer_list_id_, &property_trees_);
[email protected]7aad55f2013-07-26 11:25:53668 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
[email protected]76ffd9e2012-12-20 19:12:47669 }
[email protected]615c78a2013-01-24 23:44:16670
[email protected]e4be0262013-10-19 16:54:28671 {
danakj4902c302015-02-13 22:12:16672 TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion",
673 "IsActive", IsActiveTree(), "SourceFrameNumber",
674 source_frame_number_);
danakj00f7925e2015-06-15 21:19:22675 OcclusionTracker occlusion_tracker(
danakj4902c302015-02-13 22:12:16676 root_layer()->render_surface()->content_rect());
677 occlusion_tracker.set_minimum_tracking_size(
678 settings().minimum_occlusion_tracking_size);
boliu7473f7f52014-10-01 16:54:56679
[email protected]e4be0262013-10-19 16:54:28680 // LayerIterator is used here instead of CallFunctionForSubtree to only
681 // UpdateTilePriorities on layers that will be visible (and thus have valid
682 // draw properties) and not because any ordering is required.
enne389d1a12015-06-18 20:40:51683 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
684 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
danakj4902c302015-02-13 22:12:16685 it != end; ++it) {
686 occlusion_tracker.EnterLayer(it);
[email protected]562b7ad2014-06-23 22:17:11687
danakj4902c302015-02-13 22:12:16688 // There are very few render targets so this should be cheap to do for
689 // each layer instead of something more complicated.
690 bool inside_replica = false;
691 LayerImpl* layer = it->render_target();
692 while (layer && !inside_replica) {
693 if (layer->render_target()->has_replica())
694 inside_replica = true;
695 layer = layer->render_target()->parent();
696 }
697
698 // Don't use occlusion if a layer will appear in a replica, since the
699 // tile raster code does not know how to look for the replica and would
700 // consider it occluded even though the replica is visible.
701 // Since occlusion is only used for browser compositor (i.e.
702 // use_occlusion_for_tile_prioritization) and it won't use replicas,
703 // this should matter not.
vmpstrcdcb5f72014-09-11 00:58:37704
boliu7473f7f52014-10-01 16:54:56705 if (it.represents_itself()) {
danakj4902c302015-02-13 22:12:16706 Occlusion occlusion =
707 inside_replica ? Occlusion()
708 : occlusion_tracker.GetCurrentOcclusionForLayer(
709 it->draw_transform());
710 it->draw_properties().occlusion_in_content_space = occlusion;
boliu7473f7f52014-10-01 16:54:56711 }
[email protected]e4be0262013-10-19 16:54:28712
danakj4902c302015-02-13 22:12:16713 if (it.represents_contributing_render_surface()) {
714 // Surfaces aren't used by the tile raster code, so they can have
715 // occlusion regardless of replicas.
716 Occlusion occlusion =
717 occlusion_tracker.GetCurrentOcclusionForContributingSurface(
718 it->render_surface()->draw_transform());
719 it->render_surface()->set_occlusion_in_content_space(occlusion);
720 // Masks are used to draw the contributing surface, so should have
721 // the same occlusion as the surface (nothing inside the surface
722 // occludes them).
723 if (LayerImpl* mask = it->mask_layer()) {
724 Occlusion mask_occlusion =
725 inside_replica
726 ? Occlusion()
727 : occlusion_tracker.GetCurrentOcclusionForContributingSurface(
728 it->render_surface()->draw_transform() *
729 it->draw_transform());
730 mask->draw_properties().occlusion_in_content_space = mask_occlusion;
731 }
732 if (LayerImpl* replica = it->replica_layer()) {
733 if (LayerImpl* mask = replica->mask_layer())
734 mask->draw_properties().occlusion_in_content_space = Occlusion();
735 }
736 }
737
738 occlusion_tracker.LeaveLayer(it);
739 }
740
741 unoccluded_screen_space_region_ =
742 occlusion_tracker.ComputeVisibleRegionInScreen();
743 }
744
enneaf5bda32015-02-19 01:27:36745 // It'd be ideal if this could be done earlier, but when the raster source
746 // is updated from the main thread during push properties, update draw
747 // properties has not occurred yet and so it's not clear whether or not the
748 // layer can or cannot use lcd text. So, this is the cleanup pass to
749 // determine if the raster source needs to be replaced with a non-lcd
750 // raster source due to draw properties.
751 if (update_lcd_text) {
752 // TODO(enne): Make LTHI::sync_tree return this value.
753 LayerTreeImpl* sync_tree =
754 layer_tree_host_impl_->proxy()->CommitToActiveTree()
755 ? layer_tree_host_impl_->active_tree()
756 : layer_tree_host_impl_->pending_tree();
757 // If this is not the sync tree, then it is not safe to update lcd text
758 // as it causes invalidations and the tiles may be in use.
759 DCHECK_EQ(this, sync_tree);
760 for (const auto& layer : picture_layers_)
761 layer->UpdateCanUseLCDTextAfterCommit();
762 }
763
danakj4902c302015-02-13 22:12:16764 {
765 TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles",
766 "IsActive", IsActiveTree(), "SourceFrameNumber",
767 source_frame_number_);
768 const bool resourceless_software_draw =
769 (layer_tree_host_impl_->GetDrawMode() ==
770 DRAW_MODE_RESOURCELESS_SOFTWARE);
danakj4902c302015-02-13 22:12:16771 size_t layers_updated_count = 0;
772 bool tile_priorities_updated = false;
773 for (PictureLayerImpl* layer : picture_layers_) {
danakj4902c302015-02-13 22:12:16774 if (!layer->IsDrawnRenderSurfaceLayerListMember())
[email protected]6355d2d2014-05-07 15:07:27775 continue;
danakj4902c302015-02-13 22:12:16776 ++layers_updated_count;
danakj83c3d4a82015-02-14 01:42:57777 tile_priorities_updated |= layer->UpdateTiles(resourceless_software_draw);
[email protected]e4be0262013-10-19 16:54:28778 }
vmpstrd6166202014-11-05 18:45:40779
vmpstr5377520a2014-12-29 23:26:13780 if (tile_priorities_updated)
781 DidModifyTilePriorities();
782
vmpstrd6166202014-11-05 18:45:40783 TRACE_EVENT_END1("cc", "LayerTreeImpl::UpdateTilePriorities",
784 "layers_updated_count", layers_updated_count);
[email protected]e4be0262013-10-19 16:54:28785 }
786
[email protected]615c78a2013-01-24 23:44:16787 DCHECK(!needs_update_draw_properties_) <<
[email protected]7d19dc342013-05-02 22:02:04788 "CalcDrawProperties should not set_needs_update_draw_properties()";
[email protected]8f7f298822014-06-13 00:23:32789 return true;
[email protected]76ffd9e2012-12-20 19:12:47790}
791
enne7c733af2015-05-27 23:32:48792void LayerTreeImpl::BuildPropertyTreesForTesting() {
jaydasikad36e7fa2015-07-14 15:15:04793 LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_.get());
enne7c733af2015-05-27 23:32:48794 PropertyTreeBuilder::BuildPropertyTrees(
aeliasc26b50b72015-07-14 20:18:25795 root_layer_.get(), PageScaleLayer(), InnerViewportScrollLayer(),
796 OuterViewportScrollLayer(), current_page_scale_factor(),
enne7c733af2015-05-27 23:32:48797 device_scale_factor(), gfx::Rect(DrawViewportSize()),
798 layer_tree_host_impl_->DrawTransform(), &property_trees_);
799}
800
[email protected]50761e92013-03-29 20:51:28801const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
[email protected]76ffd9e2012-12-20 19:12:47802 // If this assert triggers, then the list is dirty.
[email protected]615c78a2013-01-24 23:44:16803 DCHECK(!needs_update_draw_properties_);
[email protected]76ffd9e2012-12-20 19:12:47804 return render_surface_layer_list_;
805}
806
danakj4902c302015-02-13 22:12:16807const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
808 // If this assert triggers, then the render_surface_layer_list_ is dirty, so
809 // the unoccluded_screen_space_region_ is not valid anymore.
810 DCHECK(!needs_update_draw_properties_);
811 return unoccluded_screen_space_region_;
812}
813
bokan574c43632015-08-14 02:22:07814gfx::SizeF LayerTreeImpl::ScrollableSize() const {
[email protected]adeda572014-01-31 00:49:47815 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
816 ? OuterViewportScrollLayer()
817 : InnerViewportScrollLayer();
818 if (!root_scroll_layer || root_scroll_layer->children().empty())
danakjddaec912015-09-25 19:38:40819 return gfx::SizeF();
bokan574c43632015-08-14 02:22:07820
821 gfx::SizeF content_size =
822 root_scroll_layer->children()[0]->BoundsForScrolling();
823 gfx::SizeF viewport_size =
824 root_scroll_layer->scroll_clip_layer()->BoundsForScrolling();
825
826 content_size.SetToMax(viewport_size);
827 return content_size;
[email protected]caa567d2012-12-20 07:56:16828}
829
loysobb93bef2015-07-03 00:19:50830LayerImpl* LayerTreeImpl::LayerById(int id) const {
831 LayerIdMap::const_iterator iter = layer_id_map_.find(id);
[email protected]361bc00d2012-12-14 07:03:24832 return iter != layer_id_map_.end() ? iter->second : NULL;
833}
834
835void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
836 DCHECK(!LayerById(layer->id()));
837 layer_id_map_[layer->id()] = layer;
loysobb93bef2015-07-03 00:19:50838 if (layer_tree_host_impl_->animation_host())
839 layer_tree_host_impl_->animation_host()->RegisterLayer(
840 layer->id(),
841 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING);
[email protected]361bc00d2012-12-14 07:03:24842}
843
844void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
845 DCHECK(LayerById(layer->id()));
loysobb93bef2015-07-03 00:19:50846 if (layer_tree_host_impl_->animation_host())
847 layer_tree_host_impl_->animation_host()->UnregisterLayer(
848 layer->id(),
849 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING);
[email protected]361bc00d2012-12-14 07:03:24850 layer_id_map_.erase(layer->id());
851}
852
[email protected]aebf4622014-07-14 16:57:59853size_t LayerTreeImpl::NumLayers() {
854 return layer_id_map_.size();
855}
856
[email protected]37386f052013-01-13 00:42:22857void LayerTreeImpl::DidBecomeActive() {
[email protected]12a63da2014-06-13 06:06:22858 if (next_activation_forces_redraw_) {
859 layer_tree_host_impl_->SetFullRootLayerDamage();
860 next_activation_forces_redraw_ = false;
861 }
862
[email protected]7dcf5632014-06-25 01:11:55863 // Always reset this flag on activation, as we would only have activated
864 // if we were in a good state.
vmpstr61ed94a12014-10-09 04:49:30865 layer_tree_host_impl_->ResetRequiresHighResToDraw();
[email protected]7dcf5632014-06-25 01:11:55866
vmpstra73f18d2015-03-02 21:04:39867 if (root_layer()) {
868 LayerTreeHostCommon::CallFunctionForSubtree(
869 root_layer(), [](LayerImpl* layer) { layer->DidBecomeActive(); });
870 }
[email protected]7dcf5632014-06-25 01:11:55871
tobiasjs93d464842015-05-15 17:52:44872 for (auto* swap_promise : swap_promise_list_)
873 swap_promise->DidActivate();
[email protected]12a63da2014-06-13 06:06:22874 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
875 source_frame_number_);
[email protected]37386f052013-01-13 00:42:22876}
877
[email protected]3d609bb2014-02-01 01:10:23878bool LayerTreeImpl::RequiresHighResToDraw() const {
vmpstr61ed94a12014-10-09 04:49:30879 return layer_tree_host_impl_->RequiresHighResToDraw();
[email protected]3d609bb2014-02-01 01:10:23880}
881
[email protected]318822852013-02-14 00:54:27882bool LayerTreeImpl::ViewportSizeInvalid() const {
883 return viewport_size_invalid_;
884}
885
886void LayerTreeImpl::SetViewportSizeInvalid() {
887 viewport_size_invalid_ = true;
[email protected]c1bb5af2013-03-13 19:06:27888 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27889}
890
891void LayerTreeImpl::ResetViewportSizeInvalid() {
892 viewport_size_invalid_ = false;
[email protected]c1bb5af2013-03-13 19:06:27893 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27894}
895
[email protected]48871fc2013-01-23 07:36:51896Proxy* LayerTreeImpl::proxy() const {
897 return layer_tree_host_impl_->proxy();
898}
899
[email protected]ff762fb2012-12-12 19:18:37900const LayerTreeSettings& LayerTreeImpl::settings() const {
[email protected]c1bb5af2013-03-13 19:06:27901 return layer_tree_host_impl_->settings();
[email protected]ff762fb2012-12-12 19:18:37902}
903
danakj875efa42015-02-10 22:18:23904const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
905 return layer_tree_host_impl_->debug_state();
906}
907
[email protected]7a8bcd262014-01-15 12:54:58908const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
[email protected]c1bb5af2013-03-13 19:06:27909 return layer_tree_host_impl_->GetRendererCapabilities();
[email protected]bf5b3a02013-02-13 02:02:52910}
911
[email protected]0634cdd42013-08-16 00:46:09912ContextProvider* LayerTreeImpl::context_provider() const {
dcheng6afa17002014-08-26 19:11:31913 return output_surface()->context_provider();
[email protected]0634cdd42013-08-16 00:46:09914}
915
[email protected]ff762fb2012-12-12 19:18:37916OutputSurface* LayerTreeImpl::output_surface() const {
[email protected]c1bb5af2013-03-13 19:06:27917 return layer_tree_host_impl_->output_surface();
[email protected]ff762fb2012-12-12 19:18:37918}
919
920ResourceProvider* LayerTreeImpl::resource_provider() const {
[email protected]c1bb5af2013-03-13 19:06:27921 return layer_tree_host_impl_->resource_provider();
[email protected]ff762fb2012-12-12 19:18:37922}
923
924TileManager* LayerTreeImpl::tile_manager() const {
[email protected]c1bb5af2013-03-13 19:06:27925 return layer_tree_host_impl_->tile_manager();
[email protected]ff762fb2012-12-12 19:18:37926}
927
928FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27929 return layer_tree_host_impl_->fps_counter();
[email protected]ff762fb2012-12-12 19:18:37930}
931
[email protected]1191d9d2013-02-02 06:00:33932MemoryHistory* LayerTreeImpl::memory_history() const {
[email protected]c1bb5af2013-03-13 19:06:27933 return layer_tree_host_impl_->memory_history();
[email protected]1191d9d2013-02-02 06:00:33934}
935
[email protected]4a6c091d2014-04-24 21:06:46936gfx::Size LayerTreeImpl::device_viewport_size() const {
937 return layer_tree_host_impl_->device_viewport_size();
938}
939
danakj875efa42015-02-10 22:18:23940DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
941 return layer_tree_host_impl_->debug_rect_history();
942}
943
[email protected]f117a4c2012-12-16 04:53:10944bool LayerTreeImpl::IsActiveTree() const {
[email protected]c1bb5af2013-03-13 19:06:27945 return layer_tree_host_impl_->active_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10946}
947
948bool LayerTreeImpl::IsPendingTree() const {
[email protected]c1bb5af2013-03-13 19:06:27949 return layer_tree_host_impl_->pending_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10950}
951
[email protected]48871fc2013-01-23 07:36:51952bool LayerTreeImpl::IsRecycleTree() const {
[email protected]c1bb5af2013-03-13 19:06:27953 return layer_tree_host_impl_->recycle_tree() == this;
[email protected]48871fc2013-01-23 07:36:51954}
955
enneaf5bda32015-02-19 01:27:36956bool LayerTreeImpl::IsSyncTree() const {
957 return layer_tree_host_impl_->sync_tree() == this;
958}
959
[email protected]f117a4c2012-12-16 04:53:10960LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27961 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
[email protected]f117a4c2012-12-16 04:53:10962 if (!tree)
963 return NULL;
964 return tree->LayerById(id);
965}
966
967LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27968 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
[email protected]f117a4c2012-12-16 04:53:10969 if (!tree)
970 return NULL;
971 return tree->LayerById(id);
972}
973
[email protected]166db5c82013-01-09 23:54:31974bool LayerTreeImpl::PinchGestureActive() const {
[email protected]c1bb5af2013-03-13 19:06:27975 return layer_tree_host_impl_->pinch_gesture_active();
[email protected]166db5c82013-01-09 23:54:31976}
977
[email protected]04c5900d2014-08-18 13:38:36978BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const {
979 return layer_tree_host_impl_->CurrentBeginFrameArgs();
[email protected]fb7425a2013-04-22 16:28:55980}
981
mithro0bdb49d2015-05-27 13:08:01982base::TimeDelta LayerTreeImpl::CurrentBeginFrameInterval() const {
983 return layer_tree_host_impl_->CurrentBeginFrameInterval();
[email protected]c92195e2014-05-07 18:18:49984}
985
[email protected]d7eb8c72013-03-23 22:57:13986void LayerTreeImpl::SetNeedsCommit() {
987 layer_tree_host_impl_->SetNeedsCommit();
988}
989
[email protected]bd5324592014-07-31 09:09:33990gfx::Rect LayerTreeImpl::DeviceViewport() const {
991 return layer_tree_host_impl_->DeviceViewport();
992}
993
[email protected]54af03522013-09-05 00:43:28994gfx::Size LayerTreeImpl::DrawViewportSize() const {
995 return layer_tree_host_impl_->DrawViewportSize();
996}
997
[email protected]bd5324592014-07-31 09:09:33998const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
999 return layer_tree_host_impl_->ViewportRectForTilePriority();
1000}
1001
[email protected]930ff43b2014-05-02 05:24:001002scoped_ptr<ScrollbarAnimationController>
aeliasa57c40d122015-10-08 00:20:091003LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) {
[email protected]930ff43b2014-05-02 05:24:001004 DCHECK(settings().scrollbar_fade_delay_ms);
1005 DCHECK(settings().scrollbar_fade_duration_ms);
1006 base::TimeDelta delay =
1007 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
sataya.m07f11a82014-10-07 14:29:181008 base::TimeDelta resize_delay = base::TimeDelta::FromMilliseconds(
1009 settings().scrollbar_fade_resize_delay_ms);
[email protected]930ff43b2014-05-02 05:24:001010 base::TimeDelta duration =
1011 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
1012 switch (settings().scrollbar_animator) {
ericrk7c030992015-02-20 01:39:381013 case LayerTreeSettings::LINEAR_FADE: {
[email protected]930ff43b2014-05-02 05:24:001014 return ScrollbarAnimationControllerLinearFade::Create(
aeliasa57c40d122015-10-08 00:20:091015 scroll_layer_id, layer_tree_host_impl_, delay, resize_delay,
sataya.m07f11a82014-10-07 14:29:181016 duration);
[email protected]930ff43b2014-05-02 05:24:001017 }
ericrk7c030992015-02-20 01:39:381018 case LayerTreeSettings::THINNING: {
aeliasa57c40d122015-10-08 00:20:091019 return ScrollbarAnimationControllerThinning::Create(
1020 scroll_layer_id, layer_tree_host_impl_, delay, resize_delay,
1021 duration);
[email protected]930ff43b2014-05-02 05:24:001022 }
ericrk7c030992015-02-20 01:39:381023 case LayerTreeSettings::NO_ANIMATOR:
[email protected]930ff43b2014-05-02 05:24:001024 NOTREACHED();
1025 break;
1026 }
danakjf446a072014-09-27 21:55:481027 return nullptr;
[email protected]2ea5aba2013-09-11 14:26:561028}
1029
[email protected]b8384e22013-12-03 02:20:481030void LayerTreeImpl::DidAnimateScrollOffset() {
1031 layer_tree_host_impl_->DidAnimateScrollOffset();
1032}
1033
[email protected]13525d62014-05-20 21:22:041034bool LayerTreeImpl::use_gpu_rasterization() const {
1035 return layer_tree_host_impl_->use_gpu_rasterization();
1036}
1037
hendrikwc2bbd612014-12-03 23:49:341038GpuRasterizationStatus LayerTreeImpl::GetGpuRasterizationStatus() const {
1039 return layer_tree_host_impl_->gpu_rasterization_status();
1040}
1041
[email protected]473f1f22014-05-22 08:19:171042bool LayerTreeImpl::create_low_res_tiling() const {
1043 return layer_tree_host_impl_->create_low_res_tiling();
1044}
1045
[email protected]ff762fb2012-12-12 19:18:371046void LayerTreeImpl::SetNeedsRedraw() {
[email protected]59adb112013-04-09 04:48:441047 layer_tree_host_impl_->SetNeedsRedraw();
[email protected]ff762fb2012-12-12 19:18:371048}
1049
sunnypsea328be12015-02-26 06:03:271050AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
[email protected]c1bb5af2013-03-13 19:06:271051 return layer_tree_host_impl_->animation_registrar();
[email protected]de4afb5e2012-12-20 00:11:341052}
[email protected]ff762fb2012-12-12 19:18:371053
hendrikwc5e915852015-05-13 01:29:031054void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
1055 std::vector<PrioritizedTile>* prioritized_tiles) const {
enne389d1a12015-06-18 20:40:511056 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
1057 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
1058 it != end; ++it) {
vmpstrd7de03c2014-08-27 18:11:011059 if (!it.represents_itself())
1060 continue;
1061 LayerImpl* layer_impl = *it;
hendrikwc5e915852015-05-13 01:29:031062 layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles);
vmpstrd7de03c2014-08-27 18:11:011063 }
1064}
1065
ssid911e40e2015-02-09 17:55:201066void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
[email protected]d12aa932014-08-01 13:10:381067 TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this);
nduca929378a02014-08-23 19:48:521068 state->SetInteger("source_frame_number", source_frame_number_);
[email protected]f6742f52013-05-08 23:52:221069
[email protected]d12aa932014-08-01 13:10:381070 state->BeginDictionary("root_layer");
1071 root_layer_->AsValueInto(state);
1072 state->EndDictionary();
[email protected]f6742f52013-05-08 23:52:221073
[email protected]d12aa932014-08-01 13:10:381074 state->BeginArray("render_surface_layer_list");
enne389d1a12015-06-18 20:40:511075 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
1076 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
1077 it != end; ++it) {
[email protected]71dfcc72013-03-20 21:30:091078 if (!it.represents_itself())
[email protected]8c5690222013-02-15 17:36:431079 continue;
[email protected]d12aa932014-08-01 13:10:381080 TracedValue::AppendIDRef(*it, state);
[email protected]8c5690222013-02-15 17:36:431081 }
[email protected]d12aa932014-08-01 13:10:381082 state->EndArray();
skyostil43c330f72014-09-22 16:49:111083
1084 state->BeginArray("swap_promise_trace_ids");
tobiasjs93d464842015-05-15 17:52:441085 for (auto* swap_promise : swap_promise_list_)
1086 state->AppendDouble(swap_promise->TraceId());
skyostil43c330f72014-09-22 16:49:111087 state->EndArray();
tobiasjs2e02f73e2015-09-02 12:08:031088
1089 state->BeginArray("pinned_swap_promise_trace_ids");
1090 for (auto* swap_promise : pinned_swap_promise_list_)
1091 state->AppendDouble(swap_promise->TraceId());
1092 state->EndArray();
[email protected]8c5690222013-02-15 17:36:431093}
1094
danakj0481b572015-09-10 01:18:011095void LayerTreeImpl::DistributeRootScrollOffset(
1096 const gfx::ScrollOffset& root_offset) {
hush33370e12015-04-07 03:49:501097 if (!InnerViewportScrollLayer())
1098 return;
1099
1100 DCHECK(OuterViewportScrollLayer());
[email protected]adeda572014-01-31 00:49:471101
1102 // If we get here, we have both inner/outer viewports, and need to distribute
1103 // the scroll offset between them.
miletusf57925d2014-10-01 19:38:131104 gfx::ScrollOffset inner_viewport_offset =
hush33370e12015-04-07 03:49:501105 InnerViewportScrollLayer()->CurrentScrollOffset();
miletusf57925d2014-10-01 19:38:131106 gfx::ScrollOffset outer_viewport_offset =
hush33370e12015-04-07 03:49:501107 OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471108
1109 // It may be nothing has changed.
danakj2c513262015-09-16 00:43:011110 DCHECK(inner_viewport_offset + outer_viewport_offset == TotalScrollOffset());
hush33370e12015-04-07 03:49:501111 if (inner_viewport_offset + outer_viewport_offset == root_offset)
1112 return;
[email protected]adeda572014-01-31 00:49:471113
miletusf57925d2014-10-01 19:38:131114 gfx::ScrollOffset max_outer_viewport_scroll_offset =
[email protected]adeda572014-01-31 00:49:471115 OuterViewportScrollLayer()->MaxScrollOffset();
1116
hush33370e12015-04-07 03:49:501117 outer_viewport_offset = root_offset - inner_viewport_offset;
[email protected]adeda572014-01-31 00:49:471118 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
miletusf57925d2014-10-01 19:38:131119 outer_viewport_offset.SetToMax(gfx::ScrollOffset());
[email protected]adeda572014-01-31 00:49:471120
danakja342d6f3b2015-09-17 22:25:481121 OuterViewportScrollLayer()->SetCurrentScrollOffset(outer_viewport_offset);
hush33370e12015-04-07 03:49:501122 inner_viewport_offset = root_offset - outer_viewport_offset;
danakja342d6f3b2015-09-17 22:25:481123 InnerViewportScrollLayer()->SetCurrentScrollOffset(inner_viewport_offset);
[email protected]adeda572014-01-31 00:49:471124}
1125
[email protected]b69c1db2013-11-27 00:05:191126void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1127 DCHECK(swap_promise);
[email protected]b69c1db2013-11-27 00:05:191128 swap_promise_list_.push_back(swap_promise.Pass());
1129}
1130
tobiasjs2e02f73e2015-09-02 12:08:031131void LayerTreeImpl::QueuePinnedSwapPromise(
1132 scoped_ptr<SwapPromise> swap_promise) {
1133 DCHECK(IsActiveTree());
1134 DCHECK(swap_promise);
1135 pinned_swap_promise_list_.push_back(swap_promise.Pass());
1136}
1137
[email protected]b69c1db2013-11-27 00:05:191138void LayerTreeImpl::PassSwapPromises(
1139 ScopedPtrVector<SwapPromise>* new_swap_promise) {
tobiasjs2e02f73e2015-09-02 12:08:031140 for (auto* swap_promise : swap_promise_list_)
1141 swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS);
1142 swap_promise_list_.clear();
1143 swap_promise_list_.swap(*new_swap_promise);
[email protected]b69c1db2013-11-27 00:05:191144}
1145
[email protected]d359203a2013-11-29 06:16:551146void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
tobiasjs93d464842015-05-15 17:52:441147 for (auto* swap_promise : swap_promise_list_)
1148 swap_promise->DidSwap(metadata);
[email protected]b69c1db2013-11-27 00:05:191149 swap_promise_list_.clear();
tobiasjs2e02f73e2015-09-02 12:08:031150 for (auto* swap_promise : pinned_swap_promise_list_)
1151 swap_promise->DidSwap(metadata);
1152 pinned_swap_promise_list_.clear();
[email protected]b69c1db2013-11-27 00:05:191153}
1154
1155void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
tobiasjs93d464842015-05-15 17:52:441156 for (auto* swap_promise : swap_promise_list_)
1157 swap_promise->DidNotSwap(reason);
[email protected]b69c1db2013-11-27 00:05:191158 swap_promise_list_.clear();
tobiasjs2e02f73e2015-09-02 12:08:031159 for (auto* swap_promise : pinned_swap_promise_list_)
1160 swap_promise->DidNotSwap(reason);
1161 pinned_swap_promise_list_.clear();
[email protected]b69c1db2013-11-27 00:05:191162}
1163
[email protected]c48536a52013-09-14 00:02:081164void LayerTreeImpl::DidModifyTilePriorities() {
1165 layer_tree_host_impl_->DidModifyTilePriorities();
[email protected]fcb846d2013-05-22 01:42:361166}
1167
[email protected]c9280762013-08-01 06:28:571168void LayerTreeImpl::set_ui_resource_request_queue(
1169 const UIResourceRequestQueue& queue) {
1170 ui_resource_request_queue_ = queue;
1171}
1172
jbaumanbbd425e2015-05-19 00:33:351173ResourceId LayerTreeImpl::ResourceIdForUIResource(UIResourceId uid) const {
[email protected]c9280762013-08-01 06:28:571174 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
1175}
1176
[email protected]709c9542013-10-26 01:43:511177bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
1178 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
1179}
1180
[email protected]c9280762013-08-01 06:28:571181void LayerTreeImpl::ProcessUIResourceRequestQueue() {
jdduke5ad36812015-01-02 17:59:321182 for (const auto& req : ui_resource_request_queue_) {
[email protected]741fba422013-09-20 03:34:141183 switch (req.GetType()) {
ericrk7c030992015-02-20 01:39:381184 case UIResourceRequest::UI_RESOURCE_CREATE:
[email protected]741fba422013-09-20 03:34:141185 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
[email protected]c9280762013-08-01 06:28:571186 break;
ericrk7c030992015-02-20 01:39:381187 case UIResourceRequest::UI_RESOURCE_DELETE:
[email protected]741fba422013-09-20 03:34:141188 layer_tree_host_impl_->DeleteUIResource(req.GetId());
[email protected]c9280762013-08-01 06:28:571189 break;
ericrk7c030992015-02-20 01:39:381190 case UIResourceRequest::UI_RESOURCE_INVALID_REQUEST:
[email protected]c9280762013-08-01 06:28:571191 NOTREACHED();
1192 break;
1193 }
1194 }
jdduke5ad36812015-01-02 17:59:321195 ui_resource_request_queue_.clear();
[email protected]127bdc1a2013-09-11 01:44:481196
1197 // If all UI resource evictions were not recreated by processing this queue,
1198 // then another commit is required.
1199 if (layer_tree_host_impl_->EvictedUIResourcesExist())
1200 layer_tree_host_impl_->SetNeedsCommit();
[email protected]c9280762013-08-01 06:28:571201}
1202
danakj7383c552015-02-11 18:01:481203void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1204 DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) ==
1205 picture_layers_.end());
1206 picture_layers_.push_back(layer);
1207}
1208
1209void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1210 std::vector<PictureLayerImpl*>::iterator it =
1211 std::find(picture_layers_.begin(), picture_layers_.end(), layer);
1212 DCHECK(it != picture_layers_.end());
1213 picture_layers_.erase(it);
1214}
1215
aeliasa57c40d122015-10-08 00:20:091216void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) {
1217 if (scrollbar_layer->ScrollLayerId() == Layer::INVALID_ID)
1218 return;
1219
1220 scrollbar_map_.insert(std::pair<int, int>(scrollbar_layer->ScrollLayerId(),
1221 scrollbar_layer->id()));
1222 if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar())
1223 layer_tree_host_impl_->RegisterScrollbarAnimationController(
1224 scrollbar_layer->ScrollLayerId());
1225
1226 DidUpdateScrollState(scrollbar_layer->ScrollLayerId());
1227}
1228
1229void LayerTreeImpl::UnregisterScrollbar(
1230 ScrollbarLayerImplBase* scrollbar_layer) {
1231 int scroll_layer_id = scrollbar_layer->ScrollLayerId();
1232 if (scroll_layer_id == Layer::INVALID_ID)
1233 return;
1234
1235 auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id);
1236 for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i)
1237 if (i->second == scrollbar_layer->id()) {
1238 scrollbar_map_.erase(i);
1239 break;
1240 }
1241
1242 if (IsActiveTree() && scrollbar_map_.count(scroll_layer_id) == 0)
1243 layer_tree_host_impl_->UnregisterScrollbarAnimationController(
1244 scroll_layer_id);
1245}
1246
1247ScrollbarSet LayerTreeImpl::ScrollbarsFor(int scroll_layer_id) const {
1248 ScrollbarSet scrollbars;
1249 auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id);
1250 for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i)
1251 scrollbars.insert(LayerById(i->second)->ToScrollbarLayer());
1252 return scrollbars;
1253}
1254
1255void LayerTreeImpl::RegisterScrollLayer(LayerImpl* layer) {
1256 if (layer->scroll_clip_layer_id() == Layer::INVALID_ID)
1257 return;
1258
1259 clip_scroll_map_.insert(
1260 std::pair<int, int>(layer->scroll_clip_layer_id(), layer->id()));
1261
1262 DidUpdateScrollState(layer->id());
1263}
1264
1265void LayerTreeImpl::UnregisterScrollLayer(LayerImpl* layer) {
1266 if (layer->scroll_clip_layer_id() == Layer::INVALID_ID)
1267 return;
1268
1269 clip_scroll_map_.erase(layer->scroll_clip_layer_id());
1270}
1271
[email protected]30fe19ff2013-07-04 00:54:451272void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
1273 // Only the active tree needs to know about layers with copy requests, as
1274 // they are aborted if not serviced during draw.
1275 DCHECK(IsActiveTree());
1276
[email protected]a4ee12812014-02-06 17:33:381277 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1278 // layers_with_copy_output_request_.end(),
1279 // layer) == layers_with_copy_output_request_.end());
1280 // TODO(danakj): Remove this once crash is found crbug.com/309777
1281 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1282 CHECK(layers_with_copy_output_request_[i] != layer)
1283 << i << " of " << layers_with_copy_output_request_.size();
1284 }
[email protected]30fe19ff2013-07-04 00:54:451285 layers_with_copy_output_request_.push_back(layer);
1286}
1287
1288void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1289 // Only the active tree needs to know about layers with copy requests, as
1290 // they are aborted if not serviced during draw.
1291 DCHECK(IsActiveTree());
1292
1293 std::vector<LayerImpl*>::iterator it = std::find(
1294 layers_with_copy_output_request_.begin(),
1295 layers_with_copy_output_request_.end(),
1296 layer);
1297 DCHECK(it != layers_with_copy_output_request_.end());
[email protected]f5de9e5b2013-07-30 22:26:571298 layers_with_copy_output_request_.erase(it);
[email protected]a4ee12812014-02-06 17:33:381299
1300 // TODO(danakj): Remove this once crash is found crbug.com/309777
1301 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1302 CHECK(layers_with_copy_output_request_[i] != layer)
1303 << i << " of " << layers_with_copy_output_request_.size();
1304 }
[email protected]30fe19ff2013-07-04 00:54:451305}
1306
[email protected]53526372013-12-07 04:31:501307const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
[email protected]30fe19ff2013-07-04 00:54:451308 const {
1309 // Only the active tree needs to know about layers with copy requests, as
1310 // they are aborted if not serviced during draw.
1311 DCHECK(IsActiveTree());
1312
1313 return layers_with_copy_output_request_;
1314}
1315
[email protected]28336d52014-05-12 19:07:281316template <typename LayerType>
1317static inline bool LayerClipsSubtree(LayerType* layer) {
1318 return layer->masks_to_bounds() || layer->mask_layer();
1319}
1320
1321static bool PointHitsRect(
1322 const gfx::PointF& screen_space_point,
1323 const gfx::Transform& local_space_to_screen_space_transform,
danakj5e6ff6d2015-09-05 04:43:441324 const gfx::Rect& local_space_rect,
[email protected]28336d52014-05-12 19:07:281325 float* distance_to_camera) {
1326 // If the transform is not invertible, then assume that this point doesn't hit
1327 // this rect.
1328 gfx::Transform inverse_local_space_to_screen_space(
1329 gfx::Transform::kSkipInitialization);
1330 if (!local_space_to_screen_space_transform.GetInverse(
1331 &inverse_local_space_to_screen_space))
1332 return false;
1333
1334 // Transform the hit test point from screen space to the local space of the
1335 // given rect.
1336 bool clipped = false;
1337 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1338 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1339 gfx::PointF hit_test_point_in_local_space =
1340 gfx::PointF(planar_point.x(), planar_point.y());
1341
1342 // If ProjectPoint could not project to a valid value, then we assume that
1343 // this point doesn't hit this rect.
1344 if (clipped)
1345 return false;
1346
danakj5e6ff6d2015-09-05 04:43:441347 if (!gfx::RectF(local_space_rect).Contains(hit_test_point_in_local_space))
[email protected]28336d52014-05-12 19:07:281348 return false;
1349
1350 if (distance_to_camera) {
1351 // To compute the distance to the camera, we have to take the planar point
1352 // and pull it back to world space and compute the displacement along the
1353 // z-axis.
1354 gfx::Point3F planar_point_in_screen_space(planar_point);
1355 local_space_to_screen_space_transform.TransformPoint(
1356 &planar_point_in_screen_space);
1357 *distance_to_camera = planar_point_in_screen_space.z();
1358 }
1359
1360 return true;
1361}
1362
1363static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1364 const gfx::Transform& screen_space_transform,
danakj2c8d12c2015-06-18 06:15:331365 const Region& layer_space_region) {
[email protected]28336d52014-05-12 19:07:281366 // If the transform is not invertible, then assume that this point doesn't hit
1367 // this region.
1368 gfx::Transform inverse_screen_space_transform(
1369 gfx::Transform::kSkipInitialization);
1370 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1371 return false;
1372
1373 // Transform the hit test point from screen space to the local space of the
1374 // given region.
1375 bool clipped = false;
danakj2c8d12c2015-06-18 06:15:331376 gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
[email protected]28336d52014-05-12 19:07:281377 inverse_screen_space_transform, screen_space_point, &clipped);
[email protected]28336d52014-05-12 19:07:281378
1379 // If ProjectPoint could not project to a valid value, then we assume that
1380 // this point doesn't hit this region.
1381 if (clipped)
1382 return false;
1383
1384 return layer_space_region.Contains(
1385 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1386}
1387
[email protected]19aec372014-07-01 19:08:491388static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
[email protected]0ec86f52014-06-12 20:54:031389 if (layer->scroll_parent())
1390 return layer->scroll_parent();
1391 if (layer->clip_parent())
1392 return layer->clip_parent();
1393 return layer->parent();
1394}
1395
[email protected]28336d52014-05-12 19:07:281396static bool PointIsClippedBySurfaceOrClipRect(
1397 const gfx::PointF& screen_space_point,
[email protected]19aec372014-07-01 19:08:491398 const LayerImpl* layer) {
[email protected]28336d52014-05-12 19:07:281399 // Walk up the layer tree and hit-test any render_surfaces and any layer
1400 // clip rects that are active.
[email protected]0ec86f52014-06-12 20:54:031401 for (; layer; layer = GetNextClippingLayer(layer)) {
1402 if (layer->render_surface() &&
1403 !PointHitsRect(screen_space_point,
1404 layer->render_surface()->screen_space_transform(),
1405 layer->render_surface()->content_rect(),
1406 NULL))
[email protected]28336d52014-05-12 19:07:281407 return true;
1408
[email protected]0ec86f52014-06-12 20:54:031409 if (LayerClipsSubtree(layer) &&
Dana Jansensc46d3742015-06-18 01:33:141410 !PointHitsRect(screen_space_point, layer->screen_space_transform(),
1411 gfx::Rect(layer->bounds()), NULL))
[email protected]28336d52014-05-12 19:07:281412 return true;
[email protected]28336d52014-05-12 19:07:281413 }
1414
1415 // If we have finished walking all ancestors without having already exited,
1416 // then the point is not clipped by any ancestors.
1417 return false;
1418}
1419
[email protected]19aec372014-07-01 19:08:491420static bool PointHitsLayer(const LayerImpl* layer,
[email protected]28336d52014-05-12 19:07:281421 const gfx::PointF& screen_space_point,
1422 float* distance_to_intersection) {
danakj5e6ff6d2015-09-05 04:43:441423 gfx::Rect content_rect(layer->bounds());
[email protected]28336d52014-05-12 19:07:281424 if (!PointHitsRect(screen_space_point,
1425 layer->screen_space_transform(),
1426 content_rect,
1427 distance_to_intersection))
1428 return false;
1429
1430 // At this point, we think the point does hit the layer, but we need to walk
1431 // up the parents to ensure that the layer was not clipped in such a way
1432 // that the hit point actually should not hit the layer.
1433 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1434 return false;
1435
1436 // Skip the HUD layer.
1437 if (layer == layer->layer_tree_impl()->hud_layer())
1438 return false;
1439
1440 return true;
1441}
1442
1443struct FindClosestMatchingLayerDataForRecursion {
1444 FindClosestMatchingLayerDataForRecursion()
1445 : closest_match(NULL),
1446 closest_distance(-std::numeric_limits<float>::infinity()) {}
1447 LayerImpl* closest_match;
1448 // Note that the positive z-axis points towards the camera, so bigger means
1449 // closer in this case, counterintuitively.
1450 float closest_distance;
1451};
1452
1453template <typename Functor>
1454static void FindClosestMatchingLayer(
1455 const gfx::PointF& screen_space_point,
1456 LayerImpl* layer,
1457 const Functor& func,
1458 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
vmpstr24b32b3e2015-06-09 22:39:331459 size_t children_size = layer->children().size();
1460 for (size_t i = 0; i < children_size; ++i) {
1461 size_t index = children_size - 1 - i;
1462 FindClosestMatchingLayer(screen_space_point, layer->children()[index], func,
1463 data_for_recursion);
[email protected]28336d52014-05-12 19:07:281464 }
1465
1466 float distance_to_intersection = 0.f;
1467 if (func(layer) &&
1468 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1469 ((!data_for_recursion->closest_match ||
1470 distance_to_intersection > data_for_recursion->closest_distance))) {
1471 data_for_recursion->closest_distance = distance_to_intersection;
1472 data_for_recursion->closest_match = layer;
1473 }
1474}
1475
1476static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1477 if (!layer->scrollable())
1478 return false;
jaydasika976cd10b2015-05-26 15:45:241479 if (layer->layer_or_descendant_is_drawn())
[email protected]28336d52014-05-12 19:07:281480 return true;
majidvp6cfcc362015-03-06 20:46:391481
[email protected]28336d52014-05-12 19:07:281482 if (!layer->scroll_children())
1483 return false;
1484 for (std::set<LayerImpl*>::const_iterator it =
1485 layer->scroll_children()->begin();
1486 it != layer->scroll_children()->end();
1487 ++it) {
jaydasika976cd10b2015-05-26 15:45:241488 if ((*it)->layer_or_descendant_is_drawn())
[email protected]28336d52014-05-12 19:07:281489 return true;
1490 }
1491 return false;
1492}
1493
1494struct FindScrollingLayerFunctor {
1495 bool operator()(LayerImpl* layer) const {
1496 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1497 }
1498};
1499
1500LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1501 const gfx::PointF& screen_space_point) {
1502 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1503 FindClosestMatchingLayer(screen_space_point,
1504 root_layer(),
1505 FindScrollingLayerFunctor(),
1506 &data_for_recursion);
1507 return data_for_recursion.closest_match;
1508}
1509
1510struct HitTestVisibleScrollableOrTouchableFunctor {
1511 bool operator()(LayerImpl* layer) const {
1512 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1513 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1514 !layer->touch_event_handler_region().IsEmpty() ||
1515 layer->have_wheel_event_handlers();
1516 }
1517};
1518
1519LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1520 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321521 if (!root_layer())
1522 return NULL;
enneaf5bda32015-02-19 01:27:361523 bool update_lcd_text = false;
1524 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321525 return NULL;
[email protected]28336d52014-05-12 19:07:281526 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1527 FindClosestMatchingLayer(screen_space_point,
1528 root_layer(),
1529 HitTestVisibleScrollableOrTouchableFunctor(),
1530 &data_for_recursion);
1531 return data_for_recursion.closest_match;
1532}
1533
1534static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1535 LayerImpl* layer_impl) {
1536 if (layer_impl->touch_event_handler_region().IsEmpty())
1537 return false;
1538
danakj2c8d12c2015-06-18 06:15:331539 if (!PointHitsRegion(screen_space_point, layer_impl->screen_space_transform(),
1540 layer_impl->touch_event_handler_region()))
[email protected]28336d52014-05-12 19:07:281541 return false;
1542
1543 // At this point, we think the point does hit the touch event handler region
1544 // on the layer, but we need to walk up the parents to ensure that the layer
1545 // was not clipped in such a way that the hit point actually should not hit
1546 // the layer.
1547 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1548 return false;
1549
1550 return true;
1551}
1552
ccameron3b607362015-02-02 22:46:291553struct FindWheelEventLayerFunctor {
1554 bool operator()(LayerImpl* layer) const {
1555 return layer->have_wheel_event_handlers();
1556 }
1557};
1558
1559LayerImpl* LayerTreeImpl::FindLayerWithWheelHandlerThatIsHitByPoint(
1560 const gfx::PointF& screen_space_point) {
1561 if (!root_layer())
1562 return NULL;
enneaf5bda32015-02-19 01:27:361563 bool update_lcd_text = false;
1564 if (!UpdateDrawProperties(update_lcd_text))
ccameron3b607362015-02-02 22:46:291565 return NULL;
1566 FindWheelEventLayerFunctor func;
1567 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1568 FindClosestMatchingLayer(screen_space_point, root_layer(), func,
1569 &data_for_recursion);
1570 return data_for_recursion.closest_match;
1571}
1572
[email protected]28336d52014-05-12 19:07:281573struct FindTouchEventLayerFunctor {
1574 bool operator()(LayerImpl* layer) const {
1575 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1576 }
1577 const gfx::PointF screen_space_point;
1578};
1579
1580LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1581 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321582 if (!root_layer())
1583 return NULL;
enneaf5bda32015-02-19 01:27:361584 bool update_lcd_text = false;
1585 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321586 return NULL;
[email protected]28336d52014-05-12 19:07:281587 FindTouchEventLayerFunctor func = {screen_space_point};
1588 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1589 FindClosestMatchingLayer(
1590 screen_space_point, root_layer(), func, &data_for_recursion);
1591 return data_for_recursion.closest_match;
1592}
1593
jdduke449b5292015-04-23 19:36:441594void LayerTreeImpl::RegisterSelection(const LayerSelection& selection) {
1595 selection_ = selection;
[email protected]19aec372014-07-01 19:08:491596}
1597
jdduke449b5292015-04-23 19:36:441598static ViewportSelectionBound ComputeViewportSelectionBound(
[email protected]6ef948732014-08-22 18:57:441599 const LayerSelectionBound& layer_bound,
[email protected]19aec372014-07-01 19:08:491600 LayerImpl* layer,
1601 float device_scale_factor) {
[email protected]6ef948732014-08-22 18:57:441602 ViewportSelectionBound viewport_bound;
1603 viewport_bound.type = layer_bound.type;
[email protected]19aec372014-07-01 19:08:491604
[email protected]6ef948732014-08-22 18:57:441605 if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY)
1606 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491607
danakj2c8d12c2015-06-18 06:15:331608 gfx::PointF layer_top = layer_bound.edge_top;
1609 gfx::PointF layer_bottom = layer_bound.edge_bottom;
[email protected]19aec372014-07-01 19:08:491610
[email protected]6ef948732014-08-22 18:57:441611 bool clipped = false;
danakj2c8d12c2015-06-18 06:15:331612 gfx::PointF screen_top =
1613 MathUtil::MapPoint(layer->screen_space_transform(), layer_top, &clipped);
[email protected]6ef948732014-08-22 18:57:441614 gfx::PointF screen_bottom = MathUtil::MapPoint(
danakj2c8d12c2015-06-18 06:15:331615 layer->screen_space_transform(), layer_bottom, &clipped);
[email protected]6ef948732014-08-22 18:57:441616
ajuma9384b9c22015-09-17 20:35:031617 // MapPoint can produce points with NaN components (even when no inputs are
1618 // NaN). Since consumers of ViewportSelectionBounds may round |edge_top| or
1619 // |edge_bottom| (and since rounding will crash on NaN), we return an empty
1620 // bound instead.
1621 if (std::isnan(screen_top.x()) || std::isnan(screen_top.y()) ||
1622 std::isnan(screen_bottom.x()) || std::isnan(screen_bottom.y()))
1623 return ViewportSelectionBound();
1624
[email protected]6ef948732014-08-22 18:57:441625 const float inv_scale = 1.f / device_scale_factor;
1626 viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale);
1627 viewport_bound.edge_bottom = gfx::ScalePoint(screen_bottom, inv_scale);
1628
1629 // The bottom edge point is used for visibility testing as it is the logical
[email protected]19aec372014-07-01 19:08:491630 // focal point for bound selection handles (this may change in the future).
[email protected]6ef948732014-08-22 18:57:441631 // Shifting the visibility point fractionally inward ensures that neighboring
1632 // or logically coincident layers aligned to integral DPI coordinates will not
1633 // spuriously occlude the bound.
danakj2c8d12c2015-06-18 06:15:331634 gfx::Vector2dF visibility_offset = layer_top - layer_bottom;
[email protected]6ef948732014-08-22 18:57:441635 visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
danakj2c8d12c2015-06-18 06:15:331636 gfx::PointF visibility_point = layer_bottom + visibility_offset;
[email protected]6ef948732014-08-22 18:57:441637 if (visibility_point.x() <= 0)
1638 visibility_point.set_x(visibility_point.x() + device_scale_factor);
1639 visibility_point = MathUtil::MapPoint(
1640 layer->screen_space_transform(), visibility_point, &clipped);
1641
[email protected]19aec372014-07-01 19:08:491642 float intersect_distance = 0.f;
[email protected]6ef948732014-08-22 18:57:441643 viewport_bound.visible =
1644 PointHitsLayer(layer, visibility_point, &intersect_distance);
[email protected]19aec372014-07-01 19:08:491645
[email protected]6ef948732014-08-22 18:57:441646 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491647}
1648
jdduke449b5292015-04-23 19:36:441649void LayerTreeImpl::GetViewportSelection(ViewportSelection* selection) {
1650 DCHECK(selection);
[email protected]19aec372014-07-01 19:08:491651
jdduke449b5292015-04-23 19:36:441652 selection->start = ComputeViewportSelectionBound(
1653 selection_.start,
1654 selection_.start.layer_id ? LayerById(selection_.start.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491655 device_scale_factor());
jdduke449b5292015-04-23 19:36:441656 selection->is_editable = selection_.is_editable;
1657 selection->is_empty_text_form_control = selection_.is_empty_text_form_control;
1658 if (selection->start.type == SELECTION_BOUND_CENTER ||
1659 selection->start.type == SELECTION_BOUND_EMPTY) {
1660 selection->end = selection->start;
[email protected]19aec372014-07-01 19:08:491661 } else {
jdduke449b5292015-04-23 19:36:441662 selection->end = ComputeViewportSelectionBound(
1663 selection_.end,
1664 selection_.end.layer_id ? LayerById(selection_.end.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491665 device_scale_factor());
1666 }
1667}
1668
[email protected]749cbc62014-07-10 01:06:351669void LayerTreeImpl::InputScrollAnimationFinished() {
1670 layer_tree_host_impl_->ScrollEnd();
1671}
1672
vmpstr56ace232014-10-09 20:16:281673bool LayerTreeImpl::SmoothnessTakesPriority() const {
1674 return layer_tree_host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY;
1675}
1676
skyostil3976a3f2014-09-04 22:07:231677BlockingTaskRunner* LayerTreeImpl::BlockingMainThreadTaskRunner() const {
1678 return proxy()->blocking_main_thread_task_runner();
1679}
1680
sunnyps7d073dc2015-04-16 23:29:121681VideoFrameControllerClient* LayerTreeImpl::GetVideoFrameControllerClient()
1682 const {
1683 return layer_tree_host_impl_;
1684}
1685
bokanfcdbc182014-11-21 21:53:331686void LayerTreeImpl::SetPendingPageScaleAnimation(
1687 scoped_ptr<PendingPageScaleAnimation> pending_animation) {
1688 pending_page_scale_animation_ = pending_animation.Pass();
bokan915bf352014-10-02 21:57:141689}
1690
bokanfcdbc182014-11-21 21:53:331691scoped_ptr<PendingPageScaleAnimation>
1692 LayerTreeImpl::TakePendingPageScaleAnimation() {
1693 return pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:141694}
1695
loysod71ece82015-07-03 13:48:501696bool LayerTreeImpl::IsAnimatingFilterProperty(const LayerImpl* layer) const {
ajuma315a4782015-07-24 21:16:341697 LayerTreeType tree_type =
1698 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501699 return layer_tree_host_impl_->animation_host()
1700 ? layer_tree_host_impl_->animation_host()
ajuma315a4782015-07-24 21:16:341701 ->IsAnimatingFilterProperty(layer->id(), tree_type)
loysod71ece82015-07-03 13:48:501702 : false;
1703}
1704
1705bool LayerTreeImpl::IsAnimatingOpacityProperty(const LayerImpl* layer) const {
ajuma315a4782015-07-24 21:16:341706 LayerTreeType tree_type =
1707 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501708 return layer_tree_host_impl_->animation_host()
1709 ? layer_tree_host_impl_->animation_host()
ajuma315a4782015-07-24 21:16:341710 ->IsAnimatingOpacityProperty(layer->id(), tree_type)
loysod71ece82015-07-03 13:48:501711 : false;
1712}
1713
1714bool LayerTreeImpl::IsAnimatingTransformProperty(const LayerImpl* layer) const {
ajuma315a4782015-07-24 21:16:341715 LayerTreeType tree_type =
1716 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501717 return layer_tree_host_impl_->animation_host()
1718 ? layer_tree_host_impl_->animation_host()
ajuma315a4782015-07-24 21:16:341719 ->IsAnimatingTransformProperty(layer->id(), tree_type)
1720 : false;
1721}
1722
1723bool LayerTreeImpl::HasPotentiallyRunningFilterAnimation(
1724 const LayerImpl* layer) const {
1725 LayerTreeType tree_type =
1726 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
1727 return layer_tree_host_impl_->animation_host()
1728 ? layer_tree_host_impl_->animation_host()
1729 ->HasPotentiallyRunningFilterAnimation(layer->id(),
1730 tree_type)
loysod71ece82015-07-03 13:48:501731 : false;
1732}
1733
1734bool LayerTreeImpl::HasPotentiallyRunningOpacityAnimation(
1735 const LayerImpl* layer) const {
ajuma315a4782015-07-24 21:16:341736 LayerTreeType tree_type =
1737 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501738 return layer_tree_host_impl_->animation_host()
1739 ? layer_tree_host_impl_->animation_host()
ajuma315a4782015-07-24 21:16:341740 ->HasPotentiallyRunningOpacityAnimation(layer->id(),
1741 tree_type)
loysod71ece82015-07-03 13:48:501742 : false;
1743}
1744
1745bool LayerTreeImpl::HasPotentiallyRunningTransformAnimation(
1746 const LayerImpl* layer) const {
ajuma315a4782015-07-24 21:16:341747 LayerTreeType tree_type =
1748 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501749 return layer_tree_host_impl_->animation_host()
1750 ? layer_tree_host_impl_->animation_host()
ajuma315a4782015-07-24 21:16:341751 ->HasPotentiallyRunningTransformAnimation(layer->id(),
1752 tree_type)
loysod71ece82015-07-03 13:48:501753 : false;
1754}
1755
ajumae7425272015-07-13 18:37:341756bool LayerTreeImpl::HasAnyAnimationTargetingProperty(
1757 const LayerImpl* layer,
1758 Animation::TargetProperty property) const {
1759 return layer_tree_host_impl_->animation_host()
1760 ? layer_tree_host_impl_->animation_host()
1761 ->HasAnyAnimationTargetingProperty(layer->id(), property)
1762 : false;
1763}
1764
loysod71ece82015-07-03 13:48:501765bool LayerTreeImpl::FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const {
1766 return layer_tree_host_impl_->animation_host()
1767 ? layer_tree_host_impl_->animation_host()
1768 ->FilterIsAnimatingOnImplOnly(layer->id())
1769 : false;
1770}
1771
1772bool LayerTreeImpl::OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const {
1773 return layer_tree_host_impl_->animation_host()
1774 ? layer_tree_host_impl_->animation_host()
1775 ->OpacityIsAnimatingOnImplOnly(layer->id())
1776 : false;
1777}
1778
1779bool LayerTreeImpl::TransformIsAnimatingOnImplOnly(
1780 const LayerImpl* layer) const {
1781 return layer_tree_host_impl_->animation_host()
1782 ? layer_tree_host_impl_->animation_host()
1783 ->TransformIsAnimatingOnImplOnly(layer->id())
1784 : false;
1785}
1786
1787bool LayerTreeImpl::HasOnlyTranslationTransforms(const LayerImpl* layer) const {
ajumadd3592c2015-08-20 15:07:291788 LayerTreeType tree_type =
1789 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501790 return layer_tree_host_impl_->animation_host()
1791 ? layer_tree_host_impl_->animation_host()
ajumadd3592c2015-08-20 15:07:291792 ->HasOnlyTranslationTransforms(layer->id(), tree_type)
loysod71ece82015-07-03 13:48:501793 : true;
1794}
1795
1796bool LayerTreeImpl::MaximumTargetScale(const LayerImpl* layer,
1797 float* max_scale) const {
1798 *max_scale = 0.f;
ajumadd3592c2015-08-20 15:07:291799 LayerTreeType tree_type =
1800 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501801 return layer_tree_host_impl_->animation_host()
1802 ? layer_tree_host_impl_->animation_host()->MaximumTargetScale(
ajumadd3592c2015-08-20 15:07:291803 layer->id(), tree_type, max_scale)
loysod71ece82015-07-03 13:48:501804 : true;
1805}
1806
1807bool LayerTreeImpl::AnimationStartScale(const LayerImpl* layer,
1808 float* start_scale) const {
1809 *start_scale = 0.f;
ajumadd3592c2015-08-20 15:07:291810 LayerTreeType tree_type =
1811 IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING;
loysod71ece82015-07-03 13:48:501812 return layer_tree_host_impl_->animation_host()
1813 ? layer_tree_host_impl_->animation_host()->AnimationStartScale(
ajumadd3592c2015-08-20 15:07:291814 layer->id(), tree_type, start_scale)
loysod71ece82015-07-03 13:48:501815 : true;
1816}
1817
1818bool LayerTreeImpl::HasFilterAnimationThatInflatesBounds(
1819 const LayerImpl* layer) const {
1820 return layer_tree_host_impl_->animation_host()
1821 ? layer_tree_host_impl_->animation_host()
1822 ->HasFilterAnimationThatInflatesBounds(layer->id())
1823 : false;
1824}
1825
1826bool LayerTreeImpl::HasTransformAnimationThatInflatesBounds(
1827 const LayerImpl* layer) const {
1828 return layer_tree_host_impl_->animation_host()
1829 ? layer_tree_host_impl_->animation_host()
1830 ->HasTransformAnimationThatInflatesBounds(layer->id())
1831 : false;
1832}
1833
1834bool LayerTreeImpl::HasAnimationThatInflatesBounds(
1835 const LayerImpl* layer) const {
1836 return layer_tree_host_impl_->animation_host()
1837 ? layer_tree_host_impl_->animation_host()
1838 ->HasAnimationThatInflatesBounds(layer->id())
1839 : false;
1840}
1841
1842bool LayerTreeImpl::FilterAnimationBoundsForBox(const LayerImpl* layer,
1843 const gfx::BoxF& box,
1844 gfx::BoxF* bounds) const {
1845 return layer_tree_host_impl_->animation_host()
1846 ? layer_tree_host_impl_->animation_host()
1847 ->FilterAnimationBoundsForBox(layer->id(), box, bounds)
1848 : false;
1849}
1850
1851bool LayerTreeImpl::TransformAnimationBoundsForBox(const LayerImpl* layer,
1852 const gfx::BoxF& box,
1853 gfx::BoxF* bounds) const {
1854 *bounds = gfx::BoxF();
1855 return layer_tree_host_impl_->animation_host()
1856 ? layer_tree_host_impl_->animation_host()
1857 ->TransformAnimationBoundsForBox(layer->id(), box, bounds)
1858 : true;
1859}
1860
[email protected]ca2902e92013-03-28 01:45:351861} // namespace cc