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