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