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