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