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