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