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