layer_tree_host.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
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
10#include "base/bind.h"
11#include "base/command_line.h"
12#include "base/debug/trace_event.h"
13#include "base/message_loop.h"
14#include "base/metrics/histogram.h"
15#include "base/stl_util.h"
16#include "base/strings/string_number_conversions.h"
17#include "cc/animation/animation_registrar.h"
18#include "cc/animation/layer_animation_controller.h"
19#include "cc/base/math_util.h"
20#include "cc/base/thread.h"
21#include "cc/debug/overdraw_metrics.h"
22#include "cc/debug/rendering_stats_instrumentation.h"
23#include "cc/input/top_controls_manager.h"
24#include "cc/layers/heads_up_display_layer.h"
25#include "cc/layers/heads_up_display_layer_impl.h"
26#include "cc/layers/layer.h"
27#include "cc/layers/layer_iterator.h"
28#include "cc/layers/render_surface.h"
29#include "cc/layers/scrollbar_layer.h"
30#include "cc/resources/prioritized_resource_manager.h"
31#include "cc/trees/layer_tree_host_client.h"
32#include "cc/trees/layer_tree_host_common.h"
33#include "cc/trees/layer_tree_host_impl.h"
34#include "cc/trees/layer_tree_impl.h"
35#include "cc/trees/occlusion_tracker.h"
36#include "cc/trees/single_thread_proxy.h"
37#include "cc/trees/thread_proxy.h"
38#include "cc/trees/tree_synchronizer.h"
39#include "ui/gfx/size_conversions.h"
40
41namespace {
42static int s_num_layer_tree_instances;
43}
44
45namespace cc {
46
47RendererCapabilities::RendererCapabilities()
48    : best_texture_format(0),
49      using_partial_swap(false),
50      using_set_visibility(false),
51      using_gpu_memory_manager(false),
52      using_egl_image(false),
53      allow_partial_texture_updates(false),
54      using_offscreen_context3d(false),
55      max_texture_size(0),
56      avoid_pow2_textures(false),
57      using_map_image(false) {}
58
59RendererCapabilities::~RendererCapabilities() {}
60
61bool LayerTreeHost::AnyLayerTreeHostInstanceExists() {
62  return s_num_layer_tree_instances > 0;
63}
64
65scoped_ptr<LayerTreeHost> LayerTreeHost::Create(
66    LayerTreeHostClient* client,
67    const LayerTreeSettings& settings,
68    scoped_ptr<Thread> impl_thread) {
69  scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(client,
70                                                              settings));
71  if (!layer_tree_host->Initialize(impl_thread.Pass()))
72    return scoped_ptr<LayerTreeHost>();
73  return layer_tree_host.Pass();
74}
75
76LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
77                             const LayerTreeSettings& settings)
78    : animating_(false),
79      needs_full_tree_sync_(true),
80      needs_filter_context_(false),
81      client_(client),
82      commit_number_(0),
83      rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
84      output_surface_can_be_initialized_(true),
85      output_surface_lost_(true),
86      num_failed_recreate_attempts_(0),
87      settings_(settings),
88      debug_state_(settings.initial_debug_state),
89      overdraw_bottom_height_(0.f),
90      device_scale_factor_(1.f),
91      visible_(true),
92      page_scale_factor_(1.f),
93      min_page_scale_factor_(1.f),
94      max_page_scale_factor_(1.f),
95      trigger_idle_updates_(true),
96      background_color_(SK_ColorWHITE),
97      has_transparent_background_(false),
98      partial_texture_update_requests_(0),
99      in_paint_layer_contents_(false),
100      total_frames_used_for_lcd_text_metrics_(0) {
101  if (settings_.accelerated_animation_enabled)
102    animation_registrar_ = AnimationRegistrar::Create();
103  s_num_layer_tree_instances++;
104
105  rendering_stats_instrumentation_->set_record_rendering_stats(
106      debug_state_.RecordRenderingStats());
107}
108
109bool LayerTreeHost::Initialize(scoped_ptr<Thread> impl_thread) {
110  if (impl_thread)
111    return InitializeProxy(ThreadProxy::Create(this, impl_thread.Pass()));
112  else
113    return InitializeProxy(SingleThreadProxy::Create(this));
114}
115
116bool LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
117  return InitializeProxy(proxy_for_testing.Pass());
118}
119
120bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
121  TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
122
123  scoped_ptr<OutputSurface> output_surface(CreateOutputSurface());
124  if (!output_surface)
125    return false;
126
127  proxy_ = proxy.Pass();
128  proxy_->Start(output_surface.Pass());
129  return true;
130}
131
132LayerTreeHost::~LayerTreeHost() {
133  TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
134  if (root_layer_.get())
135    root_layer_->SetLayerTreeHost(NULL);
136
137  if (proxy_) {
138    DCHECK(proxy_->IsMainThread());
139    proxy_->Stop();
140  }
141
142  s_num_layer_tree_instances--;
143  RateLimiterMap::iterator it = rate_limiters_.begin();
144  if (it != rate_limiters_.end())
145    it->second->Stop();
146
147  if (root_layer_.get()) {
148    // The layer tree must be destroyed before the layer tree host. We've
149    // made a contract with our animation controllers that the registrar
150    // will outlive them, and we must make good.
151    root_layer_ = NULL;
152  }
153}
154
155void LayerTreeHost::SetLayerTreeHostClientReady() {
156  proxy_->SetLayerTreeHostClientReady();
157}
158
159LayerTreeHost::CreateResult
160LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
161  TRACE_EVENT1("cc",
162               "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
163               "success",
164               success);
165
166  DCHECK(output_surface_lost_);
167  if (success) {
168    output_surface_lost_ = false;
169
170    // Update settings_ based on partial update capability.
171    size_t max_partial_texture_updates = 0;
172    if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
173        !settings_.impl_side_painting) {
174      max_partial_texture_updates = std::min(
175          settings_.max_partial_texture_updates,
176          proxy_->MaxPartialTextureUpdates());
177    }
178    settings_.max_partial_texture_updates = max_partial_texture_updates;
179
180    if (!contents_texture_manager_ &&
181        (!settings_.impl_side_painting || !settings_.solid_color_scrollbars)) {
182      contents_texture_manager_ =
183          PrioritizedResourceManager::Create(proxy_.get());
184      surface_memory_placeholder_ =
185          contents_texture_manager_->CreateTexture(gfx::Size(), GL_RGBA);
186    }
187
188    client_->DidInitializeOutputSurface(true);
189    return CreateSucceeded;
190  }
191
192  // Failure path.
193
194  client_->DidFailToInitializeOutputSurface();
195
196  // Tolerate a certain number of recreation failures to work around races
197  // in the output-surface-lost machinery.
198  ++num_failed_recreate_attempts_;
199  if (num_failed_recreate_attempts_ >= 5) {
200    // We have tried too many times to recreate the output surface. Tell the
201    // host to fall back to software rendering.
202    output_surface_can_be_initialized_ = false;
203    client_->DidInitializeOutputSurface(false);
204    return CreateFailedAndGaveUp;
205  }
206
207  return CreateFailedButTryAgain;
208}
209
210void LayerTreeHost::DeleteContentsTexturesOnImplThread(
211    ResourceProvider* resource_provider) {
212  DCHECK(proxy_->IsImplThread());
213  if (contents_texture_manager_)
214    contents_texture_manager_->ClearAllMemory(resource_provider);
215}
216
217void LayerTreeHost::AcquireLayerTextures() {
218  DCHECK(proxy_->IsMainThread());
219  proxy_->AcquireLayerTextures();
220}
221
222void LayerTreeHost::DidBeginFrame() {
223  client_->DidBeginFrame();
224}
225
226void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
227  animating_ = true;
228  client_->Animate((frame_begin_time - base::TimeTicks()).InSecondsF());
229  animating_ = false;
230}
231
232void LayerTreeHost::DidStopFlinging() {
233  proxy_->MainThreadHasStoppedFlinging();
234}
235
236void LayerTreeHost::Layout() {
237  client_->Layout();
238}
239
240void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
241  DCHECK(proxy_->IsImplThread());
242  TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
243}
244
245// This function commits the LayerTreeHost to an impl tree. When modifying
246// this function, keep in mind that the function *runs* on the impl thread! Any
247// code that is logically a main thread operation, e.g. deletion of a Layer,
248// should be delayed until the LayerTreeHost::CommitComplete, which will run
249// after the commit, but on the main thread.
250void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
251  DCHECK(proxy_->IsImplThread());
252
253  // If there are linked evicted backings, these backings' resources may be put
254  // into the impl tree, so we can't draw yet. Determine this before clearing
255  // all evicted backings.
256  bool new_impl_tree_has_no_evicted_resources = false;
257  if (contents_texture_manager_) {
258    new_impl_tree_has_no_evicted_resources =
259        !contents_texture_manager_->LinkedEvictedBackingsExist();
260
261    // If the memory limit has been increased since this now-finishing
262    // commit began, and the extra now-available memory would have been used,
263    // then request another commit.
264    if (contents_texture_manager_->MaxMemoryLimitBytes() <
265            host_impl->memory_allocation_limit_bytes() &&
266        contents_texture_manager_->MaxMemoryLimitBytes() <
267            contents_texture_manager_->MaxMemoryNeededBytes()) {
268      host_impl->SetNeedsCommit();
269    }
270
271    host_impl->set_max_memory_needed_bytes(
272        contents_texture_manager_->MaxMemoryNeededBytes());
273
274    contents_texture_manager_->UpdateBackingsInDrawingImplTree();
275  }
276
277  // In impl-side painting, synchronize to the pending tree so that it has
278  // time to raster before being displayed.  If no pending tree is needed,
279  // synchronization can happen directly to the active tree and
280  // unlinked contents resources can be reclaimed immediately.
281  LayerTreeImpl* sync_tree;
282  if (settings_.impl_side_painting) {
283    // Commits should not occur while there is already a pending tree.
284    DCHECK(!host_impl->pending_tree());
285    host_impl->CreatePendingTree();
286    sync_tree = host_impl->pending_tree();
287  } else {
288    contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
289    sync_tree = host_impl->active_tree();
290  }
291
292  if (needs_full_tree_sync_)
293    sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
294        root_layer(), sync_tree->DetachLayerTree(), sync_tree));
295  {
296    TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
297    TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
298  }
299
300  sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
301  needs_full_tree_sync_ = false;
302
303  if (hud_layer_.get()) {
304    LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
305        sync_tree->root_layer(), hud_layer_->id());
306    sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
307  } else {
308    sync_tree->set_hud_layer(NULL);
309  }
310
311  sync_tree->set_source_frame_number(commit_number());
312  sync_tree->set_background_color(background_color_);
313  sync_tree->set_has_transparent_background(has_transparent_background_);
314
315  sync_tree->FindRootScrollLayer();
316
317  float page_scale_delta, sent_page_scale_delta;
318  if (settings_.impl_side_painting) {
319    // Update the delta from the active tree, which may have
320    // adjusted its delta prior to the pending tree being created.
321    // This code is equivalent to that in LayerTreeImpl::SetPageScaleDelta.
322    DCHECK_EQ(1.f, sync_tree->sent_page_scale_delta());
323    page_scale_delta = host_impl->active_tree()->page_scale_delta();
324    sent_page_scale_delta = host_impl->active_tree()->sent_page_scale_delta();
325  } else {
326    page_scale_delta = sync_tree->page_scale_delta();
327    sent_page_scale_delta = sync_tree->sent_page_scale_delta();
328    sync_tree->set_sent_page_scale_delta(1.f);
329  }
330
331  sync_tree->SetPageScaleFactorAndLimits(page_scale_factor_,
332                                         min_page_scale_factor_,
333                                         max_page_scale_factor_);
334  sync_tree->SetPageScaleDelta(page_scale_delta / sent_page_scale_delta);
335  sync_tree->SetLatencyInfo(latency_info_);
336  latency_info_.Clear();
337
338  host_impl->SetViewportSize(device_viewport_size_);
339  host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_);
340  host_impl->SetDeviceScaleFactor(device_scale_factor_);
341  host_impl->SetDebugState(debug_state_);
342  if (pending_page_scale_animation_) {
343    host_impl->StartPageScaleAnimation(
344        pending_page_scale_animation_->target_offset,
345        pending_page_scale_animation_->use_anchor,
346        pending_page_scale_animation_->scale,
347        base::TimeTicks::Now(),
348        pending_page_scale_animation_->duration);
349    pending_page_scale_animation_.reset();
350  }
351
352  DCHECK(!sync_tree->ViewportSizeInvalid());
353
354  if (new_impl_tree_has_no_evicted_resources) {
355    if (sync_tree->ContentsTexturesPurged())
356      sync_tree->ResetContentsTexturesPurged();
357  }
358
359  if (!settings_.impl_side_painting) {
360    // If we're not in impl-side painting, the tree is immediately
361    // considered active.
362    sync_tree->DidBecomeActive();
363  }
364
365  commit_number_++;
366}
367
368void LayerTreeHost::WillCommit() {
369  client_->WillCommit();
370}
371
372void LayerTreeHost::UpdateHudLayer() {
373  if (debug_state_.ShowHudInfo()) {
374    if (!hud_layer_.get())
375      hud_layer_ = HeadsUpDisplayLayer::Create();
376
377    if (root_layer_.get() && !hud_layer_->parent())
378      root_layer_->AddChild(hud_layer_);
379  } else if (hud_layer_.get()) {
380    hud_layer_->RemoveFromParent();
381    hud_layer_ = NULL;
382  }
383}
384
385void LayerTreeHost::CommitComplete() {
386  client_->DidCommit();
387}
388
389scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() {
390  return client_->CreateOutputSurface();
391}
392
393scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
394    LayerTreeHostImplClient* client) {
395  DCHECK(proxy_->IsImplThread());
396  scoped_ptr<LayerTreeHostImpl> host_impl =
397      LayerTreeHostImpl::Create(settings_,
398                                client,
399                                proxy_.get(),
400                                rendering_stats_instrumentation_.get());
401  if (settings_.calculate_top_controls_position &&
402      host_impl->top_controls_manager()) {
403    top_controls_manager_weak_ptr_ =
404        host_impl->top_controls_manager()->AsWeakPtr();
405  }
406  input_handler_weak_ptr_ = host_impl->AsWeakPtr();
407  return host_impl.Pass();
408}
409
410void LayerTreeHost::DidLoseOutputSurface() {
411  TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
412  DCHECK(proxy_->IsMainThread());
413
414  if (output_surface_lost_)
415    return;
416
417  num_failed_recreate_attempts_ = 0;
418  output_surface_lost_ = true;
419  SetNeedsCommit();
420}
421
422bool LayerTreeHost::CompositeAndReadback(void* pixels,
423                                         gfx::Rect rect_in_device_viewport) {
424  trigger_idle_updates_ = false;
425  bool ret = proxy_->CompositeAndReadback(pixels, rect_in_device_viewport);
426  trigger_idle_updates_ = true;
427  return ret;
428}
429
430void LayerTreeHost::FinishAllRendering() {
431  proxy_->FinishAllRendering();
432}
433
434void LayerTreeHost::SetDeferCommits(bool defer_commits) {
435  proxy_->SetDeferCommits(defer_commits);
436}
437
438void LayerTreeHost::DidDeferCommit() {}
439
440void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
441  std::stack<Layer*> layer_stack;
442  layer_stack.push(root_layer());
443  while (!layer_stack.empty()) {
444    Layer* current_layer = layer_stack.top();
445    layer_stack.pop();
446    current_layer->SetNeedsDisplay();
447    for (unsigned int i = 0; i < current_layer->children().size(); i++) {
448      layer_stack.push(current_layer->child_at(i));
449    }
450  }
451}
452
453void LayerTreeHost::CollectRenderingStats(RenderingStats* stats) const {
454  CHECK(debug_state_.RecordRenderingStats());
455  *stats = rendering_stats_instrumentation_->GetRenderingStats();
456}
457
458const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
459  return proxy_->GetRendererCapabilities();
460}
461
462void LayerTreeHost::SetNeedsAnimate() {
463  DCHECK(proxy_->HasImplThread());
464  proxy_->SetNeedsAnimate();
465}
466
467void LayerTreeHost::SetNeedsCommit() {
468  if (!prepaint_callback_.IsCancelled()) {
469    TRACE_EVENT_INSTANT0("cc",
470                         "LayerTreeHost::SetNeedsCommit::cancel prepaint",
471                         TRACE_EVENT_SCOPE_THREAD);
472    prepaint_callback_.Cancel();
473  }
474  proxy_->SetNeedsCommit();
475}
476
477void LayerTreeHost::SetNeedsFullTreeSync() {
478  needs_full_tree_sync_ = true;
479  SetNeedsCommit();
480}
481
482void LayerTreeHost::SetNeedsRedraw() {
483  SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
484}
485
486void LayerTreeHost::SetNeedsRedrawRect(gfx::Rect damage_rect) {
487  proxy_->SetNeedsRedraw(damage_rect);
488  if (!proxy_->ImplThread())
489    client_->ScheduleComposite();
490}
491
492bool LayerTreeHost::CommitRequested() const {
493  return proxy_->CommitRequested();
494}
495
496void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
497                                       base::Time wall_clock_time) {
498  DCHECK(proxy_->IsMainThread());
499  for (size_t event_index = 0; event_index < events->size(); ++event_index) {
500    int event_layer_id = (*events)[event_index].layer_id;
501
502    // Use the map of all controllers, not just active ones, since non-active
503    // controllers may still receive events for impl-only animations.
504    const AnimationRegistrar::AnimationControllerMap& animation_controllers =
505        animation_registrar_->all_animation_controllers();
506    AnimationRegistrar::AnimationControllerMap::const_iterator iter =
507        animation_controllers.find(event_layer_id);
508    if (iter != animation_controllers.end()) {
509      switch ((*events)[event_index].type) {
510        case AnimationEvent::Started:
511          (*iter).second->NotifyAnimationStarted((*events)[event_index],
512                                                 wall_clock_time.ToDoubleT());
513          break;
514
515        case AnimationEvent::Finished:
516          (*iter).second->NotifyAnimationFinished((*events)[event_index],
517                                                  wall_clock_time.ToDoubleT());
518          break;
519
520        case AnimationEvent::PropertyUpdate:
521          (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
522          break;
523
524        default:
525          NOTREACHED();
526      }
527    }
528  }
529}
530
531void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
532  if (root_layer_.get() == root_layer.get())
533    return;
534
535  if (root_layer_.get())
536    root_layer_->SetLayerTreeHost(NULL);
537  root_layer_ = root_layer;
538  if (root_layer_.get())
539    root_layer_->SetLayerTreeHost(this);
540
541  if (hud_layer_.get())
542    hud_layer_->RemoveFromParent();
543
544  SetNeedsFullTreeSync();
545}
546
547void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
548  LayerTreeDebugState new_debug_state =
549      LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
550
551  if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
552    return;
553
554  debug_state_ = new_debug_state;
555
556  rendering_stats_instrumentation_->set_record_rendering_stats(
557      debug_state_.RecordRenderingStats());
558
559  SetNeedsCommit();
560}
561
562void LayerTreeHost::SetViewportSize(gfx::Size device_viewport_size) {
563  if (device_viewport_size == device_viewport_size_)
564    return;
565
566  device_viewport_size_ = device_viewport_size;
567
568  SetNeedsCommit();
569}
570
571void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) {
572  if (overdraw_bottom_height_ == overdraw_bottom_height)
573    return;
574
575  overdraw_bottom_height_ = overdraw_bottom_height;
576  SetNeedsCommit();
577}
578
579void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
580                                                float min_page_scale_factor,
581                                                float max_page_scale_factor) {
582  if (page_scale_factor == page_scale_factor_ &&
583      min_page_scale_factor == min_page_scale_factor_ &&
584      max_page_scale_factor == max_page_scale_factor_)
585    return;
586
587  page_scale_factor_ = page_scale_factor;
588  min_page_scale_factor_ = min_page_scale_factor;
589  max_page_scale_factor_ = max_page_scale_factor;
590  SetNeedsCommit();
591}
592
593void LayerTreeHost::SetVisible(bool visible) {
594  if (visible_ == visible)
595    return;
596  visible_ = visible;
597  if (!visible)
598    ReduceMemoryUsage();
599  proxy_->SetVisible(visible);
600}
601
602void LayerTreeHost::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
603  latency_info_.MergeWith(latency_info);
604}
605
606void LayerTreeHost::StartPageScaleAnimation(gfx::Vector2d target_offset,
607                                            bool use_anchor,
608                                            float scale,
609                                            base::TimeDelta duration) {
610  pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
611  pending_page_scale_animation_->target_offset = target_offset;
612  pending_page_scale_animation_->use_anchor = use_anchor;
613  pending_page_scale_animation_->scale = scale;
614  pending_page_scale_animation_->duration = duration;
615
616  SetNeedsCommit();
617}
618
619void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
620  if (!proxy_->HasImplThread())
621    static_cast<SingleThreadProxy*>(proxy_.get())->CompositeImmediately(
622        frame_begin_time);
623  else
624    SetNeedsCommit();
625}
626
627void LayerTreeHost::ScheduleComposite() {
628  client_->ScheduleComposite();
629}
630
631bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() {
632  if (!output_surface_can_be_initialized_)
633    return false;
634
635  if (output_surface_lost_)
636    proxy_->CreateAndInitializeOutputSurface();
637  return !output_surface_lost_;
638}
639
640void LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue,
641                                 size_t memory_allocation_limit_bytes) {
642  DCHECK(!output_surface_lost_);
643
644  if (!root_layer())
645    return;
646
647  if (device_viewport_size().IsEmpty())
648    return;
649
650  if (contents_texture_manager_ && memory_allocation_limit_bytes) {
651    contents_texture_manager_->SetMaxMemoryLimitBytes(
652        memory_allocation_limit_bytes);
653  }
654
655  UpdateLayers(root_layer(), queue);
656}
657
658static Layer* FindFirstScrollableLayer(Layer* layer) {
659  if (!layer)
660    return NULL;
661
662  if (layer->scrollable())
663    return layer;
664
665  for (size_t i = 0; i < layer->children().size(); ++i) {
666    Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
667    if (found)
668      return found;
669  }
670
671  return NULL;
672}
673
674class CalculateLCDTextMetricsFunctor {
675 public:
676  void operator()(Layer* layer) {
677    LayerTreeHost* layer_tree_host = layer->layer_tree_host();
678    if (!layer_tree_host)
679      return;
680
681    if (!layer->SupportsLCDText())
682      return;
683
684    bool update_total_num_cc_layers_can_use_lcd_text = false;
685    bool update_total_num_cc_layers_will_use_lcd_text = false;
686    if (layer->draw_properties().can_use_lcd_text) {
687      update_total_num_cc_layers_can_use_lcd_text = true;
688      if (layer->contents_opaque())
689        update_total_num_cc_layers_will_use_lcd_text = true;
690    }
691
692    layer_tree_host->IncrementLCDTextMetrics(
693        update_total_num_cc_layers_can_use_lcd_text,
694        update_total_num_cc_layers_will_use_lcd_text);
695  }
696};
697
698void LayerTreeHost::IncrementLCDTextMetrics(
699    bool update_total_num_cc_layers_can_use_lcd_text,
700    bool update_total_num_cc_layers_will_use_lcd_text) {
701  lcd_text_metrics_.total_num_cc_layers++;
702  if (update_total_num_cc_layers_can_use_lcd_text)
703    lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
704  if (update_total_num_cc_layers_will_use_lcd_text) {
705    DCHECK(update_total_num_cc_layers_can_use_lcd_text);
706    lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
707  }
708}
709
710void LayerTreeHost::UpdateLayers(Layer* root_layer,
711                                 ResourceUpdateQueue* queue) {
712  TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
713               "commit_number", commit_number());
714
715  LayerList update_list;
716  {
717    UpdateHudLayer();
718
719    Layer* root_scroll = FindFirstScrollableLayer(root_layer);
720
721    TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
722    LayerTreeHostCommon::CalculateDrawProperties(
723        root_layer,
724        device_viewport_size(),
725        gfx::Transform(),
726        device_scale_factor_,
727        page_scale_factor_,
728        root_scroll,
729        GetRendererCapabilities().max_texture_size,
730        settings_.can_use_lcd_text,
731        settings_.layer_transforms_should_scale_layer_contents,
732        &update_list);
733
734    if (total_frames_used_for_lcd_text_metrics_ <=
735        kTotalFramesToUseForLCDTextMetrics) {
736      LayerTreeHostCommon::CallFunctionForSubtree<
737          CalculateLCDTextMetricsFunctor, Layer>(root_layer);
738      total_frames_used_for_lcd_text_metrics_++;
739    }
740
741    if (total_frames_used_for_lcd_text_metrics_ ==
742        kTotalFramesToUseForLCDTextMetrics) {
743      total_frames_used_for_lcd_text_metrics_++;
744
745      UMA_HISTOGRAM_PERCENTAGE(
746          "Renderer4.LCDText.PercentageOfCandidateLayers",
747          lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 /
748          lcd_text_metrics_.total_num_cc_layers);
749      UMA_HISTOGRAM_PERCENTAGE(
750          "Renderer4.LCDText.PercentageOfAALayers",
751          lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 /
752          lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text);
753    }
754  }
755
756  // Reset partial texture update requests.
757  partial_texture_update_requests_ = 0;
758
759  bool need_more_updates = PaintLayerContents(update_list, queue);
760  if (trigger_idle_updates_ && need_more_updates) {
761    TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
762    prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
763                                        base::Unretained(this)));
764    static base::TimeDelta prepaint_delay =
765        base::TimeDelta::FromMilliseconds(100);
766    base::MessageLoop::current()->PostDelayedTask(
767        FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
768  }
769
770  for (size_t i = 0; i < update_list.size(); ++i)
771    update_list[i]->ClearRenderSurface();
772}
773
774void LayerTreeHost::TriggerPrepaint() {
775  prepaint_callback_.Cancel();
776  TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
777  SetNeedsCommit();
778}
779
780class LayerTreeHostReduceMemoryFunctor {
781 public:
782  void operator()(Layer* layer) {
783    layer->ReduceMemoryUsage();
784  }
785};
786
787void LayerTreeHost::ReduceMemoryUsage() {
788  if (!root_layer())
789    return;
790
791  LayerTreeHostCommon::CallFunctionForSubtree<
792      LayerTreeHostReduceMemoryFunctor, Layer>(root_layer());
793}
794
795void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
796  DCHECK(surface_memory_placeholder_);
797
798  // Surfaces have a place holder for their memory since they are managed
799  // independantly but should still be tracked and reduce other memory usage.
800  surface_memory_placeholder_->SetTextureManager(
801      contents_texture_manager_.get());
802  surface_memory_placeholder_->set_request_priority(
803      PriorityCalculator::RenderSurfacePriority());
804  surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
805      surface_memory_bytes);
806}
807
808void LayerTreeHost::SetPrioritiesForLayers(const LayerList& update_list) {
809  // Use BackToFront since it's cheap and this isn't order-dependent.
810  typedef LayerIterator<Layer,
811                        LayerList,
812                        RenderSurface,
813                        LayerIteratorActions::BackToFront> LayerIteratorType;
814
815  PriorityCalculator calculator;
816  LayerIteratorType end = LayerIteratorType::End(&update_list);
817  for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
818       it != end;
819       ++it) {
820    if (it.represents_itself()) {
821      it->SetTexturePriorities(calculator);
822    } else if (it.represents_target_render_surface()) {
823      if (it->mask_layer())
824        it->mask_layer()->SetTexturePriorities(calculator);
825      if (it->replica_layer() && it->replica_layer()->mask_layer())
826        it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
827    }
828  }
829}
830
831void LayerTreeHost::PrioritizeTextures(
832    const LayerList& render_surface_layer_list, OverdrawMetrics* metrics) {
833  if (!contents_texture_manager_)
834    return;
835
836  contents_texture_manager_->ClearPriorities();
837
838  size_t memory_for_render_surfaces_metric =
839      CalculateMemoryForRenderSurfaces(render_surface_layer_list);
840
841  SetPrioritiesForLayers(render_surface_layer_list);
842  SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
843
844  metrics->DidUseContentsTextureMemoryBytes(
845      contents_texture_manager_->MemoryAboveCutoffBytes());
846  metrics->DidUseRenderSurfaceTextureMemoryBytes(
847      memory_for_render_surfaces_metric);
848
849  contents_texture_manager_->PrioritizeTextures();
850}
851
852size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
853    const LayerList& update_list) {
854  size_t readback_bytes = 0;
855  size_t max_background_texture_bytes = 0;
856  size_t contents_texture_bytes = 0;
857
858  // Start iteration at 1 to skip the root surface as it does not have a texture
859  // cost.
860  for (size_t i = 1; i < update_list.size(); ++i) {
861    Layer* render_surface_layer = update_list[i].get();
862    RenderSurface* render_surface = render_surface_layer->render_surface();
863
864    size_t bytes =
865        Resource::MemorySizeBytes(render_surface->content_rect().size(),
866                                  GL_RGBA);
867    contents_texture_bytes += bytes;
868
869    if (render_surface_layer->background_filters().isEmpty())
870      continue;
871
872    if (bytes > max_background_texture_bytes)
873      max_background_texture_bytes = bytes;
874    if (!readback_bytes) {
875      readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
876                                                 GL_RGBA);
877    }
878  }
879  return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
880}
881
882bool LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
883                                               ResourceUpdateQueue* queue,
884                                               RenderingStats* stats) {
885  // Note: Masks and replicas only exist for layers that own render surfaces. If
886  // we reach this point in code, we already know that at least something will
887  // be drawn into this render surface, so the mask and replica should be
888  // painted.
889
890  bool need_more_updates = false;
891  Layer* mask_layer = render_surface_layer->mask_layer();
892  if (mask_layer) {
893    mask_layer->Update(queue, NULL, stats);
894    need_more_updates |= mask_layer->NeedMoreUpdates();
895  }
896
897  Layer* replica_mask_layer =
898      render_surface_layer->replica_layer() ?
899      render_surface_layer->replica_layer()->mask_layer() : NULL;
900  if (replica_mask_layer) {
901    replica_mask_layer->Update(queue, NULL, stats);
902    need_more_updates |= replica_mask_layer->NeedMoreUpdates();
903  }
904  return need_more_updates;
905}
906
907bool LayerTreeHost::PaintLayerContents(
908    const LayerList& render_surface_layer_list, ResourceUpdateQueue* queue) {
909  // Use FrontToBack to allow for testing occlusion and performing culling
910  // during the tree walk.
911  typedef LayerIterator<Layer,
912                        LayerList,
913                        RenderSurface,
914                        LayerIteratorActions::FrontToBack> LayerIteratorType;
915
916  bool need_more_updates = false;
917  bool record_metrics_for_frame =
918      settings_.show_overdraw_in_tracing &&
919      base::debug::TraceLog::GetInstance() &&
920      base::debug::TraceLog::GetInstance()->IsEnabled();
921  OcclusionTracker occlusion_tracker(
922      root_layer_->render_surface()->content_rect(), record_metrics_for_frame);
923  occlusion_tracker.set_minimum_tracking_size(
924      settings_.minimum_occlusion_tracking_size);
925
926  PrioritizeTextures(render_surface_layer_list,
927                     occlusion_tracker.overdraw_metrics());
928
929  // TODO(egraether): Use RenderingStatsInstrumentation in Layer::update()
930  RenderingStats stats;
931  RenderingStats* stats_ptr =
932      debug_state_.RecordRenderingStats() ? &stats : NULL;
933
934  in_paint_layer_contents_ = true;
935
936  LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
937  for (LayerIteratorType it =
938           LayerIteratorType::Begin(&render_surface_layer_list);
939       it != end;
940       ++it) {
941    bool prevent_occlusion = it.target_render_surface_layer()->HasCopyRequest();
942    occlusion_tracker.EnterLayer(it, prevent_occlusion);
943
944    if (it.represents_target_render_surface()) {
945      DCHECK(it->render_surface()->draw_opacity() ||
946             it->render_surface()->draw_opacity_is_animating());
947      need_more_updates |= PaintMasksForRenderSurface(*it, queue, stats_ptr);
948    } else if (it.represents_itself()) {
949      DCHECK(!it->paint_properties().bounds.IsEmpty());
950      it->Update(queue, &occlusion_tracker, stats_ptr);
951      need_more_updates |= it->NeedMoreUpdates();
952    }
953
954    occlusion_tracker.LeaveLayer(it);
955  }
956
957  in_paint_layer_contents_ = false;
958
959  rendering_stats_instrumentation_->AddStats(stats);
960
961  occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
962
963  return need_more_updates;
964}
965
966void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) {
967  if (!root_layer_.get())
968    return;
969
970  Layer* root_scroll_layer = FindFirstScrollableLayer(root_layer_.get());
971  gfx::Vector2d root_scroll_delta;
972
973  for (size_t i = 0; i < info.scrolls.size(); ++i) {
974    Layer* layer =
975        LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(),
976                                                info.scrolls[i].layer_id);
977    if (!layer)
978      continue;
979    if (layer == root_scroll_layer) {
980      root_scroll_delta += info.scrolls[i].scroll_delta;
981    } else {
982      layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
983                                         info.scrolls[i].scroll_delta);
984    }
985  }
986  if (!root_scroll_delta.IsZero() || info.page_scale_delta != 1.f)
987    client_->ApplyScrollAndScale(root_scroll_delta, info.page_scale_delta);
988}
989
990void LayerTreeHost::StartRateLimiter(WebKit::WebGraphicsContext3D* context3d) {
991  if (animating_)
992    return;
993
994  DCHECK(context3d);
995  RateLimiterMap::iterator it = rate_limiters_.find(context3d);
996  if (it != rate_limiters_.end()) {
997    it->second->Start();
998  } else {
999    scoped_refptr<RateLimiter> rate_limiter =
1000        RateLimiter::Create(context3d, this, proxy_->MainThread());
1001    rate_limiters_[context3d] = rate_limiter;
1002    rate_limiter->Start();
1003  }
1004}
1005
1006void LayerTreeHost::StopRateLimiter(WebKit::WebGraphicsContext3D* context3d) {
1007  RateLimiterMap::iterator it = rate_limiters_.find(context3d);
1008  if (it != rate_limiters_.end()) {
1009    it->second->Stop();
1010    rate_limiters_.erase(it);
1011  }
1012}
1013
1014void LayerTreeHost::RateLimit() {
1015  // Force a no-op command on the compositor context, so that any ratelimiting
1016  // commands will wait for the compositing context, and therefore for the
1017  // SwapBuffers.
1018  proxy_->ForceSerializeOnSwapBuffers();
1019}
1020
1021bool LayerTreeHost::RequestPartialTextureUpdate() {
1022  if (partial_texture_update_requests_ >= settings_.max_partial_texture_updates)
1023    return false;
1024
1025  partial_texture_update_requests_++;
1026  return true;
1027}
1028
1029void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1030  if (device_scale_factor ==  device_scale_factor_)
1031    return;
1032  device_scale_factor_ = device_scale_factor;
1033
1034  SetNeedsCommit();
1035}
1036
1037void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1038                                           TopControlsState current,
1039                                           bool animate) {
1040  if (!settings_.calculate_top_controls_position)
1041    return;
1042
1043  // Top controls are only used in threaded mode.
1044  proxy_->ImplThread()->PostTask(
1045      base::Bind(&TopControlsManager::UpdateTopControlsState,
1046                 top_controls_manager_weak_ptr_,
1047                 constraints,
1048                 current,
1049                 animate));
1050}
1051
1052bool LayerTreeHost::BlocksPendingCommit() const {
1053  if (!root_layer_.get())
1054    return false;
1055  return root_layer_->BlocksPendingCommitRecursive();
1056}
1057
1058scoped_ptr<base::Value> LayerTreeHost::AsValue() const {
1059  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1060  state->Set("proxy", proxy_->AsValue().release());
1061  return state.PassAs<base::Value>();
1062}
1063
1064void LayerTreeHost::AnimateLayers(base::TimeTicks time) {
1065  rendering_stats_instrumentation_->IncrementAnimationFrameCount();
1066  if (!settings_.accelerated_animation_enabled ||
1067      animation_registrar_->active_animation_controllers().empty())
1068    return;
1069
1070  TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1071
1072  double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1073
1074  AnimationRegistrar::AnimationControllerMap copy =
1075      animation_registrar_->active_animation_controllers();
1076  for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1077       iter != copy.end();
1078       ++iter) {
1079    (*iter).second->Animate(monotonic_time);
1080    bool start_ready_animations = true;
1081    (*iter).second->UpdateState(start_ready_animations, NULL);
1082  }
1083}
1084
1085skia::RefPtr<SkPicture> LayerTreeHost::CapturePicture() {
1086  return proxy_->CapturePicture();
1087}
1088
1089}  // namespace cc
1090