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.
5 #include "cc/trees/layer_tree_host.h"
11 #include "base/atomic_sequence_num.h"
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/debug/trace_event.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "cc/animation/animation_registrar.h"
20 #include "cc/animation/layer_animation_controller.h"
21 #include "cc/base/math_util.h"
22 #include "cc/debug/devtools_instrumentation.h"
23 #include "cc/debug/overdraw_metrics.h"
24 #include "cc/debug/rendering_stats_instrumentation.h"
25 #include "cc/input/top_controls_manager.h"
26 #include "cc/layers/heads_up_display_layer.h"
27 #include "cc/layers/heads_up_display_layer_impl.h"
28 #include "cc/layers/layer.h"
29 #include "cc/layers/layer_iterator.h"
30 #include "cc/layers/painted_scrollbar_layer.h"
31 #include "cc/layers/render_surface.h"
32 #include "cc/resources/prioritized_resource_manager.h"
33 #include "cc/resources/ui_resource_request.h"
34 #include "cc/trees/layer_tree_host_client.h"
35 #include "cc/trees/layer_tree_host_common.h"
36 #include "cc/trees/layer_tree_host_impl.h"
37 #include "cc/trees/layer_tree_impl.h"
38 #include "cc/trees/occlusion_tracker.h"
39 #include "cc/trees/single_thread_proxy.h"
40 #include "cc/trees/thread_proxy.h"
41 #include "cc/trees/tree_synchronizer.h"
42 #include "ui/gfx/size_conversions.h"
45 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
50 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
51 bool allow_partial_texture_updates,
52 bool using_offscreen_context3d,
54 bool using_shared_memory_resources)
55 : best_texture_format(best_texture_format),
56 allow_partial_texture_updates(allow_partial_texture_updates),
57 using_offscreen_context3d(using_offscreen_context3d),
58 max_texture_size(max_texture_size),
59 using_shared_memory_resources(using_shared_memory_resources) {}
61 RendererCapabilities::RendererCapabilities()
62 : best_texture_format(RGBA_8888),
63 allow_partial_texture_updates(false),
64 using_offscreen_context3d(false),
66 using_shared_memory_resources(false) {}
68 RendererCapabilities::~RendererCapabilities() {}
70 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
71 LayerTreeHostClient* client,
72 SharedBitmapManager* manager,
73 const LayerTreeSettings& settings,
74 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
75 DCHECK(impl_task_runner);
76 scoped_ptr<LayerTreeHost> layer_tree_host(
77 new LayerTreeHost(client, manager, settings));
78 layer_tree_host->InitializeThreaded(impl_task_runner);
79 return layer_tree_host.Pass();
82 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
83 LayerTreeHostClient* client,
84 LayerTreeHostSingleThreadClient* single_thread_client,
85 SharedBitmapManager* manager,
86 const LayerTreeSettings& settings) {
87 scoped_ptr<LayerTreeHost> layer_tree_host(
88 new LayerTreeHost(client, manager, settings));
89 layer_tree_host->InitializeSingleThreaded(single_thread_client);
90 return layer_tree_host.Pass();
94 LayerTreeHost::LayerTreeHost(
95 LayerTreeHostClient* client,
96 SharedBitmapManager* manager,
97 const LayerTreeSettings& settings)
98 : micro_benchmark_controller_(this),
99 next_ui_resource_id_(1),
101 needs_full_tree_sync_(true),
102 needs_filter_context_(false),
104 source_frame_number_(0),
105 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
106 output_surface_can_be_initialized_(true),
107 output_surface_lost_(true),
108 num_failed_recreate_attempts_(0),
110 debug_state_(settings.initial_debug_state),
111 overdraw_bottom_height_(0.f),
112 device_scale_factor_(1.f),
114 page_scale_factor_(1.f),
115 min_page_scale_factor_(1.f),
116 max_page_scale_factor_(1.f),
117 trigger_idle_updates_(true),
118 background_color_(SK_ColorWHITE),
119 has_transparent_background_(false),
120 partial_texture_update_requests_(0),
121 in_paint_layer_contents_(false),
122 total_frames_used_for_lcd_text_metrics_(0),
123 id_(s_layer_tree_host_sequence_number.GetNext() + 1),
124 next_commit_forces_redraw_(false),
125 shared_bitmap_manager_(manager) {
126 if (settings_.accelerated_animation_enabled)
127 animation_registrar_ = AnimationRegistrar::Create();
128 rendering_stats_instrumentation_->set_record_rendering_stats(
129 debug_state_.RecordRenderingStats());
132 void LayerTreeHost::InitializeThreaded(
133 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
134 InitializeProxy(ThreadProxy::Create(this, impl_task_runner));
137 void LayerTreeHost::InitializeSingleThreaded(
138 LayerTreeHostSingleThreadClient* single_thread_client) {
139 InitializeProxy(SingleThreadProxy::Create(this, single_thread_client));
142 void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
143 InitializeProxy(proxy_for_testing.Pass());
146 void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
147 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
149 proxy_ = proxy.Pass();
153 LayerTreeHost::~LayerTreeHost() {
154 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
156 overhang_ui_resource_.reset();
158 if (root_layer_.get())
159 root_layer_->SetLayerTreeHost(NULL);
162 DCHECK(proxy_->IsMainThread());
166 // We must clear any pointers into the layer tree prior to destroying it.
167 RegisterViewportLayers(NULL, NULL, NULL);
169 if (root_layer_.get()) {
170 // The layer tree must be destroyed before the layer tree host. We've
171 // made a contract with our animation controllers that the registrar
172 // will outlive them, and we must make good.
177 void LayerTreeHost::SetLayerTreeHostClientReady() {
178 proxy_->SetLayerTreeHostClientReady();
181 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
182 layer->OnOutputSurfaceCreated();
185 LayerTreeHost::CreateResult
186 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
188 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
192 DCHECK(output_surface_lost_);
194 output_surface_lost_ = false;
196 if (!contents_texture_manager_ && !settings_.impl_side_painting) {
197 contents_texture_manager_ =
198 PrioritizedResourceManager::Create(proxy_.get());
199 surface_memory_placeholder_ =
200 contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
204 LayerTreeHostCommon::CallFunctionForSubtree(
206 base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
209 client_->DidInitializeOutputSurface(true);
210 return CreateSucceeded;
215 client_->DidFailToInitializeOutputSurface();
217 // Tolerate a certain number of recreation failures to work around races
218 // in the output-surface-lost machinery.
219 ++num_failed_recreate_attempts_;
220 if (num_failed_recreate_attempts_ >= 5) {
221 // We have tried too many times to recreate the output surface. Tell the
222 // host to fall back to software rendering.
223 output_surface_can_be_initialized_ = false;
224 client_->DidInitializeOutputSurface(false);
225 return CreateFailedAndGaveUp;
228 return CreateFailedButTryAgain;
231 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
232 ResourceProvider* resource_provider) {
233 DCHECK(proxy_->IsImplThread());
234 if (contents_texture_manager_)
235 contents_texture_manager_->ClearAllMemory(resource_provider);
238 void LayerTreeHost::AcquireLayerTextures() {
239 DCHECK(proxy_->IsMainThread());
240 proxy_->AcquireLayerTextures();
243 void LayerTreeHost::DidBeginMainFrame() {
244 client_->DidBeginMainFrame();
247 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
249 client_->Animate(frame_begin_time);
253 void LayerTreeHost::DidStopFlinging() {
254 proxy_->MainThreadHasStoppedFlinging();
257 void LayerTreeHost::Layout() {
261 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
262 DCHECK(proxy_->IsImplThread());
263 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
266 // This function commits the LayerTreeHost to an impl tree. When modifying
267 // this function, keep in mind that the function *runs* on the impl thread! Any
268 // code that is logically a main thread operation, e.g. deletion of a Layer,
269 // should be delayed until the LayerTreeHost::CommitComplete, which will run
270 // after the commit, but on the main thread.
271 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
272 DCHECK(proxy_->IsImplThread());
274 // If there are linked evicted backings, these backings' resources may be put
275 // into the impl tree, so we can't draw yet. Determine this before clearing
276 // all evicted backings.
277 bool new_impl_tree_has_no_evicted_resources = false;
278 if (contents_texture_manager_) {
279 new_impl_tree_has_no_evicted_resources =
280 !contents_texture_manager_->LinkedEvictedBackingsExist();
282 // If the memory limit has been increased since this now-finishing
283 // commit began, and the extra now-available memory would have been used,
284 // then request another commit.
285 if (contents_texture_manager_->MaxMemoryLimitBytes() <
286 host_impl->memory_allocation_limit_bytes() &&
287 contents_texture_manager_->MaxMemoryLimitBytes() <
288 contents_texture_manager_->MaxMemoryNeededBytes()) {
289 host_impl->SetNeedsCommit();
292 host_impl->set_max_memory_needed_bytes(
293 contents_texture_manager_->MaxMemoryNeededBytes());
295 contents_texture_manager_->UpdateBackingsState(
296 host_impl->resource_provider());
299 // In impl-side painting, synchronize to the pending tree so that it has
300 // time to raster before being displayed. If no pending tree is needed,
301 // synchronization can happen directly to the active tree and
302 // unlinked contents resources can be reclaimed immediately.
303 LayerTreeImpl* sync_tree;
304 if (settings_.impl_side_painting) {
305 // Commits should not occur while there is already a pending tree.
306 DCHECK(!host_impl->pending_tree());
307 host_impl->CreatePendingTree();
308 sync_tree = host_impl->pending_tree();
309 if (next_commit_forces_redraw_)
310 sync_tree->ForceRedrawNextActivation();
312 if (next_commit_forces_redraw_)
313 host_impl->SetFullRootLayerDamage();
314 contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
315 sync_tree = host_impl->active_tree();
318 next_commit_forces_redraw_ = false;
320 sync_tree->set_source_frame_number(source_frame_number());
322 if (needs_full_tree_sync_)
323 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
324 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
326 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
327 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
330 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
331 needs_full_tree_sync_ = false;
333 if (hud_layer_.get()) {
334 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
335 sync_tree->root_layer(), hud_layer_->id());
336 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
338 sync_tree->set_hud_layer(NULL);
341 sync_tree->set_background_color(background_color_);
342 sync_tree->set_has_transparent_background(has_transparent_background_);
344 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
345 sync_tree->SetViewportLayersFromIds(
346 page_scale_layer_->id(),
347 inner_viewport_scroll_layer_->id(),
348 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
349 : Layer::INVALID_ID);
351 sync_tree->ClearViewportLayers();
354 float page_scale_delta, sent_page_scale_delta;
355 if (settings_.impl_side_painting) {
356 // Update the delta from the active tree, which may have
357 // adjusted its delta prior to the pending tree being created.
358 // This code is equivalent to that in LayerTreeImpl::SetPageScaleDelta.
359 DCHECK_EQ(1.f, sync_tree->sent_page_scale_delta());
360 page_scale_delta = host_impl->active_tree()->page_scale_delta();
361 sent_page_scale_delta = host_impl->active_tree()->sent_page_scale_delta();
363 page_scale_delta = sync_tree->page_scale_delta();
364 sent_page_scale_delta = sync_tree->sent_page_scale_delta();
365 sync_tree->set_sent_page_scale_delta(1.f);
368 sync_tree->SetPageScaleFactorAndLimits(page_scale_factor_,
369 min_page_scale_factor_,
370 max_page_scale_factor_);
371 sync_tree->SetPageScaleDelta(page_scale_delta / sent_page_scale_delta);
373 sync_tree->PassSwapPromises(&swap_promise_list_);
375 host_impl->SetViewportSize(device_viewport_size_);
376 host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_);
377 host_impl->SetDeviceScaleFactor(device_scale_factor_);
378 host_impl->SetDebugState(debug_state_);
379 if (pending_page_scale_animation_) {
380 host_impl->StartPageScaleAnimation(
381 pending_page_scale_animation_->target_offset,
382 pending_page_scale_animation_->use_anchor,
383 pending_page_scale_animation_->scale,
384 pending_page_scale_animation_->duration);
385 pending_page_scale_animation_.reset();
388 if (!ui_resource_request_queue_.empty()) {
389 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
390 ui_resource_request_queue_.clear();
391 // Process any ui resource requests in the queue. For impl-side-painting,
392 // the queue is processed in LayerTreeHostImpl::ActivatePendingTree.
393 if (!settings_.impl_side_painting)
394 sync_tree->ProcessUIResourceRequestQueue();
396 if (overhang_ui_resource_) {
397 host_impl->SetOverhangUIResource(
398 overhang_ui_resource_->id(),
399 GetUIResourceSize(overhang_ui_resource_->id()));
402 DCHECK(!sync_tree->ViewportSizeInvalid());
404 if (new_impl_tree_has_no_evicted_resources) {
405 if (sync_tree->ContentsTexturesPurged())
406 sync_tree->ResetContentsTexturesPurged();
409 if (!settings_.impl_side_painting) {
410 // If we're not in impl-side painting, the tree is immediately
411 // considered active.
412 sync_tree->DidBecomeActive();
413 devtools_instrumentation::DidActivateLayerTree(id_, source_frame_number_);
416 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
418 source_frame_number_++;
421 void LayerTreeHost::WillCommit() {
422 client_->WillCommit();
425 void LayerTreeHost::UpdateHudLayer() {
426 if (debug_state_.ShowHudInfo()) {
427 if (!hud_layer_.get())
428 hud_layer_ = HeadsUpDisplayLayer::Create();
430 if (root_layer_.get() && !hud_layer_->parent())
431 root_layer_->AddChild(hud_layer_);
432 } else if (hud_layer_.get()) {
433 hud_layer_->RemoveFromParent();
438 void LayerTreeHost::CommitComplete() {
439 client_->DidCommit();
442 scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() {
443 return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4);
446 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
447 LayerTreeHostImplClient* client) {
448 DCHECK(proxy_->IsImplThread());
449 scoped_ptr<LayerTreeHostImpl> host_impl =
450 LayerTreeHostImpl::Create(settings_,
453 rendering_stats_instrumentation_.get(),
454 shared_bitmap_manager_,
456 shared_bitmap_manager_ = NULL;
457 if (settings_.calculate_top_controls_position &&
458 host_impl->top_controls_manager()) {
459 top_controls_manager_weak_ptr_ =
460 host_impl->top_controls_manager()->AsWeakPtr();
462 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
463 return host_impl.Pass();
466 void LayerTreeHost::DidLoseOutputSurface() {
467 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
468 DCHECK(proxy_->IsMainThread());
470 if (output_surface_lost_)
473 num_failed_recreate_attempts_ = 0;
474 output_surface_lost_ = true;
478 bool LayerTreeHost::CompositeAndReadback(
480 const gfx::Rect& rect_in_device_viewport) {
481 trigger_idle_updates_ = false;
482 bool ret = proxy_->CompositeAndReadback(pixels, rect_in_device_viewport);
483 trigger_idle_updates_ = true;
487 void LayerTreeHost::FinishAllRendering() {
488 proxy_->FinishAllRendering();
491 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
492 proxy_->SetDeferCommits(defer_commits);
495 void LayerTreeHost::DidDeferCommit() {}
497 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
498 std::stack<Layer*> layer_stack;
499 layer_stack.push(root_layer());
500 while (!layer_stack.empty()) {
501 Layer* current_layer = layer_stack.top();
503 current_layer->SetNeedsDisplay();
504 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
505 layer_stack.push(current_layer->child_at(i));
510 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
511 return proxy_->GetRendererCapabilities();
514 void LayerTreeHost::SetNeedsAnimate() {
515 proxy_->SetNeedsAnimate();
516 NotifySwapPromiseMonitorsOfSetNeedsCommit();
519 void LayerTreeHost::SetNeedsUpdateLayers() {
520 proxy_->SetNeedsUpdateLayers();
521 NotifySwapPromiseMonitorsOfSetNeedsCommit();
524 void LayerTreeHost::SetNeedsCommit() {
525 if (!prepaint_callback_.IsCancelled()) {
526 TRACE_EVENT_INSTANT0("cc",
527 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
528 TRACE_EVENT_SCOPE_THREAD);
529 prepaint_callback_.Cancel();
531 proxy_->SetNeedsCommit();
532 NotifySwapPromiseMonitorsOfSetNeedsCommit();
535 void LayerTreeHost::SetNeedsFullTreeSync() {
536 needs_full_tree_sync_ = true;
540 void LayerTreeHost::SetNeedsRedraw() {
541 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
544 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
545 proxy_->SetNeedsRedraw(damage_rect);
548 bool LayerTreeHost::CommitRequested() const {
549 return proxy_->CommitRequested();
552 bool LayerTreeHost::BeginMainFrameRequested() const {
553 return proxy_->BeginMainFrameRequested();
557 void LayerTreeHost::SetNextCommitWaitsForActivation() {
558 proxy_->SetNextCommitWaitsForActivation();
561 void LayerTreeHost::SetNextCommitForcesRedraw() {
562 next_commit_forces_redraw_ = true;
565 void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
566 base::Time wall_clock_time) {
567 DCHECK(proxy_->IsMainThread());
568 for (size_t event_index = 0; event_index < events->size(); ++event_index) {
569 int event_layer_id = (*events)[event_index].layer_id;
571 // Use the map of all controllers, not just active ones, since non-active
572 // controllers may still receive events for impl-only animations.
573 const AnimationRegistrar::AnimationControllerMap& animation_controllers =
574 animation_registrar_->all_animation_controllers();
575 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
576 animation_controllers.find(event_layer_id);
577 if (iter != animation_controllers.end()) {
578 switch ((*events)[event_index].type) {
579 case AnimationEvent::Started:
580 (*iter).second->NotifyAnimationStarted((*events)[event_index],
581 wall_clock_time.ToDoubleT());
584 case AnimationEvent::Finished:
585 (*iter).second->NotifyAnimationFinished((*events)[event_index],
586 wall_clock_time.ToDoubleT());
589 case AnimationEvent::Aborted:
590 (*iter).second->NotifyAnimationAborted((*events)[event_index]);
593 case AnimationEvent::PropertyUpdate:
594 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
601 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
602 if (root_layer_.get() == root_layer.get())
605 if (root_layer_.get())
606 root_layer_->SetLayerTreeHost(NULL);
607 root_layer_ = root_layer;
608 if (root_layer_.get()) {
609 DCHECK(!root_layer_->parent());
610 root_layer_->SetLayerTreeHost(this);
613 if (hud_layer_.get())
614 hud_layer_->RemoveFromParent();
616 SetNeedsFullTreeSync();
619 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
620 LayerTreeDebugState new_debug_state =
621 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
623 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
626 debug_state_ = new_debug_state;
628 rendering_stats_instrumentation_->set_record_rendering_stats(
629 debug_state_.RecordRenderingStats());
634 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
635 if (device_viewport_size == device_viewport_size_)
638 device_viewport_size_ = device_viewport_size;
643 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) {
644 if (overdraw_bottom_height_ == overdraw_bottom_height)
647 overdraw_bottom_height_ = overdraw_bottom_height;
651 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
652 DCHECK(CommitRequested());
653 page_scale_factor_ *= page_scale_delta;
656 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
657 float min_page_scale_factor,
658 float max_page_scale_factor) {
659 if (page_scale_factor == page_scale_factor_ &&
660 min_page_scale_factor == min_page_scale_factor_ &&
661 max_page_scale_factor == max_page_scale_factor_)
664 page_scale_factor_ = page_scale_factor;
665 min_page_scale_factor_ = min_page_scale_factor;
666 max_page_scale_factor_ = max_page_scale_factor;
670 void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
671 DCHECK(bitmap.width() && bitmap.height());
672 DCHECK_EQ(bitmap.bytesPerPixel(), 4);
674 SkBitmap bitmap_copy;
675 if (bitmap.isImmutable()) {
676 bitmap_copy = bitmap;
678 bitmap.copyTo(&bitmap_copy, bitmap.config());
679 bitmap_copy.setImmutable();
682 UIResourceBitmap overhang_bitmap(bitmap_copy);
683 overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
684 overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
687 void LayerTreeHost::SetVisible(bool visible) {
688 if (visible_ == visible)
693 proxy_->SetVisible(visible);
696 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
699 base::TimeDelta duration) {
700 pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
701 pending_page_scale_animation_->target_offset = target_offset;
702 pending_page_scale_animation_->use_anchor = use_anchor;
703 pending_page_scale_animation_->scale = scale;
704 pending_page_scale_animation_->duration = duration;
709 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
710 proxy_->NotifyInputThrottledUntilCommit();
713 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
714 if (!proxy_->HasImplThread())
715 static_cast<SingleThreadProxy*>(proxy_.get())->CompositeImmediately(
721 bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() {
722 if (!output_surface_can_be_initialized_)
725 if (output_surface_lost_)
726 proxy_->CreateAndInitializeOutputSurface();
727 return !output_surface_lost_;
730 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
731 DCHECK(!output_surface_lost_);
736 DCHECK(!root_layer()->parent());
738 bool result = UpdateLayers(root_layer(), queue);
740 micro_benchmark_controller_.DidUpdateLayers();
745 static Layer* FindFirstScrollableLayer(Layer* layer) {
749 if (layer->scrollable())
752 for (size_t i = 0; i < layer->children().size(); ++i) {
753 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
761 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) {
762 if (!layer->SupportsLCDText())
765 lcd_text_metrics_.total_num_cc_layers++;
766 if (layer->draw_properties().can_use_lcd_text) {
767 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
768 if (layer->contents_opaque())
769 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
773 bool LayerTreeHost::UsingSharedMemoryResources() {
774 return GetRendererCapabilities().using_shared_memory_resources;
777 bool LayerTreeHost::UpdateLayers(Layer* root_layer,
778 ResourceUpdateQueue* queue) {
779 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
780 "source_frame_number", source_frame_number());
782 RenderSurfaceLayerList update_list;
786 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
787 Layer* page_scale_layer = page_scale_layer_;
788 if (!page_scale_layer && root_scroll)
789 page_scale_layer = root_scroll->parent();
792 hud_layer_->PrepareForCalculateDrawProperties(
793 device_viewport_size(), device_scale_factor_);
796 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
797 bool can_render_to_separate_surface = true;
798 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
800 device_viewport_size(),
802 device_scale_factor_,
805 GetRendererCapabilities().max_texture_size,
806 settings_.can_use_lcd_text,
807 can_render_to_separate_surface,
808 settings_.layer_transforms_should_scale_layer_contents,
810 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
812 if (total_frames_used_for_lcd_text_metrics_ <=
813 kTotalFramesToUseForLCDTextMetrics) {
814 LayerTreeHostCommon::CallFunctionForSubtree(
816 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback,
817 base::Unretained(this)));
818 total_frames_used_for_lcd_text_metrics_++;
821 if (total_frames_used_for_lcd_text_metrics_ ==
822 kTotalFramesToUseForLCDTextMetrics) {
823 total_frames_used_for_lcd_text_metrics_++;
825 UMA_HISTOGRAM_PERCENTAGE(
826 "Renderer4.LCDText.PercentageOfCandidateLayers",
827 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 /
828 lcd_text_metrics_.total_num_cc_layers);
829 UMA_HISTOGRAM_PERCENTAGE(
830 "Renderer4.LCDText.PercentageOfAALayers",
831 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 /
832 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text);
836 // Reset partial texture update requests.
837 partial_texture_update_requests_ = 0;
839 bool did_paint_content = false;
840 bool need_more_updates = false;
842 update_list, queue, &did_paint_content, &need_more_updates);
843 if (trigger_idle_updates_ && need_more_updates) {
844 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
845 prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
846 base::Unretained(this)));
847 static base::TimeDelta prepaint_delay =
848 base::TimeDelta::FromMilliseconds(100);
849 base::MessageLoop::current()->PostDelayedTask(
850 FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
853 return did_paint_content;
856 void LayerTreeHost::TriggerPrepaint() {
857 prepaint_callback_.Cancel();
858 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
862 static void LayerTreeHostReduceMemoryCallback(Layer* layer) {
863 layer->ReduceMemoryUsage();
866 void LayerTreeHost::ReduceMemoryUsage() {
870 LayerTreeHostCommon::CallFunctionForSubtree(
872 base::Bind(&LayerTreeHostReduceMemoryCallback));
875 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
876 DCHECK(surface_memory_placeholder_);
878 // Surfaces have a place holder for their memory since they are managed
879 // independantly but should still be tracked and reduce other memory usage.
880 surface_memory_placeholder_->SetTextureManager(
881 contents_texture_manager_.get());
882 surface_memory_placeholder_->set_request_priority(
883 PriorityCalculator::RenderSurfacePriority());
884 surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
885 surface_memory_bytes);
888 void LayerTreeHost::SetPrioritiesForLayers(
889 const RenderSurfaceLayerList& update_list) {
890 PriorityCalculator calculator;
891 typedef LayerIterator<Layer> LayerIteratorType;
892 LayerIteratorType end = LayerIteratorType::End(&update_list);
893 for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
896 if (it.represents_itself()) {
897 it->SetTexturePriorities(calculator);
898 } else if (it.represents_target_render_surface()) {
899 if (it->mask_layer())
900 it->mask_layer()->SetTexturePriorities(calculator);
901 if (it->replica_layer() && it->replica_layer()->mask_layer())
902 it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
907 void LayerTreeHost::PrioritizeTextures(
908 const RenderSurfaceLayerList& render_surface_layer_list,
909 OverdrawMetrics* metrics) {
910 if (!contents_texture_manager_)
913 contents_texture_manager_->ClearPriorities();
915 size_t memory_for_render_surfaces_metric =
916 CalculateMemoryForRenderSurfaces(render_surface_layer_list);
918 SetPrioritiesForLayers(render_surface_layer_list);
919 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
921 metrics->DidUseContentsTextureMemoryBytes(
922 contents_texture_manager_->MemoryAboveCutoffBytes());
923 metrics->DidUseRenderSurfaceTextureMemoryBytes(
924 memory_for_render_surfaces_metric);
926 contents_texture_manager_->PrioritizeTextures();
929 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
930 const RenderSurfaceLayerList& update_list) {
931 size_t readback_bytes = 0;
932 size_t max_background_texture_bytes = 0;
933 size_t contents_texture_bytes = 0;
935 // Start iteration at 1 to skip the root surface as it does not have a texture
937 for (size_t i = 1; i < update_list.size(); ++i) {
938 Layer* render_surface_layer = update_list.at(i);
939 RenderSurface* render_surface = render_surface_layer->render_surface();
942 Resource::MemorySizeBytes(render_surface->content_rect().size(),
944 contents_texture_bytes += bytes;
946 if (render_surface_layer->background_filters().IsEmpty())
949 if (bytes > max_background_texture_bytes)
950 max_background_texture_bytes = bytes;
951 if (!readback_bytes) {
952 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
956 return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
959 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
960 ResourceUpdateQueue* queue,
961 bool* did_paint_content,
962 bool* need_more_updates) {
963 // Note: Masks and replicas only exist for layers that own render surfaces. If
964 // we reach this point in code, we already know that at least something will
965 // be drawn into this render surface, so the mask and replica should be
968 Layer* mask_layer = render_surface_layer->mask_layer();
970 *did_paint_content |= mask_layer->Update(queue, NULL);
971 *need_more_updates |= mask_layer->NeedMoreUpdates();
974 Layer* replica_mask_layer =
975 render_surface_layer->replica_layer() ?
976 render_surface_layer->replica_layer()->mask_layer() : NULL;
977 if (replica_mask_layer) {
978 *did_paint_content |= replica_mask_layer->Update(queue, NULL);
979 *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
983 void LayerTreeHost::PaintLayerContents(
984 const RenderSurfaceLayerList& render_surface_layer_list,
985 ResourceUpdateQueue* queue,
986 bool* did_paint_content,
987 bool* need_more_updates) {
988 bool record_metrics_for_frame =
989 settings_.show_overdraw_in_tracing &&
990 base::debug::TraceLog::GetInstance() &&
991 base::debug::TraceLog::GetInstance()->IsEnabled();
992 OcclusionTracker occlusion_tracker(
993 root_layer_->render_surface()->content_rect(), record_metrics_for_frame);
994 occlusion_tracker.set_minimum_tracking_size(
995 settings_.minimum_occlusion_tracking_size);
997 PrioritizeTextures(render_surface_layer_list,
998 occlusion_tracker.overdraw_metrics());
1000 in_paint_layer_contents_ = true;
1002 // Iterates front-to-back to allow for testing occlusion and performing
1003 // culling during the tree walk.
1004 typedef LayerIterator<Layer> LayerIteratorType;
1005 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1006 for (LayerIteratorType it =
1007 LayerIteratorType::Begin(&render_surface_layer_list);
1010 occlusion_tracker.EnterLayer(it);
1012 if (it.represents_target_render_surface()) {
1013 PaintMasksForRenderSurface(
1014 *it, queue, did_paint_content, need_more_updates);
1015 } else if (it.represents_itself() && it->DrawsContent()) {
1016 DCHECK(!it->paint_properties().bounds.IsEmpty());
1017 *did_paint_content |= it->Update(queue, &occlusion_tracker);
1018 *need_more_updates |= it->NeedMoreUpdates();
1021 occlusion_tracker.LeaveLayer(it);
1024 in_paint_layer_contents_ = false;
1026 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
1029 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) {
1030 if (!root_layer_.get())
1033 gfx::Vector2d inner_viewport_scroll_delta;
1034 gfx::Vector2d outer_viewport_scroll_delta;
1036 for (size_t i = 0; i < info.scrolls.size(); ++i) {
1038 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(),
1039 info.scrolls[i].layer_id);
1042 if (layer == outer_viewport_scroll_layer_.get()) {
1043 outer_viewport_scroll_delta += info.scrolls[i].scroll_delta;
1044 } else if (layer == inner_viewport_scroll_layer_.get()) {
1045 inner_viewport_scroll_delta += info.scrolls[i].scroll_delta;
1047 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
1048 info.scrolls[i].scroll_delta);
1052 if (!inner_viewport_scroll_delta.IsZero() ||
1053 !outer_viewport_scroll_delta.IsZero() || info.page_scale_delta != 1.f) {
1054 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1055 // so re-get this layer before doing anything to it.
1057 // Preemptively apply the scroll offset and scale delta here before sending
1058 // it to the client. If the client comes back and sets it to the same
1059 // value, then the layer can early out without needing a full commit.
1060 DCHECK(inner_viewport_scroll_layer_); // We should always have this.
1062 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1063 inner_viewport_scroll_layer_->scroll_offset() +
1064 inner_viewport_scroll_delta);
1065 if (outer_viewport_scroll_layer_) {
1066 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1067 outer_viewport_scroll_layer_->scroll_offset() +
1068 outer_viewport_scroll_delta);
1070 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta);
1072 client_->ApplyScrollAndScale(
1073 inner_viewport_scroll_delta + outer_viewport_scroll_delta,
1074 info.page_scale_delta);
1078 gfx::Vector2d LayerTreeHost::DistributeScrollOffsetToViewports(
1079 const gfx::Vector2d offset,
1082 if (layer != outer_viewport_scroll_layer_.get())
1085 gfx::Vector2d inner_viewport_offset =
1086 inner_viewport_scroll_layer_->scroll_offset();
1087 gfx::Vector2d outer_viewport_offset =
1088 outer_viewport_scroll_layer_->scroll_offset();
1090 if (offset == inner_viewport_offset + outer_viewport_offset) {
1091 // In this case, nothing should change, so we just return to the outer
1092 // viewport the offset is already has.
1093 return outer_viewport_offset;
1096 // In the spirit of document-scrolls-first, we always want any change to
1097 // go to the outer viewport first.
1098 gfx::Vector2d max_outer_viewport_scroll_offset =
1099 outer_viewport_scroll_layer_->MaxScrollOffset();
1100 gfx::Vector2d max_inner_viewport_scroll_offset =
1101 inner_viewport_scroll_layer_->MaxScrollOffset();
1103 // TODO(bokan): This trips on zoom-out due to how Blink orders scale-scroll.
1104 // Disabled until that's sorted out: crbug.com/336574
1105 // gfx::Vector2d total_max_scroll_offset =
1106 // max_outer_viewport_scroll_offset + max_inner_viewport_scroll_offset;
1107 // DCHECK(total_max_scroll_offset.x() >= offset.x() &&
1108 // total_max_scroll_offset.y() >= offset.y());
1110 outer_viewport_offset = offset - inner_viewport_offset;
1111 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
1112 outer_viewport_offset.SetToMax(gfx::Vector2d());
1114 inner_viewport_offset = offset - outer_viewport_offset;
1115 inner_viewport_offset.SetToMin(max_inner_viewport_scroll_offset);
1116 inner_viewport_offset.SetToMax(gfx::Vector2d());
1117 inner_viewport_scroll_layer_->SetScrollOffset(inner_viewport_offset);
1119 return outer_viewport_offset;
1122 void LayerTreeHost::StartRateLimiter() {
1126 if (!rate_limit_timer_.IsRunning()) {
1127 rate_limit_timer_.Start(FROM_HERE,
1130 &LayerTreeHost::RateLimit);
1134 void LayerTreeHost::StopRateLimiter() {
1135 rate_limit_timer_.Stop();
1138 void LayerTreeHost::RateLimit() {
1139 // Force a no-op command on the compositor context, so that any ratelimiting
1140 // commands will wait for the compositing context, and therefore for the
1142 proxy_->ForceSerializeOnSwapBuffers();
1143 client_->RateLimitSharedMainThreadContext();
1146 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1147 if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
1149 return !proxy_->HasImplThread();
1152 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1153 size_t max_partial_texture_updates = 0;
1154 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
1155 !settings_.impl_side_painting) {
1156 max_partial_texture_updates =
1157 std::min(settings_.max_partial_texture_updates,
1158 proxy_->MaxPartialTextureUpdates());
1160 return max_partial_texture_updates;
1163 bool LayerTreeHost::RequestPartialTextureUpdate() {
1164 if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
1167 partial_texture_update_requests_++;
1171 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1172 if (device_scale_factor == device_scale_factor_)
1174 device_scale_factor_ = device_scale_factor;
1179 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1180 TopControlsState current,
1182 if (!settings_.calculate_top_controls_position)
1185 // Top controls are only used in threaded mode.
1186 proxy_->ImplThreadTaskRunner()->PostTask(
1188 base::Bind(&TopControlsManager::UpdateTopControlsState,
1189 top_controls_manager_weak_ptr_,
1195 scoped_ptr<base::Value> LayerTreeHost::AsValue() const {
1196 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1197 state->Set("proxy", proxy_->AsValue().release());
1198 return state.PassAs<base::Value>();
1201 void LayerTreeHost::AnimateLayers(base::TimeTicks time) {
1202 if (!settings_.accelerated_animation_enabled ||
1203 animation_registrar_->active_animation_controllers().empty())
1206 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1208 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1210 AnimationRegistrar::AnimationControllerMap copy =
1211 animation_registrar_->active_animation_controllers();
1212 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1215 (*iter).second->Animate(monotonic_time);
1216 bool start_ready_animations = true;
1217 (*iter).second->UpdateState(start_ready_animations, NULL);
1221 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
1224 UIResourceId next_id = next_ui_resource_id_++;
1225 DCHECK(ui_resource_client_map_.find(next_id) ==
1226 ui_resource_client_map_.end());
1228 bool resource_lost = false;
1229 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1231 client->GetBitmap(next_id, resource_lost));
1232 ui_resource_request_queue_.push_back(request);
1234 UIResourceClientData data;
1235 data.client = client;
1236 data.size = request.GetBitmap().GetSize();
1238 ui_resource_client_map_[request.GetId()] = data;
1239 return request.GetId();
1242 // Deletes a UI resource. May safely be called more than once.
1243 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
1244 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
1245 if (iter == ui_resource_client_map_.end())
1248 UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
1249 ui_resource_request_queue_.push_back(request);
1250 ui_resource_client_map_.erase(iter);
1253 void LayerTreeHost::RecreateUIResources() {
1254 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
1255 iter != ui_resource_client_map_.end();
1257 UIResourceId uid = iter->first;
1258 const UIResourceClientData& data = iter->second;
1259 bool resource_lost = true;
1260 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1262 data.client->GetBitmap(uid, resource_lost));
1263 ui_resource_request_queue_.push_back(request);
1267 // Returns the size of a resource given its id.
1268 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
1269 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
1270 if (iter == ui_resource_client_map_.end())
1273 const UIResourceClientData& data = iter->second;
1277 void LayerTreeHost::RegisterViewportLayers(
1278 scoped_refptr<Layer> page_scale_layer,
1279 scoped_refptr<Layer> inner_viewport_scroll_layer,
1280 scoped_refptr<Layer> outer_viewport_scroll_layer) {
1281 page_scale_layer_ = page_scale_layer;
1282 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
1283 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1286 bool LayerTreeHost::ScheduleMicroBenchmark(
1287 const std::string& benchmark_name,
1288 scoped_ptr<base::Value> value,
1289 const MicroBenchmark::DoneCallback& callback) {
1290 return micro_benchmark_controller_.ScheduleRun(
1291 benchmark_name, value.Pass(), callback);
1294 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1295 swap_promise_monitor_.insert(monitor);
1298 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1299 swap_promise_monitor_.erase(monitor);
1302 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1303 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1304 for (; it != swap_promise_monitor_.end(); it++)
1305 (*it)->OnSetNeedsCommitOnMain();
1308 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1309 DCHECK(swap_promise);
1310 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
1311 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
1312 swap_promise_list_.push_back(swap_promise.Pass());
1315 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1316 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1317 swap_promise_list_[i]->DidNotSwap(reason);
1318 swap_promise_list_.clear();