blob: cf95f587a0d4acd6caba987b4294fe812591085b [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]3744e27b2013-11-06 21:44:0819#include "cc/base/util.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"
hush33370e12015-04-07 03:49:5022#include "cc/input/layer_scroll_offset_delegate.h"
bokan915bf352014-10-02 21:57:1423#include "cc/input/page_scale_animation.h"
[email protected]cc3cfaa2013-03-18 09:05:5224#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]57ac9482013-09-17 21:13:3925#include "cc/layers/layer.h"
[email protected]34ba1ffb2014-03-05 06:55:0326#include "cc/layers/layer_iterator.h"
[email protected]50761e92013-03-29 20:51:2827#include "cc/layers/render_surface_impl.h"
[email protected]80413d72013-08-30 20:25:3328#include "cc/layers/scrollbar_layer_impl_base.h"
[email protected]e1042192013-11-08 05:44:2429#include "cc/resources/ui_resource_request.h"
[email protected]556fd292013-03-18 08:03:0430#include "cc/trees/layer_tree_host_common.h"
31#include "cc/trees/layer_tree_host_impl.h"
[email protected]562b7ad2014-06-23 22:17:1132#include "cc/trees/occlusion_tracker.h"
heejin.r.chungd28506ba2014-10-23 16:36:2033#include "ui/gfx/geometry/point_conversions.h"
34#include "ui/gfx/geometry/size_conversions.h"
35#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]3b31c6ac2012-12-06 21:27:2936
37namespace cc {
[email protected]adeda572014-01-31 00:49:4738
aelias58eec0812014-12-04 01:04:4039LayerTreeImpl::LayerTreeImpl(
40 LayerTreeHostImpl* layer_tree_host_impl,
ccameronb9aec4502014-12-05 19:31:0041 scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
aelias6004fe02015-02-07 21:43:0142 scoped_refptr<SyncedTopControls> top_controls_shown_ratio,
ccameronb9aec4502014-12-05 19:31:0043 scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)
[email protected]db8259f2013-02-01 05:25:0444 : layer_tree_host_impl_(layer_tree_host_impl),
45 source_frame_number_(-1),
46 hud_layer_(0),
[email protected]1960a712013-04-30 17:06:4747 currently_scrolling_layer_(NULL),
48 root_layer_scroll_offset_delegate_(NULL),
[email protected]db8259f2013-02-01 05:25:0449 background_color_(0),
50 has_transparent_background_(false),
ccameronb9aec4502014-12-05 19:31:0051 overscroll_elasticity_layer_(NULL),
[email protected]57ac9482013-09-17 21:13:3952 page_scale_layer_(NULL),
53 inner_viewport_scroll_layer_(NULL),
54 outer_viewport_scroll_layer_(NULL),
aelias58eec0812014-12-04 01:04:4055 page_scale_factor_(page_scale_factor),
[email protected]db8259f2013-02-01 05:25:0456 min_page_scale_factor_(0),
57 max_page_scale_factor_(0),
ccameronb9aec4502014-12-05 19:31:0058 elastic_overscroll_(elastic_overscroll),
[email protected]db8259f2013-02-01 05:25:0459 scrolling_layer_id_from_previous_tree_(0),
60 contents_textures_purged_(false),
[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() {
[email protected]586871b2014-07-22 17:05:1173 BreakSwapPromises(SwapPromise::SWAP_FAILS);
74
[email protected]361bc00d2012-12-14 07:03:2475 // Need to explicitly clear the tree prior to destroying this so that
76 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
[email protected]df17af52014-02-06 02:20:4077 DCHECK(!root_layer_);
78 DCHECK(layers_with_copy_output_request_.empty());
[email protected]3b31c6ac2012-12-06 21:27:2979}
80
danakjf446a072014-09-27 21:55:4881void LayerTreeImpl::Shutdown() {
82 root_layer_ = nullptr;
83}
[email protected]df17af52014-02-06 02:20:4084
[email protected]aeef2f02014-05-10 12:15:4885void LayerTreeImpl::ReleaseResources() {
vmpstra73f18d2015-03-02 21:04:3986 if (root_layer_) {
87 LayerTreeHostCommon::CallFunctionForSubtree(
88 root_layer_.get(), [](LayerImpl* layer) { layer->ReleaseResources(); });
89 }
vmpstr9ce5c662015-02-05 23:29:2690}
91
92void LayerTreeImpl::RecreateResources() {
vmpstra73f18d2015-03-02 21:04:3993 if (root_layer_) {
94 LayerTreeHostCommon::CallFunctionForSubtree(
95 root_layer_.get(),
96 [](LayerImpl* layer) { layer->RecreateResources(); });
97 }
[email protected]aeef2f02014-05-10 12:15:4898}
99
vmpstrd704c872015-04-03 20:29:51100void LayerTreeImpl::GatherFrameTimingRequestIds(
101 std::vector<int64_t>* request_ids) {
102 if (!root_layer_)
103 return;
104
105 // TODO(vmpstr): Early out if there are no requests on any of the layers. For
106 // that, we need to inform LayerTreeImpl whenever there are requests when we
107 // get them.
108 LayerTreeHostCommon::CallFunctionForSubtree(
109 root_layer_.get(), [request_ids](LayerImpl* layer) {
110 layer->GatherFrameTimingRequestIds(request_ids);
111 });
112}
113
hush33370e12015-04-07 03:49:50114bool LayerTreeImpl::IsExternalFlingActive() const {
115 return root_layer_scroll_offset_delegate_ &&
116 root_layer_scroll_offset_delegate_->IsExternalFlingActive();
117}
[email protected]adeda572014-01-31 00:49:47118
hush33370e12015-04-07 03:49:50119void LayerTreeImpl::DidUpdateScrollOffset(int layer_id) {
120 int inner_layer_id = InnerViewportScrollLayer()
121 ? InnerViewportScrollLayer()->id()
122 : Layer::INVALID_ID;
123 int outer_layer_id = OuterViewportScrollLayer()
124 ? OuterViewportScrollLayer()->id()
125 : Layer::INVALID_ID;
126 if (layer_id != outer_layer_id && layer_id != inner_layer_id)
127 return;
128
129 if (!root_layer_scroll_offset_delegate_)
130 return;
131
132 UpdateRootScrollOffsetDelegate();
133}
134
135void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
[email protected]3b31c6ac2012-12-06 21:27:29136 root_layer_ = layer.Pass();
[email protected]5c4824e12013-01-12 16:34:53137 currently_scrolling_layer_ = NULL;
[email protected]adeda572014-01-31 00:49:47138 inner_viewport_scroll_layer_ = NULL;
139 outer_viewport_scroll_layer_ = NULL;
140 page_scale_layer_ = NULL;
[email protected]5c4824e12013-01-12 16:34:53141
[email protected]c1bb5af2013-03-13 19:06:27142 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]5c4824e12013-01-12 16:34:53143}
144
[email protected]adeda572014-01-31 00:49:47145LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
146 return inner_viewport_scroll_layer_;
147}
[email protected]3b31c6ac2012-12-06 21:27:29148
[email protected]adeda572014-01-31 00:49:47149LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
150 return outer_viewport_scroll_layer_;
151}
[email protected]1960a712013-04-30 17:06:47152
miletusf57925d2014-10-01 19:38:13153gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
154 gfx::ScrollOffset offset;
[email protected]3b31c6ac2012-12-06 21:27:29155
[email protected]adeda572014-01-31 00:49:47156 if (inner_viewport_scroll_layer_)
aeliasd0070ba2015-01-31 13:44:49157 offset += inner_viewport_scroll_layer_->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47158
159 if (outer_viewport_scroll_layer_)
aeliasd0070ba2015-01-31 13:44:49160 offset += outer_viewport_scroll_layer_->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:47161
162 return offset;
163}
164
miletusf57925d2014-10-01 19:38:13165gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const {
166 gfx::ScrollOffset offset;
[email protected]adeda572014-01-31 00:49:47167
168 if (inner_viewport_scroll_layer_)
169 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
170
171 if (outer_viewport_scroll_layer_)
172 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
173
174 return offset;
175}
[email protected]3b31c6ac2012-12-06 21:27:29176
177scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
178 // Clear all data structures that have direct references to the layer tree.
179 scrolling_layer_id_from_previous_tree_ =
180 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
[email protected]adeda572014-01-31 00:49:47181 inner_viewport_scroll_layer_ = NULL;
182 outer_viewport_scroll_layer_ = NULL;
183 page_scale_layer_ = NULL;
[email protected]3b31c6ac2012-12-06 21:27:29184 currently_scrolling_layer_ = NULL;
185
[email protected]76ffd9e2012-12-20 19:12:47186 render_surface_layer_list_.clear();
[email protected]615c78a2013-01-24 23:44:16187 set_needs_update_draw_properties();
[email protected]3b31c6ac2012-12-06 21:27:29188 return root_layer_.Pass();
189}
190
[email protected]7aba6662013-03-12 10:17:34191void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
[email protected]c9280762013-08-01 06:28:57192 // The request queue should have been processed and does not require a push.
193 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
194
[email protected]7d08a9352013-10-15 08:24:56195 if (next_activation_forces_redraw_) {
[email protected]12a63da2014-06-13 06:06:22196 target_tree->ForceRedrawNextActivation();
[email protected]7d08a9352013-10-15 08:24:56197 next_activation_forces_redraw_ = false;
198 }
199
[email protected]b69c1db2013-11-27 00:05:19200 target_tree->PassSwapPromises(&swap_promise_list_);
201
aelias6004fe02015-02-07 21:43:01202 target_tree->set_top_controls_shrink_blink_size(
203 top_controls_shrink_blink_size_);
204 target_tree->set_top_controls_height(top_controls_height_);
205 target_tree->PushTopControls(nullptr);
bokan88eae012014-09-09 20:40:42206
aelias58eec0812014-12-04 01:04:40207 // Active tree already shares the page_scale_factor object with pending
208 // tree so only the limits need to be provided.
209 target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
210 max_page_scale_factor());
ccameronb9aec4502014-12-05 19:31:00211 target_tree->elastic_overscroll()->PushPendingToActive();
[email protected]c60279472013-01-30 12:10:51212
bokanfcdbc182014-11-21 21:53:33213 target_tree->pending_page_scale_animation_ =
214 pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:14215
[email protected]adeda572014-01-31 00:49:47216 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
[email protected]57ac9482013-09-17 21:13:39217 target_tree->SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18218 overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
219 : Layer::INVALID_ID,
220 page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
[email protected]57ac9482013-09-17 21:13:39221 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
222 : Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47223 } else {
224 target_tree->ClearViewportLayers();
[email protected]57ac9482013-09-17 21:13:39225 }
[email protected]19aec372014-07-01 19:08:49226
[email protected]ebb179b2014-07-16 17:54:41227 target_tree->RegisterSelection(selection_start_, selection_end_);
[email protected]19aec372014-07-01 19:08:49228
[email protected]c60279472013-01-30 12:10:51229 // This should match the property synchronization in
230 // LayerTreeHost::finishCommitOnImplThread().
231 target_tree->set_source_frame_number(source_frame_number());
232 target_tree->set_background_color(background_color());
233 target_tree->set_has_transparent_background(has_transparent_background());
234
235 if (ContentsTexturesPurged())
236 target_tree->SetContentsTexturesPurged();
237 else
238 target_tree->ResetContentsTexturesPurged();
239
[email protected]318822852013-02-14 00:54:27240 if (ViewportSizeInvalid())
241 target_tree->SetViewportSizeInvalid();
242 else
243 target_tree->ResetViewportSizeInvalid();
244
[email protected]c60279472013-01-30 12:10:51245 if (hud_layer())
246 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
[email protected]6ba914122013-03-22 16:26:39247 LayerTreeHostCommon::FindLayerInSubtree(
[email protected]c1bb5af2013-03-13 19:06:27248 target_tree->root_layer(), hud_layer()->id())));
[email protected]c60279472013-01-30 12:10:51249 else
250 target_tree->set_hud_layer(NULL);
[email protected]759dc9f2014-07-23 19:18:51251
252 target_tree->has_ever_been_drawn_ = false;
[email protected]c60279472013-01-30 12:10:51253}
254
[email protected]fef74fd2014-02-27 06:28:17255LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
256 return inner_viewport_scroll_layer_
257 ? inner_viewport_scroll_layer_->scroll_clip_layer()
258 : NULL;
[email protected]ffb2720f2013-03-15 19:18:37259}
260
bokanef971462014-10-13 22:58:32261LayerImpl* LayerTreeImpl::OuterViewportContainerLayer() const {
262 return outer_viewport_scroll_layer_
263 ? outer_viewport_scroll_layer_->scroll_clip_layer()
264 : NULL;
265}
266
[email protected]ffb2720f2013-03-15 19:18:37267LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
[email protected]69b50ec2013-01-19 04:58:01268 DCHECK(IsActiveTree());
269 return currently_scrolling_layer_;
270}
271
[email protected]0fc818e2013-03-18 06:45:20272void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
273 if (currently_scrolling_layer_ == layer)
274 return;
275
276 if (currently_scrolling_layer_ &&
277 currently_scrolling_layer_->scrollbar_animation_controller())
[email protected]1dc06162014-03-26 22:54:45278 currently_scrolling_layer_->scrollbar_animation_controller()
[email protected]930ff43b2014-05-02 05:24:00279 ->DidScrollEnd();
[email protected]0fc818e2013-03-18 06:45:20280 currently_scrolling_layer_ = layer;
281 if (layer && layer->scrollbar_animation_controller())
[email protected]930ff43b2014-05-02 05:24:00282 layer->scrollbar_animation_controller()->DidScrollBegin();
[email protected]0fc818e2013-03-18 06:45:20283}
284
[email protected]3b31c6ac2012-12-06 21:27:29285void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
[email protected]0fc818e2013-03-18 06:45:20286 SetCurrentlyScrollingLayer(NULL);
[email protected]3b31c6ac2012-12-06 21:27:29287 scrolling_layer_id_from_previous_tree_ = 0;
288}
289
[email protected]adeda572014-01-31 00:49:47290namespace {
291
292void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
293 if (!current_layer)
294 return;
295
296 while (current_layer) {
sataya.m07f11a82014-10-07 14:29:18297 current_layer->ScrollbarParametersDidChange(false);
[email protected]adeda572014-01-31 00:49:47298 current_layer = current_layer->parent();
299 }
300}
301
302} // namespace
303
aelias58eec0812014-12-04 01:04:40304float LayerTreeImpl::ClampPageScaleFactorToLimits(
305 float page_scale_factor) const {
306 if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_)
307 page_scale_factor = min_page_scale_factor_;
308 else if (max_page_scale_factor_ && page_scale_factor > max_page_scale_factor_)
309 page_scale_factor = max_page_scale_factor_;
310 return page_scale_factor;
[email protected]d6021f6a2014-06-12 21:15:24311}
[email protected]c60279472013-01-30 12:10:51312
aelias58eec0812014-12-04 01:04:40313void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
314 DCHECK(IsActiveTree());
315 if (page_scale_factor()->SetCurrent(
316 ClampPageScaleFactorToLimits(active_page_scale)))
317 DidUpdatePageScale();
[email protected]d6021f6a2014-06-12 21:15:24318}
319
aelias58eec0812014-12-04 01:04:40320void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
321 float min_page_scale_factor,
322 float max_page_scale_factor) {
323 PushPageScaleFactorAndLimits(&page_scale_factor, min_page_scale_factor,
324 max_page_scale_factor);
325}
326
327void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
328 float min_page_scale_factor,
329 float max_page_scale_factor) {
330 DCHECK(page_scale_factor || IsActiveTree());
331 bool changed_page_scale = false;
332 if (page_scale_factor) {
333 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
334 changed_page_scale |=
335 page_scale_factor_->PushFromMainThread(*page_scale_factor);
336 }
337 if (IsActiveTree())
338 changed_page_scale |= page_scale_factor_->PushPendingToActive();
339 changed_page_scale |=
340 SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
341
342 if (changed_page_scale)
343 DidUpdatePageScale();
344}
345
aelias6004fe02015-02-07 21:43:01346void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) {
347 if (top_controls_shrink_blink_size_ == shrink)
348 return;
349
350 top_controls_shrink_blink_size_ = shrink;
351 if (IsActiveTree())
352 layer_tree_host_impl_->UpdateViewportContainerSizes();
353}
354
355void LayerTreeImpl::set_top_controls_height(float top_controls_height) {
356 if (top_controls_height_ == top_controls_height)
357 return;
358
359 top_controls_height_ = top_controls_height;
360 if (IsActiveTree())
361 layer_tree_host_impl_->UpdateViewportContainerSizes();
362}
363
364bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) {
365 ratio = std::max(ratio, 0.f);
366 ratio = std::min(ratio, 1.f);
367 return top_controls_shown_ratio_->SetCurrent(ratio);
368}
369
370void LayerTreeImpl::PushTopControlsFromMainThread(
371 float top_controls_shown_ratio) {
372 PushTopControls(&top_controls_shown_ratio);
373}
374
375void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) {
376 DCHECK(top_controls_shown_ratio || IsActiveTree());
377
378 if (top_controls_shown_ratio) {
379 DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
380 top_controls_shown_ratio_->PushFromMainThread(*top_controls_shown_ratio);
381 }
382 if (IsActiveTree()) {
383 if (top_controls_shown_ratio_->PushPendingToActive())
384 layer_tree_host_impl_->DidChangeTopControlsPosition();
385 }
386}
387
aelias58eec0812014-12-04 01:04:40388bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
389 float max_page_scale_factor) {
390 if (min_page_scale_factor == min_page_scale_factor_ &&
391 max_page_scale_factor == max_page_scale_factor_)
392 return false;
[email protected]7265e74e2014-02-07 23:43:06393
[email protected]c60279472013-01-30 12:10:51394 min_page_scale_factor_ = min_page_scale_factor;
395 max_page_scale_factor_ = max_page_scale_factor;
[email protected]20d2b742013-09-26 05:41:34396
aelias58eec0812014-12-04 01:04:40397 return true;
398}
[email protected]d6021f6a2014-06-12 21:15:24399
aelias58eec0812014-12-04 01:04:40400void LayerTreeImpl::DidUpdatePageScale() {
401 if (IsActiveTree())
402 page_scale_factor()->SetCurrent(
403 ClampPageScaleFactorToLimits(current_page_scale_factor()));
[email protected]d6021f6a2014-06-12 21:15:24404
aelias58eec0812014-12-04 01:04:40405 set_needs_update_draw_properties();
[email protected]d6021f6a2014-06-12 21:15:24406
[email protected]22f200a2013-10-09 18:08:29407 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:00408 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:40409 TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
410 current_page_scale_factor(), min_page_scale_factor_,
[email protected]d6021f6a2014-06-12 21:15:24411 max_page_scale_factor_);
[email protected]22f200a2013-10-09 18:08:29412 }
[email protected]adeda572014-01-31 00:49:47413
414 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
bokanc784a6f2015-01-28 04:11:50415
416 HideInnerViewportScrollbarsIfNearMinimumScale();
417}
418
419void LayerTreeImpl::HideInnerViewportScrollbarsIfNearMinimumScale() {
420 if (!InnerViewportContainerLayer())
421 return;
422
423 LayerImpl::ScrollbarSet* scrollbars =
424 InnerViewportContainerLayer()->scrollbars();
425
426 if (!scrollbars)
427 return;
428
429 for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
430 it != scrollbars->end();
431 ++it) {
432 ScrollbarLayerImplBase* scrollbar = *it;
433 float minimum_scale_to_show_at =
434 min_page_scale_factor() * settings().scrollbar_show_scale_threshold;
435 scrollbar->SetHideLayerAndSubtree(
436 current_page_scale_factor() < minimum_scale_to_show_at);
437 }
[email protected]c60279472013-01-30 12:10:51438}
439
aelias58eec0812014-12-04 01:04:40440SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
441 return page_scale_factor_.get();
442}
443
444const SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() const {
445 return page_scale_factor_.get();
446}
447
[email protected]257abfa82013-01-29 23:47:24448gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
[email protected]587941d2014-08-22 01:40:01449 if (!InnerViewportContainerLayer())
450 return gfx::SizeF();
451
bokanef971462014-10-13 22:58:32452 return gfx::ScaleSize(InnerViewportContainerLayer()->BoundsForScrolling(),
aelias58eec0812014-12-04 01:04:40453 1.0f / current_page_scale_factor());
[email protected]257abfa82013-01-29 23:47:24454}
455
[email protected]3744e27b2013-11-06 21:44:08456gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
[email protected]adeda572014-01-31 00:49:47457 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
458 ? OuterViewportScrollLayer()
459 : InnerViewportScrollLayer();
460 if (!root_scroll_layer || root_scroll_layer->children().empty())
[email protected]3744e27b2013-11-06 21:44:08461 return gfx::Rect();
[email protected]adeda572014-01-31 00:49:47462 LayerImpl* layer = root_scroll_layer->children()[0];
[email protected]8a822692014-02-12 17:30:55463 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
464 gfx::Rect(layer->content_bounds()));
[email protected]3744e27b2013-11-06 21:44:08465}
466
[email protected]58241dc2013-08-20 01:39:25467void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
[email protected]3519b872013-07-30 07:17:50468 DCHECK(IsActiveTree());
469
aelias58eec0812014-12-04 01:04:40470 page_scale_factor()->AbortCommit();
aelias6004fe02015-02-07 21:43:01471 top_controls_shown_ratio()->AbortCommit();
ccameronb9aec4502014-12-05 19:31:00472 elastic_overscroll()->AbortCommit();
[email protected]3519b872013-07-30 07:17:50473
474 if (!root_layer())
475 return;
476
477 LayerTreeHostCommon::CallFunctionForSubtree(
vmpstra73f18d2015-03-02 21:04:39478 root_layer(), [](LayerImpl* layer) {
479 layer->ApplySentScrollDeltasFromAbortedCommit();
480 });
[email protected]58241dc2013-08-20 01:39:25481}
482
[email protected]57ac9482013-09-17 21:13:39483void LayerTreeImpl::SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18484 int overscroll_elasticity_layer_id,
[email protected]57ac9482013-09-17 21:13:39485 int page_scale_layer_id,
486 int inner_viewport_scroll_layer_id,
487 int outer_viewport_scroll_layer_id) {
ccameron8230b68b2014-11-21 19:25:18488 overscroll_elasticity_layer_ = LayerById(overscroll_elasticity_layer_id);
[email protected]57ac9482013-09-17 21:13:39489 page_scale_layer_ = LayerById(page_scale_layer_id);
490 DCHECK(page_scale_layer_);
491
492 inner_viewport_scroll_layer_ =
493 LayerById(inner_viewport_scroll_layer_id);
494 DCHECK(inner_viewport_scroll_layer_);
495
496 outer_viewport_scroll_layer_ =
497 LayerById(outer_viewport_scroll_layer_id);
498 DCHECK(outer_viewport_scroll_layer_ ||
499 outer_viewport_scroll_layer_id == Layer::INVALID_ID);
[email protected]adeda572014-01-31 00:49:47500
bokanc784a6f2015-01-28 04:11:50501 HideInnerViewportScrollbarsIfNearMinimumScale();
[email protected]57ac9482013-09-17 21:13:39502}
503
504void LayerTreeImpl::ClearViewportLayers() {
505 page_scale_layer_ = NULL;
506 inner_viewport_scroll_layer_ = NULL;
507 outer_viewport_scroll_layer_ = NULL;
508}
509
enneaf5bda32015-02-19 01:27:36510bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
[email protected]8f7f298822014-06-13 00:23:32511 if (!needs_update_draw_properties_)
512 return true;
[email protected]615c78a2013-01-24 23:44:16513
enne0acea6ae2015-02-19 20:01:51514 // Calling UpdateDrawProperties must clear this flag, so there can be no
515 // early outs before this.
516 needs_update_draw_properties_ = false;
517
518 // For max_texture_size. When the renderer is re-created in
519 // CreateAndSetRenderer, the needs update draw properties flag is set
520 // again.
[email protected]615c78a2013-01-24 23:44:16521 if (!layer_tree_host_impl_->renderer())
[email protected]8f7f298822014-06-13 00:23:32522 return false;
[email protected]615c78a2013-01-24 23:44:16523
enne0acea6ae2015-02-19 20:01:51524 // Clear this after the renderer early out, as it should still be
525 // possible to hit test even without a renderer.
526 render_surface_layer_list_.clear();
527
[email protected]c1bb5af2013-03-13 19:06:27528 if (!root_layer())
[email protected]8f7f298822014-06-13 00:23:32529 return false;
530
[email protected]76ffd9e2012-12-20 19:12:47531 {
danakj4902c302015-02-13 22:12:16532 TRACE_EVENT2(
533 "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties",
534 "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_);
[email protected]57ac9482013-09-17 21:13:39535 LayerImpl* page_scale_layer =
[email protected]fef74fd2014-02-27 06:28:17536 page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
hush367d7dd2014-08-29 23:56:01537 bool can_render_to_separate_surface =
538 (layer_tree_host_impl_->GetDrawMode() !=
539 DRAW_MODE_RESOURCELESS_SOFTWARE);
[email protected]390bb1ff2014-05-09 17:14:40540
541 ++render_surface_layer_list_id_;
ennec3011472015-04-09 01:27:25542
543 // TODO(enne): Synchronize property trees to compositor thread and use
544 // them here.
545 PropertyTrees* property_trees = nullptr;
[email protected]7aad55f2013-07-26 11:25:53546 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
danakj3f76ace2014-11-18 16:56:00547 root_layer(), DrawViewportSize(),
548 layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
aelias58eec0812014-12-04 01:04:40549 current_page_scale_factor(), page_scale_layer,
ccameronb9aec4502014-12-05 19:31:00550 elastic_overscroll()->Current(IsActiveTree()),
551 overscroll_elasticity_layer_, resource_provider()->max_texture_size(),
552 settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text,
[email protected]45948712013-09-27 02:46:48553 can_render_to_separate_surface,
[email protected]35a99a12013-05-09 23:52:29554 settings().layer_transforms_should_scale_layer_contents,
ennec3011472015-04-09 01:27:25555 settings().verify_property_trees, &render_surface_layer_list_,
556 render_surface_layer_list_id_, property_trees);
[email protected]7aad55f2013-07-26 11:25:53557 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
[email protected]76ffd9e2012-12-20 19:12:47558 }
[email protected]615c78a2013-01-24 23:44:16559
[email protected]e4be0262013-10-19 16:54:28560 {
danakj4902c302015-02-13 22:12:16561 TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion",
562 "IsActive", IsActiveTree(), "SourceFrameNumber",
563 source_frame_number_);
564 OcclusionTracker<LayerImpl> occlusion_tracker(
565 root_layer()->render_surface()->content_rect());
566 occlusion_tracker.set_minimum_tracking_size(
567 settings().minimum_occlusion_tracking_size);
boliu7473f7f52014-10-01 16:54:56568
[email protected]e4be0262013-10-19 16:54:28569 // LayerIterator is used here instead of CallFunctionForSubtree to only
570 // UpdateTilePriorities on layers that will be visible (and thus have valid
571 // draw properties) and not because any ordering is required.
danakj4902c302015-02-13 22:12:16572 auto end = LayerIterator<LayerImpl>::End(&render_surface_layer_list_);
573 for (auto it = LayerIterator<LayerImpl>::Begin(&render_surface_layer_list_);
574 it != end; ++it) {
575 occlusion_tracker.EnterLayer(it);
[email protected]562b7ad2014-06-23 22:17:11576
danakj4902c302015-02-13 22:12:16577 // There are very few render targets so this should be cheap to do for
578 // each layer instead of something more complicated.
579 bool inside_replica = false;
580 LayerImpl* layer = it->render_target();
581 while (layer && !inside_replica) {
582 if (layer->render_target()->has_replica())
583 inside_replica = true;
584 layer = layer->render_target()->parent();
585 }
586
587 // Don't use occlusion if a layer will appear in a replica, since the
588 // tile raster code does not know how to look for the replica and would
589 // consider it occluded even though the replica is visible.
590 // Since occlusion is only used for browser compositor (i.e.
591 // use_occlusion_for_tile_prioritization) and it won't use replicas,
592 // this should matter not.
vmpstrcdcb5f72014-09-11 00:58:37593
boliu7473f7f52014-10-01 16:54:56594 if (it.represents_itself()) {
danakj4902c302015-02-13 22:12:16595 Occlusion occlusion =
596 inside_replica ? Occlusion()
597 : occlusion_tracker.GetCurrentOcclusionForLayer(
598 it->draw_transform());
599 it->draw_properties().occlusion_in_content_space = occlusion;
boliu7473f7f52014-10-01 16:54:56600 }
[email protected]e4be0262013-10-19 16:54:28601
danakj4902c302015-02-13 22:12:16602 if (it.represents_contributing_render_surface()) {
603 // Surfaces aren't used by the tile raster code, so they can have
604 // occlusion regardless of replicas.
605 Occlusion occlusion =
606 occlusion_tracker.GetCurrentOcclusionForContributingSurface(
607 it->render_surface()->draw_transform());
608 it->render_surface()->set_occlusion_in_content_space(occlusion);
609 // Masks are used to draw the contributing surface, so should have
610 // the same occlusion as the surface (nothing inside the surface
611 // occludes them).
612 if (LayerImpl* mask = it->mask_layer()) {
613 Occlusion mask_occlusion =
614 inside_replica
615 ? Occlusion()
616 : occlusion_tracker.GetCurrentOcclusionForContributingSurface(
617 it->render_surface()->draw_transform() *
618 it->draw_transform());
619 mask->draw_properties().occlusion_in_content_space = mask_occlusion;
620 }
621 if (LayerImpl* replica = it->replica_layer()) {
622 if (LayerImpl* mask = replica->mask_layer())
623 mask->draw_properties().occlusion_in_content_space = Occlusion();
624 }
625 }
626
627 occlusion_tracker.LeaveLayer(it);
628 }
629
630 unoccluded_screen_space_region_ =
631 occlusion_tracker.ComputeVisibleRegionInScreen();
632 }
633
enneaf5bda32015-02-19 01:27:36634 // It'd be ideal if this could be done earlier, but when the raster source
635 // is updated from the main thread during push properties, update draw
636 // properties has not occurred yet and so it's not clear whether or not the
637 // layer can or cannot use lcd text. So, this is the cleanup pass to
638 // determine if the raster source needs to be replaced with a non-lcd
639 // raster source due to draw properties.
640 if (update_lcd_text) {
641 // TODO(enne): Make LTHI::sync_tree return this value.
642 LayerTreeImpl* sync_tree =
643 layer_tree_host_impl_->proxy()->CommitToActiveTree()
644 ? layer_tree_host_impl_->active_tree()
645 : layer_tree_host_impl_->pending_tree();
646 // If this is not the sync tree, then it is not safe to update lcd text
647 // as it causes invalidations and the tiles may be in use.
648 DCHECK_EQ(this, sync_tree);
649 for (const auto& layer : picture_layers_)
650 layer->UpdateCanUseLCDTextAfterCommit();
651 }
652
danakj4902c302015-02-13 22:12:16653 {
654 TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles",
655 "IsActive", IsActiveTree(), "SourceFrameNumber",
656 source_frame_number_);
657 const bool resourceless_software_draw =
658 (layer_tree_host_impl_->GetDrawMode() ==
659 DRAW_MODE_RESOURCELESS_SOFTWARE);
danakj4902c302015-02-13 22:12:16660 size_t layers_updated_count = 0;
661 bool tile_priorities_updated = false;
662 for (PictureLayerImpl* layer : picture_layers_) {
danakj4902c302015-02-13 22:12:16663 if (!layer->IsDrawnRenderSurfaceLayerListMember())
[email protected]6355d2d2014-05-07 15:07:27664 continue;
danakj4902c302015-02-13 22:12:16665 ++layers_updated_count;
danakj83c3d4a82015-02-14 01:42:57666 tile_priorities_updated |= layer->UpdateTiles(resourceless_software_draw);
[email protected]e4be0262013-10-19 16:54:28667 }
vmpstrd6166202014-11-05 18:45:40668
vmpstr5377520a2014-12-29 23:26:13669 if (tile_priorities_updated)
670 DidModifyTilePriorities();
671
vmpstrd6166202014-11-05 18:45:40672 TRACE_EVENT_END1("cc", "LayerTreeImpl::UpdateTilePriorities",
673 "layers_updated_count", layers_updated_count);
[email protected]e4be0262013-10-19 16:54:28674 }
675
[email protected]615c78a2013-01-24 23:44:16676 DCHECK(!needs_update_draw_properties_) <<
[email protected]7d19dc342013-05-02 22:02:04677 "CalcDrawProperties should not set_needs_update_draw_properties()";
[email protected]8f7f298822014-06-13 00:23:32678 return true;
[email protected]76ffd9e2012-12-20 19:12:47679}
680
[email protected]50761e92013-03-29 20:51:28681const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
[email protected]76ffd9e2012-12-20 19:12:47682 // If this assert triggers, then the list is dirty.
[email protected]615c78a2013-01-24 23:44:16683 DCHECK(!needs_update_draw_properties_);
[email protected]76ffd9e2012-12-20 19:12:47684 return render_surface_layer_list_;
685}
686
danakj4902c302015-02-13 22:12:16687const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
688 // If this assert triggers, then the render_surface_layer_list_ is dirty, so
689 // the unoccluded_screen_space_region_ is not valid anymore.
690 DCHECK(!needs_update_draw_properties_);
691 return unoccluded_screen_space_region_;
692}
693
bokancccfde72014-10-08 15:15:22694gfx::Size LayerTreeImpl::ScrollableSize() const {
[email protected]adeda572014-01-31 00:49:47695 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
696 ? OuterViewportScrollLayer()
697 : InnerViewportScrollLayer();
698 if (!root_scroll_layer || root_scroll_layer->children().empty())
bokancccfde72014-10-08 15:15:22699 return gfx::Size();
[email protected]adeda572014-01-31 00:49:47700 return root_scroll_layer->children()[0]->bounds();
[email protected]caa567d2012-12-20 07:56:16701}
702
[email protected]361bc00d2012-12-14 07:03:24703LayerImpl* LayerTreeImpl::LayerById(int id) {
704 LayerIdMap::iterator iter = layer_id_map_.find(id);
705 return iter != layer_id_map_.end() ? iter->second : NULL;
706}
707
708void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
709 DCHECK(!LayerById(layer->id()));
710 layer_id_map_[layer->id()] = layer;
711}
712
713void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
714 DCHECK(LayerById(layer->id()));
715 layer_id_map_.erase(layer->id());
716}
717
[email protected]aebf4622014-07-14 16:57:59718size_t LayerTreeImpl::NumLayers() {
719 return layer_id_map_.size();
720}
721
[email protected]ed511b8d2013-03-25 03:29:29722void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
[email protected]a90fac72013-06-06 18:56:13723 pending_tree->SetCurrentlyScrollingLayer(
724 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
725 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
[email protected]1e0f8d62013-01-09 07:41:35726}
727
[email protected]37386f052013-01-13 00:42:22728void LayerTreeImpl::DidBecomeActive() {
[email protected]12a63da2014-06-13 06:06:22729 if (next_activation_forces_redraw_) {
730 layer_tree_host_impl_->SetFullRootLayerDamage();
731 next_activation_forces_redraw_ = false;
732 }
733
[email protected]adeda572014-01-31 00:49:47734 if (scrolling_layer_id_from_previous_tree_) {
735 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
[email protected]7dcf5632014-06-25 01:11:55736 root_layer(), scrolling_layer_id_from_previous_tree_);
[email protected]adeda572014-01-31 00:49:47737 }
738
[email protected]7dcf5632014-06-25 01:11:55739 // Always reset this flag on activation, as we would only have activated
740 // if we were in a good state.
vmpstr61ed94a12014-10-09 04:49:30741 layer_tree_host_impl_->ResetRequiresHighResToDraw();
[email protected]7dcf5632014-06-25 01:11:55742
vmpstra73f18d2015-03-02 21:04:39743 if (root_layer()) {
744 LayerTreeHostCommon::CallFunctionForSubtree(
745 root_layer(), [](LayerImpl* layer) { layer->DidBecomeActive(); });
746 }
[email protected]7dcf5632014-06-25 01:11:55747
[email protected]12a63da2014-06-13 06:06:22748 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
749 source_frame_number_);
[email protected]37386f052013-01-13 00:42:22750}
751
[email protected]6f90b9e2013-01-17 23:42:00752bool LayerTreeImpl::ContentsTexturesPurged() const {
753 return contents_textures_purged_;
754}
755
756void LayerTreeImpl::SetContentsTexturesPurged() {
[email protected]94bf75c2013-06-12 13:20:04757 if (contents_textures_purged_)
758 return;
[email protected]6f90b9e2013-01-17 23:42:00759 contents_textures_purged_ = true;
[email protected]c1bb5af2013-03-13 19:06:27760 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]6f90b9e2013-01-17 23:42:00761}
762
763void LayerTreeImpl::ResetContentsTexturesPurged() {
[email protected]94bf75c2013-06-12 13:20:04764 if (!contents_textures_purged_)
765 return;
[email protected]6f90b9e2013-01-17 23:42:00766 contents_textures_purged_ = false;
[email protected]c1bb5af2013-03-13 19:06:27767 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]6f90b9e2013-01-17 23:42:00768}
769
[email protected]3d609bb2014-02-01 01:10:23770bool LayerTreeImpl::RequiresHighResToDraw() const {
vmpstr61ed94a12014-10-09 04:49:30771 return layer_tree_host_impl_->RequiresHighResToDraw();
[email protected]3d609bb2014-02-01 01:10:23772}
773
[email protected]318822852013-02-14 00:54:27774bool LayerTreeImpl::ViewportSizeInvalid() const {
775 return viewport_size_invalid_;
776}
777
778void LayerTreeImpl::SetViewportSizeInvalid() {
779 viewport_size_invalid_ = true;
[email protected]c1bb5af2013-03-13 19:06:27780 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27781}
782
783void LayerTreeImpl::ResetViewportSizeInvalid() {
784 viewport_size_invalid_ = false;
[email protected]c1bb5af2013-03-13 19:06:27785 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
[email protected]318822852013-02-14 00:54:27786}
787
[email protected]48871fc2013-01-23 07:36:51788Proxy* LayerTreeImpl::proxy() const {
789 return layer_tree_host_impl_->proxy();
790}
791
[email protected]ff762fb2012-12-12 19:18:37792const LayerTreeSettings& LayerTreeImpl::settings() const {
[email protected]c1bb5af2013-03-13 19:06:27793 return layer_tree_host_impl_->settings();
[email protected]ff762fb2012-12-12 19:18:37794}
795
danakj875efa42015-02-10 22:18:23796const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
797 return layer_tree_host_impl_->debug_state();
798}
799
[email protected]7a8bcd262014-01-15 12:54:58800const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
[email protected]c1bb5af2013-03-13 19:06:27801 return layer_tree_host_impl_->GetRendererCapabilities();
[email protected]bf5b3a02013-02-13 02:02:52802}
803
[email protected]0634cdd42013-08-16 00:46:09804ContextProvider* LayerTreeImpl::context_provider() const {
dcheng6afa17002014-08-26 19:11:31805 return output_surface()->context_provider();
[email protected]0634cdd42013-08-16 00:46:09806}
807
[email protected]ff762fb2012-12-12 19:18:37808OutputSurface* LayerTreeImpl::output_surface() const {
[email protected]c1bb5af2013-03-13 19:06:27809 return layer_tree_host_impl_->output_surface();
[email protected]ff762fb2012-12-12 19:18:37810}
811
812ResourceProvider* LayerTreeImpl::resource_provider() const {
[email protected]c1bb5af2013-03-13 19:06:27813 return layer_tree_host_impl_->resource_provider();
[email protected]ff762fb2012-12-12 19:18:37814}
815
816TileManager* LayerTreeImpl::tile_manager() const {
[email protected]c1bb5af2013-03-13 19:06:27817 return layer_tree_host_impl_->tile_manager();
[email protected]ff762fb2012-12-12 19:18:37818}
819
820FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27821 return layer_tree_host_impl_->fps_counter();
[email protected]ff762fb2012-12-12 19:18:37822}
823
[email protected]71691c22013-01-18 03:14:22824PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
[email protected]c1bb5af2013-03-13 19:06:27825 return layer_tree_host_impl_->paint_time_counter();
[email protected]71691c22013-01-18 03:14:22826}
827
[email protected]1191d9d2013-02-02 06:00:33828MemoryHistory* LayerTreeImpl::memory_history() const {
[email protected]c1bb5af2013-03-13 19:06:27829 return layer_tree_host_impl_->memory_history();
[email protected]1191d9d2013-02-02 06:00:33830}
831
[email protected]4a6c091d2014-04-24 21:06:46832gfx::Size LayerTreeImpl::device_viewport_size() const {
833 return layer_tree_host_impl_->device_viewport_size();
834}
835
danakj875efa42015-02-10 22:18:23836float LayerTreeImpl::device_scale_factor() const {
837 return layer_tree_host_impl_->device_scale_factor();
838}
839
840DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
841 return layer_tree_host_impl_->debug_rect_history();
842}
843
[email protected]f117a4c2012-12-16 04:53:10844bool LayerTreeImpl::IsActiveTree() const {
[email protected]c1bb5af2013-03-13 19:06:27845 return layer_tree_host_impl_->active_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10846}
847
848bool LayerTreeImpl::IsPendingTree() const {
[email protected]c1bb5af2013-03-13 19:06:27849 return layer_tree_host_impl_->pending_tree() == this;
[email protected]f117a4c2012-12-16 04:53:10850}
851
[email protected]48871fc2013-01-23 07:36:51852bool LayerTreeImpl::IsRecycleTree() const {
[email protected]c1bb5af2013-03-13 19:06:27853 return layer_tree_host_impl_->recycle_tree() == this;
[email protected]48871fc2013-01-23 07:36:51854}
855
enneaf5bda32015-02-19 01:27:36856bool LayerTreeImpl::IsSyncTree() const {
857 return layer_tree_host_impl_->sync_tree() == this;
858}
859
[email protected]f117a4c2012-12-16 04:53:10860LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27861 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
[email protected]f117a4c2012-12-16 04:53:10862 if (!tree)
863 return NULL;
864 return tree->LayerById(id);
865}
866
867LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
[email protected]c1bb5af2013-03-13 19:06:27868 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
[email protected]f117a4c2012-12-16 04:53:10869 if (!tree)
870 return NULL;
871 return tree->LayerById(id);
872}
873
[email protected]166db5c82013-01-09 23:54:31874bool LayerTreeImpl::PinchGestureActive() const {
[email protected]c1bb5af2013-03-13 19:06:27875 return layer_tree_host_impl_->pinch_gesture_active();
[email protected]166db5c82013-01-09 23:54:31876}
877
[email protected]04c5900d2014-08-18 13:38:36878BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const {
879 return layer_tree_host_impl_->CurrentBeginFrameArgs();
[email protected]fb7425a2013-04-22 16:28:55880}
881
[email protected]c92195e2014-05-07 18:18:49882base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
883 return layer_tree_host_impl_->begin_impl_frame_interval();
884}
885
[email protected]d7eb8c72013-03-23 22:57:13886void LayerTreeImpl::SetNeedsCommit() {
887 layer_tree_host_impl_->SetNeedsCommit();
888}
889
[email protected]bd5324592014-07-31 09:09:33890gfx::Rect LayerTreeImpl::DeviceViewport() const {
891 return layer_tree_host_impl_->DeviceViewport();
892}
893
[email protected]54af03522013-09-05 00:43:28894gfx::Size LayerTreeImpl::DrawViewportSize() const {
895 return layer_tree_host_impl_->DrawViewportSize();
896}
897
[email protected]bd5324592014-07-31 09:09:33898const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
899 return layer_tree_host_impl_->ViewportRectForTilePriority();
900}
901
[email protected]930ff43b2014-05-02 05:24:00902scoped_ptr<ScrollbarAnimationController>
903LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
904 DCHECK(settings().scrollbar_fade_delay_ms);
905 DCHECK(settings().scrollbar_fade_duration_ms);
906 base::TimeDelta delay =
907 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
sataya.m07f11a82014-10-07 14:29:18908 base::TimeDelta resize_delay = base::TimeDelta::FromMilliseconds(
909 settings().scrollbar_fade_resize_delay_ms);
[email protected]930ff43b2014-05-02 05:24:00910 base::TimeDelta duration =
911 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
912 switch (settings().scrollbar_animator) {
ericrk7c030992015-02-20 01:39:38913 case LayerTreeSettings::LINEAR_FADE: {
[email protected]930ff43b2014-05-02 05:24:00914 return ScrollbarAnimationControllerLinearFade::Create(
sataya.m07f11a82014-10-07 14:29:18915 scrolling_layer,
916 layer_tree_host_impl_,
917 delay,
918 resize_delay,
919 duration);
[email protected]930ff43b2014-05-02 05:24:00920 }
ericrk7c030992015-02-20 01:39:38921 case LayerTreeSettings::THINNING: {
sataya.m07f11a82014-10-07 14:29:18922 return ScrollbarAnimationControllerThinning::Create(scrolling_layer,
923 layer_tree_host_impl_,
924 delay,
925 resize_delay,
926 duration);
[email protected]930ff43b2014-05-02 05:24:00927 }
ericrk7c030992015-02-20 01:39:38928 case LayerTreeSettings::NO_ANIMATOR:
[email protected]930ff43b2014-05-02 05:24:00929 NOTREACHED();
930 break;
931 }
danakjf446a072014-09-27 21:55:48932 return nullptr;
[email protected]2ea5aba2013-09-11 14:26:56933}
934
[email protected]b8384e22013-12-03 02:20:48935void LayerTreeImpl::DidAnimateScrollOffset() {
936 layer_tree_host_impl_->DidAnimateScrollOffset();
937}
938
[email protected]13525d62014-05-20 21:22:04939bool LayerTreeImpl::use_gpu_rasterization() const {
940 return layer_tree_host_impl_->use_gpu_rasterization();
941}
942
hendrikwc2bbd612014-12-03 23:49:34943GpuRasterizationStatus LayerTreeImpl::GetGpuRasterizationStatus() const {
944 return layer_tree_host_impl_->gpu_rasterization_status();
945}
946
[email protected]473f1f22014-05-22 08:19:17947bool LayerTreeImpl::create_low_res_tiling() const {
948 return layer_tree_host_impl_->create_low_res_tiling();
949}
950
[email protected]ff762fb2012-12-12 19:18:37951void LayerTreeImpl::SetNeedsRedraw() {
[email protected]59adb112013-04-09 04:48:44952 layer_tree_host_impl_->SetNeedsRedraw();
[email protected]ff762fb2012-12-12 19:18:37953}
954
sunnypsea328be12015-02-26 06:03:27955AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
[email protected]c1bb5af2013-03-13 19:06:27956 return layer_tree_host_impl_->animation_registrar();
[email protected]de4afb5e2012-12-20 00:11:34957}
[email protected]ff762fb2012-12-12 19:18:37958
vmpstrdcf21da2015-03-23 19:16:32959void LayerTreeImpl::GetAllTilesAndPrioritiesForTracing(
960 std::map<const Tile*, TilePriority>* tile_map) const {
vmpstrd7de03c2014-08-27 18:11:01961 typedef LayerIterator<LayerImpl> LayerIteratorType;
962 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
963 for (LayerIteratorType it =
964 LayerIteratorType::Begin(&render_surface_layer_list_);
965 it != end;
966 ++it) {
967 if (!it.represents_itself())
968 continue;
969 LayerImpl* layer_impl = *it;
vmpstrdcf21da2015-03-23 19:16:32970 layer_impl->GetAllTilesAndPrioritiesForTracing(tile_map);
vmpstrd7de03c2014-08-27 18:11:01971 }
972}
973
ssid911e40e2015-02-09 17:55:20974void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
[email protected]d12aa932014-08-01 13:10:38975 TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this);
nduca929378a02014-08-23 19:48:52976 state->SetInteger("source_frame_number", source_frame_number_);
[email protected]f6742f52013-05-08 23:52:22977
[email protected]d12aa932014-08-01 13:10:38978 state->BeginDictionary("root_layer");
979 root_layer_->AsValueInto(state);
980 state->EndDictionary();
[email protected]f6742f52013-05-08 23:52:22981
[email protected]d12aa932014-08-01 13:10:38982 state->BeginArray("render_surface_layer_list");
[email protected]ba1b33e2014-02-28 16:44:51983 typedef LayerIterator<LayerImpl> LayerIteratorType;
[email protected]71dfcc72013-03-20 21:30:09984 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
985 for (LayerIteratorType it = LayerIteratorType::Begin(
[email protected]8c5690222013-02-15 17:36:43986 &render_surface_layer_list_); it != end; ++it) {
[email protected]71dfcc72013-03-20 21:30:09987 if (!it.represents_itself())
[email protected]8c5690222013-02-15 17:36:43988 continue;
[email protected]d12aa932014-08-01 13:10:38989 TracedValue::AppendIDRef(*it, state);
[email protected]8c5690222013-02-15 17:36:43990 }
[email protected]d12aa932014-08-01 13:10:38991 state->EndArray();
skyostil43c330f72014-09-22 16:49:11992
993 state->BeginArray("swap_promise_trace_ids");
994 for (size_t i = 0; i < swap_promise_list_.size(); i++)
995 state->AppendDouble(swap_promise_list_[i]->TraceId());
996 state->EndArray();
[email protected]8c5690222013-02-15 17:36:43997}
998
[email protected]1960a712013-04-30 17:06:47999void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
[email protected]c9280762013-08-01 06:28:571000 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
[email protected]20d2b742013-09-26 05:41:341001 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
1002 return;
1003
[email protected]adeda572014-01-31 00:49:471004 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
1005
[email protected]20d2b742013-09-26 05:41:341006 if (root_layer_scroll_offset_delegate_) {
[email protected]ec2322e2014-05-15 16:32:001007 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:401008 TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
1009 current_page_scale_factor(), min_page_scale_factor(),
[email protected]68fe60f2014-02-12 13:49:111010 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:471011
hush33370e12015-04-07 03:49:501012 DistributeRootScrollOffset();
[email protected]20d2b742013-09-26 05:41:341013 }
[email protected]1960a712013-04-30 17:06:471014}
1015
hush33370e12015-04-07 03:49:501016void LayerTreeImpl::UpdateRootScrollOffsetDelegate() {
[email protected]adeda572014-01-31 00:49:471017 DCHECK(root_layer_scroll_offset_delegate_);
1018
hush33370e12015-04-07 03:49:501019 gfx::ScrollOffset offset = InnerViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471020
1021 if (OuterViewportScrollLayer())
hush33370e12015-04-07 03:49:501022 offset += OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471023
[email protected]ec2322e2014-05-15 16:32:001024 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
aelias58eec0812014-12-04 01:04:401025 offset, TotalMaxScrollOffset(), ScrollableSize(),
1026 current_page_scale_factor(), min_page_scale_factor(),
[email protected]ec2322e2014-05-15 16:32:001027 max_page_scale_factor());
[email protected]adeda572014-01-31 00:49:471028}
1029
hush33370e12015-04-07 03:49:501030void LayerTreeImpl::DistributeRootScrollOffset() {
1031 if (!root_layer_scroll_offset_delegate_)
1032 return;
1033
1034 gfx::ScrollOffset root_offset =
1035 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
1036
1037 if (!InnerViewportScrollLayer())
1038 return;
1039
1040 DCHECK(OuterViewportScrollLayer());
[email protected]adeda572014-01-31 00:49:471041
1042 // If we get here, we have both inner/outer viewports, and need to distribute
1043 // the scroll offset between them.
miletusf57925d2014-10-01 19:38:131044 gfx::ScrollOffset inner_viewport_offset =
hush33370e12015-04-07 03:49:501045 InnerViewportScrollLayer()->CurrentScrollOffset();
miletusf57925d2014-10-01 19:38:131046 gfx::ScrollOffset outer_viewport_offset =
hush33370e12015-04-07 03:49:501047 OuterViewportScrollLayer()->CurrentScrollOffset();
[email protected]adeda572014-01-31 00:49:471048
1049 // It may be nothing has changed.
hush33370e12015-04-07 03:49:501050 if (inner_viewport_offset + outer_viewport_offset == root_offset)
1051 return;
[email protected]adeda572014-01-31 00:49:471052
miletusf57925d2014-10-01 19:38:131053 gfx::ScrollOffset max_outer_viewport_scroll_offset =
[email protected]adeda572014-01-31 00:49:471054 OuterViewportScrollLayer()->MaxScrollOffset();
1055
hush33370e12015-04-07 03:49:501056 outer_viewport_offset = root_offset - inner_viewport_offset;
[email protected]adeda572014-01-31 00:49:471057 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
miletusf57925d2014-10-01 19:38:131058 outer_viewport_offset.SetToMax(gfx::ScrollOffset());
[email protected]adeda572014-01-31 00:49:471059
hush33370e12015-04-07 03:49:501060 OuterViewportScrollLayer()->SetCurrentScrollOffsetFromDelegate(
1061 outer_viewport_offset);
1062 inner_viewport_offset = root_offset - outer_viewport_offset;
1063 InnerViewportScrollLayer()->SetCurrentScrollOffsetFromDelegate(
1064 inner_viewport_offset);
[email protected]adeda572014-01-31 00:49:471065
hush33370e12015-04-07 03:49:501066 UpdateRootScrollOffsetDelegate();
[email protected]adeda572014-01-31 00:49:471067}
1068
[email protected]b69c1db2013-11-27 00:05:191069void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1070 DCHECK(swap_promise);
[email protected]b69c1db2013-11-27 00:05:191071 swap_promise_list_.push_back(swap_promise.Pass());
1072}
1073
1074void LayerTreeImpl::PassSwapPromises(
1075 ScopedPtrVector<SwapPromise>* new_swap_promise) {
1076 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
weiliangcc1878c62014-09-02 22:43:171077 new_swap_promise);
[email protected]b69c1db2013-11-27 00:05:191078 new_swap_promise->clear();
1079}
1080
[email protected]d359203a2013-11-29 06:16:551081void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
[email protected]b69c1db2013-11-27 00:05:191082 for (size_t i = 0; i < swap_promise_list_.size(); i++)
[email protected]d359203a2013-11-29 06:16:551083 swap_promise_list_[i]->DidSwap(metadata);
[email protected]b69c1db2013-11-27 00:05:191084 swap_promise_list_.clear();
1085}
1086
1087void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1088 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1089 swap_promise_list_[i]->DidNotSwap(reason);
1090 swap_promise_list_.clear();
1091}
1092
[email protected]c48536a52013-09-14 00:02:081093void LayerTreeImpl::DidModifyTilePriorities() {
1094 layer_tree_host_impl_->DidModifyTilePriorities();
[email protected]fcb846d2013-05-22 01:42:361095}
1096
[email protected]c9280762013-08-01 06:28:571097void LayerTreeImpl::set_ui_resource_request_queue(
1098 const UIResourceRequestQueue& queue) {
1099 ui_resource_request_queue_ = queue;
1100}
1101
1102ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
1103 UIResourceId uid) const {
1104 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
1105}
1106
[email protected]709c9542013-10-26 01:43:511107bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
1108 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
1109}
1110
[email protected]c9280762013-08-01 06:28:571111void LayerTreeImpl::ProcessUIResourceRequestQueue() {
jdduke5ad36812015-01-02 17:59:321112 for (const auto& req : ui_resource_request_queue_) {
[email protected]741fba422013-09-20 03:34:141113 switch (req.GetType()) {
ericrk7c030992015-02-20 01:39:381114 case UIResourceRequest::UI_RESOURCE_CREATE:
[email protected]741fba422013-09-20 03:34:141115 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
[email protected]c9280762013-08-01 06:28:571116 break;
ericrk7c030992015-02-20 01:39:381117 case UIResourceRequest::UI_RESOURCE_DELETE:
[email protected]741fba422013-09-20 03:34:141118 layer_tree_host_impl_->DeleteUIResource(req.GetId());
[email protected]c9280762013-08-01 06:28:571119 break;
ericrk7c030992015-02-20 01:39:381120 case UIResourceRequest::UI_RESOURCE_INVALID_REQUEST:
[email protected]c9280762013-08-01 06:28:571121 NOTREACHED();
1122 break;
1123 }
1124 }
jdduke5ad36812015-01-02 17:59:321125 ui_resource_request_queue_.clear();
[email protected]127bdc1a2013-09-11 01:44:481126
1127 // If all UI resource evictions were not recreated by processing this queue,
1128 // then another commit is required.
1129 if (layer_tree_host_impl_->EvictedUIResourcesExist())
1130 layer_tree_host_impl_->SetNeedsCommit();
[email protected]c9280762013-08-01 06:28:571131}
1132
danakj7383c552015-02-11 18:01:481133void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1134 DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) ==
1135 picture_layers_.end());
1136 picture_layers_.push_back(layer);
1137}
1138
1139void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1140 std::vector<PictureLayerImpl*>::iterator it =
1141 std::find(picture_layers_.begin(), picture_layers_.end(), layer);
1142 DCHECK(it != picture_layers_.end());
1143 picture_layers_.erase(it);
1144}
1145
[email protected]30fe19ff2013-07-04 00:54:451146void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
1147 // Only the active tree needs to know about layers with copy requests, as
1148 // they are aborted if not serviced during draw.
1149 DCHECK(IsActiveTree());
1150
[email protected]a4ee12812014-02-06 17:33:381151 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1152 // layers_with_copy_output_request_.end(),
1153 // layer) == layers_with_copy_output_request_.end());
1154 // TODO(danakj): Remove this once crash is found crbug.com/309777
1155 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1156 CHECK(layers_with_copy_output_request_[i] != layer)
1157 << i << " of " << layers_with_copy_output_request_.size();
1158 }
[email protected]30fe19ff2013-07-04 00:54:451159 layers_with_copy_output_request_.push_back(layer);
1160}
1161
1162void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1163 // Only the active tree needs to know about layers with copy requests, as
1164 // they are aborted if not serviced during draw.
1165 DCHECK(IsActiveTree());
1166
1167 std::vector<LayerImpl*>::iterator it = std::find(
1168 layers_with_copy_output_request_.begin(),
1169 layers_with_copy_output_request_.end(),
1170 layer);
1171 DCHECK(it != layers_with_copy_output_request_.end());
[email protected]f5de9e5b2013-07-30 22:26:571172 layers_with_copy_output_request_.erase(it);
[email protected]a4ee12812014-02-06 17:33:381173
1174 // TODO(danakj): Remove this once crash is found crbug.com/309777
1175 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1176 CHECK(layers_with_copy_output_request_[i] != layer)
1177 << i << " of " << layers_with_copy_output_request_.size();
1178 }
[email protected]30fe19ff2013-07-04 00:54:451179}
1180
[email protected]53526372013-12-07 04:31:501181const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
[email protected]30fe19ff2013-07-04 00:54:451182 const {
1183 // Only the active tree needs to know about layers with copy requests, as
1184 // they are aborted if not serviced during draw.
1185 DCHECK(IsActiveTree());
1186
1187 return layers_with_copy_output_request_;
1188}
1189
[email protected]28336d52014-05-12 19:07:281190template <typename LayerType>
1191static inline bool LayerClipsSubtree(LayerType* layer) {
1192 return layer->masks_to_bounds() || layer->mask_layer();
1193}
1194
1195static bool PointHitsRect(
1196 const gfx::PointF& screen_space_point,
1197 const gfx::Transform& local_space_to_screen_space_transform,
1198 const gfx::RectF& local_space_rect,
1199 float* distance_to_camera) {
1200 // If the transform is not invertible, then assume that this point doesn't hit
1201 // this rect.
1202 gfx::Transform inverse_local_space_to_screen_space(
1203 gfx::Transform::kSkipInitialization);
1204 if (!local_space_to_screen_space_transform.GetInverse(
1205 &inverse_local_space_to_screen_space))
1206 return false;
1207
1208 // Transform the hit test point from screen space to the local space of the
1209 // given rect.
1210 bool clipped = false;
1211 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1212 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1213 gfx::PointF hit_test_point_in_local_space =
1214 gfx::PointF(planar_point.x(), planar_point.y());
1215
1216 // If ProjectPoint could not project to a valid value, then we assume that
1217 // this point doesn't hit this rect.
1218 if (clipped)
1219 return false;
1220
1221 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1222 return false;
1223
1224 if (distance_to_camera) {
1225 // To compute the distance to the camera, we have to take the planar point
1226 // and pull it back to world space and compute the displacement along the
1227 // z-axis.
1228 gfx::Point3F planar_point_in_screen_space(planar_point);
1229 local_space_to_screen_space_transform.TransformPoint(
1230 &planar_point_in_screen_space);
1231 *distance_to_camera = planar_point_in_screen_space.z();
1232 }
1233
1234 return true;
1235}
1236
1237static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1238 const gfx::Transform& screen_space_transform,
1239 const Region& layer_space_region,
1240 float layer_content_scale_x,
1241 float layer_content_scale_y) {
1242 // If the transform is not invertible, then assume that this point doesn't hit
1243 // this region.
1244 gfx::Transform inverse_screen_space_transform(
1245 gfx::Transform::kSkipInitialization);
1246 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1247 return false;
1248
1249 // Transform the hit test point from screen space to the local space of the
1250 // given region.
1251 bool clipped = false;
1252 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1253 inverse_screen_space_transform, screen_space_point, &clipped);
1254 gfx::PointF hit_test_point_in_layer_space =
1255 gfx::ScalePoint(hit_test_point_in_content_space,
1256 1.f / layer_content_scale_x,
1257 1.f / layer_content_scale_y);
1258
1259 // If ProjectPoint could not project to a valid value, then we assume that
1260 // this point doesn't hit this region.
1261 if (clipped)
1262 return false;
1263
1264 return layer_space_region.Contains(
1265 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1266}
1267
[email protected]19aec372014-07-01 19:08:491268static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
[email protected]0ec86f52014-06-12 20:54:031269 if (layer->scroll_parent())
1270 return layer->scroll_parent();
1271 if (layer->clip_parent())
1272 return layer->clip_parent();
1273 return layer->parent();
1274}
1275
[email protected]28336d52014-05-12 19:07:281276static bool PointIsClippedBySurfaceOrClipRect(
1277 const gfx::PointF& screen_space_point,
[email protected]19aec372014-07-01 19:08:491278 const LayerImpl* layer) {
[email protected]28336d52014-05-12 19:07:281279 // Walk up the layer tree and hit-test any render_surfaces and any layer
1280 // clip rects that are active.
[email protected]0ec86f52014-06-12 20:54:031281 for (; layer; layer = GetNextClippingLayer(layer)) {
1282 if (layer->render_surface() &&
1283 !PointHitsRect(screen_space_point,
1284 layer->render_surface()->screen_space_transform(),
1285 layer->render_surface()->content_rect(),
1286 NULL))
[email protected]28336d52014-05-12 19:07:281287 return true;
1288
[email protected]0ec86f52014-06-12 20:54:031289 if (LayerClipsSubtree(layer) &&
1290 !PointHitsRect(screen_space_point,
1291 layer->screen_space_transform(),
1292 gfx::Rect(layer->content_bounds()),
1293 NULL))
[email protected]28336d52014-05-12 19:07:281294 return true;
[email protected]28336d52014-05-12 19:07:281295 }
1296
1297 // If we have finished walking all ancestors without having already exited,
1298 // then the point is not clipped by any ancestors.
1299 return false;
1300}
1301
[email protected]19aec372014-07-01 19:08:491302static bool PointHitsLayer(const LayerImpl* layer,
[email protected]28336d52014-05-12 19:07:281303 const gfx::PointF& screen_space_point,
1304 float* distance_to_intersection) {
1305 gfx::RectF content_rect(layer->content_bounds());
1306 if (!PointHitsRect(screen_space_point,
1307 layer->screen_space_transform(),
1308 content_rect,
1309 distance_to_intersection))
1310 return false;
1311
1312 // At this point, we think the point does hit the layer, but we need to walk
1313 // up the parents to ensure that the layer was not clipped in such a way
1314 // that the hit point actually should not hit the layer.
1315 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1316 return false;
1317
1318 // Skip the HUD layer.
1319 if (layer == layer->layer_tree_impl()->hud_layer())
1320 return false;
1321
1322 return true;
1323}
1324
1325struct FindClosestMatchingLayerDataForRecursion {
1326 FindClosestMatchingLayerDataForRecursion()
1327 : closest_match(NULL),
1328 closest_distance(-std::numeric_limits<float>::infinity()) {}
1329 LayerImpl* closest_match;
1330 // Note that the positive z-axis points towards the camera, so bigger means
1331 // closer in this case, counterintuitively.
1332 float closest_distance;
1333};
1334
1335template <typename Functor>
1336static void FindClosestMatchingLayer(
1337 const gfx::PointF& screen_space_point,
1338 LayerImpl* layer,
1339 const Functor& func,
1340 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
1341 for (int i = layer->children().size() - 1; i >= 0; --i) {
1342 FindClosestMatchingLayer(
1343 screen_space_point, layer->children()[i], func, data_for_recursion);
1344 }
1345
1346 float distance_to_intersection = 0.f;
1347 if (func(layer) &&
1348 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1349 ((!data_for_recursion->closest_match ||
1350 distance_to_intersection > data_for_recursion->closest_distance))) {
1351 data_for_recursion->closest_distance = distance_to_intersection;
1352 data_for_recursion->closest_match = layer;
1353 }
1354}
1355
1356static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1357 if (!layer->scrollable())
1358 return false;
majidvp6cfcc362015-03-06 20:46:391359 if (layer->draw_properties().layer_or_descendant_is_drawn)
[email protected]28336d52014-05-12 19:07:281360 return true;
majidvp6cfcc362015-03-06 20:46:391361
[email protected]28336d52014-05-12 19:07:281362 if (!layer->scroll_children())
1363 return false;
1364 for (std::set<LayerImpl*>::const_iterator it =
1365 layer->scroll_children()->begin();
1366 it != layer->scroll_children()->end();
1367 ++it) {
majidvp6cfcc362015-03-06 20:46:391368 if ((*it)->draw_properties().layer_or_descendant_is_drawn)
[email protected]28336d52014-05-12 19:07:281369 return true;
1370 }
1371 return false;
1372}
1373
1374struct FindScrollingLayerFunctor {
1375 bool operator()(LayerImpl* layer) const {
1376 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1377 }
1378};
1379
1380LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1381 const gfx::PointF& screen_space_point) {
1382 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1383 FindClosestMatchingLayer(screen_space_point,
1384 root_layer(),
1385 FindScrollingLayerFunctor(),
1386 &data_for_recursion);
1387 return data_for_recursion.closest_match;
1388}
1389
1390struct HitTestVisibleScrollableOrTouchableFunctor {
1391 bool operator()(LayerImpl* layer) const {
1392 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1393 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1394 !layer->touch_event_handler_region().IsEmpty() ||
1395 layer->have_wheel_event_handlers();
1396 }
1397};
1398
1399LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1400 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321401 if (!root_layer())
1402 return NULL;
enneaf5bda32015-02-19 01:27:361403 bool update_lcd_text = false;
1404 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321405 return NULL;
[email protected]28336d52014-05-12 19:07:281406 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1407 FindClosestMatchingLayer(screen_space_point,
1408 root_layer(),
1409 HitTestVisibleScrollableOrTouchableFunctor(),
1410 &data_for_recursion);
1411 return data_for_recursion.closest_match;
1412}
1413
1414static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1415 LayerImpl* layer_impl) {
1416 if (layer_impl->touch_event_handler_region().IsEmpty())
1417 return false;
1418
1419 if (!PointHitsRegion(screen_space_point,
1420 layer_impl->screen_space_transform(),
1421 layer_impl->touch_event_handler_region(),
1422 layer_impl->contents_scale_x(),
1423 layer_impl->contents_scale_y()))
1424 return false;
1425
1426 // At this point, we think the point does hit the touch event handler region
1427 // on the layer, but we need to walk up the parents to ensure that the layer
1428 // was not clipped in such a way that the hit point actually should not hit
1429 // the layer.
1430 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1431 return false;
1432
1433 return true;
1434}
1435
ccameron3b607362015-02-02 22:46:291436struct FindWheelEventLayerFunctor {
1437 bool operator()(LayerImpl* layer) const {
1438 return layer->have_wheel_event_handlers();
1439 }
1440};
1441
1442LayerImpl* LayerTreeImpl::FindLayerWithWheelHandlerThatIsHitByPoint(
1443 const gfx::PointF& screen_space_point) {
1444 if (!root_layer())
1445 return NULL;
enneaf5bda32015-02-19 01:27:361446 bool update_lcd_text = false;
1447 if (!UpdateDrawProperties(update_lcd_text))
ccameron3b607362015-02-02 22:46:291448 return NULL;
1449 FindWheelEventLayerFunctor func;
1450 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1451 FindClosestMatchingLayer(screen_space_point, root_layer(), func,
1452 &data_for_recursion);
1453 return data_for_recursion.closest_match;
1454}
1455
[email protected]28336d52014-05-12 19:07:281456struct FindTouchEventLayerFunctor {
1457 bool operator()(LayerImpl* layer) const {
1458 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1459 }
1460 const gfx::PointF screen_space_point;
1461};
1462
1463LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1464 const gfx::PointF& screen_space_point) {
[email protected]8f7f298822014-06-13 00:23:321465 if (!root_layer())
1466 return NULL;
enneaf5bda32015-02-19 01:27:361467 bool update_lcd_text = false;
1468 if (!UpdateDrawProperties(update_lcd_text))
[email protected]8f7f298822014-06-13 00:23:321469 return NULL;
[email protected]28336d52014-05-12 19:07:281470 FindTouchEventLayerFunctor func = {screen_space_point};
1471 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1472 FindClosestMatchingLayer(
1473 screen_space_point, root_layer(), func, &data_for_recursion);
1474 return data_for_recursion.closest_match;
1475}
1476
[email protected]ebb179b2014-07-16 17:54:411477void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& start,
1478 const LayerSelectionBound& end) {
1479 selection_start_ = start;
1480 selection_end_ = end;
[email protected]19aec372014-07-01 19:08:491481}
1482
1483static ViewportSelectionBound ComputeViewportSelection(
[email protected]6ef948732014-08-22 18:57:441484 const LayerSelectionBound& layer_bound,
[email protected]19aec372014-07-01 19:08:491485 LayerImpl* layer,
1486 float device_scale_factor) {
[email protected]6ef948732014-08-22 18:57:441487 ViewportSelectionBound viewport_bound;
1488 viewport_bound.type = layer_bound.type;
[email protected]19aec372014-07-01 19:08:491489
[email protected]6ef948732014-08-22 18:57:441490 if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY)
1491 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491492
[email protected]6ef948732014-08-22 18:57:441493 gfx::PointF layer_scaled_top = gfx::ScalePoint(layer_bound.edge_top,
1494 layer->contents_scale_x(),
1495 layer->contents_scale_y());
1496 gfx::PointF layer_scaled_bottom = gfx::ScalePoint(layer_bound.edge_bottom,
1497 layer->contents_scale_x(),
1498 layer->contents_scale_y());
[email protected]19aec372014-07-01 19:08:491499
[email protected]6ef948732014-08-22 18:57:441500 bool clipped = false;
1501 gfx::PointF screen_top = MathUtil::MapPoint(
1502 layer->screen_space_transform(), layer_scaled_top, &clipped);
1503 gfx::PointF screen_bottom = MathUtil::MapPoint(
1504 layer->screen_space_transform(), layer_scaled_bottom, &clipped);
1505
1506 const float inv_scale = 1.f / device_scale_factor;
1507 viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale);
1508 viewport_bound.edge_bottom = gfx::ScalePoint(screen_bottom, inv_scale);
1509
1510 // The bottom edge point is used for visibility testing as it is the logical
[email protected]19aec372014-07-01 19:08:491511 // focal point for bound selection handles (this may change in the future).
[email protected]6ef948732014-08-22 18:57:441512 // Shifting the visibility point fractionally inward ensures that neighboring
1513 // or logically coincident layers aligned to integral DPI coordinates will not
1514 // spuriously occlude the bound.
1515 gfx::Vector2dF visibility_offset = layer_scaled_top - layer_scaled_bottom;
1516 visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
1517 gfx::PointF visibility_point = layer_scaled_bottom + visibility_offset;
1518 if (visibility_point.x() <= 0)
1519 visibility_point.set_x(visibility_point.x() + device_scale_factor);
1520 visibility_point = MathUtil::MapPoint(
1521 layer->screen_space_transform(), visibility_point, &clipped);
1522
[email protected]19aec372014-07-01 19:08:491523 float intersect_distance = 0.f;
[email protected]6ef948732014-08-22 18:57:441524 viewport_bound.visible =
1525 PointHitsLayer(layer, visibility_point, &intersect_distance);
[email protected]19aec372014-07-01 19:08:491526
[email protected]6ef948732014-08-22 18:57:441527 return viewport_bound;
[email protected]19aec372014-07-01 19:08:491528}
1529
[email protected]ebb179b2014-07-16 17:54:411530void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* start,
1531 ViewportSelectionBound* end) {
1532 DCHECK(start);
1533 DCHECK(end);
[email protected]19aec372014-07-01 19:08:491534
[email protected]ebb179b2014-07-16 17:54:411535 *start = ComputeViewportSelection(
1536 selection_start_,
1537 selection_start_.layer_id ? LayerById(selection_start_.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491538 device_scale_factor());
[email protected]ebb179b2014-07-16 17:54:411539 if (start->type == SELECTION_BOUND_CENTER ||
1540 start->type == SELECTION_BOUND_EMPTY) {
1541 *end = *start;
[email protected]19aec372014-07-01 19:08:491542 } else {
[email protected]ebb179b2014-07-16 17:54:411543 *end = ComputeViewportSelection(
1544 selection_end_,
1545 selection_end_.layer_id ? LayerById(selection_end_.layer_id) : NULL,
[email protected]19aec372014-07-01 19:08:491546 device_scale_factor());
1547 }
1548}
1549
[email protected]749cbc62014-07-10 01:06:351550void LayerTreeImpl::InputScrollAnimationFinished() {
1551 layer_tree_host_impl_->ScrollEnd();
1552}
1553
vmpstr56ace232014-10-09 20:16:281554bool LayerTreeImpl::SmoothnessTakesPriority() const {
1555 return layer_tree_host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY;
1556}
1557
skyostil3976a3f2014-09-04 22:07:231558BlockingTaskRunner* LayerTreeImpl::BlockingMainThreadTaskRunner() const {
1559 return proxy()->blocking_main_thread_task_runner();
1560}
1561
sunnyps7d073dc2015-04-16 23:29:121562VideoFrameControllerClient* LayerTreeImpl::GetVideoFrameControllerClient()
1563 const {
1564 return layer_tree_host_impl_;
1565}
1566
bokanfcdbc182014-11-21 21:53:331567void LayerTreeImpl::SetPendingPageScaleAnimation(
1568 scoped_ptr<PendingPageScaleAnimation> pending_animation) {
1569 pending_page_scale_animation_ = pending_animation.Pass();
bokan915bf352014-10-02 21:57:141570}
1571
bokanfcdbc182014-11-21 21:53:331572scoped_ptr<PendingPageScaleAnimation>
1573 LayerTreeImpl::TakePendingPageScaleAnimation() {
1574 return pending_page_scale_animation_.Pass();
bokan915bf352014-10-02 21:57:141575}
1576
[email protected]ca2902e92013-03-28 01:45:351577} // namespace cc