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_host.h" 6 7 #include <algorithm> 8 #include <stack> 9 10 #include "base/bind.h" 11 #include "base/command_line.h" 12 #include "base/debug/trace_event.h" 13 #include "base/message_loop/message_loop.h" 14 #include "base/metrics/histogram.h" 15 #include "base/stl_util.h" 16 #include "base/strings/string_number_conversions.h" 17 #include "cc/animation/animation_registrar.h" 18 #include "cc/animation/layer_animation_controller.h" 19 #include "cc/base/math_util.h" 20 #include "cc/debug/benchmark_instrumentation.h" 21 #include "cc/debug/devtools_instrumentation.h" 22 #include "cc/debug/overdraw_metrics.h" 23 #include "cc/debug/rendering_stats_instrumentation.h" 24 #include "cc/input/top_controls_manager.h" 25 #include "cc/layers/heads_up_display_layer.h" 26 #include "cc/layers/heads_up_display_layer_impl.h" 27 #include "cc/layers/layer.h" 28 #include "cc/layers/layer_iterator.h" 29 #include "cc/layers/render_surface.h" 30 #include "cc/layers/scrollbar_layer.h" 31 #include "cc/resources/prioritized_resource_manager.h" 32 #include "cc/resources/ui_resource_client.h" 33 #include "cc/trees/layer_tree_host_client.h" 34 #include "cc/trees/layer_tree_host_common.h" 35 #include "cc/trees/layer_tree_host_impl.h" 36 #include "cc/trees/layer_tree_impl.h" 37 #include "cc/trees/occlusion_tracker.h" 38 #include "cc/trees/single_thread_proxy.h" 39 #include "cc/trees/thread_proxy.h" 40 #include "cc/trees/tree_synchronizer.h" 41 #include "ui/gfx/size_conversions.h" 42 43 namespace { 44 static int s_num_layer_tree_instances; 45 } 46 47 namespace cc { 48 49 RendererCapabilities::RendererCapabilities() 50 : best_texture_format(0), 51 using_partial_swap(false), 52 using_set_visibility(false), 53 using_egl_image(false), 54 allow_partial_texture_updates(false), 55 using_offscreen_context3d(false), 56 max_texture_size(0), 57 avoid_pow2_textures(false), 58 using_map_image(false), 59 using_shared_memory_resources(false) {} 60 61 RendererCapabilities::~RendererCapabilities() {} 62 63 UIResourceRequest::UIResourceRequest() 64 : type(UIResourceInvalidRequest), id(0), bitmap(NULL) {} 65 66 UIResourceRequest::~UIResourceRequest() {} 67 68 bool LayerTreeHost::AnyLayerTreeHostInstanceExists() { 69 return s_num_layer_tree_instances > 0; 70 } 71 72 scoped_ptr<LayerTreeHost> LayerTreeHost::Create( 73 LayerTreeHostClient* client, 74 const LayerTreeSettings& settings, 75 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { 76 scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(client, 77 settings)); 78 if (!layer_tree_host->Initialize(impl_task_runner)) 79 return scoped_ptr<LayerTreeHost>(); 80 return layer_tree_host.Pass(); 81 } 82 83 static int s_next_tree_id = 1; 84 85 LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, 86 const LayerTreeSettings& settings) 87 : next_ui_resource_id_(1), 88 animating_(false), 89 needs_full_tree_sync_(true), 90 needs_filter_context_(false), 91 client_(client), 92 source_frame_number_(0), 93 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()), 94 output_surface_can_be_initialized_(true), 95 output_surface_lost_(true), 96 num_failed_recreate_attempts_(0), 97 settings_(settings), 98 debug_state_(settings.initial_debug_state), 99 overdraw_bottom_height_(0.f), 100 device_scale_factor_(1.f), 101 visible_(true), 102 page_scale_factor_(1.f), 103 min_page_scale_factor_(1.f), 104 max_page_scale_factor_(1.f), 105 trigger_idle_updates_(true), 106 background_color_(SK_ColorWHITE), 107 has_transparent_background_(false), 108 partial_texture_update_requests_(0), 109 in_paint_layer_contents_(false), 110 total_frames_used_for_lcd_text_metrics_(0), 111 tree_id_(s_next_tree_id++) { 112 if (settings_.accelerated_animation_enabled) 113 animation_registrar_ = AnimationRegistrar::Create(); 114 s_num_layer_tree_instances++; 115 rendering_stats_instrumentation_->set_record_rendering_stats( 116 debug_state_.RecordRenderingStats()); 117 } 118 119 bool LayerTreeHost::Initialize( 120 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { 121 if (impl_task_runner.get()) 122 return InitializeProxy(ThreadProxy::Create(this, impl_task_runner)); 123 else 124 return InitializeProxy(SingleThreadProxy::Create(this)); 125 } 126 127 bool LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) { 128 return InitializeProxy(proxy_for_testing.Pass()); 129 } 130 131 bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { 132 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); 133 134 scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); 135 if (!output_surface) 136 return false; 137 138 proxy_ = proxy.Pass(); 139 proxy_->Start(output_surface.Pass()); 140 return true; 141 } 142 143 LayerTreeHost::~LayerTreeHost() { 144 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost"); 145 if (root_layer_.get()) 146 root_layer_->SetLayerTreeHost(NULL); 147 148 if (proxy_) { 149 DCHECK(proxy_->IsMainThread()); 150 proxy_->Stop(); 151 } 152 153 s_num_layer_tree_instances--; 154 RateLimiterMap::iterator it = rate_limiters_.begin(); 155 if (it != rate_limiters_.end()) 156 it->second->Stop(); 157 158 if (root_layer_.get()) { 159 // The layer tree must be destroyed before the layer tree host. We've 160 // made a contract with our animation controllers that the registrar 161 // will outlive them, and we must make good. 162 root_layer_ = NULL; 163 } 164 } 165 166 void LayerTreeHost::SetLayerTreeHostClientReady() { 167 proxy_->SetLayerTreeHostClientReady(); 168 } 169 170 LayerTreeHost::CreateResult 171 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) { 172 TRACE_EVENT1("cc", 173 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted", 174 "success", 175 success); 176 177 DCHECK(output_surface_lost_); 178 if (success) { 179 output_surface_lost_ = false; 180 181 // Update settings_ based on partial update capability. 182 size_t max_partial_texture_updates = 0; 183 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates && 184 !settings_.impl_side_painting) { 185 max_partial_texture_updates = std::min( 186 settings_.max_partial_texture_updates, 187 proxy_->MaxPartialTextureUpdates()); 188 } 189 settings_.max_partial_texture_updates = max_partial_texture_updates; 190 191 if (!contents_texture_manager_ && 192 (!settings_.impl_side_painting || !settings_.solid_color_scrollbars)) { 193 contents_texture_manager_ = 194 PrioritizedResourceManager::Create(proxy_.get()); 195 surface_memory_placeholder_ = 196 contents_texture_manager_->CreateTexture(gfx::Size(), GL_RGBA); 197 } 198 199 client_->DidInitializeOutputSurface(true); 200 return CreateSucceeded; 201 } 202 203 // Failure path. 204 205 client_->DidFailToInitializeOutputSurface(); 206 207 // Tolerate a certain number of recreation failures to work around races 208 // in the output-surface-lost machinery. 209 ++num_failed_recreate_attempts_; 210 if (num_failed_recreate_attempts_ >= 5) { 211 // We have tried too many times to recreate the output surface. Tell the 212 // host to fall back to software rendering. 213 output_surface_can_be_initialized_ = false; 214 client_->DidInitializeOutputSurface(false); 215 return CreateFailedAndGaveUp; 216 } 217 218 return CreateFailedButTryAgain; 219 } 220 221 void LayerTreeHost::DeleteContentsTexturesOnImplThread( 222 ResourceProvider* resource_provider) { 223 DCHECK(proxy_->IsImplThread()); 224 if (contents_texture_manager_) 225 contents_texture_manager_->ClearAllMemory(resource_provider); 226 } 227 228 void LayerTreeHost::AcquireLayerTextures() { 229 DCHECK(proxy_->IsMainThread()); 230 proxy_->AcquireLayerTextures(); 231 } 232 233 void LayerTreeHost::DidBeginFrame() { 234 client_->DidBeginFrame(); 235 } 236 237 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) { 238 animating_ = true; 239 client_->Animate((frame_begin_time - base::TimeTicks()).InSecondsF()); 240 animating_ = false; 241 } 242 243 void LayerTreeHost::DidStopFlinging() { 244 proxy_->MainThreadHasStoppedFlinging(); 245 } 246 247 void LayerTreeHost::Layout() { 248 client_->Layout(); 249 } 250 251 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) { 252 DCHECK(proxy_->IsImplThread()); 253 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo"); 254 } 255 256 // This function commits the LayerTreeHost to an impl tree. When modifying 257 // this function, keep in mind that the function *runs* on the impl thread! Any 258 // code that is logically a main thread operation, e.g. deletion of a Layer, 259 // should be delayed until the LayerTreeHost::CommitComplete, which will run 260 // after the commit, but on the main thread. 261 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { 262 DCHECK(proxy_->IsImplThread()); 263 264 // If there are linked evicted backings, these backings' resources may be put 265 // into the impl tree, so we can't draw yet. Determine this before clearing 266 // all evicted backings. 267 bool new_impl_tree_has_no_evicted_resources = false; 268 if (contents_texture_manager_) { 269 new_impl_tree_has_no_evicted_resources = 270 !contents_texture_manager_->LinkedEvictedBackingsExist(); 271 272 // If the memory limit has been increased since this now-finishing 273 // commit began, and the extra now-available memory would have been used, 274 // then request another commit. 275 if (contents_texture_manager_->MaxMemoryLimitBytes() < 276 host_impl->memory_allocation_limit_bytes() && 277 contents_texture_manager_->MaxMemoryLimitBytes() < 278 contents_texture_manager_->MaxMemoryNeededBytes()) { 279 host_impl->SetNeedsCommit(); 280 } 281 282 host_impl->set_max_memory_needed_bytes( 283 contents_texture_manager_->MaxMemoryNeededBytes()); 284 285 contents_texture_manager_->UpdateBackingsInDrawingImplTree(); 286 } 287 288 // In impl-side painting, synchronize to the pending tree so that it has 289 // time to raster before being displayed. If no pending tree is needed, 290 // synchronization can happen directly to the active tree and 291 // unlinked contents resources can be reclaimed immediately. 292 LayerTreeImpl* sync_tree; 293 if (settings_.impl_side_painting) { 294 // Commits should not occur while there is already a pending tree. 295 DCHECK(!host_impl->pending_tree()); 296 host_impl->CreatePendingTree(); 297 sync_tree = host_impl->pending_tree(); 298 } else { 299 contents_texture_manager_->ReduceMemory(host_impl->resource_provider()); 300 sync_tree = host_impl->active_tree(); 301 } 302 303 sync_tree->set_source_frame_number(source_frame_number()); 304 305 if (needs_full_tree_sync_) 306 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees( 307 root_layer(), sync_tree->DetachLayerTree(), sync_tree)); 308 { 309 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties"); 310 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer()); 311 } 312 313 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_); 314 needs_full_tree_sync_ = false; 315 316 if (hud_layer_.get()) { 317 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree( 318 sync_tree->root_layer(), hud_layer_->id()); 319 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl)); 320 } else { 321 sync_tree->set_hud_layer(NULL); 322 } 323 324 sync_tree->set_background_color(background_color_); 325 sync_tree->set_has_transparent_background(has_transparent_background_); 326 327 sync_tree->FindRootScrollLayer(); 328 329 float page_scale_delta, sent_page_scale_delta; 330 if (settings_.impl_side_painting) { 331 // Update the delta from the active tree, which may have 332 // adjusted its delta prior to the pending tree being created. 333 // This code is equivalent to that in LayerTreeImpl::SetPageScaleDelta. 334 DCHECK_EQ(1.f, sync_tree->sent_page_scale_delta()); 335 page_scale_delta = host_impl->active_tree()->page_scale_delta(); 336 sent_page_scale_delta = host_impl->active_tree()->sent_page_scale_delta(); 337 } else { 338 page_scale_delta = sync_tree->page_scale_delta(); 339 sent_page_scale_delta = sync_tree->sent_page_scale_delta(); 340 sync_tree->set_sent_page_scale_delta(1.f); 341 } 342 343 sync_tree->SetPageScaleFactorAndLimits(page_scale_factor_, 344 min_page_scale_factor_, 345 max_page_scale_factor_); 346 sync_tree->SetPageScaleDelta(page_scale_delta / sent_page_scale_delta); 347 sync_tree->SetLatencyInfo(latency_info_); 348 latency_info_.Clear(); 349 350 host_impl->SetViewportSize(device_viewport_size_); 351 host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_); 352 host_impl->SetDeviceScaleFactor(device_scale_factor_); 353 host_impl->SetDebugState(debug_state_); 354 if (pending_page_scale_animation_) { 355 host_impl->StartPageScaleAnimation( 356 pending_page_scale_animation_->target_offset, 357 pending_page_scale_animation_->use_anchor, 358 pending_page_scale_animation_->scale, 359 base::TimeTicks::Now(), 360 pending_page_scale_animation_->duration); 361 pending_page_scale_animation_.reset(); 362 } 363 364 if (!ui_resource_request_queue_.empty()) { 365 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_); 366 ui_resource_request_queue_.clear(); 367 // Process any ui resource requests in the queue. For impl-side-painting, 368 // the queue is processed in LayerTreeHostImpl::ActivatePendingTree. 369 if (!settings_.impl_side_painting) 370 sync_tree->ProcessUIResourceRequestQueue(); 371 } 372 373 DCHECK(!sync_tree->ViewportSizeInvalid()); 374 375 if (new_impl_tree_has_no_evicted_resources) { 376 if (sync_tree->ContentsTexturesPurged()) 377 sync_tree->ResetContentsTexturesPurged(); 378 } 379 380 if (!settings_.impl_side_painting) { 381 // If we're not in impl-side painting, the tree is immediately 382 // considered active. 383 sync_tree->DidBecomeActive(); 384 } 385 386 source_frame_number_++; 387 } 388 389 void LayerTreeHost::WillCommit() { 390 client_->WillCommit(); 391 } 392 393 void LayerTreeHost::UpdateHudLayer() { 394 if (debug_state_.ShowHudInfo()) { 395 if (!hud_layer_.get()) 396 hud_layer_ = HeadsUpDisplayLayer::Create(); 397 398 if (root_layer_.get() && !hud_layer_->parent()) 399 root_layer_->AddChild(hud_layer_); 400 } else if (hud_layer_.get()) { 401 hud_layer_->RemoveFromParent(); 402 hud_layer_ = NULL; 403 } 404 } 405 406 void LayerTreeHost::CommitComplete() { 407 client_->DidCommit(); 408 } 409 410 scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() { 411 return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4); 412 } 413 414 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( 415 LayerTreeHostImplClient* client) { 416 DCHECK(proxy_->IsImplThread()); 417 scoped_ptr<LayerTreeHostImpl> host_impl = 418 LayerTreeHostImpl::Create(settings_, 419 client, 420 proxy_.get(), 421 rendering_stats_instrumentation_.get()); 422 if (settings_.calculate_top_controls_position && 423 host_impl->top_controls_manager()) { 424 top_controls_manager_weak_ptr_ = 425 host_impl->top_controls_manager()->AsWeakPtr(); 426 } 427 input_handler_weak_ptr_ = host_impl->AsWeakPtr(); 428 return host_impl.Pass(); 429 } 430 431 void LayerTreeHost::DidLoseOutputSurface() { 432 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface"); 433 DCHECK(proxy_->IsMainThread()); 434 435 if (output_surface_lost_) 436 return; 437 438 DidLoseUIResources(); 439 440 num_failed_recreate_attempts_ = 0; 441 output_surface_lost_ = true; 442 SetNeedsCommit(); 443 } 444 445 bool LayerTreeHost::CompositeAndReadback(void* pixels, 446 gfx::Rect rect_in_device_viewport) { 447 trigger_idle_updates_ = false; 448 bool ret = proxy_->CompositeAndReadback(pixels, rect_in_device_viewport); 449 trigger_idle_updates_ = true; 450 return ret; 451 } 452 453 void LayerTreeHost::FinishAllRendering() { 454 proxy_->FinishAllRendering(); 455 } 456 457 void LayerTreeHost::SetDeferCommits(bool defer_commits) { 458 proxy_->SetDeferCommits(defer_commits); 459 } 460 461 void LayerTreeHost::DidDeferCommit() {} 462 463 void LayerTreeHost::SetNeedsDisplayOnAllLayers() { 464 std::stack<Layer*> layer_stack; 465 layer_stack.push(root_layer()); 466 while (!layer_stack.empty()) { 467 Layer* current_layer = layer_stack.top(); 468 layer_stack.pop(); 469 current_layer->SetNeedsDisplay(); 470 for (unsigned int i = 0; i < current_layer->children().size(); i++) { 471 layer_stack.push(current_layer->child_at(i)); 472 } 473 } 474 } 475 476 void LayerTreeHost::CollectRenderingStats(RenderingStats* stats) const { 477 CHECK(debug_state_.RecordRenderingStats()); 478 *stats = rendering_stats_instrumentation_->GetRenderingStats(); 479 } 480 481 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const { 482 return proxy_->GetRendererCapabilities(); 483 } 484 485 void LayerTreeHost::SetNeedsAnimate() { 486 DCHECK(proxy_->HasImplThread()); 487 proxy_->SetNeedsAnimate(); 488 } 489 490 void LayerTreeHost::SetNeedsUpdateLayers() { proxy_->SetNeedsUpdateLayers(); } 491 492 void LayerTreeHost::SetNeedsCommit() { 493 if (!prepaint_callback_.IsCancelled()) { 494 TRACE_EVENT_INSTANT0("cc", 495 "LayerTreeHost::SetNeedsCommit::cancel prepaint", 496 TRACE_EVENT_SCOPE_THREAD); 497 prepaint_callback_.Cancel(); 498 } 499 proxy_->SetNeedsCommit(); 500 } 501 502 void LayerTreeHost::SetNeedsFullTreeSync() { 503 needs_full_tree_sync_ = true; 504 SetNeedsCommit(); 505 } 506 507 void LayerTreeHost::SetNeedsRedraw() { 508 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_)); 509 } 510 511 void LayerTreeHost::SetNeedsRedrawRect(gfx::Rect damage_rect) { 512 proxy_->SetNeedsRedraw(damage_rect); 513 if (!proxy_->HasImplThread()) 514 client_->ScheduleComposite(); 515 } 516 517 bool LayerTreeHost::CommitRequested() const { 518 return proxy_->CommitRequested(); 519 } 520 521 void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events, 522 base::Time wall_clock_time) { 523 DCHECK(proxy_->IsMainThread()); 524 for (size_t event_index = 0; event_index < events->size(); ++event_index) { 525 int event_layer_id = (*events)[event_index].layer_id; 526 527 // Use the map of all controllers, not just active ones, since non-active 528 // controllers may still receive events for impl-only animations. 529 const AnimationRegistrar::AnimationControllerMap& animation_controllers = 530 animation_registrar_->all_animation_controllers(); 531 AnimationRegistrar::AnimationControllerMap::const_iterator iter = 532 animation_controllers.find(event_layer_id); 533 if (iter != animation_controllers.end()) { 534 switch ((*events)[event_index].type) { 535 case AnimationEvent::Started: 536 (*iter).second->NotifyAnimationStarted((*events)[event_index], 537 wall_clock_time.ToDoubleT()); 538 break; 539 540 case AnimationEvent::Finished: 541 (*iter).second->NotifyAnimationFinished((*events)[event_index], 542 wall_clock_time.ToDoubleT()); 543 break; 544 545 case AnimationEvent::PropertyUpdate: 546 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]); 547 break; 548 549 default: 550 NOTREACHED(); 551 } 552 } 553 } 554 } 555 556 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) { 557 if (root_layer_.get() == root_layer.get()) 558 return; 559 560 if (root_layer_.get()) 561 root_layer_->SetLayerTreeHost(NULL); 562 root_layer_ = root_layer; 563 if (root_layer_.get()) { 564 DCHECK(!root_layer_->parent()); 565 root_layer_->SetLayerTreeHost(this); 566 } 567 568 if (hud_layer_.get()) 569 hud_layer_->RemoveFromParent(); 570 571 SetNeedsFullTreeSync(); 572 } 573 574 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) { 575 LayerTreeDebugState new_debug_state = 576 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state); 577 578 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state)) 579 return; 580 581 debug_state_ = new_debug_state; 582 583 rendering_stats_instrumentation_->set_record_rendering_stats( 584 debug_state_.RecordRenderingStats()); 585 586 SetNeedsCommit(); 587 } 588 589 void LayerTreeHost::SetViewportSize(gfx::Size device_viewport_size) { 590 if (device_viewport_size == device_viewport_size_) 591 return; 592 593 device_viewport_size_ = device_viewport_size; 594 595 SetNeedsCommit(); 596 } 597 598 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) { 599 if (overdraw_bottom_height_ == overdraw_bottom_height) 600 return; 601 602 overdraw_bottom_height_ = overdraw_bottom_height; 603 SetNeedsCommit(); 604 } 605 606 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) { 607 DCHECK(CommitRequested()); 608 page_scale_factor_ *= page_scale_delta; 609 } 610 611 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor, 612 float min_page_scale_factor, 613 float max_page_scale_factor) { 614 if (page_scale_factor == page_scale_factor_ && 615 min_page_scale_factor == min_page_scale_factor_ && 616 max_page_scale_factor == max_page_scale_factor_) 617 return; 618 619 page_scale_factor_ = page_scale_factor; 620 min_page_scale_factor_ = min_page_scale_factor; 621 max_page_scale_factor_ = max_page_scale_factor; 622 SetNeedsCommit(); 623 } 624 625 void LayerTreeHost::SetVisible(bool visible) { 626 if (visible_ == visible) 627 return; 628 visible_ = visible; 629 if (!visible) 630 ReduceMemoryUsage(); 631 proxy_->SetVisible(visible); 632 } 633 634 void LayerTreeHost::SetLatencyInfo(const ui::LatencyInfo& latency_info) { 635 latency_info_.MergeWith(latency_info); 636 } 637 638 void LayerTreeHost::StartPageScaleAnimation(gfx::Vector2d target_offset, 639 bool use_anchor, 640 float scale, 641 base::TimeDelta duration) { 642 pending_page_scale_animation_.reset(new PendingPageScaleAnimation); 643 pending_page_scale_animation_->target_offset = target_offset; 644 pending_page_scale_animation_->use_anchor = use_anchor; 645 pending_page_scale_animation_->scale = scale; 646 pending_page_scale_animation_->duration = duration; 647 648 SetNeedsCommit(); 649 } 650 651 void LayerTreeHost::NotifyInputThrottledUntilCommit() { 652 proxy_->NotifyInputThrottledUntilCommit(); 653 } 654 655 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) { 656 if (!proxy_->HasImplThread()) 657 static_cast<SingleThreadProxy*>(proxy_.get())->CompositeImmediately( 658 frame_begin_time); 659 else 660 SetNeedsCommit(); 661 } 662 663 void LayerTreeHost::ScheduleComposite() { 664 client_->ScheduleComposite(); 665 } 666 667 bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() { 668 if (!output_surface_can_be_initialized_) 669 return false; 670 671 if (output_surface_lost_) 672 proxy_->CreateAndInitializeOutputSurface(); 673 return !output_surface_lost_; 674 } 675 676 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue, 677 size_t memory_allocation_limit_bytes) { 678 DCHECK(!output_surface_lost_); 679 680 if (!root_layer()) 681 return false; 682 683 DCHECK(!root_layer()->parent()); 684 685 if (contents_texture_manager_ && memory_allocation_limit_bytes) { 686 contents_texture_manager_->SetMaxMemoryLimitBytes( 687 memory_allocation_limit_bytes); 688 } 689 690 return UpdateLayers(root_layer(), queue); 691 } 692 693 static Layer* FindFirstScrollableLayer(Layer* layer) { 694 if (!layer) 695 return NULL; 696 697 if (layer->scrollable()) 698 return layer; 699 700 for (size_t i = 0; i < layer->children().size(); ++i) { 701 Layer* found = FindFirstScrollableLayer(layer->children()[i].get()); 702 if (found) 703 return found; 704 } 705 706 return NULL; 707 } 708 709 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) { 710 if (!layer->SupportsLCDText()) 711 return; 712 713 lcd_text_metrics_.total_num_cc_layers++; 714 if (layer->draw_properties().can_use_lcd_text) { 715 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++; 716 if (layer->contents_opaque()) 717 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++; 718 } 719 } 720 721 bool LayerTreeHost::UsingSharedMemoryResources() { 722 return GetRendererCapabilities().using_shared_memory_resources; 723 } 724 725 bool LayerTreeHost::UpdateLayers(Layer* root_layer, 726 ResourceUpdateQueue* queue) { 727 TRACE_EVENT1(benchmark_instrumentation::kCategory, 728 benchmark_instrumentation::kLayerTreeHostUpdateLayers, 729 benchmark_instrumentation::kSourceFrameNumber, 730 source_frame_number()); 731 732 RenderSurfaceLayerList update_list; 733 { 734 UpdateHudLayer(); 735 736 Layer* root_scroll = FindFirstScrollableLayer(root_layer); 737 738 if (hud_layer_) { 739 hud_layer_->PrepareForCalculateDrawProperties( 740 device_viewport_size(), device_scale_factor_); 741 } 742 743 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps"); 744 bool can_render_to_separate_surface = true; 745 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs( 746 root_layer, 747 device_viewport_size(), 748 gfx::Transform(), 749 device_scale_factor_, 750 page_scale_factor_, 751 root_scroll ? root_scroll->parent() : NULL, 752 GetRendererCapabilities().max_texture_size, 753 settings_.can_use_lcd_text, 754 can_render_to_separate_surface, 755 settings_.layer_transforms_should_scale_layer_contents, 756 false, 757 &update_list); 758 LayerTreeHostCommon::CalculateDrawProperties(&inputs); 759 760 if (total_frames_used_for_lcd_text_metrics_ <= 761 kTotalFramesToUseForLCDTextMetrics) { 762 LayerTreeHostCommon::CallFunctionForSubtree( 763 root_layer, 764 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback, 765 base::Unretained(this))); 766 total_frames_used_for_lcd_text_metrics_++; 767 } 768 769 if (total_frames_used_for_lcd_text_metrics_ == 770 kTotalFramesToUseForLCDTextMetrics) { 771 total_frames_used_for_lcd_text_metrics_++; 772 773 UMA_HISTOGRAM_PERCENTAGE( 774 "Renderer4.LCDText.PercentageOfCandidateLayers", 775 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 / 776 lcd_text_metrics_.total_num_cc_layers); 777 UMA_HISTOGRAM_PERCENTAGE( 778 "Renderer4.LCDText.PercentageOfAALayers", 779 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 / 780 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text); 781 } 782 } 783 784 // Reset partial texture update requests. 785 partial_texture_update_requests_ = 0; 786 787 bool did_paint_content = false; 788 bool need_more_updates = false; 789 PaintLayerContents( 790 update_list, queue, &did_paint_content, &need_more_updates); 791 if (trigger_idle_updates_ && need_more_updates) { 792 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task"); 793 prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint, 794 base::Unretained(this))); 795 static base::TimeDelta prepaint_delay = 796 base::TimeDelta::FromMilliseconds(100); 797 base::MessageLoop::current()->PostDelayedTask( 798 FROM_HERE, prepaint_callback_.callback(), prepaint_delay); 799 } 800 801 return did_paint_content; 802 } 803 804 void LayerTreeHost::TriggerPrepaint() { 805 prepaint_callback_.Cancel(); 806 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint"); 807 SetNeedsCommit(); 808 } 809 810 static void LayerTreeHostReduceMemoryCallback(Layer* layer) { 811 layer->ReduceMemoryUsage(); 812 } 813 814 void LayerTreeHost::ReduceMemoryUsage() { 815 if (!root_layer()) 816 return; 817 818 LayerTreeHostCommon::CallFunctionForSubtree( 819 root_layer(), 820 base::Bind(&LayerTreeHostReduceMemoryCallback)); 821 } 822 823 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) { 824 DCHECK(surface_memory_placeholder_); 825 826 // Surfaces have a place holder for their memory since they are managed 827 // independantly but should still be tracked and reduce other memory usage. 828 surface_memory_placeholder_->SetTextureManager( 829 contents_texture_manager_.get()); 830 surface_memory_placeholder_->set_request_priority( 831 PriorityCalculator::RenderSurfacePriority()); 832 surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder( 833 surface_memory_bytes); 834 } 835 836 void LayerTreeHost::SetPrioritiesForLayers( 837 const RenderSurfaceLayerList& update_list) { 838 // Use BackToFront since it's cheap and this isn't order-dependent. 839 typedef LayerIterator<Layer, 840 RenderSurfaceLayerList, 841 RenderSurface, 842 LayerIteratorActions::BackToFront> LayerIteratorType; 843 844 PriorityCalculator calculator; 845 LayerIteratorType end = LayerIteratorType::End(&update_list); 846 for (LayerIteratorType it = LayerIteratorType::Begin(&update_list); 847 it != end; 848 ++it) { 849 if (it.represents_itself()) { 850 it->SetTexturePriorities(calculator); 851 } else if (it.represents_target_render_surface()) { 852 if (it->mask_layer()) 853 it->mask_layer()->SetTexturePriorities(calculator); 854 if (it->replica_layer() && it->replica_layer()->mask_layer()) 855 it->replica_layer()->mask_layer()->SetTexturePriorities(calculator); 856 } 857 } 858 } 859 860 void LayerTreeHost::PrioritizeTextures( 861 const RenderSurfaceLayerList& render_surface_layer_list, 862 OverdrawMetrics* metrics) { 863 if (!contents_texture_manager_) 864 return; 865 866 contents_texture_manager_->ClearPriorities(); 867 868 size_t memory_for_render_surfaces_metric = 869 CalculateMemoryForRenderSurfaces(render_surface_layer_list); 870 871 SetPrioritiesForLayers(render_surface_layer_list); 872 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric); 873 874 metrics->DidUseContentsTextureMemoryBytes( 875 contents_texture_manager_->MemoryAboveCutoffBytes()); 876 metrics->DidUseRenderSurfaceTextureMemoryBytes( 877 memory_for_render_surfaces_metric); 878 879 contents_texture_manager_->PrioritizeTextures(); 880 } 881 882 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces( 883 const RenderSurfaceLayerList& update_list) { 884 size_t readback_bytes = 0; 885 size_t max_background_texture_bytes = 0; 886 size_t contents_texture_bytes = 0; 887 888 // Start iteration at 1 to skip the root surface as it does not have a texture 889 // cost. 890 for (size_t i = 1; i < update_list.size(); ++i) { 891 Layer* render_surface_layer = update_list.at(i); 892 RenderSurface* render_surface = render_surface_layer->render_surface(); 893 894 size_t bytes = 895 Resource::MemorySizeBytes(render_surface->content_rect().size(), 896 GL_RGBA); 897 contents_texture_bytes += bytes; 898 899 if (render_surface_layer->background_filters().IsEmpty()) 900 continue; 901 902 if (bytes > max_background_texture_bytes) 903 max_background_texture_bytes = bytes; 904 if (!readback_bytes) { 905 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_, 906 GL_RGBA); 907 } 908 } 909 return readback_bytes + max_background_texture_bytes + contents_texture_bytes; 910 } 911 912 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer, 913 ResourceUpdateQueue* queue, 914 bool* did_paint_content, 915 bool* need_more_updates) { 916 // Note: Masks and replicas only exist for layers that own render surfaces. If 917 // we reach this point in code, we already know that at least something will 918 // be drawn into this render surface, so the mask and replica should be 919 // painted. 920 921 Layer* mask_layer = render_surface_layer->mask_layer(); 922 if (mask_layer) { 923 devtools_instrumentation::ScopedLayerTreeTask 924 update_layer(devtools_instrumentation::kUpdateLayer, 925 mask_layer->id(), 926 id()); 927 *did_paint_content |= mask_layer->Update(queue, NULL); 928 *need_more_updates |= mask_layer->NeedMoreUpdates(); 929 } 930 931 Layer* replica_mask_layer = 932 render_surface_layer->replica_layer() ? 933 render_surface_layer->replica_layer()->mask_layer() : NULL; 934 if (replica_mask_layer) { 935 devtools_instrumentation::ScopedLayerTreeTask 936 update_layer(devtools_instrumentation::kUpdateLayer, 937 replica_mask_layer->id(), 938 id()); 939 *did_paint_content |= replica_mask_layer->Update(queue, NULL); 940 *need_more_updates |= replica_mask_layer->NeedMoreUpdates(); 941 } 942 } 943 944 void LayerTreeHost::PaintLayerContents( 945 const RenderSurfaceLayerList& render_surface_layer_list, 946 ResourceUpdateQueue* queue, 947 bool* did_paint_content, 948 bool* need_more_updates) { 949 // Use FrontToBack to allow for testing occlusion and performing culling 950 // during the tree walk. 951 typedef LayerIterator<Layer, 952 RenderSurfaceLayerList, 953 RenderSurface, 954 LayerIteratorActions::FrontToBack> LayerIteratorType; 955 956 bool record_metrics_for_frame = 957 settings_.show_overdraw_in_tracing && 958 base::debug::TraceLog::GetInstance() && 959 base::debug::TraceLog::GetInstance()->IsEnabled(); 960 OcclusionTracker occlusion_tracker( 961 root_layer_->render_surface()->content_rect(), record_metrics_for_frame); 962 occlusion_tracker.set_minimum_tracking_size( 963 settings_.minimum_occlusion_tracking_size); 964 965 PrioritizeTextures(render_surface_layer_list, 966 occlusion_tracker.overdraw_metrics()); 967 968 in_paint_layer_contents_ = true; 969 970 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); 971 for (LayerIteratorType it = 972 LayerIteratorType::Begin(&render_surface_layer_list); 973 it != end; 974 ++it) { 975 bool prevent_occlusion = it.target_render_surface_layer()->HasCopyRequest(); 976 occlusion_tracker.EnterLayer(it, prevent_occlusion); 977 978 if (it.represents_target_render_surface()) { 979 PaintMasksForRenderSurface( 980 *it, queue, did_paint_content, need_more_updates); 981 } else if (it.represents_itself()) { 982 devtools_instrumentation::ScopedLayerTreeTask 983 update_layer(devtools_instrumentation::kUpdateLayer, it->id(), id()); 984 DCHECK(!it->paint_properties().bounds.IsEmpty()); 985 *did_paint_content |= it->Update(queue, &occlusion_tracker); 986 *need_more_updates |= it->NeedMoreUpdates(); 987 } 988 989 occlusion_tracker.LeaveLayer(it); 990 } 991 992 in_paint_layer_contents_ = false; 993 994 occlusion_tracker.overdraw_metrics()->RecordMetrics(this); 995 } 996 997 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) { 998 if (!root_layer_.get()) 999 return; 1000 1001 gfx::Vector2d root_scroll_delta; 1002 Layer* root_scroll_layer = FindFirstScrollableLayer(root_layer_.get()); 1003 1004 for (size_t i = 0; i < info.scrolls.size(); ++i) { 1005 Layer* layer = 1006 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(), 1007 info.scrolls[i].layer_id); 1008 if (!layer) 1009 continue; 1010 if (layer == root_scroll_layer) { 1011 root_scroll_delta += info.scrolls[i].scroll_delta; 1012 } else { 1013 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() + 1014 info.scrolls[i].scroll_delta); 1015 } 1016 } 1017 1018 if (!root_scroll_delta.IsZero() || info.page_scale_delta != 1.f) { 1019 // SetScrollOffsetFromImplSide above could have destroyed the tree, 1020 // so re-get this layer before doing anything to it. 1021 root_scroll_layer = FindFirstScrollableLayer(root_layer_.get()); 1022 1023 // Preemptively apply the scroll offset and scale delta here before sending 1024 // it to the client. If the client comes back and sets it to the same 1025 // value, then the layer can early out without needing a full commit. 1026 if (root_scroll_layer) { 1027 root_scroll_layer->SetScrollOffsetFromImplSide( 1028 root_scroll_layer->scroll_offset() + root_scroll_delta); 1029 } 1030 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); 1031 client_->ApplyScrollAndScale(root_scroll_delta, info.page_scale_delta); 1032 } 1033 } 1034 1035 void LayerTreeHost::StartRateLimiter(WebKit::WebGraphicsContext3D* context3d) { 1036 if (animating_) 1037 return; 1038 1039 DCHECK(context3d); 1040 RateLimiterMap::iterator it = rate_limiters_.find(context3d); 1041 if (it != rate_limiters_.end()) { 1042 it->second->Start(); 1043 } else { 1044 scoped_refptr<RateLimiter> rate_limiter = 1045 RateLimiter::Create(context3d, this, proxy_->MainThreadTaskRunner()); 1046 rate_limiters_[context3d] = rate_limiter; 1047 rate_limiter->Start(); 1048 } 1049 } 1050 1051 void LayerTreeHost::StopRateLimiter(WebKit::WebGraphicsContext3D* context3d) { 1052 RateLimiterMap::iterator it = rate_limiters_.find(context3d); 1053 if (it != rate_limiters_.end()) { 1054 it->second->Stop(); 1055 rate_limiters_.erase(it); 1056 } 1057 } 1058 1059 void LayerTreeHost::RateLimit() { 1060 // Force a no-op command on the compositor context, so that any ratelimiting 1061 // commands will wait for the compositing context, and therefore for the 1062 // SwapBuffers. 1063 proxy_->ForceSerializeOnSwapBuffers(); 1064 } 1065 1066 bool LayerTreeHost::RequestPartialTextureUpdate() { 1067 if (partial_texture_update_requests_ >= settings_.max_partial_texture_updates) 1068 return false; 1069 1070 partial_texture_update_requests_++; 1071 return true; 1072 } 1073 1074 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) { 1075 if (device_scale_factor == device_scale_factor_) 1076 return; 1077 device_scale_factor_ = device_scale_factor; 1078 1079 SetNeedsCommit(); 1080 } 1081 1082 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints, 1083 TopControlsState current, 1084 bool animate) { 1085 if (!settings_.calculate_top_controls_position) 1086 return; 1087 1088 // Top controls are only used in threaded mode. 1089 proxy_->ImplThreadTaskRunner()->PostTask( 1090 FROM_HERE, 1091 base::Bind(&TopControlsManager::UpdateTopControlsState, 1092 top_controls_manager_weak_ptr_, 1093 constraints, 1094 current, 1095 animate)); 1096 } 1097 1098 bool LayerTreeHost::BlocksPendingCommit() const { 1099 if (!root_layer_.get()) 1100 return false; 1101 return root_layer_->BlocksPendingCommitRecursive(); 1102 } 1103 1104 scoped_ptr<base::Value> LayerTreeHost::AsValue() const { 1105 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 1106 state->Set("proxy", proxy_->AsValue().release()); 1107 return state.PassAs<base::Value>(); 1108 } 1109 1110 void LayerTreeHost::AnimateLayers(base::TimeTicks time) { 1111 rendering_stats_instrumentation_->IncrementAnimationFrameCount(); 1112 if (!settings_.accelerated_animation_enabled || 1113 animation_registrar_->active_animation_controllers().empty()) 1114 return; 1115 1116 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers"); 1117 1118 double monotonic_time = (time - base::TimeTicks()).InSecondsF(); 1119 1120 AnimationRegistrar::AnimationControllerMap copy = 1121 animation_registrar_->active_animation_controllers(); 1122 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); 1123 iter != copy.end(); 1124 ++iter) { 1125 (*iter).second->Animate(monotonic_time); 1126 bool start_ready_animations = true; 1127 (*iter).second->UpdateState(start_ready_animations, NULL); 1128 } 1129 } 1130 1131 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) { 1132 DCHECK(client); 1133 1134 UIResourceRequest request; 1135 bool resource_lost = false; 1136 request.type = UIResourceRequest::UIResourceCreate; 1137 request.id = next_ui_resource_id_++; 1138 1139 DCHECK(ui_resource_client_map_.find(request.id) == 1140 ui_resource_client_map_.end()); 1141 1142 request.bitmap = client->GetBitmap(request.id, resource_lost); 1143 ui_resource_request_queue_.push_back(request); 1144 ui_resource_client_map_[request.id] = client; 1145 return request.id; 1146 } 1147 1148 // Deletes a UI resource. May safely be called more than once. 1149 void LayerTreeHost::DeleteUIResource(UIResourceId uid) { 1150 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid); 1151 if (iter == ui_resource_client_map_.end()) 1152 return; 1153 1154 UIResourceRequest request; 1155 request.type = UIResourceRequest::UIResourceDelete; 1156 request.id = uid; 1157 ui_resource_request_queue_.push_back(request); 1158 ui_resource_client_map_.erase(uid); 1159 } 1160 1161 void LayerTreeHost::UIResourceLost(UIResourceId uid) { 1162 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid); 1163 if (iter == ui_resource_client_map_.end()) 1164 return; 1165 1166 UIResourceRequest request; 1167 bool resource_lost = true; 1168 request.type = UIResourceRequest::UIResourceCreate; 1169 request.id = uid; 1170 request.bitmap = iter->second->GetBitmap(uid, resource_lost); 1171 DCHECK(request.bitmap.get()); 1172 ui_resource_request_queue_.push_back(request); 1173 } 1174 1175 void LayerTreeHost::DidLoseUIResources() { 1176 // When output surface is lost, we need to recreate the resource. 1177 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin(); 1178 iter != ui_resource_client_map_.end(); 1179 ++iter) { 1180 UIResourceLost(iter->first); 1181 } 1182 } 1183 1184 } // namespace cc 1185