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