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