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