1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/trees/layer_tree_impl.h"
6
7 #include <limits>
8 #include <set>
9
10 #include "base/debug/trace_event.h"
11 #include "cc/animation/keyframed_animation_curve.h"
12 #include "cc/animation/scrollbar_animation_controller.h"
13 #include "cc/animation/scrollbar_animation_controller_linear_fade.h"
14 #include "cc/animation/scrollbar_animation_controller_thinning.h"
15 #include "cc/base/math_util.h"
16 #include "cc/base/util.h"
17 #include "cc/debug/devtools_instrumentation.h"
18 #include "cc/debug/traced_value.h"
19 #include "cc/layers/heads_up_display_layer_impl.h"
20 #include "cc/layers/layer.h"
21 #include "cc/layers/layer_iterator.h"
22 #include "cc/layers/render_surface_impl.h"
23 #include "cc/layers/scrollbar_layer_impl_base.h"
24 #include "cc/resources/ui_resource_request.h"
25 #include "cc/trees/layer_tree_host_common.h"
26 #include "cc/trees/layer_tree_host_impl.h"
27 #include "ui/gfx/point_conversions.h"
28 #include "ui/gfx/size_conversions.h"
29 #include "ui/gfx/vector2d_conversions.h"
30
31 namespace cc {
32
33 // This class exists to split the LayerScrollOffsetDelegate between the
34 // InnerViewportScrollLayer and the OuterViewportScrollLayer in a manner
35 // that never requires the embedder or LayerImpl to know about.
36 class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
37 public:
LayerScrollOffsetDelegateProxy(LayerImpl * layer,LayerScrollOffsetDelegate * delegate,LayerTreeImpl * layer_tree)38 LayerScrollOffsetDelegateProxy(LayerImpl* layer,
39 LayerScrollOffsetDelegate* delegate,
40 LayerTreeImpl* layer_tree)
41 : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {}
~LayerScrollOffsetDelegateProxy()42 virtual ~LayerScrollOffsetDelegateProxy() {}
43
last_set_scroll_offset() const44 gfx::Vector2dF last_set_scroll_offset() const {
45 return last_set_scroll_offset_;
46 }
47
48 // LayerScrollOffsetDelegate implementation.
SetTotalScrollOffset(const gfx::Vector2dF & new_offset)49 virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_offset) OVERRIDE {
50 last_set_scroll_offset_ = new_offset;
51 layer_tree_impl_->UpdateScrollOffsetDelegate();
52 }
53
GetTotalScrollOffset()54 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
55 return layer_tree_impl_->GetDelegatedScrollOffset(layer_);
56 }
57
IsExternalFlingActive() const58 virtual bool IsExternalFlingActive() const OVERRIDE {
59 return delegate_->IsExternalFlingActive();
60 }
61
62 private:
63 LayerImpl* layer_;
64 LayerScrollOffsetDelegate* delegate_;
65 LayerTreeImpl* layer_tree_impl_;
66 gfx::Vector2dF last_set_scroll_offset_;
67 };
68
LayerTreeImpl(LayerTreeHostImpl * layer_tree_host_impl)69 LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
70 : layer_tree_host_impl_(layer_tree_host_impl),
71 source_frame_number_(-1),
72 hud_layer_(0),
73 currently_scrolling_layer_(NULL),
74 root_layer_scroll_offset_delegate_(NULL),
75 background_color_(0),
76 has_transparent_background_(false),
77 page_scale_layer_(NULL),
78 inner_viewport_scroll_layer_(NULL),
79 outer_viewport_scroll_layer_(NULL),
80 page_scale_factor_(1),
81 page_scale_delta_(1),
82 sent_page_scale_delta_(1),
83 min_page_scale_factor_(0),
84 max_page_scale_factor_(0),
85 scrolling_layer_id_from_previous_tree_(0),
86 contents_textures_purged_(false),
87 requires_high_res_to_draw_(false),
88 viewport_size_invalid_(false),
89 needs_update_draw_properties_(true),
90 needs_full_tree_sync_(true),
91 next_activation_forces_redraw_(false),
92 render_surface_layer_list_id_(0) {
93 }
94
~LayerTreeImpl()95 LayerTreeImpl::~LayerTreeImpl() {
96 // Need to explicitly clear the tree prior to destroying this so that
97 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
98 DCHECK(!root_layer_);
99 DCHECK(layers_with_copy_output_request_.empty());
100 }
101
Shutdown()102 void LayerTreeImpl::Shutdown() { root_layer_.reset(); }
103
ReleaseResources()104 void LayerTreeImpl::ReleaseResources() {
105 if (root_layer_)
106 ReleaseResourcesRecursive(root_layer_.get());
107 }
108
SetRootLayer(scoped_ptr<LayerImpl> layer)109 void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
110 if (inner_viewport_scroll_layer_)
111 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
112 if (outer_viewport_scroll_layer_)
113 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
114 inner_viewport_scroll_delegate_proxy_.reset();
115 outer_viewport_scroll_delegate_proxy_.reset();
116
117 root_layer_ = layer.Pass();
118 currently_scrolling_layer_ = NULL;
119 inner_viewport_scroll_layer_ = NULL;
120 outer_viewport_scroll_layer_ = NULL;
121 page_scale_layer_ = NULL;
122
123 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
124 }
125
InnerViewportScrollLayer() const126 LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
127 return inner_viewport_scroll_layer_;
128 }
129
OuterViewportScrollLayer() const130 LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
131 return outer_viewport_scroll_layer_;
132 }
133
TotalScrollOffset() const134 gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const {
135 gfx::Vector2dF offset;
136
137 if (inner_viewport_scroll_layer_)
138 offset += inner_viewport_scroll_layer_->TotalScrollOffset();
139
140 if (outer_viewport_scroll_layer_)
141 offset += outer_viewport_scroll_layer_->TotalScrollOffset();
142
143 return offset;
144 }
145
TotalMaxScrollOffset() const146 gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const {
147 gfx::Vector2dF offset;
148
149 if (inner_viewport_scroll_layer_)
150 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
151
152 if (outer_viewport_scroll_layer_)
153 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
154
155 return offset;
156 }
TotalScrollDelta() const157 gfx::Vector2dF LayerTreeImpl::TotalScrollDelta() const {
158 DCHECK(inner_viewport_scroll_layer_);
159 gfx::Vector2dF delta = inner_viewport_scroll_layer_->ScrollDelta();
160
161 if (outer_viewport_scroll_layer_)
162 delta += outer_viewport_scroll_layer_->ScrollDelta();
163
164 return delta;
165 }
166
DetachLayerTree()167 scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
168 // Clear all data structures that have direct references to the layer tree.
169 scrolling_layer_id_from_previous_tree_ =
170 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
171 if (inner_viewport_scroll_layer_)
172 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
173 if (outer_viewport_scroll_layer_)
174 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
175 inner_viewport_scroll_delegate_proxy_.reset();
176 outer_viewport_scroll_delegate_proxy_.reset();
177 inner_viewport_scroll_layer_ = NULL;
178 outer_viewport_scroll_layer_ = NULL;
179 page_scale_layer_ = NULL;
180 currently_scrolling_layer_ = NULL;
181
182 render_surface_layer_list_.clear();
183 set_needs_update_draw_properties();
184 return root_layer_.Pass();
185 }
186
PushPropertiesTo(LayerTreeImpl * target_tree)187 void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
188 // The request queue should have been processed and does not require a push.
189 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
190
191 if (next_activation_forces_redraw_) {
192 target_tree->ForceRedrawNextActivation();
193 next_activation_forces_redraw_ = false;
194 }
195
196 target_tree->PassSwapPromises(&swap_promise_list_);
197
198 target_tree->SetPageScaleValues(
199 page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(),
200 target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
201 target_tree->set_sent_page_scale_delta(1);
202
203 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
204 target_tree->SetViewportLayersFromIds(
205 page_scale_layer_->id(),
206 inner_viewport_scroll_layer_->id(),
207 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
208 : Layer::INVALID_ID);
209 } else {
210 target_tree->ClearViewportLayers();
211 }
212 // This should match the property synchronization in
213 // LayerTreeHost::finishCommitOnImplThread().
214 target_tree->set_source_frame_number(source_frame_number());
215 target_tree->set_background_color(background_color());
216 target_tree->set_has_transparent_background(has_transparent_background());
217
218 if (ContentsTexturesPurged())
219 target_tree->SetContentsTexturesPurged();
220 else
221 target_tree->ResetContentsTexturesPurged();
222
223 // Always reset this flag on activation, as we would only have activated
224 // if we were in a good state.
225 target_tree->ResetRequiresHighResToDraw();
226
227 if (ViewportSizeInvalid())
228 target_tree->SetViewportSizeInvalid();
229 else
230 target_tree->ResetViewportSizeInvalid();
231
232 if (hud_layer())
233 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
234 LayerTreeHostCommon::FindLayerInSubtree(
235 target_tree->root_layer(), hud_layer()->id())));
236 else
237 target_tree->set_hud_layer(NULL);
238 }
239
InnerViewportContainerLayer() const240 LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
241 return inner_viewport_scroll_layer_
242 ? inner_viewport_scroll_layer_->scroll_clip_layer()
243 : NULL;
244 }
245
CurrentlyScrollingLayer() const246 LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
247 DCHECK(IsActiveTree());
248 return currently_scrolling_layer_;
249 }
250
SetCurrentlyScrollingLayer(LayerImpl * layer)251 void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
252 if (currently_scrolling_layer_ == layer)
253 return;
254
255 if (currently_scrolling_layer_ &&
256 currently_scrolling_layer_->scrollbar_animation_controller())
257 currently_scrolling_layer_->scrollbar_animation_controller()
258 ->DidScrollEnd();
259 currently_scrolling_layer_ = layer;
260 if (layer && layer->scrollbar_animation_controller())
261 layer->scrollbar_animation_controller()->DidScrollBegin();
262 }
263
ClearCurrentlyScrollingLayer()264 void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
265 SetCurrentlyScrollingLayer(NULL);
266 scrolling_layer_id_from_previous_tree_ = 0;
267 }
268
VerticalAdjust(const int clip_layer_id) const269 float LayerTreeImpl::VerticalAdjust(const int clip_layer_id) const {
270 LayerImpl* container_layer = InnerViewportContainerLayer();
271 if (!container_layer || clip_layer_id != container_layer->id())
272 return 0.f;
273
274 return layer_tree_host_impl_->VerticalAdjust();
275 }
276
277 namespace {
278
ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl * current_layer)279 void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
280 if (!current_layer)
281 return;
282
283 while (current_layer) {
284 current_layer->ScrollbarParametersDidChange();
285 current_layer = current_layer->parent();
286 }
287 }
288
289 } // namespace
290
SetPageScaleFactorAndLimits(float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)291 void LayerTreeImpl::SetPageScaleFactorAndLimits(float page_scale_factor,
292 float min_page_scale_factor, float max_page_scale_factor) {
293 SetPageScaleValues(page_scale_factor, min_page_scale_factor,
294 max_page_scale_factor, page_scale_delta_);
295 }
296
SetPageScaleDelta(float delta)297 void LayerTreeImpl::SetPageScaleDelta(float delta) {
298 SetPageScaleValues(page_scale_factor_, min_page_scale_factor_,
299 max_page_scale_factor_, delta);
300 }
301
SetPageScaleValues(float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor,float page_scale_delta)302 void LayerTreeImpl::SetPageScaleValues(float page_scale_factor,
303 float min_page_scale_factor, float max_page_scale_factor,
304 float page_scale_delta) {
305 bool page_scale_changed =
306 min_page_scale_factor != min_page_scale_factor_ ||
307 max_page_scale_factor != max_page_scale_factor_ ||
308 page_scale_factor != page_scale_factor_;
309
310 min_page_scale_factor_ = min_page_scale_factor;
311 max_page_scale_factor_ = max_page_scale_factor;
312 page_scale_factor_ = page_scale_factor;
313
314 float total = page_scale_factor_ * page_scale_delta;
315 if (min_page_scale_factor_ && total < min_page_scale_factor_)
316 page_scale_delta = min_page_scale_factor_ / page_scale_factor_;
317 else if (max_page_scale_factor_ && total > max_page_scale_factor_)
318 page_scale_delta = max_page_scale_factor_ / page_scale_factor_;
319
320 if (page_scale_delta_ == page_scale_delta && !page_scale_changed)
321 return;
322
323 if (page_scale_delta_ != page_scale_delta) {
324 page_scale_delta_ = page_scale_delta;
325
326 if (IsActiveTree()) {
327 LayerTreeImpl* pending_tree = layer_tree_host_impl_->pending_tree();
328 if (pending_tree) {
329 DCHECK_EQ(1, pending_tree->sent_page_scale_delta());
330 pending_tree->SetPageScaleDelta(
331 page_scale_delta_ / sent_page_scale_delta_);
332 }
333 }
334
335 set_needs_update_draw_properties();
336 }
337
338 if (root_layer_scroll_offset_delegate_) {
339 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
340 TotalScrollOffset(),
341 TotalMaxScrollOffset(),
342 ScrollableSize(),
343 total_page_scale_factor(),
344 min_page_scale_factor_,
345 max_page_scale_factor_);
346 }
347
348 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
349 }
350
ScrollableViewportSize() const351 gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
352 if (outer_viewport_scroll_layer_)
353 return layer_tree_host_impl_->UnscaledScrollableViewportSize();
354 else
355 return gfx::ScaleSize(
356 layer_tree_host_impl_->UnscaledScrollableViewportSize(),
357 1.0f / total_page_scale_factor());
358 }
359
RootScrollLayerDeviceViewportBounds() const360 gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
361 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
362 ? OuterViewportScrollLayer()
363 : InnerViewportScrollLayer();
364 if (!root_scroll_layer || root_scroll_layer->children().empty())
365 return gfx::Rect();
366 LayerImpl* layer = root_scroll_layer->children()[0];
367 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
368 gfx::Rect(layer->content_bounds()));
369 }
370
ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl * layer)371 static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) {
372 layer->ApplySentScrollDeltasFromAbortedCommit();
373 }
374
ApplySentScrollAndScaleDeltasFromAbortedCommit()375 void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
376 DCHECK(IsActiveTree());
377
378 page_scale_factor_ *= sent_page_scale_delta_;
379 page_scale_delta_ /= sent_page_scale_delta_;
380 sent_page_scale_delta_ = 1.f;
381
382 if (!root_layer())
383 return;
384
385 LayerTreeHostCommon::CallFunctionForSubtree(
386 root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo));
387 }
388
ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl * layer)389 static void ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl* layer) {
390 layer->ApplyScrollDeltasSinceBeginMainFrame();
391 }
392
ApplyScrollDeltasSinceBeginMainFrame()393 void LayerTreeImpl::ApplyScrollDeltasSinceBeginMainFrame() {
394 DCHECK(IsPendingTree());
395 if (!root_layer())
396 return;
397
398 LayerTreeHostCommon::CallFunctionForSubtree(
399 root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginMainFrameTo));
400 }
401
SetViewportLayersFromIds(int page_scale_layer_id,int inner_viewport_scroll_layer_id,int outer_viewport_scroll_layer_id)402 void LayerTreeImpl::SetViewportLayersFromIds(
403 int page_scale_layer_id,
404 int inner_viewport_scroll_layer_id,
405 int outer_viewport_scroll_layer_id) {
406 page_scale_layer_ = LayerById(page_scale_layer_id);
407 DCHECK(page_scale_layer_);
408
409 inner_viewport_scroll_layer_ =
410 LayerById(inner_viewport_scroll_layer_id);
411 DCHECK(inner_viewport_scroll_layer_);
412
413 outer_viewport_scroll_layer_ =
414 LayerById(outer_viewport_scroll_layer_id);
415 DCHECK(outer_viewport_scroll_layer_ ||
416 outer_viewport_scroll_layer_id == Layer::INVALID_ID);
417
418 if (!root_layer_scroll_offset_delegate_)
419 return;
420
421 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
422 new LayerScrollOffsetDelegateProxy(inner_viewport_scroll_layer_,
423 root_layer_scroll_offset_delegate_,
424 this));
425
426 if (outer_viewport_scroll_layer_)
427 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
428 new LayerScrollOffsetDelegateProxy(outer_viewport_scroll_layer_,
429 root_layer_scroll_offset_delegate_,
430 this));
431 }
432
ClearViewportLayers()433 void LayerTreeImpl::ClearViewportLayers() {
434 page_scale_layer_ = NULL;
435 inner_viewport_scroll_layer_ = NULL;
436 outer_viewport_scroll_layer_ = NULL;
437 }
438
UpdateDrawProperties()439 bool LayerTreeImpl::UpdateDrawProperties() {
440 if (!needs_update_draw_properties_)
441 return true;
442
443 // For max_texture_size.
444 if (!layer_tree_host_impl_->renderer())
445 return false;
446
447 if (!root_layer())
448 return false;
449
450 needs_update_draw_properties_ = false;
451 render_surface_layer_list_.clear();
452
453 {
454 TRACE_EVENT2("cc",
455 "LayerTreeImpl::UpdateDrawProperties",
456 "IsActive",
457 IsActiveTree(),
458 "SourceFrameNumber",
459 source_frame_number_);
460 LayerImpl* page_scale_layer =
461 page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
462 bool can_render_to_separate_surface = !resourceless_software_draw();
463
464 ++render_surface_layer_list_id_;
465 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
466 root_layer(),
467 DrawViewportSize(),
468 layer_tree_host_impl_->DrawTransform(),
469 device_scale_factor(),
470 total_page_scale_factor(),
471 page_scale_layer,
472 MaxTextureSize(),
473 settings().can_use_lcd_text,
474 can_render_to_separate_surface,
475 settings().layer_transforms_should_scale_layer_contents,
476 &render_surface_layer_list_,
477 render_surface_layer_list_id_);
478 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
479 }
480
481 {
482 TRACE_EVENT2("cc",
483 "LayerTreeImpl::UpdateTilePriorities",
484 "IsActive",
485 IsActiveTree(),
486 "SourceFrameNumber",
487 source_frame_number_);
488 // LayerIterator is used here instead of CallFunctionForSubtree to only
489 // UpdateTilePriorities on layers that will be visible (and thus have valid
490 // draw properties) and not because any ordering is required.
491 typedef LayerIterator<LayerImpl> LayerIteratorType;
492 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
493 for (LayerIteratorType it =
494 LayerIteratorType::Begin(&render_surface_layer_list_);
495 it != end;
496 ++it) {
497 LayerImpl* layer = *it;
498 if (it.represents_itself())
499 layer->UpdateTiles();
500
501 if (!it.represents_contributing_render_surface())
502 continue;
503
504 if (layer->mask_layer())
505 layer->mask_layer()->UpdateTiles();
506 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
507 layer->replica_layer()->mask_layer()->UpdateTiles();
508 }
509 }
510
511 DCHECK(!needs_update_draw_properties_) <<
512 "CalcDrawProperties should not set_needs_update_draw_properties()";
513 return true;
514 }
515
RenderSurfaceLayerList() const516 const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
517 // If this assert triggers, then the list is dirty.
518 DCHECK(!needs_update_draw_properties_);
519 return render_surface_layer_list_;
520 }
521
ScrollableSize() const522 gfx::Size LayerTreeImpl::ScrollableSize() const {
523 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
524 ? OuterViewportScrollLayer()
525 : InnerViewportScrollLayer();
526 if (!root_scroll_layer || root_scroll_layer->children().empty())
527 return gfx::Size();
528 return root_scroll_layer->children()[0]->bounds();
529 }
530
LayerById(int id)531 LayerImpl* LayerTreeImpl::LayerById(int id) {
532 LayerIdMap::iterator iter = layer_id_map_.find(id);
533 return iter != layer_id_map_.end() ? iter->second : NULL;
534 }
535
RegisterLayer(LayerImpl * layer)536 void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
537 DCHECK(!LayerById(layer->id()));
538 layer_id_map_[layer->id()] = layer;
539 }
540
UnregisterLayer(LayerImpl * layer)541 void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
542 DCHECK(LayerById(layer->id()));
543 layer_id_map_.erase(layer->id());
544 }
545
PushPersistedState(LayerTreeImpl * pending_tree)546 void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
547 pending_tree->SetCurrentlyScrollingLayer(
548 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
549 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
550 }
551
DidBecomeActiveRecursive(LayerImpl * layer)552 static void DidBecomeActiveRecursive(LayerImpl* layer) {
553 layer->DidBecomeActive();
554 for (size_t i = 0; i < layer->children().size(); ++i)
555 DidBecomeActiveRecursive(layer->children()[i]);
556 }
557
DidBecomeActive()558 void LayerTreeImpl::DidBecomeActive() {
559 if (!root_layer())
560 return;
561
562 if (next_activation_forces_redraw_) {
563 layer_tree_host_impl_->SetFullRootLayerDamage();
564 next_activation_forces_redraw_ = false;
565 }
566
567 if (scrolling_layer_id_from_previous_tree_) {
568 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
569 root_layer_.get(), scrolling_layer_id_from_previous_tree_);
570 }
571
572 DidBecomeActiveRecursive(root_layer());
573 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
574 source_frame_number_);
575 }
576
ContentsTexturesPurged() const577 bool LayerTreeImpl::ContentsTexturesPurged() const {
578 return contents_textures_purged_;
579 }
580
SetContentsTexturesPurged()581 void LayerTreeImpl::SetContentsTexturesPurged() {
582 if (contents_textures_purged_)
583 return;
584 contents_textures_purged_ = true;
585 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
586 }
587
ResetContentsTexturesPurged()588 void LayerTreeImpl::ResetContentsTexturesPurged() {
589 if (!contents_textures_purged_)
590 return;
591 contents_textures_purged_ = false;
592 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
593 }
594
SetRequiresHighResToDraw()595 void LayerTreeImpl::SetRequiresHighResToDraw() {
596 requires_high_res_to_draw_ = true;
597 }
598
ResetRequiresHighResToDraw()599 void LayerTreeImpl::ResetRequiresHighResToDraw() {
600 requires_high_res_to_draw_ = false;
601 }
602
RequiresHighResToDraw() const603 bool LayerTreeImpl::RequiresHighResToDraw() const {
604 return requires_high_res_to_draw_;
605 }
606
ViewportSizeInvalid() const607 bool LayerTreeImpl::ViewportSizeInvalid() const {
608 return viewport_size_invalid_;
609 }
610
SetViewportSizeInvalid()611 void LayerTreeImpl::SetViewportSizeInvalid() {
612 viewport_size_invalid_ = true;
613 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
614 }
615
ResetViewportSizeInvalid()616 void LayerTreeImpl::ResetViewportSizeInvalid() {
617 viewport_size_invalid_ = false;
618 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
619 }
620
proxy() const621 Proxy* LayerTreeImpl::proxy() const {
622 return layer_tree_host_impl_->proxy();
623 }
624
settings() const625 const LayerTreeSettings& LayerTreeImpl::settings() const {
626 return layer_tree_host_impl_->settings();
627 }
628
GetRendererCapabilities() const629 const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
630 return layer_tree_host_impl_->GetRendererCapabilities();
631 }
632
context_provider() const633 ContextProvider* LayerTreeImpl::context_provider() const {
634 return output_surface()->context_provider();
635 }
636
output_surface() const637 OutputSurface* LayerTreeImpl::output_surface() const {
638 return layer_tree_host_impl_->output_surface();
639 }
640
resource_provider() const641 ResourceProvider* LayerTreeImpl::resource_provider() const {
642 return layer_tree_host_impl_->resource_provider();
643 }
644
tile_manager() const645 TileManager* LayerTreeImpl::tile_manager() const {
646 return layer_tree_host_impl_->tile_manager();
647 }
648
frame_rate_counter() const649 FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
650 return layer_tree_host_impl_->fps_counter();
651 }
652
paint_time_counter() const653 PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
654 return layer_tree_host_impl_->paint_time_counter();
655 }
656
memory_history() const657 MemoryHistory* LayerTreeImpl::memory_history() const {
658 return layer_tree_host_impl_->memory_history();
659 }
660
resourceless_software_draw() const661 bool LayerTreeImpl::resourceless_software_draw() const {
662 return layer_tree_host_impl_->GetDrawMode() ==
663 DRAW_MODE_RESOURCELESS_SOFTWARE;
664 }
665
device_viewport_size() const666 gfx::Size LayerTreeImpl::device_viewport_size() const {
667 return layer_tree_host_impl_->device_viewport_size();
668 }
669
IsActiveTree() const670 bool LayerTreeImpl::IsActiveTree() const {
671 return layer_tree_host_impl_->active_tree() == this;
672 }
673
IsPendingTree() const674 bool LayerTreeImpl::IsPendingTree() const {
675 return layer_tree_host_impl_->pending_tree() == this;
676 }
677
IsRecycleTree() const678 bool LayerTreeImpl::IsRecycleTree() const {
679 return layer_tree_host_impl_->recycle_tree() == this;
680 }
681
FindActiveTreeLayerById(int id)682 LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
683 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
684 if (!tree)
685 return NULL;
686 return tree->LayerById(id);
687 }
688
FindPendingTreeLayerById(int id)689 LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
690 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
691 if (!tree)
692 return NULL;
693 return tree->LayerById(id);
694 }
695
FindRecycleTreeLayerById(int id)696 LayerImpl* LayerTreeImpl::FindRecycleTreeLayerById(int id) {
697 LayerTreeImpl* tree = layer_tree_host_impl_->recycle_tree();
698 if (!tree)
699 return NULL;
700 return tree->LayerById(id);
701 }
702
MaxTextureSize() const703 int LayerTreeImpl::MaxTextureSize() const {
704 return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size;
705 }
706
PinchGestureActive() const707 bool LayerTreeImpl::PinchGestureActive() const {
708 return layer_tree_host_impl_->pinch_gesture_active();
709 }
710
CurrentFrameTimeTicks() const711 base::TimeTicks LayerTreeImpl::CurrentFrameTimeTicks() const {
712 return layer_tree_host_impl_->CurrentFrameTimeTicks();
713 }
714
begin_impl_frame_interval() const715 base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
716 return layer_tree_host_impl_->begin_impl_frame_interval();
717 }
718
SetNeedsCommit()719 void LayerTreeImpl::SetNeedsCommit() {
720 layer_tree_host_impl_->SetNeedsCommit();
721 }
722
DeviceViewport() const723 gfx::Rect LayerTreeImpl::DeviceViewport() const {
724 return layer_tree_host_impl_->DeviceViewport();
725 }
726
DrawViewportSize() const727 gfx::Size LayerTreeImpl::DrawViewportSize() const {
728 return layer_tree_host_impl_->DrawViewportSize();
729 }
730
ViewportRectForTilePriority() const731 const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
732 return layer_tree_host_impl_->ViewportRectForTilePriority();
733 }
734
735 scoped_ptr<ScrollbarAnimationController>
CreateScrollbarAnimationController(LayerImpl * scrolling_layer)736 LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
737 DCHECK(settings().scrollbar_fade_delay_ms);
738 DCHECK(settings().scrollbar_fade_duration_ms);
739 base::TimeDelta delay =
740 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
741 base::TimeDelta duration =
742 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
743 switch (settings().scrollbar_animator) {
744 case LayerTreeSettings::LinearFade: {
745 return ScrollbarAnimationControllerLinearFade::Create(
746 scrolling_layer, layer_tree_host_impl_, delay, duration)
747 .PassAs<ScrollbarAnimationController>();
748 }
749 case LayerTreeSettings::Thinning: {
750 return ScrollbarAnimationControllerThinning::Create(
751 scrolling_layer, layer_tree_host_impl_, delay, duration)
752 .PassAs<ScrollbarAnimationController>();
753 }
754 case LayerTreeSettings::NoAnimator:
755 NOTREACHED();
756 break;
757 }
758 return scoped_ptr<ScrollbarAnimationController>();
759 }
760
DidAnimateScrollOffset()761 void LayerTreeImpl::DidAnimateScrollOffset() {
762 layer_tree_host_impl_->DidAnimateScrollOffset();
763 }
764
use_gpu_rasterization() const765 bool LayerTreeImpl::use_gpu_rasterization() const {
766 return layer_tree_host_impl_->use_gpu_rasterization();
767 }
768
create_low_res_tiling() const769 bool LayerTreeImpl::create_low_res_tiling() const {
770 return layer_tree_host_impl_->create_low_res_tiling();
771 }
772
SetNeedsRedraw()773 void LayerTreeImpl::SetNeedsRedraw() {
774 layer_tree_host_impl_->SetNeedsRedraw();
775 }
776
debug_state() const777 const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
778 return layer_tree_host_impl_->debug_state();
779 }
780
device_scale_factor() const781 float LayerTreeImpl::device_scale_factor() const {
782 return layer_tree_host_impl_->device_scale_factor();
783 }
784
debug_rect_history() const785 DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
786 return layer_tree_host_impl_->debug_rect_history();
787 }
788
animationRegistrar() const789 AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
790 return layer_tree_host_impl_->animation_registrar();
791 }
792
GetAllTilesForTracing(std::set<const Tile * > * tiles) const793 void LayerTreeImpl::GetAllTilesForTracing(std::set<const Tile*>* tiles) const {
794 typedef LayerIterator<LayerImpl> LayerIteratorType;
795 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
796 for (LayerIteratorType it =
797 LayerIteratorType::Begin(&render_surface_layer_list_);
798 it != end;
799 ++it) {
800 if (!it.represents_itself())
801 continue;
802 LayerImpl* layer_impl = *it;
803 layer_impl->GetAllTilesForTracing(tiles);
804 }
805 }
806
AsValue() const807 scoped_ptr<base::Value> LayerTreeImpl::AsValue() const {
808 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
809 TracedValue::MakeDictIntoImplicitSnapshot(
810 state.get(), "cc::LayerTreeImpl", this);
811 state->SetInteger("source_frame_number", source_frame_number_);
812
813 state->Set("root_layer", root_layer_->AsValue().release());
814
815 scoped_ptr<base::ListValue> render_surface_layer_list(new base::ListValue());
816 typedef LayerIterator<LayerImpl> LayerIteratorType;
817 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
818 for (LayerIteratorType it = LayerIteratorType::Begin(
819 &render_surface_layer_list_); it != end; ++it) {
820 if (!it.represents_itself())
821 continue;
822 render_surface_layer_list->Append(TracedValue::CreateIDRef(*it).release());
823 }
824
825 state->Set("render_surface_layer_list",
826 render_surface_layer_list.release());
827 return state.PassAs<base::Value>();
828 }
829
SetRootLayerScrollOffsetDelegate(LayerScrollOffsetDelegate * root_layer_scroll_offset_delegate)830 void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
831 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
832 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
833 return;
834
835 if (!root_layer_scroll_offset_delegate) {
836 // Make sure we remove the proxies from their layers before
837 // releasing them.
838 if (InnerViewportScrollLayer())
839 InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
840 if (OuterViewportScrollLayer())
841 OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
842 inner_viewport_scroll_delegate_proxy_.reset();
843 outer_viewport_scroll_delegate_proxy_.reset();
844 }
845
846 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
847
848 if (root_layer_scroll_offset_delegate_) {
849 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
850 TotalScrollOffset(),
851 TotalMaxScrollOffset(),
852 ScrollableSize(),
853 total_page_scale_factor(),
854 min_page_scale_factor(),
855 max_page_scale_factor());
856
857 if (inner_viewport_scroll_layer_) {
858 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
859 new LayerScrollOffsetDelegateProxy(InnerViewportScrollLayer(),
860 root_layer_scroll_offset_delegate_,
861 this));
862 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(
863 inner_viewport_scroll_delegate_proxy_.get());
864 }
865
866 if (outer_viewport_scroll_layer_) {
867 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
868 new LayerScrollOffsetDelegateProxy(OuterViewportScrollLayer(),
869 root_layer_scroll_offset_delegate_,
870 this));
871 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(
872 outer_viewport_scroll_delegate_proxy_.get());
873 }
874 }
875 }
876
UpdateScrollOffsetDelegate()877 void LayerTreeImpl::UpdateScrollOffsetDelegate() {
878 DCHECK(InnerViewportScrollLayer());
879 DCHECK(root_layer_scroll_offset_delegate_);
880
881 gfx::Vector2dF offset =
882 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
883
884 if (OuterViewportScrollLayer())
885 offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
886
887 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
888 offset,
889 TotalMaxScrollOffset(),
890 ScrollableSize(),
891 total_page_scale_factor(),
892 min_page_scale_factor(),
893 max_page_scale_factor());
894 }
895
GetDelegatedScrollOffset(LayerImpl * layer)896 gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) {
897 DCHECK(root_layer_scroll_offset_delegate_);
898 DCHECK(InnerViewportScrollLayer());
899 if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer())
900 return root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
901
902 // If we get here, we have both inner/outer viewports, and need to distribute
903 // the scroll offset between them.
904 DCHECK(inner_viewport_scroll_delegate_proxy_);
905 DCHECK(outer_viewport_scroll_delegate_proxy_);
906 gfx::Vector2dF inner_viewport_offset =
907 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
908 gfx::Vector2dF outer_viewport_offset =
909 outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
910
911 // It may be nothing has changed.
912 gfx::Vector2dF delegate_offset =
913 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
914 if (inner_viewport_offset + outer_viewport_offset == delegate_offset) {
915 if (layer == InnerViewportScrollLayer())
916 return inner_viewport_offset;
917 else
918 return outer_viewport_offset;
919 }
920
921 gfx::Vector2d max_outer_viewport_scroll_offset =
922 OuterViewportScrollLayer()->MaxScrollOffset();
923
924 outer_viewport_offset = delegate_offset - inner_viewport_offset;
925 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
926 outer_viewport_offset.SetToMax(gfx::Vector2d());
927
928 if (layer == OuterViewportScrollLayer())
929 return outer_viewport_offset;
930
931 inner_viewport_offset = delegate_offset - outer_viewport_offset;
932
933 return inner_viewport_offset;
934 }
935
QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise)936 void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
937 DCHECK(swap_promise);
938 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
939 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
940 swap_promise_list_.push_back(swap_promise.Pass());
941 }
942
PassSwapPromises(ScopedPtrVector<SwapPromise> * new_swap_promise)943 void LayerTreeImpl::PassSwapPromises(
944 ScopedPtrVector<SwapPromise>* new_swap_promise) {
945 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
946 *new_swap_promise);
947 new_swap_promise->clear();
948 }
949
FinishSwapPromises(CompositorFrameMetadata * metadata)950 void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
951 for (size_t i = 0; i < swap_promise_list_.size(); i++)
952 swap_promise_list_[i]->DidSwap(metadata);
953 swap_promise_list_.clear();
954 }
955
BreakSwapPromises(SwapPromise::DidNotSwapReason reason)956 void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
957 for (size_t i = 0; i < swap_promise_list_.size(); i++)
958 swap_promise_list_[i]->DidNotSwap(reason);
959 swap_promise_list_.clear();
960 }
961
DidModifyTilePriorities()962 void LayerTreeImpl::DidModifyTilePriorities() {
963 layer_tree_host_impl_->DidModifyTilePriorities();
964 }
965
set_ui_resource_request_queue(const UIResourceRequestQueue & queue)966 void LayerTreeImpl::set_ui_resource_request_queue(
967 const UIResourceRequestQueue& queue) {
968 ui_resource_request_queue_ = queue;
969 }
970
ResourceIdForUIResource(UIResourceId uid) const971 ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
972 UIResourceId uid) const {
973 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
974 }
975
IsUIResourceOpaque(UIResourceId uid) const976 bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
977 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
978 }
979
ProcessUIResourceRequestQueue()980 void LayerTreeImpl::ProcessUIResourceRequestQueue() {
981 while (ui_resource_request_queue_.size() > 0) {
982 UIResourceRequest req = ui_resource_request_queue_.front();
983 ui_resource_request_queue_.pop_front();
984
985 switch (req.GetType()) {
986 case UIResourceRequest::UIResourceCreate:
987 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
988 break;
989 case UIResourceRequest::UIResourceDelete:
990 layer_tree_host_impl_->DeleteUIResource(req.GetId());
991 break;
992 case UIResourceRequest::UIResourceInvalidRequest:
993 NOTREACHED();
994 break;
995 }
996 }
997
998 // If all UI resource evictions were not recreated by processing this queue,
999 // then another commit is required.
1000 if (layer_tree_host_impl_->EvictedUIResourcesExist())
1001 layer_tree_host_impl_->SetNeedsCommit();
1002 }
1003
AddLayerWithCopyOutputRequest(LayerImpl * layer)1004 void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
1005 // Only the active tree needs to know about layers with copy requests, as
1006 // they are aborted if not serviced during draw.
1007 DCHECK(IsActiveTree());
1008
1009 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1010 // layers_with_copy_output_request_.end(),
1011 // layer) == layers_with_copy_output_request_.end());
1012 // TODO(danakj): Remove this once crash is found crbug.com/309777
1013 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1014 CHECK(layers_with_copy_output_request_[i] != layer)
1015 << i << " of " << layers_with_copy_output_request_.size();
1016 }
1017 layers_with_copy_output_request_.push_back(layer);
1018 }
1019
RemoveLayerWithCopyOutputRequest(LayerImpl * layer)1020 void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1021 // Only the active tree needs to know about layers with copy requests, as
1022 // they are aborted if not serviced during draw.
1023 DCHECK(IsActiveTree());
1024
1025 std::vector<LayerImpl*>::iterator it = std::find(
1026 layers_with_copy_output_request_.begin(),
1027 layers_with_copy_output_request_.end(),
1028 layer);
1029 DCHECK(it != layers_with_copy_output_request_.end());
1030 layers_with_copy_output_request_.erase(it);
1031
1032 // TODO(danakj): Remove this once crash is found crbug.com/309777
1033 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1034 CHECK(layers_with_copy_output_request_[i] != layer)
1035 << i << " of " << layers_with_copy_output_request_.size();
1036 }
1037 }
1038
LayersWithCopyOutputRequest() const1039 const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
1040 const {
1041 // Only the active tree needs to know about layers with copy requests, as
1042 // they are aborted if not serviced during draw.
1043 DCHECK(IsActiveTree());
1044
1045 return layers_with_copy_output_request_;
1046 }
1047
ReleaseResourcesRecursive(LayerImpl * current)1048 void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) {
1049 DCHECK(current);
1050 current->ReleaseResources();
1051 if (current->mask_layer())
1052 ReleaseResourcesRecursive(current->mask_layer());
1053 if (current->replica_layer())
1054 ReleaseResourcesRecursive(current->replica_layer());
1055 for (size_t i = 0; i < current->children().size(); ++i)
1056 ReleaseResourcesRecursive(current->children()[i]);
1057 }
1058
1059 template <typename LayerType>
LayerClipsSubtree(LayerType * layer)1060 static inline bool LayerClipsSubtree(LayerType* layer) {
1061 return layer->masks_to_bounds() || layer->mask_layer();
1062 }
1063
PointHitsRect(const gfx::PointF & screen_space_point,const gfx::Transform & local_space_to_screen_space_transform,const gfx::RectF & local_space_rect,float * distance_to_camera)1064 static bool PointHitsRect(
1065 const gfx::PointF& screen_space_point,
1066 const gfx::Transform& local_space_to_screen_space_transform,
1067 const gfx::RectF& local_space_rect,
1068 float* distance_to_camera) {
1069 // If the transform is not invertible, then assume that this point doesn't hit
1070 // this rect.
1071 gfx::Transform inverse_local_space_to_screen_space(
1072 gfx::Transform::kSkipInitialization);
1073 if (!local_space_to_screen_space_transform.GetInverse(
1074 &inverse_local_space_to_screen_space))
1075 return false;
1076
1077 // Transform the hit test point from screen space to the local space of the
1078 // given rect.
1079 bool clipped = false;
1080 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1081 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1082 gfx::PointF hit_test_point_in_local_space =
1083 gfx::PointF(planar_point.x(), planar_point.y());
1084
1085 // If ProjectPoint could not project to a valid value, then we assume that
1086 // this point doesn't hit this rect.
1087 if (clipped)
1088 return false;
1089
1090 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1091 return false;
1092
1093 if (distance_to_camera) {
1094 // To compute the distance to the camera, we have to take the planar point
1095 // and pull it back to world space and compute the displacement along the
1096 // z-axis.
1097 gfx::Point3F planar_point_in_screen_space(planar_point);
1098 local_space_to_screen_space_transform.TransformPoint(
1099 &planar_point_in_screen_space);
1100 *distance_to_camera = planar_point_in_screen_space.z();
1101 }
1102
1103 return true;
1104 }
1105
PointHitsRegion(const gfx::PointF & screen_space_point,const gfx::Transform & screen_space_transform,const Region & layer_space_region,float layer_content_scale_x,float layer_content_scale_y)1106 static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1107 const gfx::Transform& screen_space_transform,
1108 const Region& layer_space_region,
1109 float layer_content_scale_x,
1110 float layer_content_scale_y) {
1111 // If the transform is not invertible, then assume that this point doesn't hit
1112 // this region.
1113 gfx::Transform inverse_screen_space_transform(
1114 gfx::Transform::kSkipInitialization);
1115 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1116 return false;
1117
1118 // Transform the hit test point from screen space to the local space of the
1119 // given region.
1120 bool clipped = false;
1121 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1122 inverse_screen_space_transform, screen_space_point, &clipped);
1123 gfx::PointF hit_test_point_in_layer_space =
1124 gfx::ScalePoint(hit_test_point_in_content_space,
1125 1.f / layer_content_scale_x,
1126 1.f / layer_content_scale_y);
1127
1128 // If ProjectPoint could not project to a valid value, then we assume that
1129 // this point doesn't hit this region.
1130 if (clipped)
1131 return false;
1132
1133 return layer_space_region.Contains(
1134 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1135 }
1136
GetNextClippingLayer(LayerImpl * layer)1137 static LayerImpl* GetNextClippingLayer(LayerImpl* layer) {
1138 if (layer->scroll_parent())
1139 return layer->scroll_parent();
1140 if (layer->clip_parent())
1141 return layer->clip_parent();
1142 return layer->parent();
1143 }
1144
PointIsClippedBySurfaceOrClipRect(const gfx::PointF & screen_space_point,LayerImpl * layer)1145 static bool PointIsClippedBySurfaceOrClipRect(
1146 const gfx::PointF& screen_space_point,
1147 LayerImpl* layer) {
1148 // Walk up the layer tree and hit-test any render_surfaces and any layer
1149 // clip rects that are active.
1150 for (; layer; layer = GetNextClippingLayer(layer)) {
1151 if (layer->render_surface() &&
1152 !PointHitsRect(screen_space_point,
1153 layer->render_surface()->screen_space_transform(),
1154 layer->render_surface()->content_rect(),
1155 NULL))
1156 return true;
1157
1158 if (LayerClipsSubtree(layer) &&
1159 !PointHitsRect(screen_space_point,
1160 layer->screen_space_transform(),
1161 gfx::Rect(layer->content_bounds()),
1162 NULL))
1163 return true;
1164 }
1165
1166 // If we have finished walking all ancestors without having already exited,
1167 // then the point is not clipped by any ancestors.
1168 return false;
1169 }
1170
PointHitsLayer(LayerImpl * layer,const gfx::PointF & screen_space_point,float * distance_to_intersection)1171 static bool PointHitsLayer(LayerImpl* layer,
1172 const gfx::PointF& screen_space_point,
1173 float* distance_to_intersection) {
1174 gfx::RectF content_rect(layer->content_bounds());
1175 if (!PointHitsRect(screen_space_point,
1176 layer->screen_space_transform(),
1177 content_rect,
1178 distance_to_intersection))
1179 return false;
1180
1181 // At this point, we think the point does hit the layer, but we need to walk
1182 // up the parents to ensure that the layer was not clipped in such a way
1183 // that the hit point actually should not hit the layer.
1184 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1185 return false;
1186
1187 // Skip the HUD layer.
1188 if (layer == layer->layer_tree_impl()->hud_layer())
1189 return false;
1190
1191 return true;
1192 }
1193
1194 struct FindClosestMatchingLayerDataForRecursion {
FindClosestMatchingLayerDataForRecursioncc::FindClosestMatchingLayerDataForRecursion1195 FindClosestMatchingLayerDataForRecursion()
1196 : closest_match(NULL),
1197 closest_distance(-std::numeric_limits<float>::infinity()) {}
1198 LayerImpl* closest_match;
1199 // Note that the positive z-axis points towards the camera, so bigger means
1200 // closer in this case, counterintuitively.
1201 float closest_distance;
1202 };
1203
1204 template <typename Functor>
FindClosestMatchingLayer(const gfx::PointF & screen_space_point,LayerImpl * layer,const Functor & func,FindClosestMatchingLayerDataForRecursion * data_for_recursion)1205 static void FindClosestMatchingLayer(
1206 const gfx::PointF& screen_space_point,
1207 LayerImpl* layer,
1208 const Functor& func,
1209 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
1210 for (int i = layer->children().size() - 1; i >= 0; --i) {
1211 FindClosestMatchingLayer(
1212 screen_space_point, layer->children()[i], func, data_for_recursion);
1213 }
1214
1215 float distance_to_intersection = 0.f;
1216 if (func(layer) &&
1217 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1218 ((!data_for_recursion->closest_match ||
1219 distance_to_intersection > data_for_recursion->closest_distance))) {
1220 data_for_recursion->closest_distance = distance_to_intersection;
1221 data_for_recursion->closest_match = layer;
1222 }
1223 }
1224
ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl * layer)1225 static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1226 if (!layer->scrollable())
1227 return false;
1228 if (layer->IsDrawnRenderSurfaceLayerListMember())
1229 return true;
1230 if (!layer->scroll_children())
1231 return false;
1232 for (std::set<LayerImpl*>::const_iterator it =
1233 layer->scroll_children()->begin();
1234 it != layer->scroll_children()->end();
1235 ++it) {
1236 if ((*it)->IsDrawnRenderSurfaceLayerListMember())
1237 return true;
1238 }
1239 return false;
1240 }
1241
1242 struct FindScrollingLayerFunctor {
operator ()cc::FindScrollingLayerFunctor1243 bool operator()(LayerImpl* layer) const {
1244 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1245 }
1246 };
1247
FindFirstScrollingLayerThatIsHitByPoint(const gfx::PointF & screen_space_point)1248 LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1249 const gfx::PointF& screen_space_point) {
1250 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1251 FindClosestMatchingLayer(screen_space_point,
1252 root_layer(),
1253 FindScrollingLayerFunctor(),
1254 &data_for_recursion);
1255 return data_for_recursion.closest_match;
1256 }
1257
1258 struct HitTestVisibleScrollableOrTouchableFunctor {
operator ()cc::HitTestVisibleScrollableOrTouchableFunctor1259 bool operator()(LayerImpl* layer) const {
1260 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1261 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1262 !layer->touch_event_handler_region().IsEmpty() ||
1263 layer->have_wheel_event_handlers();
1264 }
1265 };
1266
FindLayerThatIsHitByPoint(const gfx::PointF & screen_space_point)1267 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1268 const gfx::PointF& screen_space_point) {
1269 if (!root_layer())
1270 return NULL;
1271 if (!UpdateDrawProperties())
1272 return NULL;
1273 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1274 FindClosestMatchingLayer(screen_space_point,
1275 root_layer(),
1276 HitTestVisibleScrollableOrTouchableFunctor(),
1277 &data_for_recursion);
1278 return data_for_recursion.closest_match;
1279 }
1280
LayerHasTouchEventHandlersAt(const gfx::PointF & screen_space_point,LayerImpl * layer_impl)1281 static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1282 LayerImpl* layer_impl) {
1283 if (layer_impl->touch_event_handler_region().IsEmpty())
1284 return false;
1285
1286 if (!PointHitsRegion(screen_space_point,
1287 layer_impl->screen_space_transform(),
1288 layer_impl->touch_event_handler_region(),
1289 layer_impl->contents_scale_x(),
1290 layer_impl->contents_scale_y()))
1291 return false;
1292
1293 // At this point, we think the point does hit the touch event handler region
1294 // on the layer, but we need to walk up the parents to ensure that the layer
1295 // was not clipped in such a way that the hit point actually should not hit
1296 // the layer.
1297 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1298 return false;
1299
1300 return true;
1301 }
1302
1303 struct FindTouchEventLayerFunctor {
operator ()cc::FindTouchEventLayerFunctor1304 bool operator()(LayerImpl* layer) const {
1305 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1306 }
1307 const gfx::PointF screen_space_point;
1308 };
1309
FindLayerThatIsHitByPointInTouchHandlerRegion(const gfx::PointF & screen_space_point)1310 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1311 const gfx::PointF& screen_space_point) {
1312 if (!root_layer())
1313 return NULL;
1314 if (!UpdateDrawProperties())
1315 return NULL;
1316 FindTouchEventLayerFunctor func = {screen_space_point};
1317 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1318 FindClosestMatchingLayer(
1319 screen_space_point, root_layer(), func, &data_for_recursion);
1320 return data_for_recursion.closest_match;
1321 }
1322
RegisterPictureLayerImpl(PictureLayerImpl * layer)1323 void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1324 layer_tree_host_impl_->RegisterPictureLayerImpl(layer);
1325 }
1326
UnregisterPictureLayerImpl(PictureLayerImpl * layer)1327 void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1328 layer_tree_host_impl_->UnregisterPictureLayerImpl(layer);
1329 }
1330
1331 } // namespace cc
1332