• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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