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"
10 #include "base/debug/trace_event.h"
11 #include "base/debug/trace_event_argument.h"
12 #include "cc/animation/keyframed_animation_curve.h"
13 #include "cc/animation/scrollbar_animation_controller.h"
14 #include "cc/animation/scrollbar_animation_controller_linear_fade.h"
15 #include "cc/animation/scrollbar_animation_controller_thinning.h"
16 #include "cc/base/math_util.h"
17 #include "cc/base/util.h"
18 #include "cc/debug/devtools_instrumentation.h"
19 #include "cc/debug/traced_value.h"
20 #include "cc/layers/heads_up_display_layer_impl.h"
21 #include "cc/layers/layer.h"
22 #include "cc/layers/layer_iterator.h"
23 #include "cc/layers/render_surface_impl.h"
24 #include "cc/layers/scrollbar_layer_impl_base.h"
25 #include "cc/resources/ui_resource_request.h"
26 #include "cc/trees/layer_tree_host_common.h"
27 #include "cc/trees/layer_tree_host_impl.h"
28 #include "cc/trees/occlusion_tracker.h"
29 #include "ui/gfx/point_conversions.h"
30 #include "ui/gfx/size_conversions.h"
31 #include "ui/gfx/vector2d_conversions.h"
35 // This class exists to split the LayerScrollOffsetDelegate between the
36 // InnerViewportScrollLayer and the OuterViewportScrollLayer in a manner
37 // that never requires the embedder or LayerImpl to know about.
38 class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
40 LayerScrollOffsetDelegateProxy(LayerImpl* layer,
41 LayerScrollOffsetDelegate* delegate,
42 LayerTreeImpl* layer_tree)
43 : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {}
44 virtual ~LayerScrollOffsetDelegateProxy() {}
46 gfx::Vector2dF last_set_scroll_offset() const {
47 return last_set_scroll_offset_;
50 // LayerScrollOffsetDelegate implementation.
51 virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_offset) OVERRIDE {
52 last_set_scroll_offset_ = new_offset;
53 layer_tree_impl_->UpdateScrollOffsetDelegate();
56 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
57 return layer_tree_impl_->GetDelegatedScrollOffset(layer_);
60 virtual bool IsExternalFlingActive() const OVERRIDE {
61 return delegate_->IsExternalFlingActive();
66 LayerScrollOffsetDelegate* delegate_;
67 LayerTreeImpl* layer_tree_impl_;
68 gfx::Vector2dF last_set_scroll_offset_;
71 LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
72 : layer_tree_host_impl_(layer_tree_host_impl),
73 source_frame_number_(-1),
75 currently_scrolling_layer_(NULL),
76 root_layer_scroll_offset_delegate_(NULL),
78 has_transparent_background_(false),
79 page_scale_layer_(NULL),
80 inner_viewport_scroll_layer_(NULL),
81 outer_viewport_scroll_layer_(NULL),
82 page_scale_factor_(1),
84 sent_page_scale_delta_(1),
85 min_page_scale_factor_(0),
86 max_page_scale_factor_(0),
87 scrolling_layer_id_from_previous_tree_(0),
88 contents_textures_purged_(false),
89 requires_high_res_to_draw_(false),
90 viewport_size_invalid_(false),
91 needs_update_draw_properties_(true),
92 needs_full_tree_sync_(true),
93 next_activation_forces_redraw_(false),
94 has_ever_been_drawn_(false),
95 render_surface_layer_list_id_(0) {
98 LayerTreeImpl::~LayerTreeImpl() {
99 BreakSwapPromises(SwapPromise::SWAP_FAILS);
101 // Need to explicitly clear the tree prior to destroying this so that
102 // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
103 DCHECK(!root_layer_);
104 DCHECK(layers_with_copy_output_request_.empty());
107 void LayerTreeImpl::Shutdown() { root_layer_.reset(); }
109 void LayerTreeImpl::ReleaseResources() {
111 ReleaseResourcesRecursive(root_layer_.get());
114 void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
115 if (inner_viewport_scroll_layer_)
116 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
117 if (outer_viewport_scroll_layer_)
118 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
119 inner_viewport_scroll_delegate_proxy_.reset();
120 outer_viewport_scroll_delegate_proxy_.reset();
122 root_layer_ = layer.Pass();
123 currently_scrolling_layer_ = NULL;
124 inner_viewport_scroll_layer_ = NULL;
125 outer_viewport_scroll_layer_ = NULL;
126 page_scale_layer_ = NULL;
128 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
131 LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const {
132 return inner_viewport_scroll_layer_;
135 LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const {
136 return outer_viewport_scroll_layer_;
139 gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const {
140 gfx::Vector2dF offset;
142 if (inner_viewport_scroll_layer_)
143 offset += inner_viewport_scroll_layer_->TotalScrollOffset();
145 if (outer_viewport_scroll_layer_)
146 offset += outer_viewport_scroll_layer_->TotalScrollOffset();
151 gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const {
152 gfx::Vector2dF offset;
154 if (inner_viewport_scroll_layer_)
155 offset += inner_viewport_scroll_layer_->MaxScrollOffset();
157 if (outer_viewport_scroll_layer_)
158 offset += outer_viewport_scroll_layer_->MaxScrollOffset();
162 gfx::Vector2dF LayerTreeImpl::TotalScrollDelta() const {
163 DCHECK(inner_viewport_scroll_layer_);
164 gfx::Vector2dF delta = inner_viewport_scroll_layer_->ScrollDelta();
166 if (outer_viewport_scroll_layer_)
167 delta += outer_viewport_scroll_layer_->ScrollDelta();
172 scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
173 // Clear all data structures that have direct references to the layer tree.
174 scrolling_layer_id_from_previous_tree_ =
175 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
176 if (inner_viewport_scroll_layer_)
177 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
178 if (outer_viewport_scroll_layer_)
179 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
180 inner_viewport_scroll_delegate_proxy_.reset();
181 outer_viewport_scroll_delegate_proxy_.reset();
182 inner_viewport_scroll_layer_ = NULL;
183 outer_viewport_scroll_layer_ = NULL;
184 page_scale_layer_ = NULL;
185 currently_scrolling_layer_ = NULL;
187 render_surface_layer_list_.clear();
188 set_needs_update_draw_properties();
189 return root_layer_.Pass();
192 void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
193 // The request queue should have been processed and does not require a push.
194 DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
196 if (next_activation_forces_redraw_) {
197 target_tree->ForceRedrawNextActivation();
198 next_activation_forces_redraw_ = false;
201 target_tree->PassSwapPromises(&swap_promise_list_);
203 target_tree->SetPageScaleValues(
204 page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(),
205 target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
206 target_tree->set_sent_page_scale_delta(1);
208 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
209 target_tree->SetViewportLayersFromIds(
210 page_scale_layer_->id(),
211 inner_viewport_scroll_layer_->id(),
212 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
213 : Layer::INVALID_ID);
215 target_tree->ClearViewportLayers();
218 target_tree->RegisterSelection(selection_start_, selection_end_);
220 // This should match the property synchronization in
221 // LayerTreeHost::finishCommitOnImplThread().
222 target_tree->set_source_frame_number(source_frame_number());
223 target_tree->set_background_color(background_color());
224 target_tree->set_has_transparent_background(has_transparent_background());
226 if (ContentsTexturesPurged())
227 target_tree->SetContentsTexturesPurged();
229 target_tree->ResetContentsTexturesPurged();
231 if (ViewportSizeInvalid())
232 target_tree->SetViewportSizeInvalid();
234 target_tree->ResetViewportSizeInvalid();
237 target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
238 LayerTreeHostCommon::FindLayerInSubtree(
239 target_tree->root_layer(), hud_layer()->id())));
241 target_tree->set_hud_layer(NULL);
243 target_tree->has_ever_been_drawn_ = false;
246 LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const {
247 return inner_viewport_scroll_layer_
248 ? inner_viewport_scroll_layer_->scroll_clip_layer()
252 LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const {
253 DCHECK(IsActiveTree());
254 return currently_scrolling_layer_;
257 void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) {
258 if (currently_scrolling_layer_ == layer)
261 if (currently_scrolling_layer_ &&
262 currently_scrolling_layer_->scrollbar_animation_controller())
263 currently_scrolling_layer_->scrollbar_animation_controller()
265 currently_scrolling_layer_ = layer;
266 if (layer && layer->scrollbar_animation_controller())
267 layer->scrollbar_animation_controller()->DidScrollBegin();
270 void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
271 SetCurrentlyScrollingLayer(NULL);
272 scrolling_layer_id_from_previous_tree_ = 0;
275 float LayerTreeImpl::VerticalAdjust(const int clip_layer_id) const {
276 LayerImpl* container_layer = InnerViewportContainerLayer();
277 if (!container_layer || clip_layer_id != container_layer->id())
280 return layer_tree_host_impl_->VerticalAdjust();
285 void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
289 while (current_layer) {
290 current_layer->ScrollbarParametersDidChange();
291 current_layer = current_layer->parent();
297 void LayerTreeImpl::SetPageScaleFactorAndLimits(float page_scale_factor,
298 float min_page_scale_factor, float max_page_scale_factor) {
299 SetPageScaleValues(page_scale_factor, min_page_scale_factor,
300 max_page_scale_factor, page_scale_delta_);
303 void LayerTreeImpl::SetPageScaleDelta(float delta) {
304 SetPageScaleValues(page_scale_factor_, min_page_scale_factor_,
305 max_page_scale_factor_, delta);
308 void LayerTreeImpl::SetPageScaleValues(float page_scale_factor,
309 float min_page_scale_factor, float max_page_scale_factor,
310 float page_scale_delta) {
311 bool page_scale_changed =
312 min_page_scale_factor != min_page_scale_factor_ ||
313 max_page_scale_factor != max_page_scale_factor_ ||
314 page_scale_factor != page_scale_factor_;
316 min_page_scale_factor_ = min_page_scale_factor;
317 max_page_scale_factor_ = max_page_scale_factor;
318 page_scale_factor_ = page_scale_factor;
320 float total = page_scale_factor_ * page_scale_delta;
321 if (min_page_scale_factor_ && total < min_page_scale_factor_)
322 page_scale_delta = min_page_scale_factor_ / page_scale_factor_;
323 else if (max_page_scale_factor_ && total > max_page_scale_factor_)
324 page_scale_delta = max_page_scale_factor_ / page_scale_factor_;
326 if (page_scale_delta_ == page_scale_delta && !page_scale_changed)
329 if (page_scale_delta_ != page_scale_delta) {
330 page_scale_delta_ = page_scale_delta;
332 if (IsActiveTree()) {
333 LayerTreeImpl* pending_tree = layer_tree_host_impl_->pending_tree();
335 DCHECK_EQ(1, pending_tree->sent_page_scale_delta());
336 pending_tree->SetPageScaleDelta(
337 page_scale_delta_ / sent_page_scale_delta_);
341 set_needs_update_draw_properties();
344 if (root_layer_scroll_offset_delegate_) {
345 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
347 TotalMaxScrollOffset(),
349 total_page_scale_factor(),
350 min_page_scale_factor_,
351 max_page_scale_factor_);
354 ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
357 gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
358 if (outer_viewport_scroll_layer_)
359 return layer_tree_host_impl_->UnscaledScrollableViewportSize();
361 return gfx::ScaleSize(
362 layer_tree_host_impl_->UnscaledScrollableViewportSize(),
363 1.0f / total_page_scale_factor());
366 gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
367 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
368 ? OuterViewportScrollLayer()
369 : InnerViewportScrollLayer();
370 if (!root_scroll_layer || root_scroll_layer->children().empty())
372 LayerImpl* layer = root_scroll_layer->children()[0];
373 return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
374 gfx::Rect(layer->content_bounds()));
377 static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) {
378 layer->ApplySentScrollDeltasFromAbortedCommit();
381 void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
382 DCHECK(IsActiveTree());
384 page_scale_factor_ *= sent_page_scale_delta_;
385 page_scale_delta_ /= sent_page_scale_delta_;
386 sent_page_scale_delta_ = 1.f;
391 LayerTreeHostCommon::CallFunctionForSubtree(
392 root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo));
395 static void ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl* layer) {
396 layer->ApplyScrollDeltasSinceBeginMainFrame();
399 void LayerTreeImpl::ApplyScrollDeltasSinceBeginMainFrame() {
400 DCHECK(IsPendingTree());
404 LayerTreeHostCommon::CallFunctionForSubtree(
405 root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginMainFrameTo));
408 void LayerTreeImpl::SetViewportLayersFromIds(
409 int page_scale_layer_id,
410 int inner_viewport_scroll_layer_id,
411 int outer_viewport_scroll_layer_id) {
412 page_scale_layer_ = LayerById(page_scale_layer_id);
413 DCHECK(page_scale_layer_);
415 inner_viewport_scroll_layer_ =
416 LayerById(inner_viewport_scroll_layer_id);
417 DCHECK(inner_viewport_scroll_layer_);
419 outer_viewport_scroll_layer_ =
420 LayerById(outer_viewport_scroll_layer_id);
421 DCHECK(outer_viewport_scroll_layer_ ||
422 outer_viewport_scroll_layer_id == Layer::INVALID_ID);
424 if (!root_layer_scroll_offset_delegate_)
427 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
428 new LayerScrollOffsetDelegateProxy(inner_viewport_scroll_layer_,
429 root_layer_scroll_offset_delegate_,
432 if (outer_viewport_scroll_layer_)
433 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
434 new LayerScrollOffsetDelegateProxy(outer_viewport_scroll_layer_,
435 root_layer_scroll_offset_delegate_,
439 void LayerTreeImpl::ClearViewportLayers() {
440 page_scale_layer_ = NULL;
441 inner_viewport_scroll_layer_ = NULL;
442 outer_viewport_scroll_layer_ = NULL;
445 bool LayerTreeImpl::UpdateDrawProperties() {
446 if (!needs_update_draw_properties_)
449 // For max_texture_size.
450 if (!layer_tree_host_impl_->renderer())
456 needs_update_draw_properties_ = false;
457 render_surface_layer_list_.clear();
461 "LayerTreeImpl::UpdateDrawProperties",
465 source_frame_number_);
466 LayerImpl* page_scale_layer =
467 page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
468 bool can_render_to_separate_surface = !resourceless_software_draw();
470 ++render_surface_layer_list_id_;
471 LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
474 layer_tree_host_impl_->DrawTransform(),
475 device_scale_factor(),
476 total_page_scale_factor(),
479 settings().can_use_lcd_text,
480 can_render_to_separate_surface,
481 settings().layer_transforms_should_scale_layer_contents,
482 &render_surface_layer_list_,
483 render_surface_layer_list_id_);
484 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
489 "LayerTreeImpl::UpdateTilePriorities",
493 source_frame_number_);
494 scoped_ptr<OcclusionTracker<LayerImpl> > occlusion_tracker;
495 if (settings().use_occlusion_for_tile_prioritization) {
496 occlusion_tracker.reset(new OcclusionTracker<LayerImpl>(
497 root_layer()->render_surface()->content_rect()));
498 occlusion_tracker->set_minimum_tracking_size(
499 settings().minimum_occlusion_tracking_size);
502 // LayerIterator is used here instead of CallFunctionForSubtree to only
503 // UpdateTilePriorities on layers that will be visible (and thus have valid
504 // draw properties) and not because any ordering is required.
505 typedef LayerIterator<LayerImpl> LayerIteratorType;
506 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
507 for (LayerIteratorType it =
508 LayerIteratorType::Begin(&render_surface_layer_list_);
511 if (occlusion_tracker)
512 occlusion_tracker->EnterLayer(it);
514 LayerImpl* layer = *it;
515 if (it.represents_itself())
516 layer->UpdateTiles(occlusion_tracker.get());
518 if (!it.represents_contributing_render_surface()) {
519 if (occlusion_tracker)
520 occlusion_tracker->LeaveLayer(it);
524 if (layer->mask_layer())
525 layer->mask_layer()->UpdateTiles(occlusion_tracker.get());
526 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
527 layer->replica_layer()->mask_layer()->UpdateTiles(
528 occlusion_tracker.get());
530 if (occlusion_tracker)
531 occlusion_tracker->LeaveLayer(it);
535 DCHECK(!needs_update_draw_properties_) <<
536 "CalcDrawProperties should not set_needs_update_draw_properties()";
540 const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
541 // If this assert triggers, then the list is dirty.
542 DCHECK(!needs_update_draw_properties_);
543 return render_surface_layer_list_;
546 gfx::Size LayerTreeImpl::ScrollableSize() const {
547 LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
548 ? OuterViewportScrollLayer()
549 : InnerViewportScrollLayer();
550 if (!root_scroll_layer || root_scroll_layer->children().empty())
552 return root_scroll_layer->children()[0]->bounds();
555 LayerImpl* LayerTreeImpl::LayerById(int id) {
556 LayerIdMap::iterator iter = layer_id_map_.find(id);
557 return iter != layer_id_map_.end() ? iter->second : NULL;
560 void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
561 DCHECK(!LayerById(layer->id()));
562 layer_id_map_[layer->id()] = layer;
565 void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
566 DCHECK(LayerById(layer->id()));
567 layer_id_map_.erase(layer->id());
570 size_t LayerTreeImpl::NumLayers() {
571 return layer_id_map_.size();
574 void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
575 pending_tree->SetCurrentlyScrollingLayer(
576 LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(),
577 currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0));
580 static void DidBecomeActiveRecursive(LayerImpl* layer) {
581 layer->DidBecomeActive();
582 if (layer->mask_layer())
583 layer->mask_layer()->DidBecomeActive();
584 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
585 layer->replica_layer()->mask_layer()->DidBecomeActive();
587 for (size_t i = 0; i < layer->children().size(); ++i)
588 DidBecomeActiveRecursive(layer->children()[i]);
591 void LayerTreeImpl::DidBecomeActive() {
592 if (next_activation_forces_redraw_) {
593 layer_tree_host_impl_->SetFullRootLayerDamage();
594 next_activation_forces_redraw_ = false;
597 if (scrolling_layer_id_from_previous_tree_) {
598 currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree(
599 root_layer(), scrolling_layer_id_from_previous_tree_);
602 // Always reset this flag on activation, as we would only have activated
603 // if we were in a good state.
604 ResetRequiresHighResToDraw();
607 DidBecomeActiveRecursive(root_layer());
609 devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(),
610 source_frame_number_);
613 bool LayerTreeImpl::ContentsTexturesPurged() const {
614 return contents_textures_purged_;
617 void LayerTreeImpl::SetContentsTexturesPurged() {
618 if (contents_textures_purged_)
620 contents_textures_purged_ = true;
621 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
624 void LayerTreeImpl::ResetContentsTexturesPurged() {
625 if (!contents_textures_purged_)
627 contents_textures_purged_ = false;
628 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
631 void LayerTreeImpl::SetRequiresHighResToDraw() {
632 requires_high_res_to_draw_ = true;
635 void LayerTreeImpl::ResetRequiresHighResToDraw() {
636 requires_high_res_to_draw_ = false;
639 bool LayerTreeImpl::RequiresHighResToDraw() const {
640 return requires_high_res_to_draw_;
643 bool LayerTreeImpl::ViewportSizeInvalid() const {
644 return viewport_size_invalid_;
647 void LayerTreeImpl::SetViewportSizeInvalid() {
648 viewport_size_invalid_ = true;
649 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
652 void LayerTreeImpl::ResetViewportSizeInvalid() {
653 viewport_size_invalid_ = false;
654 layer_tree_host_impl_->OnCanDrawStateChangedForTree();
657 Proxy* LayerTreeImpl::proxy() const {
658 return layer_tree_host_impl_->proxy();
661 const LayerTreeSettings& LayerTreeImpl::settings() const {
662 return layer_tree_host_impl_->settings();
665 const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const {
666 return layer_tree_host_impl_->GetRendererCapabilities();
669 ContextProvider* LayerTreeImpl::context_provider() const {
670 return output_surface()->context_provider();
673 OutputSurface* LayerTreeImpl::output_surface() const {
674 return layer_tree_host_impl_->output_surface();
677 ResourceProvider* LayerTreeImpl::resource_provider() const {
678 return layer_tree_host_impl_->resource_provider();
681 TileManager* LayerTreeImpl::tile_manager() const {
682 return layer_tree_host_impl_->tile_manager();
685 FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
686 return layer_tree_host_impl_->fps_counter();
689 PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
690 return layer_tree_host_impl_->paint_time_counter();
693 MemoryHistory* LayerTreeImpl::memory_history() const {
694 return layer_tree_host_impl_->memory_history();
697 bool LayerTreeImpl::resourceless_software_draw() const {
698 return layer_tree_host_impl_->GetDrawMode() ==
699 DRAW_MODE_RESOURCELESS_SOFTWARE;
702 gfx::Size LayerTreeImpl::device_viewport_size() const {
703 return layer_tree_host_impl_->device_viewport_size();
706 bool LayerTreeImpl::IsActiveTree() const {
707 return layer_tree_host_impl_->active_tree() == this;
710 bool LayerTreeImpl::IsPendingTree() const {
711 return layer_tree_host_impl_->pending_tree() == this;
714 bool LayerTreeImpl::IsRecycleTree() const {
715 return layer_tree_host_impl_->recycle_tree() == this;
718 LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
719 LayerTreeImpl* tree = layer_tree_host_impl_->active_tree();
722 return tree->LayerById(id);
725 LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
726 LayerTreeImpl* tree = layer_tree_host_impl_->pending_tree();
729 return tree->LayerById(id);
732 LayerImpl* LayerTreeImpl::FindRecycleTreeLayerById(int id) {
733 LayerTreeImpl* tree = layer_tree_host_impl_->recycle_tree();
736 return tree->LayerById(id);
739 int LayerTreeImpl::MaxTextureSize() const {
740 return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size;
743 bool LayerTreeImpl::PinchGestureActive() const {
744 return layer_tree_host_impl_->pinch_gesture_active();
747 base::TimeTicks LayerTreeImpl::CurrentFrameTimeTicks() const {
748 return layer_tree_host_impl_->CurrentFrameTimeTicks();
751 base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
752 return layer_tree_host_impl_->begin_impl_frame_interval();
755 void LayerTreeImpl::SetNeedsCommit() {
756 layer_tree_host_impl_->SetNeedsCommit();
759 gfx::Rect LayerTreeImpl::DeviceViewport() const {
760 return layer_tree_host_impl_->DeviceViewport();
763 gfx::Size LayerTreeImpl::DrawViewportSize() const {
764 return layer_tree_host_impl_->DrawViewportSize();
767 const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
768 return layer_tree_host_impl_->ViewportRectForTilePriority();
771 scoped_ptr<ScrollbarAnimationController>
772 LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
773 DCHECK(settings().scrollbar_fade_delay_ms);
774 DCHECK(settings().scrollbar_fade_duration_ms);
775 base::TimeDelta delay =
776 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
777 base::TimeDelta duration =
778 base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
779 switch (settings().scrollbar_animator) {
780 case LayerTreeSettings::LinearFade: {
781 return ScrollbarAnimationControllerLinearFade::Create(
782 scrolling_layer, layer_tree_host_impl_, delay, duration)
783 .PassAs<ScrollbarAnimationController>();
785 case LayerTreeSettings::Thinning: {
786 return ScrollbarAnimationControllerThinning::Create(
787 scrolling_layer, layer_tree_host_impl_, delay, duration)
788 .PassAs<ScrollbarAnimationController>();
790 case LayerTreeSettings::NoAnimator:
794 return scoped_ptr<ScrollbarAnimationController>();
797 void LayerTreeImpl::DidAnimateScrollOffset() {
798 layer_tree_host_impl_->DidAnimateScrollOffset();
801 bool LayerTreeImpl::use_gpu_rasterization() const {
802 return layer_tree_host_impl_->use_gpu_rasterization();
805 bool LayerTreeImpl::create_low_res_tiling() const {
806 return layer_tree_host_impl_->create_low_res_tiling();
809 void LayerTreeImpl::SetNeedsRedraw() {
810 layer_tree_host_impl_->SetNeedsRedraw();
813 const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
814 return layer_tree_host_impl_->debug_state();
817 float LayerTreeImpl::device_scale_factor() const {
818 return layer_tree_host_impl_->device_scale_factor();
821 DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
822 return layer_tree_host_impl_->debug_rect_history();
825 AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
826 return layer_tree_host_impl_->animation_registrar();
829 void LayerTreeImpl::AsValueInto(base::debug::TracedValue* state) const {
830 TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this);
832 state->BeginDictionary("root_layer");
833 root_layer_->AsValueInto(state);
834 state->EndDictionary();
836 state->BeginArray("render_surface_layer_list");
837 typedef LayerIterator<LayerImpl> LayerIteratorType;
838 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
839 for (LayerIteratorType it = LayerIteratorType::Begin(
840 &render_surface_layer_list_); it != end; ++it) {
841 if (!it.represents_itself())
843 TracedValue::AppendIDRef(*it, state);
848 void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
849 LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
850 if (root_layer_scroll_offset_delegate_ == root_layer_scroll_offset_delegate)
853 if (!root_layer_scroll_offset_delegate) {
854 // Make sure we remove the proxies from their layers before
856 if (InnerViewportScrollLayer())
857 InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
858 if (OuterViewportScrollLayer())
859 OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
860 inner_viewport_scroll_delegate_proxy_.reset();
861 outer_viewport_scroll_delegate_proxy_.reset();
864 root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
866 if (root_layer_scroll_offset_delegate_) {
867 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
869 TotalMaxScrollOffset(),
871 total_page_scale_factor(),
872 min_page_scale_factor(),
873 max_page_scale_factor());
875 if (inner_viewport_scroll_layer_) {
876 inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
877 new LayerScrollOffsetDelegateProxy(InnerViewportScrollLayer(),
878 root_layer_scroll_offset_delegate_,
880 inner_viewport_scroll_layer_->SetScrollOffsetDelegate(
881 inner_viewport_scroll_delegate_proxy_.get());
884 if (outer_viewport_scroll_layer_) {
885 outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
886 new LayerScrollOffsetDelegateProxy(OuterViewportScrollLayer(),
887 root_layer_scroll_offset_delegate_,
889 outer_viewport_scroll_layer_->SetScrollOffsetDelegate(
890 outer_viewport_scroll_delegate_proxy_.get());
895 void LayerTreeImpl::UpdateScrollOffsetDelegate() {
896 DCHECK(InnerViewportScrollLayer());
897 DCHECK(root_layer_scroll_offset_delegate_);
899 gfx::Vector2dF offset =
900 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
902 if (OuterViewportScrollLayer())
903 offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
905 root_layer_scroll_offset_delegate_->UpdateRootLayerState(
907 TotalMaxScrollOffset(),
909 total_page_scale_factor(),
910 min_page_scale_factor(),
911 max_page_scale_factor());
914 gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) {
915 DCHECK(root_layer_scroll_offset_delegate_);
916 DCHECK(InnerViewportScrollLayer());
917 if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer())
918 return root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
920 // If we get here, we have both inner/outer viewports, and need to distribute
921 // the scroll offset between them.
922 DCHECK(inner_viewport_scroll_delegate_proxy_);
923 DCHECK(outer_viewport_scroll_delegate_proxy_);
924 gfx::Vector2dF inner_viewport_offset =
925 inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
926 gfx::Vector2dF outer_viewport_offset =
927 outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
929 // It may be nothing has changed.
930 gfx::Vector2dF delegate_offset =
931 root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
932 if (inner_viewport_offset + outer_viewport_offset == delegate_offset) {
933 if (layer == InnerViewportScrollLayer())
934 return inner_viewport_offset;
936 return outer_viewport_offset;
939 gfx::Vector2d max_outer_viewport_scroll_offset =
940 OuterViewportScrollLayer()->MaxScrollOffset();
942 outer_viewport_offset = delegate_offset - inner_viewport_offset;
943 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
944 outer_viewport_offset.SetToMax(gfx::Vector2d());
946 if (layer == OuterViewportScrollLayer())
947 return outer_viewport_offset;
949 inner_viewport_offset = delegate_offset - outer_viewport_offset;
951 return inner_viewport_offset;
954 void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
955 DCHECK(swap_promise);
956 swap_promise_list_.push_back(swap_promise.Pass());
959 void LayerTreeImpl::PassSwapPromises(
960 ScopedPtrVector<SwapPromise>* new_swap_promise) {
961 swap_promise_list_.insert_and_take(swap_promise_list_.end(),
963 new_swap_promise->clear();
966 void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
967 for (size_t i = 0; i < swap_promise_list_.size(); i++)
968 swap_promise_list_[i]->DidSwap(metadata);
969 swap_promise_list_.clear();
972 void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
973 for (size_t i = 0; i < swap_promise_list_.size(); i++)
974 swap_promise_list_[i]->DidNotSwap(reason);
975 swap_promise_list_.clear();
978 void LayerTreeImpl::DidModifyTilePriorities() {
979 layer_tree_host_impl_->DidModifyTilePriorities();
982 void LayerTreeImpl::set_ui_resource_request_queue(
983 const UIResourceRequestQueue& queue) {
984 ui_resource_request_queue_ = queue;
987 ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
988 UIResourceId uid) const {
989 return layer_tree_host_impl_->ResourceIdForUIResource(uid);
992 bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
993 return layer_tree_host_impl_->IsUIResourceOpaque(uid);
996 void LayerTreeImpl::ProcessUIResourceRequestQueue() {
997 while (ui_resource_request_queue_.size() > 0) {
998 UIResourceRequest req = ui_resource_request_queue_.front();
999 ui_resource_request_queue_.pop_front();
1001 switch (req.GetType()) {
1002 case UIResourceRequest::UIResourceCreate:
1003 layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
1005 case UIResourceRequest::UIResourceDelete:
1006 layer_tree_host_impl_->DeleteUIResource(req.GetId());
1008 case UIResourceRequest::UIResourceInvalidRequest:
1014 // If all UI resource evictions were not recreated by processing this queue,
1015 // then another commit is required.
1016 if (layer_tree_host_impl_->EvictedUIResourcesExist())
1017 layer_tree_host_impl_->SetNeedsCommit();
1020 void LayerTreeImpl::AddLayerWithCopyOutputRequest(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());
1025 // DCHECK(std::find(layers_with_copy_output_request_.begin(),
1026 // layers_with_copy_output_request_.end(),
1027 // layer) == layers_with_copy_output_request_.end());
1028 // TODO(danakj): Remove this once crash is found crbug.com/309777
1029 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1030 CHECK(layers_with_copy_output_request_[i] != layer)
1031 << i << " of " << layers_with_copy_output_request_.size();
1033 layers_with_copy_output_request_.push_back(layer);
1036 void LayerTreeImpl::RemoveLayerWithCopyOutputRequest(LayerImpl* layer) {
1037 // Only the active tree needs to know about layers with copy requests, as
1038 // they are aborted if not serviced during draw.
1039 DCHECK(IsActiveTree());
1041 std::vector<LayerImpl*>::iterator it = std::find(
1042 layers_with_copy_output_request_.begin(),
1043 layers_with_copy_output_request_.end(),
1045 DCHECK(it != layers_with_copy_output_request_.end());
1046 layers_with_copy_output_request_.erase(it);
1048 // TODO(danakj): Remove this once crash is found crbug.com/309777
1049 for (size_t i = 0; i < layers_with_copy_output_request_.size(); ++i) {
1050 CHECK(layers_with_copy_output_request_[i] != layer)
1051 << i << " of " << layers_with_copy_output_request_.size();
1055 const std::vector<LayerImpl*>& LayerTreeImpl::LayersWithCopyOutputRequest()
1057 // Only the active tree needs to know about layers with copy requests, as
1058 // they are aborted if not serviced during draw.
1059 DCHECK(IsActiveTree());
1061 return layers_with_copy_output_request_;
1064 void LayerTreeImpl::ReleaseResourcesRecursive(LayerImpl* current) {
1066 current->ReleaseResources();
1067 if (current->mask_layer())
1068 ReleaseResourcesRecursive(current->mask_layer());
1069 if (current->replica_layer())
1070 ReleaseResourcesRecursive(current->replica_layer());
1071 for (size_t i = 0; i < current->children().size(); ++i)
1072 ReleaseResourcesRecursive(current->children()[i]);
1075 template <typename LayerType>
1076 static inline bool LayerClipsSubtree(LayerType* layer) {
1077 return layer->masks_to_bounds() || layer->mask_layer();
1080 static bool PointHitsRect(
1081 const gfx::PointF& screen_space_point,
1082 const gfx::Transform& local_space_to_screen_space_transform,
1083 const gfx::RectF& local_space_rect,
1084 float* distance_to_camera) {
1085 // If the transform is not invertible, then assume that this point doesn't hit
1087 gfx::Transform inverse_local_space_to_screen_space(
1088 gfx::Transform::kSkipInitialization);
1089 if (!local_space_to_screen_space_transform.GetInverse(
1090 &inverse_local_space_to_screen_space))
1093 // Transform the hit test point from screen space to the local space of the
1095 bool clipped = false;
1096 gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1097 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1098 gfx::PointF hit_test_point_in_local_space =
1099 gfx::PointF(planar_point.x(), planar_point.y());
1101 // If ProjectPoint could not project to a valid value, then we assume that
1102 // this point doesn't hit this rect.
1106 if (!local_space_rect.Contains(hit_test_point_in_local_space))
1109 if (distance_to_camera) {
1110 // To compute the distance to the camera, we have to take the planar point
1111 // and pull it back to world space and compute the displacement along the
1113 gfx::Point3F planar_point_in_screen_space(planar_point);
1114 local_space_to_screen_space_transform.TransformPoint(
1115 &planar_point_in_screen_space);
1116 *distance_to_camera = planar_point_in_screen_space.z();
1122 static bool PointHitsRegion(const gfx::PointF& screen_space_point,
1123 const gfx::Transform& screen_space_transform,
1124 const Region& layer_space_region,
1125 float layer_content_scale_x,
1126 float layer_content_scale_y) {
1127 // If the transform is not invertible, then assume that this point doesn't hit
1129 gfx::Transform inverse_screen_space_transform(
1130 gfx::Transform::kSkipInitialization);
1131 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1134 // Transform the hit test point from screen space to the local space of the
1136 bool clipped = false;
1137 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1138 inverse_screen_space_transform, screen_space_point, &clipped);
1139 gfx::PointF hit_test_point_in_layer_space =
1140 gfx::ScalePoint(hit_test_point_in_content_space,
1141 1.f / layer_content_scale_x,
1142 1.f / layer_content_scale_y);
1144 // If ProjectPoint could not project to a valid value, then we assume that
1145 // this point doesn't hit this region.
1149 return layer_space_region.Contains(
1150 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1153 static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) {
1154 if (layer->scroll_parent())
1155 return layer->scroll_parent();
1156 if (layer->clip_parent())
1157 return layer->clip_parent();
1158 return layer->parent();
1161 static bool PointIsClippedBySurfaceOrClipRect(
1162 const gfx::PointF& screen_space_point,
1163 const LayerImpl* layer) {
1164 // Walk up the layer tree and hit-test any render_surfaces and any layer
1165 // clip rects that are active.
1166 for (; layer; layer = GetNextClippingLayer(layer)) {
1167 if (layer->render_surface() &&
1168 !PointHitsRect(screen_space_point,
1169 layer->render_surface()->screen_space_transform(),
1170 layer->render_surface()->content_rect(),
1174 if (LayerClipsSubtree(layer) &&
1175 !PointHitsRect(screen_space_point,
1176 layer->screen_space_transform(),
1177 gfx::Rect(layer->content_bounds()),
1182 // If we have finished walking all ancestors without having already exited,
1183 // then the point is not clipped by any ancestors.
1187 static bool PointHitsLayer(const LayerImpl* layer,
1188 const gfx::PointF& screen_space_point,
1189 float* distance_to_intersection) {
1190 gfx::RectF content_rect(layer->content_bounds());
1191 if (!PointHitsRect(screen_space_point,
1192 layer->screen_space_transform(),
1194 distance_to_intersection))
1197 // At this point, we think the point does hit the layer, but we need to walk
1198 // up the parents to ensure that the layer was not clipped in such a way
1199 // that the hit point actually should not hit the layer.
1200 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
1203 // Skip the HUD layer.
1204 if (layer == layer->layer_tree_impl()->hud_layer())
1210 struct FindClosestMatchingLayerDataForRecursion {
1211 FindClosestMatchingLayerDataForRecursion()
1212 : closest_match(NULL),
1213 closest_distance(-std::numeric_limits<float>::infinity()) {}
1214 LayerImpl* closest_match;
1215 // Note that the positive z-axis points towards the camera, so bigger means
1216 // closer in this case, counterintuitively.
1217 float closest_distance;
1220 template <typename Functor>
1221 static void FindClosestMatchingLayer(
1222 const gfx::PointF& screen_space_point,
1224 const Functor& func,
1225 FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
1226 for (int i = layer->children().size() - 1; i >= 0; --i) {
1227 FindClosestMatchingLayer(
1228 screen_space_point, layer->children()[i], func, data_for_recursion);
1231 float distance_to_intersection = 0.f;
1233 PointHitsLayer(layer, screen_space_point, &distance_to_intersection) &&
1234 ((!data_for_recursion->closest_match ||
1235 distance_to_intersection > data_for_recursion->closest_distance))) {
1236 data_for_recursion->closest_distance = distance_to_intersection;
1237 data_for_recursion->closest_match = layer;
1241 static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
1242 if (!layer->scrollable())
1244 if (layer->IsDrawnRenderSurfaceLayerListMember())
1246 if (!layer->scroll_children())
1248 for (std::set<LayerImpl*>::const_iterator it =
1249 layer->scroll_children()->begin();
1250 it != layer->scroll_children()->end();
1252 if ((*it)->IsDrawnRenderSurfaceLayerListMember())
1258 struct FindScrollingLayerFunctor {
1259 bool operator()(LayerImpl* layer) const {
1260 return ScrollsAnyDrawnRenderSurfaceLayerListMember(layer);
1264 LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
1265 const gfx::PointF& screen_space_point) {
1266 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1267 FindClosestMatchingLayer(screen_space_point,
1269 FindScrollingLayerFunctor(),
1270 &data_for_recursion);
1271 return data_for_recursion.closest_match;
1274 struct HitTestVisibleScrollableOrTouchableFunctor {
1275 bool operator()(LayerImpl* layer) const {
1276 return layer->IsDrawnRenderSurfaceLayerListMember() ||
1277 ScrollsAnyDrawnRenderSurfaceLayerListMember(layer) ||
1278 !layer->touch_event_handler_region().IsEmpty() ||
1279 layer->have_wheel_event_handlers();
1283 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
1284 const gfx::PointF& screen_space_point) {
1287 if (!UpdateDrawProperties())
1289 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1290 FindClosestMatchingLayer(screen_space_point,
1292 HitTestVisibleScrollableOrTouchableFunctor(),
1293 &data_for_recursion);
1294 return data_for_recursion.closest_match;
1297 static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
1298 LayerImpl* layer_impl) {
1299 if (layer_impl->touch_event_handler_region().IsEmpty())
1302 if (!PointHitsRegion(screen_space_point,
1303 layer_impl->screen_space_transform(),
1304 layer_impl->touch_event_handler_region(),
1305 layer_impl->contents_scale_x(),
1306 layer_impl->contents_scale_y()))
1309 // At this point, we think the point does hit the touch event handler region
1310 // on the layer, but we need to walk up the parents to ensure that the layer
1311 // was not clipped in such a way that the hit point actually should not hit
1313 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1319 struct FindTouchEventLayerFunctor {
1320 bool operator()(LayerImpl* layer) const {
1321 return LayerHasTouchEventHandlersAt(screen_space_point, layer);
1323 const gfx::PointF screen_space_point;
1326 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
1327 const gfx::PointF& screen_space_point) {
1330 if (!UpdateDrawProperties())
1332 FindTouchEventLayerFunctor func = {screen_space_point};
1333 FindClosestMatchingLayerDataForRecursion data_for_recursion;
1334 FindClosestMatchingLayer(
1335 screen_space_point, root_layer(), func, &data_for_recursion);
1336 return data_for_recursion.closest_match;
1339 void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& start,
1340 const LayerSelectionBound& end) {
1341 selection_start_ = start;
1342 selection_end_ = end;
1345 static ViewportSelectionBound ComputeViewportSelection(
1346 const LayerSelectionBound& bound,
1348 float device_scale_factor) {
1349 ViewportSelectionBound result;
1350 result.type = bound.type;
1352 if (!layer || bound.type == SELECTION_BOUND_EMPTY)
1355 gfx::RectF layer_scaled_rect = gfx::ScaleRect(
1356 bound.layer_rect, layer->contents_scale_x(), layer->contents_scale_y());
1357 gfx::RectF screen_rect = MathUtil::ProjectClippedRect(
1358 layer->screen_space_transform(), layer_scaled_rect);
1360 // The bottom left of the bound is used for visibility because 1) the bound
1361 // edge rect is one-dimensional (no width), and 2) the bottom is the logical
1362 // focal point for bound selection handles (this may change in the future).
1363 const gfx::PointF& visibility_point = screen_rect.bottom_left();
1364 float intersect_distance = 0.f;
1365 result.visible = PointHitsLayer(layer, visibility_point, &intersect_distance);
1367 screen_rect.Scale(1.f / device_scale_factor);
1368 result.viewport_rect = screen_rect;
1373 void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* start,
1374 ViewportSelectionBound* end) {
1378 *start = ComputeViewportSelection(
1380 selection_start_.layer_id ? LayerById(selection_start_.layer_id) : NULL,
1381 device_scale_factor());
1382 if (start->type == SELECTION_BOUND_CENTER ||
1383 start->type == SELECTION_BOUND_EMPTY) {
1386 *end = ComputeViewportSelection(
1388 selection_end_.layer_id ? LayerById(selection_end_.layer_id) : NULL,
1389 device_scale_factor());
1393 void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1394 layer_tree_host_impl_->RegisterPictureLayerImpl(layer);
1397 void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1398 layer_tree_host_impl_->UnregisterPictureLayerImpl(layer);
1401 void LayerTreeImpl::InputScrollAnimationFinished() {
1402 layer_tree_host_impl_->ScrollEnd();