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