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