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