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