Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / trees / layer_tree_impl.cc
blob908e993d3ba845fcc3673c3538464f88f73a038a
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.
5 #include "cc/trees/layer_tree_impl.h"
7 #include <limits>
8 #include <set>
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 "cc/trees/occlusion_tracker.h"
28 #include "ui/gfx/point_conversions.h"
29 #include "ui/gfx/size_conversions.h"
30 #include "ui/gfx/vector2d_conversions.h"
32 namespace cc {
34 // This class exists to split the LayerScrollOffsetDelegate between the
35 // InnerViewportScrollLayer and the OuterViewportScrollLayer in a manner
36 // that never requires the embedder or LayerImpl to know about.
37 class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
38 public:
39 LayerScrollOffsetDelegateProxy(LayerImpl* layer,
40 LayerScrollOffsetDelegate* delegate,
41 LayerTreeImpl* layer_tree)
42 : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {}
43 virtual ~LayerScrollOffsetDelegateProxy() {}
45 gfx::Vector2dF last_set_scroll_offset() const {
46 return last_set_scroll_offset_;
49 // LayerScrollOffsetDelegate implementation.
50 virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_offset) OVERRIDE {
51 last_set_scroll_offset_ = new_offset;
52 layer_tree_impl_->UpdateScrollOffsetDelegate();
55 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
56 return layer_tree_impl_->GetDelegatedScrollOffset(layer_);
59 virtual bool IsExternalFlingActive() const OVERRIDE {
60 return delegate_->IsExternalFlingActive();
63 private:
64 LayerImpl* layer_;
65 LayerScrollOffsetDelegate* delegate_;
66 LayerTreeImpl* layer_tree_impl_;
67 gfx::Vector2dF last_set_scroll_offset_;
70 LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
71 : layer_tree_host_impl_(layer_tree_host_impl),
72 source_frame_number_(-1),
73 hud_layer_(0),
74 currently_scrolling_layer_(NULL),
75 root_layer_scroll_offset_delegate_(NULL),
76 background_color_(0),
77 has_transparent_background_(false),
78 page_scale_layer_(NULL),
79 inner_viewport_scroll_layer_(NULL),
80 outer_viewport_scroll_layer_(NULL),
81 page_scale_factor_(1),
82 page_scale_delta_(1),
83 sent_page_scale_delta_(1),
84 min_page_scale_factor_(0),
85 max_page_scale_factor_(0),
86 scrolling_layer_id_from_previous_tree_(0),
87 contents_textures_purged_(false),
88 requires_high_res_to_draw_(false),
89 viewport_size_invalid_(false),
90 needs_update_draw_properties_(true),
91 needs_full_tree_sync_(true),
92 next_activation_forces_redraw_(false),
93 render_surface_layer_list_id_(0) {
96 LayerTreeImpl::~LayerTreeImpl() {
97 // Need to explicitly clear the tree prior to destroying this so that
98 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
99 DCHECK(!root_layer_);
100 DCHECK(layers_with_copy_output_request_.empty());
103 void LayerTreeImpl::Shutdown() { root_layer_.reset(); }
105 void LayerTreeImpl::ReleaseResources() {
106 if (root_layer_)
107 ReleaseResourcesRecursive(root_layer_.get());
110 void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
111 if (inner_viewport_scroll_layer_)
112 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
113 if (outer_viewport_scroll_layer_)
114 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
115 inner_viewport_scroll_delegate_proxy_.reset();
116 outer_viewport_scroll_delegate_proxy_.reset();
118 root_layer_ = layer.Pass();
119 currently_scrolling_layer_ = NULL;
120 inner_viewport_scroll_layer_ = NULL;
121 outer_viewport_scroll_layer_ = NULL;
122 page_scale_layer_ = NULL;
124 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
127 LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
128 return inner_viewport_scroll_layer_;
131 LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
132 return outer_viewport_scroll_layer_;
135 gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const {
136 gfx::Vector2dF offset;
138 if (inner_viewport_scroll_layer_)
139 offset += inner_viewport_scroll_layer_->TotalScrollOffset();
141 if (outer_viewport_scroll_layer_)
142 offset += outer_viewport_scroll_layer_->TotalScrollOffset();
144 return offset;
147 gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const {
148 gfx::Vector2dF offset;
150 if (inner_viewport_scroll_layer_)
151 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
153 if (outer_viewport_scroll_layer_)
154 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
156 return offset;
158 gfx::Vector2dF LayerTreeImpl::TotalScrollDelta() const {
159 DCHECK(inner_viewport_scroll_layer_);
160 gfx::Vector2dF delta = inner_viewport_scroll_layer_->ScrollDelta();
162 if (outer_viewport_scroll_layer_)
163 delta += outer_viewport_scroll_layer_->ScrollDelta();
165 return delta;
168 scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
169 // Clear all data structures that have direct references to the layer tree.
170 scrolling_layer_id_from_previous_tree_ =
171 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
172 if (inner_viewport_scroll_layer_)
173 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
174 if (outer_viewport_scroll_layer_)
175 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
176 inner_viewport_scroll_delegate_proxy_.reset();
177 outer_viewport_scroll_delegate_proxy_.reset();
178 inner_viewport_scroll_layer_ = NULL;
179 outer_viewport_scroll_layer_ = NULL;
180 page_scale_layer_ = NULL;
181 currently_scrolling_layer_ = NULL;
183 render_surface_layer_list_.clear();
184 set_needs_update_draw_properties();
185 return root_layer_.Pass();
188 void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
189 // The request queue should have been processed and does not require a push.
190 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
192 if (next_activation_forces_redraw_) {
193 target_tree->ForceRedrawNextActivation();
194 next_activation_forces_redraw_ = false;
197 target_tree->PassSwapPromises(&swap_promise_list_);
199 target_tree->SetPageScaleValues(
200 page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(),
201 target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
202 target_tree->set_sent_page_scale_delta(1);
204 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
205 target_tree->SetViewportLayersFromIds(
206 page_scale_layer_->id(),
207 inner_viewport_scroll_layer_->id(),
208 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
209 : Layer::INVALID_ID);
210 } else {
211 target_tree->ClearViewportLayers();
214 target_tree->RegisterSelection(selection_anchor_, selection_focus_);
216 // This should match the property synchronization in
217 // LayerTreeHost::finishCommitOnImplThread().
218 target_tree->set_source_frame_number(source_frame_number());
219 target_tree->set_background_color(background_color());
220 target_tree->set_has_transparent_background(has_transparent_background());
222 if (ContentsTexturesPurged())
223 target_tree->SetContentsTexturesPurged();
224 else
225 target_tree->ResetContentsTexturesPurged();
227 if (ViewportSizeInvalid())
228 target_tree->SetViewportSizeInvalid();
229 else
230 target_tree->ResetViewportSizeInvalid();
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);
240 LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
241 return inner_viewport_scroll_layer_
242 ? inner_viewport_scroll_layer_->scroll_clip_layer()
243 : NULL;
246 LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
247 DCHECK(IsActiveTree());
248 return currently_scrolling_layer_;
251 void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
252 if (currently_scrolling_layer_ == layer)
253 return;
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();
264 void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
265 SetCurrentlyScrollingLayer(NULL);
266 scrolling_layer_id_from_previous_tree_ = 0;
269 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;
274 return layer_tree_host_impl_->VerticalAdjust();
277 namespace {
279 void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
280 if (!current_layer)
281 return;
283 while (current_layer) {
284 current_layer->ScrollbarParametersDidChange();
285 current_layer = current_layer->parent();
289 } // namespace
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_);
297 void LayerTreeImpl::SetPageScaleDelta(float delta) {
298 SetPageScaleValues(page_scale_factor_, min_page_scale_factor_,
299 max_page_scale_factor_, 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_;
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;
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_;
320 if (page_scale_delta_ == page_scale_delta && !page_scale_changed)
321 return;
323 if (page_scale_delta_ != page_scale_delta) {
324 page_scale_delta_ = page_scale_delta;
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_);
335 set_needs_update_draw_properties();
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_);
348 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
351 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());
360 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()));
371 static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) {
372 layer->ApplySentScrollDeltasFromAbortedCommit();
375 void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
376 DCHECK(IsActiveTree());
378 page_scale_factor_ *= sent_page_scale_delta_;
379 page_scale_delta_ /= sent_page_scale_delta_;
380 sent_page_scale_delta_ = 1.f;
382 if (!root_layer())
383 return;
385 LayerTreeHostCommon::CallFunctionForSubtree(
386 root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo));
389 static void ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl* layer) {
390 layer->ApplyScrollDeltasSinceBeginMainFrame();
393 void LayerTreeImpl::ApplyScrollDeltasSinceBeginMainFrame() {
394 DCHECK(IsPendingTree());
395 if (!root_layer())
396 return;
398 LayerTreeHostCommon::CallFunctionForSubtree(
399 root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginMainFrameTo));
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_);
409 inner_viewport_scroll_layer_ =
410 LayerById(inner_viewport_scroll_layer_id);
411 DCHECK(inner_viewport_scroll_layer_);
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);
418 if (!root_layer_scroll_offset_delegate_)
419 return;
421 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
422 new LayerScrollOffsetDelegateProxy(inner_viewport_scroll_layer_,
423 root_layer_scroll_offset_delegate_,
424 this));
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));
433 void LayerTreeImpl::ClearViewportLayers() {
434 page_scale_layer_ = NULL;
435 inner_viewport_scroll_layer_ = NULL;
436 outer_viewport_scroll_layer_ = NULL;
439 bool LayerTreeImpl::UpdateDrawProperties() {
440 if (!needs_update_draw_properties_)
441 return true;
443 // For max_texture_size.
444 if (!layer_tree_host_impl_->renderer())
445 return false;
447 if (!root_layer())
448 return false;
450 needs_update_draw_properties_ = false;
451 render_surface_layer_list_.clear();
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();
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);
482 TRACE_EVENT2("cc",
483 "LayerTreeImpl::UpdateTilePriorities",
484 "IsActive",
485 IsActiveTree(),
486 "SourceFrameNumber",
487 source_frame_number_);
488 scoped_ptr<OcclusionTracker<LayerImpl> > occlusion_tracker;
489 if (settings().use_occlusion_for_tile_prioritization) {
490 occlusion_tracker.reset(new OcclusionTracker<LayerImpl>(
491 root_layer()->render_surface()->content_rect()));
492 occlusion_tracker->set_minimum_tracking_size(
493 settings().minimum_occlusion_tracking_size);
496 // LayerIterator is used here instead of CallFunctionForSubtree to only
497 // UpdateTilePriorities on layers that will be visible (and thus have valid
498 // draw properties) and not because any ordering is required.
499 typedef LayerIterator<LayerImpl> LayerIteratorType;
500 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
501 for (LayerIteratorType it =
502 LayerIteratorType::Begin(&render_surface_layer_list_);
503 it != end;
504 ++it) {
505 if (occlusion_tracker)
506 occlusion_tracker->EnterLayer(it);
508 LayerImpl* layer = *it;
509 if (it.represents_itself())
510 layer->UpdateTiles(occlusion_tracker.get());
512 if (!it.represents_contributing_render_surface()) {
513 if (occlusion_tracker)
514 occlusion_tracker->LeaveLayer(it);
515 continue;
518 if (layer->mask_layer())
519 layer->mask_layer()->UpdateTiles(occlusion_tracker.get());
520 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
521 layer->replica_layer()->mask_layer()->UpdateTiles(
522 occlusion_tracker.get());
524 if (occlusion_tracker)
525 occlusion_tracker->LeaveLayer(it);
529 DCHECK(!needs_update_draw_properties_) <<
530 "CalcDrawProperties should not set_needs_update_draw_properties()";
531 return true;
534 const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
535 // If this assert triggers, then the list is dirty.
536 DCHECK(!needs_update_draw_properties_);
537 return render_surface_layer_list_;
540 gfx::Size LayerTreeImpl::ScrollableSize() const {
541 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
542 ? OuterViewportScrollLayer()
543 : InnerViewportScrollLayer();
544 if (!root_scroll_layer || root_scroll_layer->children().empty())
545 return gfx::Size();
546 return root_scroll_layer->children()[0]->bounds();
549 LayerImpl* LayerTreeImpl::LayerById(int id) {
550 LayerIdMap::iterator iter = layer_id_map_.find(id);
551 return iter != layer_id_map_.end() ? iter->second : NULL;
554 void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
555 DCHECK(!LayerById(layer->id()));
556 layer_id_map_[layer->id()] = layer;
559 void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
560 DCHECK(LayerById(layer->id()));
561 layer_id_map_.erase(layer->id());
564 void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
565 pending_tree->SetCurrentlyScrollingLayer(
566 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
567 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
570 static void DidBecomeActiveRecursive(LayerImpl* layer) {
571 layer->DidBecomeActive();
572 for (size_t i = 0; i < layer->children().size(); ++i)
573 DidBecomeActiveRecursive(layer->children()[i]);
576 void LayerTreeImpl::DidBecomeActive() {
577 if (next_activation_forces_redraw_) {
578 layer_tree_host_impl_->SetFullRootLayerDamage();
579 next_activation_forces_redraw_ = false;
582 if (scrolling_layer_id_from_previous_tree_) {
583 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
584 root_layer(), scrolling_layer_id_from_previous_tree_);
587 // Always reset this flag on activation, as we would only have activated
588 // if we were in a good state.
589 ResetRequiresHighResToDraw();
591 if (root_layer())
592 DidBecomeActiveRecursive(root_layer());
594 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
595 source_frame_number_);
598 bool LayerTreeImpl::ContentsTexturesPurged() const {
599 return contents_textures_purged_;
602 void LayerTreeImpl::SetContentsTexturesPurged() {
603 if (contents_textures_purged_)
604 return;
605 contents_textures_purged_ = true;
606 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
609 void LayerTreeImpl::ResetContentsTexturesPurged() {
610 if (!contents_textures_purged_)
611 return;
612 contents_textures_purged_ = false;
613 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
616 void LayerTreeImpl::SetRequiresHighResToDraw() {
617 requires_high_res_to_draw_ = true;
620 void LayerTreeImpl::ResetRequiresHighResToDraw() {
621 requires_high_res_to_draw_ = false;
624 bool LayerTreeImpl::RequiresHighResToDraw() const {
625 return requires_high_res_to_draw_;
628 bool LayerTreeImpl::ViewportSizeInvalid() const {
629 return viewport_size_invalid_;
632 void LayerTreeImpl::SetViewportSizeInvalid() {
633 viewport_size_invalid_ = true;
634 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
637 void LayerTreeImpl::ResetViewportSizeInvalid() {
638 viewport_size_invalid_ = false;
639 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
642 Proxy* LayerTreeImpl::proxy() const {
643 return layer_tree_host_impl_->proxy();
646 const LayerTreeSettings& LayerTreeImpl::settings() const {
647 return layer_tree_host_impl_->settings();
650 const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
651 return layer_tree_host_impl_->GetRendererCapabilities();
654 ContextProvider* LayerTreeImpl::context_provider() const {
655 return output_surface()->context_provider();
658 OutputSurface* LayerTreeImpl::output_surface() const {
659 return layer_tree_host_impl_->output_surface();
662 ResourceProvider* LayerTreeImpl::resource_provider() const {
663 return layer_tree_host_impl_->resource_provider();
666 TileManager* LayerTreeImpl::tile_manager() const {
667 return layer_tree_host_impl_->tile_manager();
670 FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
671 return layer_tree_host_impl_->fps_counter();
674 PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
675 return layer_tree_host_impl_->paint_time_counter();
678 MemoryHistory* LayerTreeImpl::memory_history() const {
679 return layer_tree_host_impl_->memory_history();
682 bool LayerTreeImpl::resourceless_software_draw() const {
683 return layer_tree_host_impl_->GetDrawMode() ==
684 DRAW_MODE_RESOURCELESS_SOFTWARE;
687 gfx::Size LayerTreeImpl::device_viewport_size() const {
688 return layer_tree_host_impl_->device_viewport_size();
691 bool LayerTreeImpl::IsActiveTree() const {
692 return layer_tree_host_impl_->active_tree() == this;
695 bool LayerTreeImpl::IsPendingTree() const {
696 return layer_tree_host_impl_->pending_tree() == this;
699 bool LayerTreeImpl::IsRecycleTree() const {
700 return layer_tree_host_impl_->recycle_tree() == this;
703 LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
704 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
705 if (!tree)
706 return NULL;
707 return tree->LayerById(id);
710 LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
711 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
712 if (!tree)
713 return NULL;
714 return tree->LayerById(id);
717 int LayerTreeImpl::MaxTextureSize() const {
718 return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size;
721 bool LayerTreeImpl::PinchGestureActive() const {
722 return layer_tree_host_impl_->pinch_gesture_active();
725 base::TimeTicks LayerTreeImpl::CurrentFrameTimeTicks() const {
726 return layer_tree_host_impl_->CurrentFrameTimeTicks();
729 base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
730 return layer_tree_host_impl_->begin_impl_frame_interval();
733 void LayerTreeImpl::SetNeedsCommit() {
734 layer_tree_host_impl_->SetNeedsCommit();
737 gfx::Size LayerTreeImpl::DrawViewportSize() const {
738 return layer_tree_host_impl_->DrawViewportSize();
741 scoped_ptr<ScrollbarAnimationController>
742 LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
743 DCHECK(settings().scrollbar_fade_delay_ms);
744 DCHECK(settings().scrollbar_fade_duration_ms);
745 base::TimeDelta delay =
746 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
747 base::TimeDelta duration =
748 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
749 switch (settings().scrollbar_animator) {
750 case LayerTreeSettings::LinearFade: {
751 return ScrollbarAnimationControllerLinearFade::Create(
752 scrolling_layer, layer_tree_host_impl_, delay, duration)
753 .PassAs<ScrollbarAnimationController>();
755 case LayerTreeSettings::Thinning: {
756 return ScrollbarAnimationControllerThinning::Create(
757 scrolling_layer, layer_tree_host_impl_, delay, duration)
758 .PassAs<ScrollbarAnimationController>();
760 case LayerTreeSettings::NoAnimator:
761 NOTREACHED();
762 break;
764 return scoped_ptr<ScrollbarAnimationController>();
767 void LayerTreeImpl::DidAnimateScrollOffset() {
768 layer_tree_host_impl_->DidAnimateScrollOffset();
771 bool LayerTreeImpl::use_gpu_rasterization() const {
772 return layer_tree_host_impl_->use_gpu_rasterization();
775 bool LayerTreeImpl::create_low_res_tiling() const {
776 return layer_tree_host_impl_->create_low_res_tiling();
779 void LayerTreeImpl::SetNeedsRedraw() {
780 layer_tree_host_impl_->SetNeedsRedraw();
783 const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
784 return layer_tree_host_impl_->debug_state();
787 float LayerTreeImpl::device_scale_factor() const {
788 return layer_tree_host_impl_->device_scale_factor();
791 DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
792 return layer_tree_host_impl_->debug_rect_history();
795 AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
796 return layer_tree_host_impl_->animation_registrar();
799 scoped_ptr<base::Value> LayerTreeImpl::AsValue() const {
800 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
801 TracedValue::MakeDictIntoImplicitSnapshot(
802 state.get(), "cc::LayerTreeImpl", this);
804 state->Set("root_layer", root_layer_->AsValue().release());
806 scoped_ptr<base::ListValue> render_surface_layer_list(new base::ListValue());
807 typedef LayerIterator<LayerImpl> LayerIteratorType;
808 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
809 for (LayerIteratorType it = LayerIteratorType::Begin(
810 &render_surface_layer_list_); it != end; ++it) {
811 if (!it.represents_itself())
812 continue;
813 render_surface_layer_list->Append(TracedValue::CreateIDRef(*it).release());
816 state->Set("render_surface_layer_list",
817 render_surface_layer_list.release());
818 return state.PassAs<base::Value>();
821 void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
822 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
823 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
824 return;
826 if (!root_layer_scroll_offset_delegate) {
827 // Make sure we remove the proxies from their layers before
828 // releasing them.
829 if (InnerViewportScrollLayer())
830 InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
831 if (OuterViewportScrollLayer())
832 OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
833 inner_viewport_scroll_delegate_proxy_.reset();
834 outer_viewport_scroll_delegate_proxy_.reset();
837 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
839 if (root_layer_scroll_offset_delegate_) {
840 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
841 TotalScrollOffset(),
842 TotalMaxScrollOffset(),
843 ScrollableSize(),
844 total_page_scale_factor(),
845 min_page_scale_factor(),
846 max_page_scale_factor());
848 if (inner_viewport_scroll_layer_) {
849 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
850 new LayerScrollOffsetDelegateProxy(InnerViewportScrollLayer(),
851 root_layer_scroll_offset_delegate_,
852 this));
853 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(
854 inner_viewport_scroll_delegate_proxy_.get());
857 if (outer_viewport_scroll_layer_) {
858 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
859 new LayerScrollOffsetDelegateProxy(OuterViewportScrollLayer(),
860 root_layer_scroll_offset_delegate_,
861 this));
862 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(
863 outer_viewport_scroll_delegate_proxy_.get());
868 void LayerTreeImpl::UpdateScrollOffsetDelegate() {
869 DCHECK(InnerViewportScrollLayer());
870 DCHECK(root_layer_scroll_offset_delegate_);
872 gfx::Vector2dF offset =
873 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
875 if (OuterViewportScrollLayer())
876 offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
878 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
879 offset,
880 TotalMaxScrollOffset(),
881 ScrollableSize(),
882 total_page_scale_factor(),
883 min_page_scale_factor(),
884 max_page_scale_factor());
887 gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) {
888 DCHECK(root_layer_scroll_offset_delegate_);
889 DCHECK(InnerViewportScrollLayer());
890 if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer())
891 return root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
893 // If we get here, we have both inner/outer viewports, and need to distribute
894 // the scroll offset between them.
895 DCHECK(inner_viewport_scroll_delegate_proxy_);
896 DCHECK(outer_viewport_scroll_delegate_proxy_);
897 gfx::Vector2dF inner_viewport_offset =
898 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
899 gfx::Vector2dF outer_viewport_offset =
900 outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
902 // It may be nothing has changed.
903 gfx::Vector2dF delegate_offset =
904 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
905 if (inner_viewport_offset + outer_viewport_offset == delegate_offset) {
906 if (layer == InnerViewportScrollLayer())
907 return inner_viewport_offset;
908 else
909 return outer_viewport_offset;
912 gfx::Vector2d max_outer_viewport_scroll_offset =
913 OuterViewportScrollLayer()->MaxScrollOffset();
915 outer_viewport_offset = delegate_offset - inner_viewport_offset;
916 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
917 outer_viewport_offset.SetToMax(gfx::Vector2d());
919 if (layer == OuterViewportScrollLayer())
920 return outer_viewport_offset;
922 inner_viewport_offset = delegate_offset - outer_viewport_offset;
924 return inner_viewport_offset;
927 void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
928 DCHECK(swap_promise);
929 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
930 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
931 swap_promise_list_.push_back(swap_promise.Pass());
934 void LayerTreeImpl::PassSwapPromises(
935 ScopedPtrVector<SwapPromise>* new_swap_promise) {
936 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
937 *new_swap_promise);
938 new_swap_promise->clear();
941 void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
942 for (size_t i = 0; i < swap_promise_list_.size(); i++)
943 swap_promise_list_[i]->DidSwap(metadata);
944 swap_promise_list_.clear();
947 void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
948 for (size_t i = 0; i < swap_promise_list_.size(); i++)
949 swap_promise_list_[i]->DidNotSwap(reason);
950 swap_promise_list_.clear();
953 void LayerTreeImpl::DidModifyTilePriorities() {
954 layer_tree_host_impl_->DidModifyTilePriorities();
957 void LayerTreeImpl::set_ui_resource_request_queue(
958 const UIResourceRequestQueue& queue) {
959 ui_resource_request_queue_ = queue;
962 ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
963 UIResourceId uid) const {
964 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
967 bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
968 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
971 void LayerTreeImpl::ProcessUIResourceRequestQueue() {
972 while (ui_resource_request_queue_.size() > 0) {
973 UIResourceRequest req = ui_resource_request_queue_.front();
974 ui_resource_request_queue_.pop_front();
976 switch (req.GetType()) {
977 case UIResourceRequest::UIResourceCreate:
978 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
979 break;
980 case UIResourceRequest::UIResourceDelete:
981 layer_tree_host_impl_->DeleteUIResource(req.GetId());
982 break;
983 case UIResourceRequest::UIResourceInvalidRequest:
984 NOTREACHED();
985 break;
989 // If all UI resource evictions were not recreated by processing this queue,
990 // then another commit is required.
991 if (layer_tree_host_impl_->EvictedUIResourcesExist())
992 layer_tree_host_impl_->SetNeedsCommit();
995 void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) {
996 // Only the active tree needs to know about layers with copy requests, as
997 // they are aborted if not serviced during draw.
998 DCHECK(IsActiveTree());
1000 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1001 // layers_with_copy_output_request_.end(),
1002 // layer) == layers_with_copy_output_request_.end());
1003 // TODO(danakj): Remove this once crash is found crbug.com/309777
1004 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1005 CHECK(layers_with_copy_output_request_[i] != layer)
1006 << i << " of " << layers_with_copy_output_request_.size();
1008 layers_with_copy_output_request_.push_back(layer);
1011 void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1012 // Only the active tree needs to know about layers with copy requests, as
1013 // they are aborted if not serviced during draw.
1014 DCHECK(IsActiveTree());
1016 std::vector<LayerImpl*>::iterator it = std::find(
1017 layers_with_copy_output_request_.begin(),
1018 layers_with_copy_output_request_.end(),
1019 layer);
1020 DCHECK(it != layers_with_copy_output_request_.end());
1021 layers_with_copy_output_request_.erase(it);
1023 // TODO(danakj): Remove this once crash is found crbug.com/309777
1024 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1025 CHECK(layers_with_copy_output_request_[i] != layer)
1026 << i << " of " << layers_with_copy_output_request_.size();
1030 const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
1031 const {
1032 // Only the active tree needs to know about layers with copy requests, as
1033 // they are aborted if not serviced during draw.
1034 DCHECK(IsActiveTree());
1036 return layers_with_copy_output_request_;
1039 void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) {
1040 DCHECK(current);
1041 current->ReleaseResources();
1042 if (current->mask_layer())
1043 ReleaseResourcesRecursive(current->mask_layer());
1044 if (current->replica_layer())
1045 ReleaseResourcesRecursive(current->replica_layer());
1046 for (size_t i = 0; i < current->children().size(); ++i)
1047 ReleaseResourcesRecursive(current->children()[i]);
1050 template <typename LayerType>
1051 static inline bool LayerClipsSubtree(LayerType* layer) {
1052 return layer->masks_to_bounds() || layer->mask_layer();
1055 static bool PointHitsRect(
1056 const gfx::PointF& screen_space_point,
1057 const gfx::Transform& local_space_to_screen_space_transform,
1058 const gfx::RectF& local_space_rect,
1059 float* distance_to_camera) {
1060 // If the transform is not invertible, then assume that this point doesn't hit
1061 // this rect.
1062 gfx::Transform inverse_local_space_to_screen_space(
1063 gfx::Transform::kSkipInitialization);
1064 if (!local_space_to_screen_space_transform.GetInverse(
1065 &inverse_local_space_to_screen_space))
1066 return false;
1068 // Transform the hit test point from screen space to the local space of the
1069 // given rect.
1070 bool clipped = false;
1071 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1072 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1073 gfx::PointF hit_test_point_in_local_space =
1074 gfx::PointF(planar_point.x(), planar_point.y());
1076 // If ProjectPoint could not project to a valid value, then we assume that
1077 // this point doesn't hit this rect.
1078 if (clipped)
1079 return false;
1081 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1082 return false;
1084 if (distance_to_camera) {
1085 // To compute the distance to the camera, we have to take the planar point
1086 // and pull it back to world space and compute the displacement along the
1087 // z-axis.
1088 gfx::Point3F planar_point_in_screen_space(planar_point);
1089 local_space_to_screen_space_transform.TransformPoint(
1090 &planar_point_in_screen_space);
1091 *distance_to_camera = planar_point_in_screen_space.z();
1094 return true;
1097 static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1098 const gfx::Transform& screen_space_transform,
1099 const Region& layer_space_region,
1100 float layer_content_scale_x,
1101 float layer_content_scale_y) {
1102 // If the transform is not invertible, then assume that this point doesn't hit
1103 // this region.
1104 gfx::Transform inverse_screen_space_transform(
1105 gfx::Transform::kSkipInitialization);
1106 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1107 return false;
1109 // Transform the hit test point from screen space to the local space of the
1110 // given region.
1111 bool clipped = false;
1112 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1113 inverse_screen_space_transform, screen_space_point, &clipped);
1114 gfx::PointF hit_test_point_in_layer_space =
1115 gfx::ScalePoint(hit_test_point_in_content_space,
1116 1.f / layer_content_scale_x,
1117 1.f / layer_content_scale_y);
1119 // If ProjectPoint could not project to a valid value, then we assume that
1120 // this point doesn't hit this region.
1121 if (clipped)
1122 return false;
1124 return layer_space_region.Contains(
1125 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1128 static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
1129 if (layer->scroll_parent())
1130 return layer->scroll_parent();
1131 if (layer->clip_parent())
1132 return layer->clip_parent();
1133 return layer->parent();
1136 static bool PointIsClippedBySurfaceOrClipRect(
1137 const gfx::PointF& screen_space_point,
1138 const LayerImpl* layer) {
1139 // Walk up the layer tree and hit-test any render_surfaces and any layer
1140 // clip rects that are active.
1141 for (; layer; layer = GetNextClippingLayer(layer)) {
1142 if (layer->render_surface() &&
1143 !PointHitsRect(screen_space_point,
1144 layer->render_surface()->screen_space_transform(),
1145 layer->render_surface()->content_rect(),
1146 NULL))
1147 return true;
1149 if (LayerClipsSubtree(layer) &&
1150 !PointHitsRect(screen_space_point,
1151 layer->screen_space_transform(),
1152 gfx::Rect(layer->content_bounds()),
1153 NULL))
1154 return true;
1157 // If we have finished walking all ancestors without having already exited,
1158 // then the point is not clipped by any ancestors.
1159 return false;
1162 static bool PointHitsLayer(const LayerImpl* layer,
1163 const gfx::PointF& screen_space_point,
1164 float* distance_to_intersection) {
1165 gfx::RectF content_rect(layer->content_bounds());
1166 if (!PointHitsRect(screen_space_point,
1167 layer->screen_space_transform(),
1168 content_rect,
1169 distance_to_intersection))
1170 return false;
1172 // At this point, we think the point does hit the layer, but we need to walk
1173 // up the parents to ensure that the layer was not clipped in such a way
1174 // that the hit point actually should not hit the layer.
1175 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1176 return false;
1178 // Skip the HUD layer.
1179 if (layer == layer->layer_tree_impl()->hud_layer())
1180 return false;
1182 return true;
1185 struct FindClosestMatchingLayerDataForRecursion {
1186 FindClosestMatchingLayerDataForRecursion()
1187 : closest_match(NULL),
1188 closest_distance(-std::numeric_limits<float>::infinity()) {}
1189 LayerImpl* closest_match;
1190 // Note that the positive z-axis points towards the camera, so bigger means
1191 // closer in this case, counterintuitively.
1192 float closest_distance;
1195 template <typename Functor>
1196 static void FindClosestMatchingLayer(
1197 const gfx::PointF& screen_space_point,
1198 LayerImpl* layer,
1199 const Functor& func,
1200 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
1201 for (int i = layer->children().size() - 1; i >= 0; --i) {
1202 FindClosestMatchingLayer(
1203 screen_space_point, layer->children()[i], func, data_for_recursion);
1206 float distance_to_intersection = 0.f;
1207 if (func(layer) &&
1208 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1209 ((!data_for_recursion->closest_match ||
1210 distance_to_intersection > data_for_recursion->closest_distance))) {
1211 data_for_recursion->closest_distance = distance_to_intersection;
1212 data_for_recursion->closest_match = layer;
1216 static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1217 if (!layer->scrollable())
1218 return false;
1219 if (layer->IsDrawnRenderSurfaceLayerListMember())
1220 return true;
1221 if (!layer->scroll_children())
1222 return false;
1223 for (std::set<LayerImpl*>::const_iterator it =
1224 layer->scroll_children()->begin();
1225 it != layer->scroll_children()->end();
1226 ++it) {
1227 if ((*it)->IsDrawnRenderSurfaceLayerListMember())
1228 return true;
1230 return false;
1233 struct FindScrollingLayerFunctor {
1234 bool operator()(LayerImpl* layer) const {
1235 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1239 LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1240 const gfx::PointF& screen_space_point) {
1241 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1242 FindClosestMatchingLayer(screen_space_point,
1243 root_layer(),
1244 FindScrollingLayerFunctor(),
1245 &data_for_recursion);
1246 return data_for_recursion.closest_match;
1249 struct HitTestVisibleScrollableOrTouchableFunctor {
1250 bool operator()(LayerImpl* layer) const {
1251 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1252 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1253 !layer->touch_event_handler_region().IsEmpty() ||
1254 layer->have_wheel_event_handlers();
1258 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1259 const gfx::PointF& screen_space_point) {
1260 if (!root_layer())
1261 return NULL;
1262 if (!UpdateDrawProperties())
1263 return NULL;
1264 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1265 FindClosestMatchingLayer(screen_space_point,
1266 root_layer(),
1267 HitTestVisibleScrollableOrTouchableFunctor(),
1268 &data_for_recursion);
1269 return data_for_recursion.closest_match;
1272 static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1273 LayerImpl* layer_impl) {
1274 if (layer_impl->touch_event_handler_region().IsEmpty())
1275 return false;
1277 if (!PointHitsRegion(screen_space_point,
1278 layer_impl->screen_space_transform(),
1279 layer_impl->touch_event_handler_region(),
1280 layer_impl->contents_scale_x(),
1281 layer_impl->contents_scale_y()))
1282 return false;
1284 // At this point, we think the point does hit the touch event handler region
1285 // on the layer, but we need to walk up the parents to ensure that the layer
1286 // was not clipped in such a way that the hit point actually should not hit
1287 // the layer.
1288 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1289 return false;
1291 return true;
1294 struct FindTouchEventLayerFunctor {
1295 bool operator()(LayerImpl* layer) const {
1296 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1298 const gfx::PointF screen_space_point;
1301 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1302 const gfx::PointF& screen_space_point) {
1303 if (!root_layer())
1304 return NULL;
1305 if (!UpdateDrawProperties())
1306 return NULL;
1307 FindTouchEventLayerFunctor func = {screen_space_point};
1308 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1309 FindClosestMatchingLayer(
1310 screen_space_point, root_layer(), func, &data_for_recursion);
1311 return data_for_recursion.closest_match;
1314 void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& anchor,
1315 const LayerSelectionBound& focus) {
1316 selection_anchor_ = anchor;
1317 selection_focus_ = focus;
1320 static ViewportSelectionBound ComputeViewportSelection(
1321 const LayerSelectionBound& bound,
1322 LayerImpl* layer,
1323 float device_scale_factor) {
1324 ViewportSelectionBound result;
1325 result.type = bound.type;
1327 if (!layer || bound.type == SELECTION_BOUND_EMPTY)
1328 return result;
1330 gfx::RectF layer_scaled_rect = gfx::ScaleRect(
1331 bound.layer_rect, layer->contents_scale_x(), layer->contents_scale_y());
1332 gfx::RectF screen_rect = MathUtil::ProjectClippedRect(
1333 layer->screen_space_transform(), layer_scaled_rect);
1335 // The bottom left of the bound is used for visibility because 1) the bound
1336 // edge rect is one-dimensional (no width), and 2) the bottom is the logical
1337 // focal point for bound selection handles (this may change in the future).
1338 const gfx::PointF& visibility_point = screen_rect.bottom_left();
1339 float intersect_distance = 0.f;
1340 result.visible = PointHitsLayer(layer, visibility_point, &intersect_distance);
1342 screen_rect.Scale(1.f / device_scale_factor);
1343 result.viewport_rect = screen_rect;
1345 return result;
1348 void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* anchor,
1349 ViewportSelectionBound* focus) {
1350 DCHECK(anchor);
1351 DCHECK(focus);
1353 *anchor = ComputeViewportSelection(
1354 selection_anchor_,
1355 selection_anchor_.layer_id ? LayerById(selection_anchor_.layer_id) : NULL,
1356 device_scale_factor());
1357 if (anchor->type == SELECTION_BOUND_CENTER ||
1358 anchor->type == SELECTION_BOUND_EMPTY) {
1359 *focus = *anchor;
1360 } else {
1361 *focus = ComputeViewportSelection(
1362 selection_focus_,
1363 selection_focus_.layer_id ? LayerById(selection_focus_.layer_id) : NULL,
1364 device_scale_factor());
1368 void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1369 layer_tree_host_impl_->RegisterPictureLayerImpl(layer);
1372 void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1373 layer_tree_host_impl_->UnregisterPictureLayerImpl(layer);
1376 void LayerTreeImpl::InputScrollAnimationFinished() {
1377 layer_tree_host_impl_->ScrollEnd();
1380 } // namespace cc