blob: 9c6c1c294aa9da4fc1ef5b5e9984268a3c91fe1c [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"
[email protected]95e4e1a02013-03-18 07:09:0913#include "cc/animation/keyframed_animation_curve.h"
14#include "cc/animation/scrollbar_animation_controller.h"
[email protected]930ff43b2014-05-02 05:24:0015#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
16#include "cc/animation/scrollbar_animation_controller_thinning.h"
[email protected]3744e27b2013-11-06 21:44:0817#include "cc/base/math_util.h"
aelias58eec0812014-12-04 01:04:4018#include "cc/base/synced_property.h"
[email protected]12a63da2014-06-13 06:06:2219#include "cc/debug/devtools_instrumentation.h"
[email protected]f6742f52013-05-08 23:52:2220#include "cc/debug/traced_value.h"
hush33370e12015-04-07 03:49:5021#include "cc/input/layer_scroll_offset_delegate.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"
heejin.r.chungd28506ba2014-10-23 16:36:2034#include "ui/gfx/geometry/point_conversions.h"
35#include "ui/gfx/geometry/size_conversions.h"
36#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2937
38namespace cc {
[email protected]adeda572014-01-31 00:49:4739
aelias58eec0812014-12-04 01:04:4040LayerTreeImpl::LayerTreeImpl(
41 LayerTreeHostImpl* layer_tree_host_impl,
ccameronb9aec4502014-12-05 19:31:0042 scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
aelias6004fe02015-02-07 21:43:0143 scoped_refptr<SyncedTopControls> top_controls_shown_ratio,
ccameronb9aec4502014-12-05 19:31:0044 scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)
[email protected]db8259f2013-02-01 05:25:0445 : layer_tree_host_impl_(layer_tree_host_impl),
46 source_frame_number_(-1),
47 hud_layer_(0),
[email protected]1960a712013-04-30 17:06:4748 currently_scrolling_layer_(NULL),
49 root_layer_scroll_offset_delegate_(NULL),
[email protected]db8259f2013-02-01 05:25:0450 background_color_(0),
51 has_transparent_background_(false),
ccameronb9aec4502014-12-05 19:31:0052 overscroll_elasticity_layer_(NULL),
[email protected]57ac9482013-09-17 21:13:3953 page_scale_layer_(NULL),
54 inner_viewport_scroll_layer_(NULL),
55 outer_viewport_scroll_layer_(NULL),
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),
ccameronb9aec4502014-12-05 19:31:0059 elastic_overscroll_(elastic_overscroll),
[email protected]db8259f2013-02-01 05:25:0460 scrolling_layer_id_from_previous_tree_(0),
[email protected]318822852013-02-14 00:54:2761 viewport_size_invalid_(false),
[email protected]db8259f2013-02-01 05:25:0462 needs_update_draw_properties_(true),
[email protected]7d08a9352013-10-15 08:24:5663 needs_full_tree_sync_(true),
[email protected]390bb1ff2014-05-09 17:14:4064 next_activation_forces_redraw_(false),
[email protected]759dc9f2014-07-23 19:18:5165 has_ever_been_drawn_(false),
bokan88eae012014-09-09 20:40:4266 render_surface_layer_list_id_(0),
dtrainorcb7779b82014-12-04 01:08:0267 top_controls_shrink_blink_size_(false),
68 top_controls_height_(0),
aelias6004fe02015-02-07 21:43:0169 top_controls_shown_ratio_(top_controls_shown_ratio) {
[email protected]390bb1ff2014-05-09 17:14:4070}
[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
hushb0ee8dc2015-06-10 00:48:57115bool LayerTreeImpl::IsExternalScrollActive() const {
hush33370e12015-04-07 03:49:50116 return root_layer_scroll_offset_delegate_ &&
hushb0ee8dc2015-06-10 00:48:57117 root_layer_scroll_offset_delegate_->IsExternalScrollActive();
hush33370e12015-04-07 03:49:50118}
[email protected]adeda572014-01-31 00:49:47119
hush33370e12015-04-07 03:49:50120void LayerTreeImpl::DidUpdateScrollOffset(int layer_id) {
121 int inner_layer_id = InnerViewportScrollLayer()
122 ? InnerViewportScrollLayer()->id()
123 : Layer::INVALID_ID;
124 int outer_layer_id = OuterViewportScrollLayer()
125 ? OuterViewportScrollLayer()->id()
126 : Layer::INVALID_ID;
127 if (layer_id != outer_layer_id && layer_id != inner_layer_id)
128 return;
129
130 if (!root_layer_scroll_offset_delegate_)
131 return;
132
133 UpdateRootScrollOffsetDelegate();
134}
135
136void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
[email protected]3b31c6ac2012-12-06 21:27:29137 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:53138 currently_scrolling_layer_ = NULL;
[email protected]adeda572014-01-31 00:49:47139 inner_viewport_scroll_layer_ = NULL;
140 outer_viewport_scroll_layer_ = NULL;
141 page_scale_layer_ = NULL;
[email protected]5c4824e12013-01-12 16:34:53142
[email protected]c1bb5af2013-03-13 19:06:27143 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]5c4824e12013-01-12 16:34:53144}
145
[email protected]adeda572014-01-31 00:49:47146LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
147 return inner_viewport_scroll_layer_;
148}
[email protected]3b31c6ac2012-12-06 21:27:29149
[email protected]adeda572014-01-31 00:49:47150LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
151 return outer_viewport_scroll_layer_;
152}
[email protected]1960a712013-04-30 17:06:47153
miletusf57925d2014-10-01 19:38:13154gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
155 gfx::ScrollOffset offset;
[email protected]3b31c6ac2012-12-06 21:27:29156
[email protected]adeda572014-01-31 00:49:47157 if (inner_viewport_scroll_layer_)
aeliasd0070ba2015-01-31 13:44:49158 offset += inner_viewport_scroll_layer_->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47159
160 if (outer_viewport_scroll_layer_)
aeliasd0070ba2015-01-31 13:44:49161 offset += outer_viewport_scroll_layer_->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47162
163 return offset;
164}
165
miletusf57925d2014-10-01 19:38:13166gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const {
167 gfx::ScrollOffset offset;
[email protected]adeda572014-01-31 00:49:47168
169 if (inner_viewport_scroll_layer_)
170 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
171
172 if (outer_viewport_scroll_layer_)
173 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
174
175 return offset;
176}
[email protected]3b31c6ac2012-12-06 21:27:29177
178scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
179 // Clear all data structures that have direct references to the layer tree.
180 scrolling_layer_id_from_previous_tree_ =
181 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
[email protected]adeda572014-01-31 00:49:47182 inner_viewport_scroll_layer_ = NULL;
183 outer_viewport_scroll_layer_ = NULL;
184 page_scale_layer_ = NULL;
[email protected]3b31c6ac2012-12-06 21:27:29185 currently_scrolling_layer_ = NULL;
186
[email protected]76ffd9e2012-12-20 19:12:47187 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16188 set_needs_update_draw_properties();
[email protected]3b31c6ac2012-12-06 21:27:29189 return root_layer_.Pass();
190}
191
ajuma6b46da22015-06-25 21:53:02192static void UpdateClipTreeForBoundsDeltaOnLayer(LayerImpl* layer,
193 ClipTree* clip_tree) {
194 if (layer && layer->masks_to_bounds()) {
195 ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index());
196 if (clip_node) {
197 DCHECK_EQ(layer->id(), clip_node->owner_id);
198 gfx::Size bounds = layer->bounds();
199 if (clip_node->data.clip.size() != bounds) {
200 clip_node->data.clip.set_size(bounds);
201 clip_tree->set_needs_update(true);
202 }
203 }
204 }
205}
206
207void LayerTreeImpl::UpdatePropertyTreesForBoundsDelta() {
208 DCHECK(IsActiveTree());
209 LayerImpl* inner_container = InnerViewportContainerLayer();
210 LayerImpl* outer_container = OuterViewportContainerLayer();
211
212 UpdateClipTreeForBoundsDeltaOnLayer(inner_container,
213 &property_trees_.clip_tree);
214 UpdateClipTreeForBoundsDeltaOnLayer(InnerViewportScrollLayer(),
215 &property_trees_.clip_tree);
216 UpdateClipTreeForBoundsDeltaOnLayer(outer_container,
217 &property_trees_.clip_tree);
218
219 TransformTree& transform_tree = property_trees_.transform_tree;
ajumadcb28302015-06-30 18:09:26220 if (inner_container) {
221 if (inner_container->bounds_delta() !=
222 transform_tree.inner_viewport_bounds_delta()) {
223 transform_tree.set_inner_viewport_bounds_delta(
224 inner_container->bounds_delta());
225 transform_tree.set_needs_update(true);
226 }
227 }
228 if (outer_container) {
229 if (outer_container->bounds_delta() !=
230 transform_tree.outer_viewport_bounds_delta()) {
231 transform_tree.set_outer_viewport_bounds_delta(
232 outer_container->bounds_delta());
233 transform_tree.set_needs_update(true);
234 }
235 }
ajuma6b46da22015-06-25 21:53:02236}
237
[email protected]7aba6662013-03-12 10:17:34238void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
[email protected]c9280762013-08-01 06:28:57239 // The request queue should have been processed and does not require a push.
240 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
241
ennee95b1542015-04-20 20:35:50242 target_tree->SetPropertyTrees(property_trees_);
243
[email protected]7d08a9352013-10-15 08:24:56244 if (next_activation_forces_redraw_) {
[email protected]12a63da2014-06-13 06:06:22245 target_tree->ForceRedrawNextActivation();
[email protected]7d08a9352013-10-15 08:24:56246 next_activation_forces_redraw_ = false;
247 }
248
[email protected]b69c1db2013-11-27 00:05:19249 target_tree->PassSwapPromises(&swap_promise_list_);
250
aelias6004fe02015-02-07 21:43:01251 target_tree->set_top_controls_shrink_blink_size(
252 top_controls_shrink_blink_size_);
253 target_tree->set_top_controls_height(top_controls_height_);
254 target_tree->PushTopControls(nullptr);
bokan88eae012014-09-09 20:40:42255
aelias58eec0812014-12-04 01:04:40256 // Active tree already shares the page_scale_factor object with pending
257 // tree so only the limits need to be provided.
258 target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
259 max_page_scale_factor());
ccameronb9aec4502014-12-05 19:31:00260 target_tree->elastic_overscroll()->PushPendingToActive();
[email protected]c60279472013-01-30 12:10:51261
bokanfcdbc182014-11-21 21:53:33262 target_tree->pending_page_scale_animation_ =
263 pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:14264
[email protected]adeda572014-01-31 00:49:47265 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
[email protected]57ac9482013-09-17 21:13:39266 target_tree->SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18267 overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
268 : Layer::INVALID_ID,
269 page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
[email protected]57ac9482013-09-17 21:13:39270 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
271 : Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47272 } else {
273 target_tree->ClearViewportLayers();
[email protected]57ac9482013-09-17 21:13:39274 }
[email protected]19aec372014-07-01 19:08:49275
jdduke449b5292015-04-23 19:36:44276 target_tree->RegisterSelection(selection_);
[email protected]19aec372014-07-01 19:08:49277
[email protected]c60279472013-01-30 12:10:51278 // This should match the property synchronization in
279 // LayerTreeHost::finishCommitOnImplThread().
280 target_tree->set_source_frame_number(source_frame_number());
281 target_tree->set_background_color(background_color());
282 target_tree->set_has_transparent_background(has_transparent_background());
283
[email protected]318822852013-02-14 00:54:27284 if (ViewportSizeInvalid())
285 target_tree->SetViewportSizeInvalid();
286 else
287 target_tree->ResetViewportSizeInvalid();
288
[email protected]c60279472013-01-30 12:10:51289 if (hud_layer())
290 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
[email protected]6ba914122013-03-22 16:26:39291 LayerTreeHostCommon::FindLayerInSubtree(
[email protected]c1bb5af2013-03-13 19:06:27292 target_tree->root_layer(), hud_layer()->id())));
[email protected]c60279472013-01-30 12:10:51293 else
294 target_tree->set_hud_layer(NULL);
[email protected]759dc9f2014-07-23 19:18:51295
296 target_tree->has_ever_been_drawn_ = false;
[email protected]c60279472013-01-30 12:10:51297}
298
[email protected]fef74fd2014-02-27 06:28:17299LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
300 return inner_viewport_scroll_layer_
301 ? inner_viewport_scroll_layer_->scroll_clip_layer()
302 : NULL;
[email protected]ffb2720f2013-03-15 19:18:37303}
304
bokanef971462014-10-13 22:58:32305LayerImpl* LayerTreeImpl::OuterViewportContainerLayer() const {
306 return outer_viewport_scroll_layer_
307 ? outer_viewport_scroll_layer_->scroll_clip_layer()
308 : NULL;
309}
310
[email protected]ffb2720f2013-03-15 19:18:37311LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
[email protected]69b50ec2013-01-19 04:58:01312 DCHECK(IsActiveTree());
313 return currently_scrolling_layer_;
314}
315
[email protected]0fc818e2013-03-18 06:45:20316void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
317 if (currently_scrolling_layer_ == layer)
318 return;
319
320 if (currently_scrolling_layer_ &&
321 currently_scrolling_layer_->scrollbar_animation_controller())
[email protected]1dc06162014-03-26 22:54:45322 currently_scrolling_layer_->scrollbar_animation_controller()
[email protected]930ff43b2014-05-02 05:24:00323 ->DidScrollEnd();
[email protected]0fc818e2013-03-18 06:45:20324 currently_scrolling_layer_ = layer;
325 if (layer && layer->scrollbar_animation_controller())
[email protected]930ff43b2014-05-02 05:24:00326 layer->scrollbar_animation_controller()->DidScrollBegin();
[email protected]0fc818e2013-03-18 06:45:20327}
328
[email protected]3b31c6ac2012-12-06 21:27:29329void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
[email protected]0fc818e2013-03-18 06:45:20330 SetCurrentlyScrollingLayer(NULL);
[email protected]3b31c6ac2012-12-06 21:27:29331 scrolling_layer_id_from_previous_tree_ = 0;
332}
333
[email protected]adeda572014-01-31 00:49:47334namespace {
335
336void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
337 if (!current_layer)
338 return;
339
340 while (current_layer) {
sataya.m07f11a82014-10-07 14:29:18341 current_layer->ScrollbarParametersDidChange(false);
[email protected]adeda572014-01-31 00:49:47342 current_layer = current_layer->parent();
343 }
344}
345
346} // namespace
347
aelias58eec0812014-12-04 01:04:40348float LayerTreeImpl::ClampPageScaleFactorToLimits(
349 float page_scale_factor) const {
350 if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_)
351 page_scale_factor = min_page_scale_factor_;
352 else if (max_page_scale_factor_ && page_scale_factor > max_page_scale_factor_)
353 page_scale_factor = max_page_scale_factor_;
354 return page_scale_factor;
[email protected]d6021f6a2014-06-12 21:15:24355}
[email protected]c60279472013-01-30 12:10:51356
ajuma9db24fb2015-06-29 20:15:07357void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() {
358 // TODO(enne): This should get replaced by pulling out scrolling and
359 // animations into their own trees. Then scrolls and animations would have
360 // their own ways of synchronizing across commits. This occurs to push
361 // updates from scrolling deltas on the compositor thread that have occurred
362 // after begin frame and updates from animations that have ticked since begin
363 // frame to a newly-committed property tree.
enne1eb3a922015-06-17 17:37:50364 if (!root_layer())
365 return;
366 LayerTreeHostCommon::CallFunctionForSubtree(
367 root_layer(), [](LayerImpl* layer) {
ajuma9db24fb2015-06-29 20:15:07368 layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
enne1eb3a922015-06-17 17:37:50369 });
370}
371
aelias58eec0812014-12-04 01:04:40372void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
373 DCHECK(IsActiveTree());
374 if (page_scale_factor()->SetCurrent(
375 ClampPageScaleFactorToLimits(active_page_scale)))
376 DidUpdatePageScale();
[email protected]d6021f6a2014-06-12 21:15:24377}
378
aelias58eec0812014-12-04 01:04:40379void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
380 float min_page_scale_factor,
381 float max_page_scale_factor) {
382 PushPageScaleFactorAndLimits(&page_scale_factor, min_page_scale_factor,
383 max_page_scale_factor);
384}
385
386void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
387 float min_page_scale_factor,
388 float max_page_scale_factor) {
389 DCHECK(page_scale_factor || IsActiveTree());
390 bool changed_page_scale = false;
391 if (page_scale_factor) {
392 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
enne1eb3a922015-06-17 17:37:50393 changed_page_scale |= page_scale_factor_->Delta() != 1.f;
394 // TODO(enne): Once CDP goes away, ignore this call below. The only time
395 // the property trees will differ is if there's been a page scale on the
396 // compositor thread after the begin frame, which is the delta check above.
aelias58eec0812014-12-04 01:04:40397 changed_page_scale |=
398 page_scale_factor_->PushFromMainThread(*page_scale_factor);
399 }
enne1eb3a922015-06-17 17:37:50400 if (IsActiveTree()) {
401 // TODO(enne): Pushing from pending to active should never require
402 // DidUpdatePageScale. The values should already be set by the fully
403 // computed property trees being synced from one tree to another. Remove
404 // this once CDP goes away.
aelias58eec0812014-12-04 01:04:40405 changed_page_scale |= page_scale_factor_->PushPendingToActive();
enne1eb3a922015-06-17 17:37:50406 }
407
aelias58eec0812014-12-04 01:04:40408 changed_page_scale |=
409 SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
410
411 if (changed_page_scale)
412 DidUpdatePageScale();
413}
414
aelias6004fe02015-02-07 21:43:01415void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) {
416 if (top_controls_shrink_blink_size_ == shrink)
417 return;
418
419 top_controls_shrink_blink_size_ = shrink;
420 if (IsActiveTree())
421 layer_tree_host_impl_->UpdateViewportContainerSizes();
422}
423
424void LayerTreeImpl::set_top_controls_height(float top_controls_height) {
425 if (top_controls_height_ == top_controls_height)
426 return;
427
428 top_controls_height_ = top_controls_height;
429 if (IsActiveTree())
430 layer_tree_host_impl_->UpdateViewportContainerSizes();
431}
432
433bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) {
434 ratio = std::max(ratio, 0.f);
435 ratio = std::min(ratio, 1.f);
436 return top_controls_shown_ratio_->SetCurrent(ratio);
437}
438
439void LayerTreeImpl::PushTopControlsFromMainThread(
440 float top_controls_shown_ratio) {
441 PushTopControls(&top_controls_shown_ratio);
442}
443
444void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) {
445 DCHECK(top_controls_shown_ratio || IsActiveTree());
446
447 if (top_controls_shown_ratio) {
448 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
449 top_controls_shown_ratio_->PushFromMainThread(*top_controls_shown_ratio);
450 }
451 if (IsActiveTree()) {
452 if (top_controls_shown_ratio_->PushPendingToActive())
453 layer_tree_host_impl_->DidChangeTopControlsPosition();
454 }
455}
456
aelias58eec0812014-12-04 01:04:40457bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
458 float max_page_scale_factor) {
459 if (min_page_scale_factor == min_page_scale_factor_ &&
460 max_page_scale_factor == max_page_scale_factor_)
461 return false;
[email protected]7265e74e2014-02-07 23:43:06462
[email protected]c60279472013-01-30 12:10:51463 min_page_scale_factor_ = min_page_scale_factor;
464 max_page_scale_factor_ = max_page_scale_factor;
[email protected]20d2b742013-09-26 05:41:34465
aelias58eec0812014-12-04 01:04:40466 return true;
467}
[email protected]d6021f6a2014-06-12 21:15:24468
aelias58eec0812014-12-04 01:04:40469void LayerTreeImpl::DidUpdatePageScale() {
470 if (IsActiveTree())
471 page_scale_factor()->SetCurrent(
472 ClampPageScaleFactorToLimits(current_page_scale_factor()));
[email protected]d6021f6a2014-06-12 21:15:24473
aelias58eec0812014-12-04 01:04:40474 set_needs_update_draw_properties();
[email protected]d6021f6a2014-06-12 21:15:24475
[email protected]22f200a2013-10-09 18:08:29476 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:00477 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:40478 TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
479 current_page_scale_factor(), min_page_scale_factor_,
[email protected]d6021f6a2014-06-12 21:15:24480 max_page_scale_factor_);
[email protected]22f200a2013-10-09 18:08:29481 }
[email protected]adeda572014-01-31 00:49:47482
enneb21df312015-05-27 00:27:18483 if (page_scale_layer() && page_scale_layer()->transform_tree_index() != -1) {
484 TransformNode* node = property_trees_.transform_tree.Node(
485 page_scale_layer()->transform_tree_index());
486 node->data.post_local_scale_factor = current_page_scale_factor();
ajumababeff12015-05-28 21:56:27487 node->data.needs_local_transform_update = true;
enneb21df312015-05-27 00:27:18488 // TODO(enne): property trees can't ask the layer these things, but
489 // the page scale layer should *just* be the page scale.
490 DCHECK_EQ(page_scale_layer()->position().ToString(),
491 gfx::PointF().ToString());
492 DCHECK_EQ(page_scale_layer()->transform_origin().ToString(),
493 gfx::Point3F().ToString());
494 node->data.update_post_local_transform(gfx::PointF(), gfx::Point3F());
495 property_trees_.transform_tree.set_needs_update(true);
496 }
497
[email protected]adeda572014-01-31 00:49:47498 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
bokanc784a6f2015-01-28 04:11:50499
500 HideInnerViewportScrollbarsIfNearMinimumScale();
501}
502
503void LayerTreeImpl::HideInnerViewportScrollbarsIfNearMinimumScale() {
504 if (!InnerViewportContainerLayer())
505 return;
506
507 LayerImpl::ScrollbarSet* scrollbars =
508 InnerViewportContainerLayer()->scrollbars();
509
510 if (!scrollbars)
511 return;
512
513 for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
514 it != scrollbars->end();
515 ++it) {
516 ScrollbarLayerImplBase* scrollbar = *it;
517 float minimum_scale_to_show_at =
518 min_page_scale_factor() * settings().scrollbar_show_scale_threshold;
519 scrollbar->SetHideLayerAndSubtree(
520 current_page_scale_factor() < minimum_scale_to_show_at);
521 }
[email protected]c60279472013-01-30 12:10:51522}
523
aelias58eec0812014-12-04 01:04:40524SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
525 return page_scale_factor_.get();
526}
527
528const SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() const {
529 return page_scale_factor_.get();
530}
531
[email protected]257abfa82013-01-29 23:47:24532gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
[email protected]587941d2014-08-22 01:40:01533 if (!InnerViewportContainerLayer())
534 return gfx::SizeF();
535
bokanef971462014-10-13 22:58:32536 return gfx::ScaleSize(InnerViewportContainerLayer()->BoundsForScrolling(),
aelias58eec0812014-12-04 01:04:40537 1.0f / current_page_scale_factor());
[email protected]257abfa82013-01-29 23:47:24538}
539
[email protected]3744e27b2013-11-06 21:44:08540gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
[email protected]adeda572014-01-31 00:49:47541 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
542 ? OuterViewportScrollLayer()
543 : InnerViewportScrollLayer();
544 if (!root_scroll_layer || root_scroll_layer->children().empty())
[email protected]3744e27b2013-11-06 21:44:08545 return gfx::Rect();
[email protected]adeda572014-01-31 00:49:47546 LayerImpl* layer = root_scroll_layer->children()[0];
[email protected]8a822692014-02-12 17:30:55547 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
Dana Jansensc46d3742015-06-18 01:33:14548 gfx::Rect(layer->bounds()));
[email protected]3744e27b2013-11-06 21:44:08549}
550
[email protected]58241dc2013-08-20 01:39:25551void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
[email protected]3519b872013-07-30 07:17:50552 DCHECK(IsActiveTree());
553
aelias58eec0812014-12-04 01:04:40554 page_scale_factor()->AbortCommit();
aelias6004fe02015-02-07 21:43:01555 top_controls_shown_ratio()->AbortCommit();
ccameronb9aec4502014-12-05 19:31:00556 elastic_overscroll()->AbortCommit();
[email protected]3519b872013-07-30 07:17:50557
558 if (!root_layer())
559 return;
560
561 LayerTreeHostCommon::CallFunctionForSubtree(
vmpstra73f18d2015-03-02 21:04:39562 root_layer(), [](LayerImpl* layer) {
563 layer->ApplySentScrollDeltasFromAbortedCommit();
564 });
[email protected]58241dc2013-08-20 01:39:25565}
566
[email protected]57ac9482013-09-17 21:13:39567void LayerTreeImpl::SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18568 int overscroll_elasticity_layer_id,
[email protected]57ac9482013-09-17 21:13:39569 int page_scale_layer_id,
570 int inner_viewport_scroll_layer_id,
571 int outer_viewport_scroll_layer_id) {
ccameron8230b68b2014-11-21 19:25:18572 overscroll_elasticity_layer_ = LayerById(overscroll_elasticity_layer_id);
[email protected]57ac9482013-09-17 21:13:39573 page_scale_layer_ = LayerById(page_scale_layer_id);
574 DCHECK(page_scale_layer_);
575
576 inner_viewport_scroll_layer_ =
577 LayerById(inner_viewport_scroll_layer_id);
578 DCHECK(inner_viewport_scroll_layer_);
579
580 outer_viewport_scroll_layer_ =
581 LayerById(outer_viewport_scroll_layer_id);
582 DCHECK(outer_viewport_scroll_layer_ ||
583 outer_viewport_scroll_layer_id == Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47584
bokanc784a6f2015-01-28 04:11:50585 HideInnerViewportScrollbarsIfNearMinimumScale();
[email protected]57ac9482013-09-17 21:13:39586}
587
588void LayerTreeImpl::ClearViewportLayers() {
589 page_scale_layer_ = NULL;
590 inner_viewport_scroll_layer_ = NULL;
591 outer_viewport_scroll_layer_ = NULL;
592}
593
enneaf5bda32015-02-19 01:27:36594bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
[email protected]8f7f298822014-06-13 00:23:32595 if (!needs_update_draw_properties_)
596 return true;
[email protected]615c78a2013-01-24 23:44:16597
enne0acea6ae2015-02-19 20:01:51598 // Calling UpdateDrawProperties must clear this flag, so there can be no
599 // early outs before this.
600 needs_update_draw_properties_ = false;
601
602 // For max_texture_size. When the renderer is re-created in
603 // CreateAndSetRenderer, the needs update draw properties flag is set
604 // again.
[email protected]615c78a2013-01-24 23:44:16605 if (!layer_tree_host_impl_->renderer())
[email protected]8f7f298822014-06-13 00:23:32606 return false;
[email protected]615c78a2013-01-24 23:44:16607
enne0acea6ae2015-02-19 20:01:51608 // Clear this after the renderer early out, as it should still be
609 // possible to hit test even without a renderer.
610 render_surface_layer_list_.clear();
611
[email protected]c1bb5af2013-03-13 19:06:27612 if (!root_layer())
[email protected]8f7f298822014-06-13 00:23:32613 return false;
614
[email protected]76ffd9e2012-12-20 19:12:47615 {
danakj4902c302015-02-13 22:12:16616 TRACE_EVENT2(
617 "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties",
618 "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_);
[email protected]57ac9482013-09-17 21:13:39619 LayerImpl* page_scale_layer =
[email protected]fef74fd2014-02-27 06:28:17620 page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
hush367d7dd2014-08-29 23:56:01621 bool can_render_to_separate_surface =
622 (layer_tree_host_impl_->GetDrawMode() !=
623 DRAW_MODE_RESOURCELESS_SOFTWARE);
[email protected]390bb1ff2014-05-09 17:14:40624
625 ++render_surface_layer_list_id_;
ennec3011472015-04-09 01:27:25626
[email protected]7aad55f2013-07-26 11:25:53627 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
danakj3f76ace2014-11-18 16:56:00628 root_layer(), DrawViewportSize(),
629 layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
aelias58eec0812014-12-04 01:04:40630 current_page_scale_factor(), page_scale_layer,
ajuma6b46da22015-06-25 21:53:02631 inner_viewport_scroll_layer_, outer_viewport_scroll_layer_,
ccameronb9aec4502014-12-05 19:31:00632 elastic_overscroll()->Current(IsActiveTree()),
633 overscroll_elasticity_layer_, resource_provider()->max_texture_size(),
634 settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text,
[email protected]45948712013-09-27 02:46:48635 can_render_to_separate_surface,
[email protected]35a99a12013-05-09 23:52:29636 settings().layer_transforms_should_scale_layer_contents,
ennec3011472015-04-09 01:27:25637 settings().verify_property_trees, &render_surface_layer_list_,
ennee95b1542015-04-20 20:35:50638 render_surface_layer_list_id_, &property_trees_);
[email protected]7aad55f2013-07-26 11:25:53639 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
[email protected]76ffd9e2012-12-20 19:12:47640 }
[email protected]615c78a2013-01-24 23:44:16641
[email protected]e4be0262013-10-19 16:54:28642 {
danakj4902c302015-02-13 22:12:16643 TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion",
644 "IsActive", IsActiveTree(), "SourceFrameNumber",
645 source_frame_number_);
danakj00f7925e2015-06-15 21:19:22646 OcclusionTracker occlusion_tracker(
danakj4902c302015-02-13 22:12:16647 root_layer()->render_surface()->content_rect());
648 occlusion_tracker.set_minimum_tracking_size(
649 settings().minimum_occlusion_tracking_size);
boliu7473f7f52014-10-01 16:54:56650
[email protected]e4be0262013-10-19 16:54:28651 // LayerIterator is used here instead of CallFunctionForSubtree to only
652 // UpdateTilePriorities on layers that will be visible (and thus have valid
653 // draw properties) and not because any ordering is required.
enne389d1a12015-06-18 20:40:51654 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
655 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
danakj4902c302015-02-13 22:12:16656 it != end; ++it) {
657 occlusion_tracker.EnterLayer(it);
[email protected]562b7ad2014-06-23 22:17:11658
danakj4902c302015-02-13 22:12:16659 // There are very few render targets so this should be cheap to do for
660 // each layer instead of something more complicated.
661 bool inside_replica = false;
662 LayerImpl* layer = it->render_target();
663 while (layer && !inside_replica) {
664 if (layer->render_target()->has_replica())
665 inside_replica = true;
666 layer = layer->render_target()->parent();
667 }
668
669 // Don't use occlusion if a layer will appear in a replica, since the
670 // tile raster code does not know how to look for the replica and would
671 // consider it occluded even though the replica is visible.
672 // Since occlusion is only used for browser compositor (i.e.
673 // use_occlusion_for_tile_prioritization) and it won't use replicas,
674 // this should matter not.
vmpstrcdcb5f72014-09-11 00:58:37675
boliu7473f7f52014-10-01 16:54:56676 if (it.represents_itself()) {
danakj4902c302015-02-13 22:12:16677 Occlusion occlusion =
678 inside_replica ? Occlusion()
679 : occlusion_tracker.GetCurrentOcclusionForLayer(
680 it->draw_transform());
681 it->draw_properties().occlusion_in_content_space = occlusion;
boliu7473f7f52014-10-01 16:54:56682 }
[email protected]e4be0262013-10-19 16:54:28683
danakj4902c302015-02-13 22:12:16684 if (it.represents_contributing_render_surface()) {
685 // Surfaces aren't used by the tile raster code, so they can have
686 // occlusion regardless of replicas.
687 Occlusion occlusion =
688 occlusion_tracker.GetCurrentOcclusionForContributingSurface(
689 it->render_surface()->draw_transform());
690 it->render_surface()->set_occlusion_in_content_space(occlusion);
691 // Masks are used to draw the contributing surface, so should have
692 // the same occlusion as the surface (nothing inside the surface
693 // occludes them).
694 if (LayerImpl* mask = it->mask_layer()) {
695 Occlusion mask_occlusion =
696 inside_replica
697 ? Occlusion()
698 : occlusion_tracker.GetCurrentOcclusionForContributingSurface(
699 it->render_surface()->draw_transform() *
700 it->draw_transform());
701 mask->draw_properties().occlusion_in_content_space = mask_occlusion;
702 }
703 if (LayerImpl* replica = it->replica_layer()) {
704 if (LayerImpl* mask = replica->mask_layer())
705 mask->draw_properties().occlusion_in_content_space = Occlusion();
706 }
707 }
708
709 occlusion_tracker.LeaveLayer(it);
710 }
711
712 unoccluded_screen_space_region_ =
713 occlusion_tracker.ComputeVisibleRegionInScreen();
714 }
715
enneaf5bda32015-02-19 01:27:36716 // It'd be ideal if this could be done earlier, but when the raster source
717 // is updated from the main thread during push properties, update draw
718 // properties has not occurred yet and so it's not clear whether or not the
719 // layer can or cannot use lcd text. So, this is the cleanup pass to
720 // determine if the raster source needs to be replaced with a non-lcd
721 // raster source due to draw properties.
722 if (update_lcd_text) {
723 // TODO(enne): Make LTHI::sync_tree return this value.
724 LayerTreeImpl* sync_tree =
725 layer_tree_host_impl_->proxy()->CommitToActiveTree()
726 ? layer_tree_host_impl_->active_tree()
727 : layer_tree_host_impl_->pending_tree();
728 // If this is not the sync tree, then it is not safe to update lcd text
729 // as it causes invalidations and the tiles may be in use.
730 DCHECK_EQ(this, sync_tree);
731 for (const auto& layer : picture_layers_)
732 layer->UpdateCanUseLCDTextAfterCommit();
733 }
734
danakj4902c302015-02-13 22:12:16735 {
736 TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles",
737 "IsActive", IsActiveTree(), "SourceFrameNumber",
738 source_frame_number_);
739 const bool resourceless_software_draw =
740 (layer_tree_host_impl_->GetDrawMode() ==
741 DRAW_MODE_RESOURCELESS_SOFTWARE);
danakj4902c302015-02-13 22:12:16742 size_t layers_updated_count = 0;
743 bool tile_priorities_updated = false;
744 for (PictureLayerImpl* layer : picture_layers_) {
danakj4902c302015-02-13 22:12:16745 if (!layer->IsDrawnRenderSurfaceLayerListMember())
[email protected]6355d2d2014-05-07 15:07:27746 continue;
danakj4902c302015-02-13 22:12:16747 ++layers_updated_count;
danakj83c3d4a82015-02-14 01:42:57748 tile_priorities_updated |= layer->UpdateTiles(resourceless_software_draw);
[email protected]e4be0262013-10-19 16:54:28749 }
vmpstrd6166202014-11-05 18:45:40750
vmpstr5377520a2014-12-29 23:26:13751 if (tile_priorities_updated)
752 DidModifyTilePriorities();
753
vmpstrd6166202014-11-05 18:45:40754 TRACE_EVENT_END1("cc", "LayerTreeImpl::UpdateTilePriorities",
755 "layers_updated_count", layers_updated_count);
[email protected]e4be0262013-10-19 16:54:28756 }
757
[email protected]615c78a2013-01-24 23:44:16758 DCHECK(!needs_update_draw_properties_) <<
[email protected]7d19dc342013-05-02 22:02:04759 "CalcDrawProperties should not set_needs_update_draw_properties()";
[email protected]8f7f298822014-06-13 00:23:32760 return true;
[email protected]76ffd9e2012-12-20 19:12:47761}
762
enne7c733af2015-05-27 23:32:48763void LayerTreeImpl::BuildPropertyTreesForTesting() {
764 PropertyTreeBuilder::BuildPropertyTrees(
ajuma6b46da22015-06-25 21:53:02765 root_layer_.get(), page_scale_layer_, inner_viewport_scroll_layer_,
766 outer_viewport_scroll_layer_, current_page_scale_factor(),
enne7c733af2015-05-27 23:32:48767 device_scale_factor(), gfx::Rect(DrawViewportSize()),
768 layer_tree_host_impl_->DrawTransform(), &property_trees_);
769}
770
[email protected]50761e92013-03-29 20:51:28771const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
[email protected]76ffd9e2012-12-20 19:12:47772 // If this assert triggers, then the list is dirty.
[email protected]615c78a2013-01-24 23:44:16773 DCHECK(!needs_update_draw_properties_);
[email protected]76ffd9e2012-12-20 19:12:47774 return render_surface_layer_list_;
775}
776
danakj4902c302015-02-13 22:12:16777const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
778 // If this assert triggers, then the render_surface_layer_list_ is dirty, so
779 // the unoccluded_screen_space_region_ is not valid anymore.
780 DCHECK(!needs_update_draw_properties_);
781 return unoccluded_screen_space_region_;
782}
783
bokancccfde72014-10-08 15:15:22784gfx::Size LayerTreeImpl::ScrollableSize() const {
[email protected]adeda572014-01-31 00:49:47785 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
786 ? OuterViewportScrollLayer()
787 : InnerViewportScrollLayer();
788 if (!root_scroll_layer || root_scroll_layer->children().empty())
bokancccfde72014-10-08 15:15:22789 return gfx::Size();
[email protected]adeda572014-01-31 00:49:47790 return root_scroll_layer->children()[0]->bounds();
[email protected]caa567d2012-12-20 07:56:16791}
792
[email protected]361bc00d2012-12-14 07:03:24793LayerImpl* LayerTreeImpl::LayerById(int id) {
794 LayerIdMap::iterator iter = layer_id_map_.find(id);
795 return iter != layer_id_map_.end() ? iter->second : NULL;
796}
797
798void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
799 DCHECK(!LayerById(layer->id()));
800 layer_id_map_[layer->id()] = layer;
801}
802
803void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
804 DCHECK(LayerById(layer->id()));
805 layer_id_map_.erase(layer->id());
806}
807
[email protected]aebf4622014-07-14 16:57:59808size_t LayerTreeImpl::NumLayers() {
809 return layer_id_map_.size();
810}
811
[email protected]ed511b8d2013-03-25 03:29:29812void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
[email protected]a90fac72013-06-06 18:56:13813 pending_tree->SetCurrentlyScrollingLayer(
814 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
815 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
[email protected]1e0f8d62013-01-09 07:41:35816}
817
[email protected]37386f052013-01-13 00:42:22818void LayerTreeImpl::DidBecomeActive() {
[email protected]12a63da2014-06-13 06:06:22819 if (next_activation_forces_redraw_) {
820 layer_tree_host_impl_->SetFullRootLayerDamage();
821 next_activation_forces_redraw_ = false;
822 }
823
[email protected]adeda572014-01-31 00:49:47824 if (scrolling_layer_id_from_previous_tree_) {
825 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
[email protected]7dcf5632014-06-25 01:11:55826 root_layer(), scrolling_layer_id_from_previous_tree_);
[email protected]adeda572014-01-31 00:49:47827 }
828
[email protected]7dcf5632014-06-25 01:11:55829 // Always reset this flag on activation, as we would only have activated
830 // if we were in a good state.
vmpstr61ed94a12014-10-09 04:49:30831 layer_tree_host_impl_->ResetRequiresHighResToDraw();
[email protected]7dcf5632014-06-25 01:11:55832
vmpstra73f18d2015-03-02 21:04:39833 if (root_layer()) {
834 LayerTreeHostCommon::CallFunctionForSubtree(
835 root_layer(), [](LayerImpl* layer) { layer->DidBecomeActive(); });
836 }
[email protected]7dcf5632014-06-25 01:11:55837
tobiasjs93d464842015-05-15 17:52:44838 for (auto* swap_promise : swap_promise_list_)
839 swap_promise->DidActivate();
[email protected]12a63da2014-06-13 06:06:22840 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
841 source_frame_number_);
[email protected]37386f052013-01-13 00:42:22842}
843
[email protected]3d609bb2014-02-01 01:10:23844bool LayerTreeImpl::RequiresHighResToDraw() const {
vmpstr61ed94a12014-10-09 04:49:30845 return layer_tree_host_impl_->RequiresHighResToDraw();
[email protected]3d609bb2014-02-01 01:10:23846}
847
[email protected]318822852013-02-14 00:54:27848bool LayerTreeImpl::ViewportSizeInvalid() const {
849 return viewport_size_invalid_;
850}
851
852void LayerTreeImpl::SetViewportSizeInvalid() {
853 viewport_size_invalid_ = true;
[email protected]c1bb5af2013-03-13 19:06:27854 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27855}
856
857void LayerTreeImpl::ResetViewportSizeInvalid() {
858 viewport_size_invalid_ = false;
[email protected]c1bb5af2013-03-13 19:06:27859 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27860}
861
[email protected]48871fc2013-01-23 07:36:51862Proxy* LayerTreeImpl::proxy() const {
863 return layer_tree_host_impl_->proxy();
864}
865
[email protected]ff762fb2012-12-12 19:18:37866const LayerTreeSettings& LayerTreeImpl::settings() const {
[email protected]c1bb5af2013-03-13 19:06:27867 return layer_tree_host_impl_->settings();
[email protected]ff762fb2012-12-12 19:18:37868}
869
danakj875efa42015-02-10 22:18:23870const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
871 return layer_tree_host_impl_->debug_state();
872}
873
[email protected]7a8bcd262014-01-15 12:54:58874const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
[email protected]c1bb5af2013-03-13 19:06:27875 return layer_tree_host_impl_->GetRendererCapabilities();
[email protected]bf5b3a02013-02-13 02:02:52876}
877
[email protected]0634cdd42013-08-16 00:46:09878ContextProvider* LayerTreeImpl::context_provider() const {
dcheng6afa17002014-08-26 19:11:31879 return output_surface()->context_provider();
[email protected]0634cdd42013-08-16 00:46:09880}
881
[email protected]ff762fb2012-12-12 19:18:37882OutputSurface* LayerTreeImpl::output_surface() const {
[email protected]c1bb5af2013-03-13 19:06:27883 return layer_tree_host_impl_->output_surface();
[email protected]ff762fb2012-12-12 19:18:37884}
885
886ResourceProvider* LayerTreeImpl::resource_provider() const {
[email protected]c1bb5af2013-03-13 19:06:27887 return layer_tree_host_impl_->resource_provider();
[email protected]ff762fb2012-12-12 19:18:37888}
889
890TileManager* LayerTreeImpl::tile_manager() const {
[email protected]c1bb5af2013-03-13 19:06:27891 return layer_tree_host_impl_->tile_manager();
[email protected]ff762fb2012-12-12 19:18:37892}
893
894FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27895 return layer_tree_host_impl_->fps_counter();
[email protected]ff762fb2012-12-12 19:18:37896}
897
[email protected]71691c22013-01-18 03:14:22898PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27899 return layer_tree_host_impl_->paint_time_counter();
[email protected]71691c22013-01-18 03:14:22900}
901
[email protected]1191d9d2013-02-02 06:00:33902MemoryHistory* LayerTreeImpl::memory_history() const {
[email protected]c1bb5af2013-03-13 19:06:27903 return layer_tree_host_impl_->memory_history();
[email protected]1191d9d2013-02-02 06:00:33904}
905
[email protected]4a6c091d2014-04-24 21:06:46906gfx::Size LayerTreeImpl::device_viewport_size() const {
907 return layer_tree_host_impl_->device_viewport_size();
908}
909
danakj875efa42015-02-10 22:18:23910float LayerTreeImpl::device_scale_factor() const {
911 return layer_tree_host_impl_->device_scale_factor();
912}
913
914DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
915 return layer_tree_host_impl_->debug_rect_history();
916}
917
[email protected]f117a4c2012-12-16 04:53:10918bool LayerTreeImpl::IsActiveTree() const {
[email protected]c1bb5af2013-03-13 19:06:27919 return layer_tree_host_impl_->active_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10920}
921
922bool LayerTreeImpl::IsPendingTree() const {
[email protected]c1bb5af2013-03-13 19:06:27923 return layer_tree_host_impl_->pending_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10924}
925
[email protected]48871fc2013-01-23 07:36:51926bool LayerTreeImpl::IsRecycleTree() const {
[email protected]c1bb5af2013-03-13 19:06:27927 return layer_tree_host_impl_->recycle_tree() == this;
[email protected]48871fc2013-01-23 07:36:51928}
929
enneaf5bda32015-02-19 01:27:36930bool LayerTreeImpl::IsSyncTree() const {
931 return layer_tree_host_impl_->sync_tree() == this;
932}
933
[email protected]f117a4c2012-12-16 04:53:10934LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27935 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
[email protected]f117a4c2012-12-16 04:53:10936 if (!tree)
937 return NULL;
938 return tree->LayerById(id);
939}
940
941LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27942 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
[email protected]f117a4c2012-12-16 04:53:10943 if (!tree)
944 return NULL;
945 return tree->LayerById(id);
946}
947
[email protected]166db5c82013-01-09 23:54:31948bool LayerTreeImpl::PinchGestureActive() const {
[email protected]c1bb5af2013-03-13 19:06:27949 return layer_tree_host_impl_->pinch_gesture_active();
[email protected]166db5c82013-01-09 23:54:31950}
951
[email protected]04c5900d2014-08-18 13:38:36952BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const {
953 return layer_tree_host_impl_->CurrentBeginFrameArgs();
[email protected]fb7425a2013-04-22 16:28:55954}
955
mithro0bdb49d2015-05-27 13:08:01956base::TimeDelta LayerTreeImpl::CurrentBeginFrameInterval() const {
957 return layer_tree_host_impl_->CurrentBeginFrameInterval();
[email protected]c92195e2014-05-07 18:18:49958}
959
[email protected]d7eb8c72013-03-23 22:57:13960void LayerTreeImpl::SetNeedsCommit() {
961 layer_tree_host_impl_->SetNeedsCommit();
962}
963
[email protected]bd5324592014-07-31 09:09:33964gfx::Rect LayerTreeImpl::DeviceViewport() const {
965 return layer_tree_host_impl_->DeviceViewport();
966}
967
[email protected]54af03522013-09-05 00:43:28968gfx::Size LayerTreeImpl::DrawViewportSize() const {
969 return layer_tree_host_impl_->DrawViewportSize();
970}
971
[email protected]bd5324592014-07-31 09:09:33972const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
973 return layer_tree_host_impl_->ViewportRectForTilePriority();
974}
975
[email protected]930ff43b2014-05-02 05:24:00976scoped_ptr<ScrollbarAnimationController>
977LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
978 DCHECK(settings().scrollbar_fade_delay_ms);
979 DCHECK(settings().scrollbar_fade_duration_ms);
980 base::TimeDelta delay =
981 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
sataya.m07f11a82014-10-07 14:29:18982 base::TimeDelta resize_delay = base::TimeDelta::FromMilliseconds(
983 settings().scrollbar_fade_resize_delay_ms);
[email protected]930ff43b2014-05-02 05:24:00984 base::TimeDelta duration =
985 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
986 switch (settings().scrollbar_animator) {
ericrk7c030992015-02-20 01:39:38987 case LayerTreeSettings::LINEAR_FADE: {
[email protected]930ff43b2014-05-02 05:24:00988 return ScrollbarAnimationControllerLinearFade::Create(
sataya.m07f11a82014-10-07 14:29:18989 scrolling_layer,
990 layer_tree_host_impl_,
991 delay,
992 resize_delay,
993 duration);
[email protected]930ff43b2014-05-02 05:24:00994 }
ericrk7c030992015-02-20 01:39:38995 case LayerTreeSettings::THINNING: {
sataya.m07f11a82014-10-07 14:29:18996 return ScrollbarAnimationControllerThinning::Create(scrolling_layer,
997 layer_tree_host_impl_,
998 delay,
999 resize_delay,
1000 duration);
[email protected]930ff43b2014-05-02 05:24:001001 }
ericrk7c030992015-02-20 01:39:381002 case LayerTreeSettings::NO_ANIMATOR:
[email protected]930ff43b2014-05-02 05:24:001003 NOTREACHED();
1004 break;
1005 }
danakjf446a072014-09-27 21:55:481006 return nullptr;
[email protected]2ea5aba2013-09-11 14:26:561007}
1008
[email protected]b8384e22013-12-03 02:20:481009void LayerTreeImpl::DidAnimateScrollOffset() {
1010 layer_tree_host_impl_->DidAnimateScrollOffset();
1011}
1012
[email protected]13525d62014-05-20 21:22:041013bool LayerTreeImpl::use_gpu_rasterization() const {
1014 return layer_tree_host_impl_->use_gpu_rasterization();
1015}
1016
hendrikwc2bbd612014-12-03 23:49:341017GpuRasterizationStatus LayerTreeImpl::GetGpuRasterizationStatus() const {
1018 return layer_tree_host_impl_->gpu_rasterization_status();
1019}
1020
[email protected]473f1f22014-05-22 08:19:171021bool LayerTreeImpl::create_low_res_tiling() const {
1022 return layer_tree_host_impl_->create_low_res_tiling();
1023}
1024
[email protected]ff762fb2012-12-12 19:18:371025void LayerTreeImpl::SetNeedsRedraw() {
[email protected]59adb112013-04-09 04:48:441026 layer_tree_host_impl_->SetNeedsRedraw();
[email protected]ff762fb2012-12-12 19:18:371027}
1028
sunnypsea328be12015-02-26 06:03:271029AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
[email protected]c1bb5af2013-03-13 19:06:271030 return layer_tree_host_impl_->animation_registrar();
[email protected]de4afb5e2012-12-20 00:11:341031}
[email protected]ff762fb2012-12-12 19:18:371032
hendrikwc5e915852015-05-13 01:29:031033void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
1034 std::vector<PrioritizedTile>* prioritized_tiles) const {
enne389d1a12015-06-18 20:40:511035 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
1036 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
1037 it != end; ++it) {
vmpstrd7de03c2014-08-27 18:11:011038 if (!it.represents_itself())
1039 continue;
1040 LayerImpl* layer_impl = *it;
hendrikwc5e915852015-05-13 01:29:031041 layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles);
vmpstrd7de03c2014-08-27 18:11:011042 }
1043}
1044
ssid911e40e2015-02-09 17:55:201045void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
[email protected]d12aa932014-08-01 13:10:381046 TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this);
nduca929378a02014-08-23 19:48:521047 state->SetInteger("source_frame_number", source_frame_number_);
[email protected]f6742f52013-05-08 23:52:221048
[email protected]d12aa932014-08-01 13:10:381049 state->BeginDictionary("root_layer");
1050 root_layer_->AsValueInto(state);
1051 state->EndDictionary();
[email protected]f6742f52013-05-08 23:52:221052
[email protected]d12aa932014-08-01 13:10:381053 state->BeginArray("render_surface_layer_list");
enne389d1a12015-06-18 20:40:511054 LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
1055 for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
1056 it != end; ++it) {
[email protected]71dfcc72013-03-20 21:30:091057 if (!it.represents_itself())
[email protected]8c5690222013-02-15 17:36:431058 continue;
[email protected]d12aa932014-08-01 13:10:381059 TracedValue::AppendIDRef(*it, state);
[email protected]8c5690222013-02-15 17:36:431060 }
[email protected]d12aa932014-08-01 13:10:381061 state->EndArray();
skyostil43c330f72014-09-22 16:49:111062
1063 state->BeginArray("swap_promise_trace_ids");
tobiasjs93d464842015-05-15 17:52:441064 for (auto* swap_promise : swap_promise_list_)
1065 state->AppendDouble(swap_promise->TraceId());
skyostil43c330f72014-09-22 16:49:111066 state->EndArray();
[email protected]8c5690222013-02-15 17:36:431067}
1068
[email protected]1960a712013-04-30 17:06:471069void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
[email protected]c9280762013-08-01 06:28:571070 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
[email protected]20d2b742013-09-26 05:41:341071 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
1072 return;
1073
[email protected]adeda572014-01-31 00:49:471074 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
1075
[email protected]20d2b742013-09-26 05:41:341076 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:001077 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:401078 TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
1079 current_page_scale_factor(), min_page_scale_factor(),
[email protected]68fe60f2014-02-12 13:49:111080 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:471081
hush33370e12015-04-07 03:49:501082 DistributeRootScrollOffset();
[email protected]20d2b742013-09-26 05:41:341083 }
[email protected]1960a712013-04-30 17:06:471084}
1085
hush33370e12015-04-07 03:49:501086void LayerTreeImpl::UpdateRootScrollOffsetDelegate() {
[email protected]adeda572014-01-31 00:49:471087 DCHECK(root_layer_scroll_offset_delegate_);
1088
hush33370e12015-04-07 03:49:501089 gfx::ScrollOffset offset = InnerViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471090
1091 if (OuterViewportScrollLayer())
hush33370e12015-04-07 03:49:501092 offset += OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471093
[email protected]ec2322e2014-05-15 16:32:001094 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:401095 offset, TotalMaxScrollOffset(), ScrollableSize(),
1096 current_page_scale_factor(), min_page_scale_factor(),
[email protected]ec2322e2014-05-15 16:32:001097 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:471098}
1099
hush33370e12015-04-07 03:49:501100void LayerTreeImpl::DistributeRootScrollOffset() {
1101 if (!root_layer_scroll_offset_delegate_)
1102 return;
1103
1104 gfx::ScrollOffset root_offset =
1105 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
1106
1107 if (!InnerViewportScrollLayer())
1108 return;
1109
1110 DCHECK(OuterViewportScrollLayer());
[email protected]adeda572014-01-31 00:49:471111
1112 // If we get here, we have both inner/outer viewports, and need to distribute
1113 // the scroll offset between them.
miletusf57925d2014-10-01 19:38:131114 gfx::ScrollOffset inner_viewport_offset =
hush33370e12015-04-07 03:49:501115 InnerViewportScrollLayer()->CurrentScrollOffset();
miletusf57925d2014-10-01 19:38:131116 gfx::ScrollOffset outer_viewport_offset =
hush33370e12015-04-07 03:49:501117 OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471118
1119 // It may be nothing has changed.
hush33370e12015-04-07 03:49:501120 if (inner_viewport_offset + outer_viewport_offset == root_offset)
1121 return;
[email protected]adeda572014-01-31 00:49:471122
miletusf57925d2014-10-01 19:38:131123 gfx::ScrollOffset max_outer_viewport_scroll_offset =
[email protected]adeda572014-01-31 00:49:471124 OuterViewportScrollLayer()->MaxScrollOffset();
1125
hush33370e12015-04-07 03:49:501126 outer_viewport_offset = root_offset - inner_viewport_offset;
[email protected]adeda572014-01-31 00:49:471127 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
miletusf57925d2014-10-01 19:38:131128 outer_viewport_offset.SetToMax(gfx::ScrollOffset());
[email protected]adeda572014-01-31 00:49:471129
hush33370e12015-04-07 03:49:501130 OuterViewportScrollLayer()->SetCurrentScrollOffsetFromDelegate(
1131 outer_viewport_offset);
1132 inner_viewport_offset = root_offset - outer_viewport_offset;
1133 InnerViewportScrollLayer()->SetCurrentScrollOffsetFromDelegate(
1134 inner_viewport_offset);
[email protected]adeda572014-01-31 00:49:471135
hush33370e12015-04-07 03:49:501136 UpdateRootScrollOffsetDelegate();
[email protected]adeda572014-01-31 00:49:471137}
1138
[email protected]b69c1db2013-11-27 00:05:191139void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1140 DCHECK(swap_promise);
[email protected]b69c1db2013-11-27 00:05:191141 swap_promise_list_.push_back(swap_promise.Pass());
1142}
1143
1144void LayerTreeImpl::PassSwapPromises(
1145 ScopedPtrVector<SwapPromise>* new_swap_promise) {
tobiasjsf0f398a2015-05-22 16:00:231146 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
1147 new_swap_promise);
1148 new_swap_promise->clear();
[email protected]b69c1db2013-11-27 00:05:191149}
1150
[email protected]d359203a2013-11-29 06:16:551151void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
tobiasjs93d464842015-05-15 17:52:441152 for (auto* swap_promise : swap_promise_list_)
1153 swap_promise->DidSwap(metadata);
[email protected]b69c1db2013-11-27 00:05:191154 swap_promise_list_.clear();
1155}
1156
1157void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
tobiasjs93d464842015-05-15 17:52:441158 for (auto* swap_promise : swap_promise_list_)
1159 swap_promise->DidNotSwap(reason);
[email protected]b69c1db2013-11-27 00:05:191160 swap_promise_list_.clear();
1161}
1162
[email protected]c48536a52013-09-14 00:02:081163void LayerTreeImpl::DidModifyTilePriorities() {
1164 layer_tree_host_impl_->DidModifyTilePriorities();
[email protected]fcb846d2013-05-22 01:42:361165}
1166
[email protected]c9280762013-08-01 06:28:571167void LayerTreeImpl::set_ui_resource_request_queue(
1168 const UIResourceRequestQueue& queue) {
1169 ui_resource_request_queue_ = queue;
1170}
1171
jbaumanbbd425e2015-05-19 00:33:351172ResourceId LayerTreeImpl::ResourceIdForUIResource(UIResourceId uid) const {
[email protected]c9280762013-08-01 06:28:571173 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
1174}
1175
[email protected]709c9542013-10-26 01:43:511176bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
1177 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
1178}
1179
[email protected]c9280762013-08-01 06:28:571180void LayerTreeImpl::ProcessUIResourceRequestQueue() {
jdduke5ad36812015-01-02 17:59:321181 for (const auto& req : ui_resource_request_queue_) {
[email protected]741fba422013-09-20 03:34:141182 switch (req.GetType()) {
ericrk7c030992015-02-20 01:39:381183 case UIResourceRequest::UI_RESOURCE_CREATE:
[email protected]741fba422013-09-20 03:34:141184 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
[email protected]c9280762013-08-01 06:28:571185 break;
ericrk7c030992015-02-20 01:39:381186 case UIResourceRequest::UI_RESOURCE_DELETE:
[email protected]741fba422013-09-20 03:34:141187 layer_tree_host_impl_->DeleteUIResource(req.GetId());
[email protected]c9280762013-08-01 06:28:571188 break;
ericrk7c030992015-02-20 01:39:381189 case UIResourceRequest::UI_RESOURCE_INVALID_REQUEST:
[email protected]c9280762013-08-01 06:28:571190 NOTREACHED();
1191 break;
1192 }
1193 }
jdduke5ad36812015-01-02 17:59:321194 ui_resource_request_queue_.clear();
[email protected]127bdc1a2013-09-11 01:44:481195
1196 // If all UI resource evictions were not recreated by processing this queue,
1197 // then another commit is required.
1198 if (layer_tree_host_impl_->EvictedUIResourcesExist())
1199 layer_tree_host_impl_->SetNeedsCommit();
[email protected]c9280762013-08-01 06:28:571200}
1201
danakj7383c552015-02-11 18:01:481202void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1203 DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) ==
1204 picture_layers_.end());
1205 picture_layers_.push_back(layer);
1206}
1207
1208void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1209 std::vector<PictureLayerImpl*>::iterator it =
1210 std::find(picture_layers_.begin(), picture_layers_.end(), layer);
1211 DCHECK(it != picture_layers_.end());
1212 picture_layers_.erase(it);
1213}
1214
[email protected]30fe19ff2013-07-04 00:54:451215void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
1216 // Only the active tree needs to know about layers with copy requests, as
1217 // they are aborted if not serviced during draw.
1218 DCHECK(IsActiveTree());
1219
[email protected]a4ee12812014-02-06 17:33:381220 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1221 // layers_with_copy_output_request_.end(),
1222 // layer) == layers_with_copy_output_request_.end());
1223 // TODO(danakj): Remove this once crash is found crbug.com/309777
1224 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1225 CHECK(layers_with_copy_output_request_[i] != layer)
1226 << i << " of " << layers_with_copy_output_request_.size();
1227 }
[email protected]30fe19ff2013-07-04 00:54:451228 layers_with_copy_output_request_.push_back(layer);
1229}
1230
1231void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1232 // Only the active tree needs to know about layers with copy requests, as
1233 // they are aborted if not serviced during draw.
1234 DCHECK(IsActiveTree());
1235
1236 std::vector<LayerImpl*>::iterator it = std::find(
1237 layers_with_copy_output_request_.begin(),
1238 layers_with_copy_output_request_.end(),
1239 layer);
1240 DCHECK(it != layers_with_copy_output_request_.end());
[email protected]f5de9e5b2013-07-30 22:26:571241 layers_with_copy_output_request_.erase(it);
[email protected]a4ee12812014-02-06 17:33:381242
1243 // TODO(danakj): Remove this once crash is found crbug.com/309777
1244 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1245 CHECK(layers_with_copy_output_request_[i] != layer)
1246 << i << " of " << layers_with_copy_output_request_.size();
1247 }
[email protected]30fe19ff2013-07-04 00:54:451248}
1249
[email protected]53526372013-12-07 04:31:501250const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
[email protected]30fe19ff2013-07-04 00:54:451251 const {
1252 // Only the active tree needs to know about layers with copy requests, as
1253 // they are aborted if not serviced during draw.
1254 DCHECK(IsActiveTree());
1255
1256 return layers_with_copy_output_request_;
1257}
1258
[email protected]28336d52014-05-12 19:07:281259template <typename LayerType>
1260static inline bool LayerClipsSubtree(LayerType* layer) {
1261 return layer->masks_to_bounds() || layer->mask_layer();
1262}
1263
1264static bool PointHitsRect(
1265 const gfx::PointF& screen_space_point,
1266 const gfx::Transform& local_space_to_screen_space_transform,
1267 const gfx::RectF& local_space_rect,
1268 float* distance_to_camera) {
1269 // If the transform is not invertible, then assume that this point doesn't hit
1270 // this rect.
1271 gfx::Transform inverse_local_space_to_screen_space(
1272 gfx::Transform::kSkipInitialization);
1273 if (!local_space_to_screen_space_transform.GetInverse(
1274 &inverse_local_space_to_screen_space))
1275 return false;
1276
1277 // Transform the hit test point from screen space to the local space of the
1278 // given rect.
1279 bool clipped = false;
1280 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1281 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1282 gfx::PointF hit_test_point_in_local_space =
1283 gfx::PointF(planar_point.x(), planar_point.y());
1284
1285 // If ProjectPoint could not project to a valid value, then we assume that
1286 // this point doesn't hit this rect.
1287 if (clipped)
1288 return false;
1289
1290 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1291 return false;
1292
1293 if (distance_to_camera) {
1294 // To compute the distance to the camera, we have to take the planar point
1295 // and pull it back to world space and compute the displacement along the
1296 // z-axis.
1297 gfx::Point3F planar_point_in_screen_space(planar_point);
1298 local_space_to_screen_space_transform.TransformPoint(
1299 &planar_point_in_screen_space);
1300 *distance_to_camera = planar_point_in_screen_space.z();
1301 }
1302
1303 return true;
1304}
1305
1306static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1307 const gfx::Transform& screen_space_transform,
danakj2c8d12c2015-06-18 06:15:331308 const Region& layer_space_region) {
[email protected]28336d52014-05-12 19:07:281309 // If the transform is not invertible, then assume that this point doesn't hit
1310 // this region.
1311 gfx::Transform inverse_screen_space_transform(
1312 gfx::Transform::kSkipInitialization);
1313 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1314 return false;
1315
1316 // Transform the hit test point from screen space to the local space of the
1317 // given region.
1318 bool clipped = false;
danakj2c8d12c2015-06-18 06:15:331319 gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
[email protected]28336d52014-05-12 19:07:281320 inverse_screen_space_transform, screen_space_point, &clipped);
[email protected]28336d52014-05-12 19:07:281321
1322 // If ProjectPoint could not project to a valid value, then we assume that
1323 // this point doesn't hit this region.
1324 if (clipped)
1325 return false;
1326
1327 return layer_space_region.Contains(
1328 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1329}
1330
[email protected]19aec372014-07-01 19:08:491331static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
[email protected]0ec86f52014-06-12 20:54:031332 if (layer->scroll_parent())
1333 return layer->scroll_parent();
1334 if (layer->clip_parent())
1335 return layer->clip_parent();
1336 return layer->parent();
1337}
1338
[email protected]28336d52014-05-12 19:07:281339static bool PointIsClippedBySurfaceOrClipRect(
1340 const gfx::PointF& screen_space_point,
[email protected]19aec372014-07-01 19:08:491341 const LayerImpl* layer) {
[email protected]28336d52014-05-12 19:07:281342 // Walk up the layer tree and hit-test any render_surfaces and any layer
1343 // clip rects that are active.
[email protected]0ec86f52014-06-12 20:54:031344 for (; layer; layer = GetNextClippingLayer(layer)) {
1345 if (layer->render_surface() &&
1346 !PointHitsRect(screen_space_point,
1347 layer->render_surface()->screen_space_transform(),
1348 layer->render_surface()->content_rect(),
1349 NULL))
[email protected]28336d52014-05-12 19:07:281350 return true;
1351
[email protected]0ec86f52014-06-12 20:54:031352 if (LayerClipsSubtree(layer) &&
Dana Jansensc46d3742015-06-18 01:33:141353 !PointHitsRect(screen_space_point, layer->screen_space_transform(),
1354 gfx::Rect(layer->bounds()), NULL))
[email protected]28336d52014-05-12 19:07:281355 return true;
[email protected]28336d52014-05-12 19:07:281356 }
1357
1358 // If we have finished walking all ancestors without having already exited,
1359 // then the point is not clipped by any ancestors.
1360 return false;
1361}
1362
[email protected]19aec372014-07-01 19:08:491363static bool PointHitsLayer(const LayerImpl* layer,
[email protected]28336d52014-05-12 19:07:281364 const gfx::PointF& screen_space_point,
1365 float* distance_to_intersection) {
Dana Jansensc46d3742015-06-18 01:33:141366 gfx::RectF content_rect(layer->bounds());
[email protected]28336d52014-05-12 19:07:281367 if (!PointHitsRect(screen_space_point,
1368 layer->screen_space_transform(),
1369 content_rect,
1370 distance_to_intersection))
1371 return false;
1372
1373 // At this point, we think the point does hit the layer, but we need to walk
1374 // up the parents to ensure that the layer was not clipped in such a way
1375 // that the hit point actually should not hit the layer.
1376 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1377 return false;
1378
1379 // Skip the HUD layer.
1380 if (layer == layer->layer_tree_impl()->hud_layer())
1381 return false;
1382
1383 return true;
1384}
1385
1386struct FindClosestMatchingLayerDataForRecursion {
1387 FindClosestMatchingLayerDataForRecursion()
1388 : closest_match(NULL),
1389 closest_distance(-std::numeric_limits<float>::infinity()) {}
1390 LayerImpl* closest_match;
1391 // Note that the positive z-axis points towards the camera, so bigger means
1392 // closer in this case, counterintuitively.
1393 float closest_distance;
1394};
1395
1396template <typename Functor>
1397static void FindClosestMatchingLayer(
1398 const gfx::PointF& screen_space_point,
1399 LayerImpl* layer,
1400 const Functor& func,
1401 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
vmpstr24b32b3e2015-06-09 22:39:331402 size_t children_size = layer->children().size();
1403 for (size_t i = 0; i < children_size; ++i) {
1404 size_t index = children_size - 1 - i;
1405 FindClosestMatchingLayer(screen_space_point, layer->children()[index], func,
1406 data_for_recursion);
[email protected]28336d52014-05-12 19:07:281407 }
1408
1409 float distance_to_intersection = 0.f;
1410 if (func(layer) &&
1411 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1412 ((!data_for_recursion->closest_match ||
1413 distance_to_intersection > data_for_recursion->closest_distance))) {
1414 data_for_recursion->closest_distance = distance_to_intersection;
1415 data_for_recursion->closest_match = layer;
1416 }
1417}
1418
1419static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1420 if (!layer->scrollable())
1421 return false;
jaydasika976cd10b2015-05-26 15:45:241422 if (layer->layer_or_descendant_is_drawn())
[email protected]28336d52014-05-12 19:07:281423 return true;
majidvp6cfcc362015-03-06 20:46:391424
[email protected]28336d52014-05-12 19:07:281425 if (!layer->scroll_children())
1426 return false;
1427 for (std::set<LayerImpl*>::const_iterator it =
1428 layer->scroll_children()->begin();
1429 it != layer->scroll_children()->end();
1430 ++it) {
jaydasika976cd10b2015-05-26 15:45:241431 if ((*it)->layer_or_descendant_is_drawn())
[email protected]28336d52014-05-12 19:07:281432 return true;
1433 }
1434 return false;
1435}
1436
1437struct FindScrollingLayerFunctor {
1438 bool operator()(LayerImpl* layer) const {
1439 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1440 }
1441};
1442
1443LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1444 const gfx::PointF& screen_space_point) {
1445 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1446 FindClosestMatchingLayer(screen_space_point,
1447 root_layer(),
1448 FindScrollingLayerFunctor(),
1449 &data_for_recursion);
1450 return data_for_recursion.closest_match;
1451}
1452
1453struct HitTestVisibleScrollableOrTouchableFunctor {
1454 bool operator()(LayerImpl* layer) const {
1455 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1456 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1457 !layer->touch_event_handler_region().IsEmpty() ||
1458 layer->have_wheel_event_handlers();
1459 }
1460};
1461
1462LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1463 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321464 if (!root_layer())
1465 return NULL;
enneaf5bda32015-02-19 01:27:361466 bool update_lcd_text = false;
1467 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321468 return NULL;
[email protected]28336d52014-05-12 19:07:281469 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1470 FindClosestMatchingLayer(screen_space_point,
1471 root_layer(),
1472 HitTestVisibleScrollableOrTouchableFunctor(),
1473 &data_for_recursion);
1474 return data_for_recursion.closest_match;
1475}
1476
1477static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1478 LayerImpl* layer_impl) {
1479 if (layer_impl->touch_event_handler_region().IsEmpty())
1480 return false;
1481
danakj2c8d12c2015-06-18 06:15:331482 if (!PointHitsRegion(screen_space_point, layer_impl->screen_space_transform(),
1483 layer_impl->touch_event_handler_region()))
[email protected]28336d52014-05-12 19:07:281484 return false;
1485
1486 // At this point, we think the point does hit the touch event handler region
1487 // on the layer, but we need to walk up the parents to ensure that the layer
1488 // was not clipped in such a way that the hit point actually should not hit
1489 // the layer.
1490 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1491 return false;
1492
1493 return true;
1494}
1495
ccameron3b607362015-02-02 22:46:291496struct FindWheelEventLayerFunctor {
1497 bool operator()(LayerImpl* layer) const {
1498 return layer->have_wheel_event_handlers();
1499 }
1500};
1501
1502LayerImpl* LayerTreeImpl::FindLayerWithWheelHandlerThatIsHitByPoint(
1503 const gfx::PointF& screen_space_point) {
1504 if (!root_layer())
1505 return NULL;
enneaf5bda32015-02-19 01:27:361506 bool update_lcd_text = false;
1507 if (!UpdateDrawProperties(update_lcd_text))
ccameron3b607362015-02-02 22:46:291508 return NULL;
1509 FindWheelEventLayerFunctor func;
1510 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1511 FindClosestMatchingLayer(screen_space_point, root_layer(), func,
1512 &data_for_recursion);
1513 return data_for_recursion.closest_match;
1514}
1515
[email protected]28336d52014-05-12 19:07:281516struct FindTouchEventLayerFunctor {
1517 bool operator()(LayerImpl* layer) const {
1518 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1519 }
1520 const gfx::PointF screen_space_point;
1521};
1522
1523LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1524 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321525 if (!root_layer())
1526 return NULL;
enneaf5bda32015-02-19 01:27:361527 bool update_lcd_text = false;
1528 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321529 return NULL;
[email protected]28336d52014-05-12 19:07:281530 FindTouchEventLayerFunctor func = {screen_space_point};
1531 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1532 FindClosestMatchingLayer(
1533 screen_space_point, root_layer(), func, &data_for_recursion);
1534 return data_for_recursion.closest_match;
1535}
1536
jdduke449b5292015-04-23 19:36:441537void LayerTreeImpl::RegisterSelection(const LayerSelection& selection) {
1538 selection_ = selection;
[email protected]19aec372014-07-01 19:08:491539}
1540
jdduke449b5292015-04-23 19:36:441541static ViewportSelectionBound ComputeViewportSelectionBound(
[email protected]6ef948732014-08-22 18:57:441542 const LayerSelectionBound& layer_bound,
[email protected]19aec372014-07-01 19:08:491543 LayerImpl* layer,
1544 float device_scale_factor) {
[email protected]6ef948732014-08-22 18:57:441545 ViewportSelectionBound viewport_bound;
1546 viewport_bound.type = layer_bound.type;
[email protected]19aec372014-07-01 19:08:491547
[email protected]6ef948732014-08-22 18:57:441548 if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY)
1549 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491550
danakj2c8d12c2015-06-18 06:15:331551 gfx::PointF layer_top = layer_bound.edge_top;
1552 gfx::PointF layer_bottom = layer_bound.edge_bottom;
[email protected]19aec372014-07-01 19:08:491553
[email protected]6ef948732014-08-22 18:57:441554 bool clipped = false;
danakj2c8d12c2015-06-18 06:15:331555 gfx::PointF screen_top =
1556 MathUtil::MapPoint(layer->screen_space_transform(), layer_top, &clipped);
[email protected]6ef948732014-08-22 18:57:441557 gfx::PointF screen_bottom = MathUtil::MapPoint(
danakj2c8d12c2015-06-18 06:15:331558 layer->screen_space_transform(), layer_bottom, &clipped);
[email protected]6ef948732014-08-22 18:57:441559
1560 const float inv_scale = 1.f / device_scale_factor;
1561 viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale);
1562 viewport_bound.edge_bottom = gfx::ScalePoint(screen_bottom, inv_scale);
1563
1564 // The bottom edge point is used for visibility testing as it is the logical
[email protected]19aec372014-07-01 19:08:491565 // focal point for bound selection handles (this may change in the future).
[email protected]6ef948732014-08-22 18:57:441566 // Shifting the visibility point fractionally inward ensures that neighboring
1567 // or logically coincident layers aligned to integral DPI coordinates will not
1568 // spuriously occlude the bound.
danakj2c8d12c2015-06-18 06:15:331569 gfx::Vector2dF visibility_offset = layer_top - layer_bottom;
[email protected]6ef948732014-08-22 18:57:441570 visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
danakj2c8d12c2015-06-18 06:15:331571 gfx::PointF visibility_point = layer_bottom + visibility_offset;
[email protected]6ef948732014-08-22 18:57:441572 if (visibility_point.x() <= 0)
1573 visibility_point.set_x(visibility_point.x() + device_scale_factor);
1574 visibility_point = MathUtil::MapPoint(
1575 layer->screen_space_transform(), visibility_point, &clipped);
1576
[email protected]19aec372014-07-01 19:08:491577 float intersect_distance = 0.f;
[email protected]6ef948732014-08-22 18:57:441578 viewport_bound.visible =
1579 PointHitsLayer(layer, visibility_point, &intersect_distance);
[email protected]19aec372014-07-01 19:08:491580
[email protected]6ef948732014-08-22 18:57:441581 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491582}
1583
jdduke449b5292015-04-23 19:36:441584void LayerTreeImpl::GetViewportSelection(ViewportSelection* selection) {
1585 DCHECK(selection);
[email protected]19aec372014-07-01 19:08:491586
jdduke449b5292015-04-23 19:36:441587 selection->start = ComputeViewportSelectionBound(
1588 selection_.start,
1589 selection_.start.layer_id ? LayerById(selection_.start.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491590 device_scale_factor());
jdduke449b5292015-04-23 19:36:441591 selection->is_editable = selection_.is_editable;
1592 selection->is_empty_text_form_control = selection_.is_empty_text_form_control;
1593 if (selection->start.type == SELECTION_BOUND_CENTER ||
1594 selection->start.type == SELECTION_BOUND_EMPTY) {
1595 selection->end = selection->start;
[email protected]19aec372014-07-01 19:08:491596 } else {
jdduke449b5292015-04-23 19:36:441597 selection->end = ComputeViewportSelectionBound(
1598 selection_.end,
1599 selection_.end.layer_id ? LayerById(selection_.end.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491600 device_scale_factor());
1601 }
1602}
1603
[email protected]749cbc62014-07-10 01:06:351604void LayerTreeImpl::InputScrollAnimationFinished() {
1605 layer_tree_host_impl_->ScrollEnd();
1606}
1607
vmpstr56ace232014-10-09 20:16:281608bool LayerTreeImpl::SmoothnessTakesPriority() const {
1609 return layer_tree_host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY;
1610}
1611
skyostil3976a3f2014-09-04 22:07:231612BlockingTaskRunner* LayerTreeImpl::BlockingMainThreadTaskRunner() const {
1613 return proxy()->blocking_main_thread_task_runner();
1614}
1615
sunnyps7d073dc2015-04-16 23:29:121616VideoFrameControllerClient* LayerTreeImpl::GetVideoFrameControllerClient()
1617 const {
1618 return layer_tree_host_impl_;
1619}
1620
bokanfcdbc182014-11-21 21:53:331621void LayerTreeImpl::SetPendingPageScaleAnimation(
1622 scoped_ptr<PendingPageScaleAnimation> pending_animation) {
1623 pending_page_scale_animation_ = pending_animation.Pass();
bokan915bf352014-10-02 21:57:141624}
1625
bokanfcdbc182014-11-21 21:53:331626scoped_ptr<PendingPageScaleAnimation>
1627 LayerTreeImpl::TakePendingPageScaleAnimation() {
1628 return pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:141629}
1630
[email protected]ca2902e92013-03-28 01:45:351631} // namespace cc