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