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