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/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_request.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"
44 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
49 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
50 bool allow_partial_texture_updates,
52 bool using_shared_memory_resources)
53 : best_texture_format(best_texture_format),
54 allow_partial_texture_updates(allow_partial_texture_updates),
55 max_texture_size(max_texture_size),
56 using_shared_memory_resources(using_shared_memory_resources) {}
58 RendererCapabilities::RendererCapabilities()
59 : best_texture_format(RGBA_8888),
60 allow_partial_texture_updates(false),
62 using_shared_memory_resources(false) {}
64 RendererCapabilities::~RendererCapabilities() {}
66 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
67 LayerTreeHostClient* client,
68 SharedBitmapManager* manager,
69 const LayerTreeSettings& settings,
70 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
71 DCHECK(impl_task_runner);
72 scoped_ptr<LayerTreeHost> layer_tree_host(
73 new LayerTreeHost(client, manager, settings));
74 layer_tree_host->InitializeThreaded(impl_task_runner);
75 return layer_tree_host.Pass();
78 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
79 LayerTreeHostClient* client,
80 LayerTreeHostSingleThreadClient* single_thread_client,
81 SharedBitmapManager* manager,
82 const LayerTreeSettings& settings) {
83 scoped_ptr<LayerTreeHost> layer_tree_host(
84 new LayerTreeHost(client, manager, settings));
85 layer_tree_host->InitializeSingleThreaded(single_thread_client);
86 return layer_tree_host.Pass();
89 LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
90 SharedBitmapManager* manager,
91 const LayerTreeSettings& settings)
92 : micro_benchmark_controller_(this),
93 next_ui_resource_id_(1),
95 needs_full_tree_sync_(true),
97 source_frame_number_(0),
98 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
99 output_surface_can_be_initialized_(true),
100 output_surface_lost_(true),
101 num_failed_recreate_attempts_(0),
103 debug_state_(settings.initial_debug_state),
104 overdraw_bottom_height_(0.f),
105 device_scale_factor_(1.f),
107 page_scale_factor_(1.f),
108 min_page_scale_factor_(1.f),
109 max_page_scale_factor_(1.f),
110 trigger_idle_updates_(true),
111 has_gpu_rasterization_trigger_(false),
112 content_is_suitable_for_gpu_rasterization_(true),
113 background_color_(SK_ColorWHITE),
114 has_transparent_background_(false),
115 partial_texture_update_requests_(0),
116 in_paint_layer_contents_(false),
117 total_frames_used_for_lcd_text_metrics_(0),
118 id_(s_layer_tree_host_sequence_number.GetNext() + 1),
119 next_commit_forces_redraw_(false),
120 shared_bitmap_manager_(manager) {
121 if (settings_.accelerated_animation_enabled)
122 animation_registrar_ = AnimationRegistrar::Create();
123 rendering_stats_instrumentation_->set_record_rendering_stats(
124 debug_state_.RecordRenderingStats());
127 void LayerTreeHost::InitializeThreaded(
128 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
129 InitializeProxy(ThreadProxy::Create(this, impl_task_runner));
132 void LayerTreeHost::InitializeSingleThreaded(
133 LayerTreeHostSingleThreadClient* single_thread_client) {
134 InitializeProxy(SingleThreadProxy::Create(this, single_thread_client));
137 void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
138 InitializeProxy(proxy_for_testing.Pass());
141 void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
142 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
144 proxy_ = proxy.Pass();
148 LayerTreeHost::~LayerTreeHost() {
149 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
151 overhang_ui_resource_.reset();
153 if (root_layer_.get())
154 root_layer_->SetLayerTreeHost(NULL);
157 DCHECK(proxy_->IsMainThread());
161 // We must clear any pointers into the layer tree prior to destroying it.
162 RegisterViewportLayers(NULL, NULL, NULL);
164 if (root_layer_.get()) {
165 // The layer tree must be destroyed before the layer tree host. We've
166 // made a contract with our animation controllers that the registrar
167 // will outlive them, and we must make good.
172 void LayerTreeHost::SetLayerTreeHostClientReady() {
173 proxy_->SetLayerTreeHostClientReady();
176 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
177 layer->OnOutputSurfaceCreated();
180 void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
181 DCHECK(output_surface_lost_);
183 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
188 // Tolerate a certain number of recreation failures to work around races
189 // in the output-surface-lost machinery.
190 ++num_failed_recreate_attempts_;
191 if (num_failed_recreate_attempts_ >= 5)
192 LOG(FATAL) << "Failed to create a fallback OutputSurface.";
193 client_->DidFailToInitializeOutputSurface();
197 output_surface_lost_ = false;
199 if (!contents_texture_manager_ && !settings_.impl_side_painting) {
200 contents_texture_manager_ =
201 PrioritizedResourceManager::Create(proxy_.get());
202 surface_memory_placeholder_ =
203 contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
207 LayerTreeHostCommon::CallFunctionForSubtree(
208 root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
211 client_->DidInitializeOutputSurface();
214 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
215 ResourceProvider* resource_provider) {
216 DCHECK(proxy_->IsImplThread());
217 if (contents_texture_manager_)
218 contents_texture_manager_->ClearAllMemory(resource_provider);
221 void LayerTreeHost::DidBeginMainFrame() {
222 client_->DidBeginMainFrame();
225 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
227 client_->Animate(frame_begin_time);
231 void LayerTreeHost::DidStopFlinging() {
232 proxy_->MainThreadHasStoppedFlinging();
235 void LayerTreeHost::Layout() {
239 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
240 DCHECK(proxy_->IsImplThread());
241 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
244 // This function commits the LayerTreeHost to an impl tree. When modifying
245 // this function, keep in mind that the function *runs* on the impl thread! Any
246 // code that is logically a main thread operation, e.g. deletion of a Layer,
247 // should be delayed until the LayerTreeHost::CommitComplete, which will run
248 // after the commit, but on the main thread.
249 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
250 DCHECK(proxy_->IsImplThread());
252 // If there are linked evicted backings, these backings' resources may be put
253 // into the impl tree, so we can't draw yet. Determine this before clearing
254 // all evicted backings.
255 bool new_impl_tree_has_no_evicted_resources = false;
256 if (contents_texture_manager_) {
257 new_impl_tree_has_no_evicted_resources =
258 !contents_texture_manager_->LinkedEvictedBackingsExist();
260 // If the memory limit has been increased since this now-finishing
261 // commit began, and the extra now-available memory would have been used,
262 // then request another commit.
263 if (contents_texture_manager_->MaxMemoryLimitBytes() <
264 host_impl->memory_allocation_limit_bytes() &&
265 contents_texture_manager_->MaxMemoryLimitBytes() <
266 contents_texture_manager_->MaxMemoryNeededBytes()) {
267 host_impl->SetNeedsCommit();
270 host_impl->set_max_memory_needed_bytes(
271 contents_texture_manager_->MaxMemoryNeededBytes());
273 contents_texture_manager_->UpdateBackingsState(
274 host_impl->resource_provider());
277 // In impl-side painting, synchronize to the pending tree so that it has
278 // time to raster before being displayed. If no pending tree is needed,
279 // synchronization can happen directly to the active tree and
280 // unlinked contents resources can be reclaimed immediately.
281 LayerTreeImpl* sync_tree;
282 if (settings_.impl_side_painting) {
283 // Commits should not occur while there is already a pending tree.
284 DCHECK(!host_impl->pending_tree());
285 host_impl->CreatePendingTree();
286 sync_tree = host_impl->pending_tree();
287 if (next_commit_forces_redraw_)
288 sync_tree->ForceRedrawNextActivation();
290 if (next_commit_forces_redraw_)
291 host_impl->SetFullRootLayerDamage();
292 contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
293 sync_tree = host_impl->active_tree();
296 next_commit_forces_redraw_ = false;
298 sync_tree->set_source_frame_number(source_frame_number());
300 if (needs_full_tree_sync_)
301 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
302 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
304 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
305 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
308 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
309 needs_full_tree_sync_ = false;
311 if (hud_layer_.get()) {
312 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
313 sync_tree->root_layer(), hud_layer_->id());
314 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
316 sync_tree->set_hud_layer(NULL);
319 sync_tree->set_background_color(background_color_);
320 sync_tree->set_has_transparent_background(has_transparent_background_);
322 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
323 sync_tree->SetViewportLayersFromIds(
324 page_scale_layer_->id(),
325 inner_viewport_scroll_layer_->id(),
326 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
327 : Layer::INVALID_ID);
329 sync_tree->ClearViewportLayers();
332 float page_scale_delta, sent_page_scale_delta;
333 if (settings_.impl_side_painting) {
334 // Update the delta from the active tree, which may have
335 // adjusted its delta prior to the pending tree being created.
336 // This code is equivalent to that in LayerTreeImpl::SetPageScaleDelta.
337 DCHECK_EQ(1.f, sync_tree->sent_page_scale_delta());
338 page_scale_delta = host_impl->active_tree()->page_scale_delta();
339 sent_page_scale_delta = host_impl->active_tree()->sent_page_scale_delta();
341 page_scale_delta = sync_tree->page_scale_delta();
342 sent_page_scale_delta = sync_tree->sent_page_scale_delta();
343 sync_tree->set_sent_page_scale_delta(1.f);
346 sync_tree->SetPageScaleFactorAndLimits(page_scale_factor_,
347 min_page_scale_factor_,
348 max_page_scale_factor_);
349 sync_tree->SetPageScaleDelta(page_scale_delta / sent_page_scale_delta);
351 sync_tree->SetUseGpuRasterization(UseGpuRasterization());
353 sync_tree->PassSwapPromises(&swap_promise_list_);
355 host_impl->SetViewportSize(device_viewport_size_);
356 host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_);
357 host_impl->SetDeviceScaleFactor(device_scale_factor_);
358 host_impl->SetDebugState(debug_state_);
359 if (pending_page_scale_animation_) {
360 host_impl->StartPageScaleAnimation(
361 pending_page_scale_animation_->target_offset,
362 pending_page_scale_animation_->use_anchor,
363 pending_page_scale_animation_->scale,
364 pending_page_scale_animation_->duration);
365 pending_page_scale_animation_.reset();
368 if (!ui_resource_request_queue_.empty()) {
369 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
370 ui_resource_request_queue_.clear();
371 // Process any ui resource requests in the queue. For impl-side-painting,
372 // the queue is processed in LayerTreeHostImpl::ActivatePendingTree.
373 if (!settings_.impl_side_painting)
374 sync_tree->ProcessUIResourceRequestQueue();
376 if (overhang_ui_resource_) {
377 host_impl->SetOverhangUIResource(
378 overhang_ui_resource_->id(),
379 GetUIResourceSize(overhang_ui_resource_->id()));
382 DCHECK(!sync_tree->ViewportSizeInvalid());
384 if (new_impl_tree_has_no_evicted_resources) {
385 if (sync_tree->ContentsTexturesPurged())
386 sync_tree->ResetContentsTexturesPurged();
389 if (!settings_.impl_side_painting) {
390 // If we're not in impl-side painting, the tree is immediately
391 // considered active.
392 sync_tree->DidBecomeActive();
393 host_impl->ActivateAnimations();
394 devtools_instrumentation::DidActivateLayerTree(id_, source_frame_number_);
397 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
399 source_frame_number_++;
402 void LayerTreeHost::WillCommit() {
403 client_->WillCommit();
406 void LayerTreeHost::UpdateHudLayer() {
407 if (debug_state_.ShowHudInfo()) {
408 if (!hud_layer_.get())
409 hud_layer_ = HeadsUpDisplayLayer::Create();
411 if (root_layer_.get() && !hud_layer_->parent())
412 root_layer_->AddChild(hud_layer_);
413 } else if (hud_layer_.get()) {
414 hud_layer_->RemoveFromParent();
419 void LayerTreeHost::CommitComplete() {
420 client_->DidCommit();
423 scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() {
424 return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4);
427 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
428 LayerTreeHostImplClient* client) {
429 DCHECK(proxy_->IsImplThread());
430 scoped_ptr<LayerTreeHostImpl> host_impl =
431 LayerTreeHostImpl::Create(settings_,
434 rendering_stats_instrumentation_.get(),
435 shared_bitmap_manager_,
437 shared_bitmap_manager_ = NULL;
438 if (settings_.calculate_top_controls_position &&
439 host_impl->top_controls_manager()) {
440 top_controls_manager_weak_ptr_ =
441 host_impl->top_controls_manager()->AsWeakPtr();
443 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
444 return host_impl.Pass();
447 void LayerTreeHost::DidLoseOutputSurface() {
448 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
449 DCHECK(proxy_->IsMainThread());
451 if (output_surface_lost_)
454 num_failed_recreate_attempts_ = 0;
455 output_surface_lost_ = true;
459 bool LayerTreeHost::CompositeAndReadback(
461 const gfx::Rect& rect_in_device_viewport) {
462 trigger_idle_updates_ = false;
463 bool ret = proxy_->CompositeAndReadback(pixels, rect_in_device_viewport);
464 trigger_idle_updates_ = true;
468 void LayerTreeHost::FinishAllRendering() {
469 proxy_->FinishAllRendering();
472 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
473 proxy_->SetDeferCommits(defer_commits);
476 void LayerTreeHost::DidDeferCommit() {}
478 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
479 std::stack<Layer*> layer_stack;
480 layer_stack.push(root_layer());
481 while (!layer_stack.empty()) {
482 Layer* current_layer = layer_stack.top();
484 current_layer->SetNeedsDisplay();
485 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
486 layer_stack.push(current_layer->child_at(i));
491 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
492 return proxy_->GetRendererCapabilities();
495 void LayerTreeHost::SetNeedsAnimate() {
496 proxy_->SetNeedsAnimate();
497 NotifySwapPromiseMonitorsOfSetNeedsCommit();
500 void LayerTreeHost::SetNeedsUpdateLayers() {
501 proxy_->SetNeedsUpdateLayers();
502 NotifySwapPromiseMonitorsOfSetNeedsCommit();
505 void LayerTreeHost::SetNeedsCommit() {
506 if (!prepaint_callback_.IsCancelled()) {
507 TRACE_EVENT_INSTANT0("cc",
508 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
509 TRACE_EVENT_SCOPE_THREAD);
510 prepaint_callback_.Cancel();
512 proxy_->SetNeedsCommit();
513 NotifySwapPromiseMonitorsOfSetNeedsCommit();
516 void LayerTreeHost::SetNeedsFullTreeSync() {
517 needs_full_tree_sync_ = true;
521 void LayerTreeHost::SetNeedsRedraw() {
522 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
525 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
526 proxy_->SetNeedsRedraw(damage_rect);
529 bool LayerTreeHost::CommitRequested() const {
530 return proxy_->CommitRequested();
533 bool LayerTreeHost::BeginMainFrameRequested() const {
534 return proxy_->BeginMainFrameRequested();
538 void LayerTreeHost::SetNextCommitWaitsForActivation() {
539 proxy_->SetNextCommitWaitsForActivation();
542 void LayerTreeHost::SetNextCommitForcesRedraw() {
543 next_commit_forces_redraw_ = true;
546 void LayerTreeHost::SetAnimationEvents(
547 scoped_ptr<AnimationEventsVector> events) {
548 DCHECK(proxy_->IsMainThread());
549 for (size_t event_index = 0; event_index < events->size(); ++event_index) {
550 int event_layer_id = (*events)[event_index].layer_id;
552 // Use the map of all controllers, not just active ones, since non-active
553 // controllers may still receive events for impl-only animations.
554 const AnimationRegistrar::AnimationControllerMap& animation_controllers =
555 animation_registrar_->all_animation_controllers();
556 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
557 animation_controllers.find(event_layer_id);
558 if (iter != animation_controllers.end()) {
559 switch ((*events)[event_index].type) {
560 case AnimationEvent::Started:
561 (*iter).second->NotifyAnimationStarted((*events)[event_index]);
564 case AnimationEvent::Finished:
565 (*iter).second->NotifyAnimationFinished((*events)[event_index]);
568 case AnimationEvent::Aborted:
569 (*iter).second->NotifyAnimationAborted((*events)[event_index]);
572 case AnimationEvent::PropertyUpdate:
573 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
580 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
581 if (root_layer_.get() == root_layer.get())
584 if (root_layer_.get())
585 root_layer_->SetLayerTreeHost(NULL);
586 root_layer_ = root_layer;
587 if (root_layer_.get()) {
588 DCHECK(!root_layer_->parent());
589 root_layer_->SetLayerTreeHost(this);
592 if (hud_layer_.get())
593 hud_layer_->RemoveFromParent();
595 // Reset gpu rasterization flag.
596 // This flag is sticky until a new tree comes along.
597 content_is_suitable_for_gpu_rasterization_ = true;
599 SetNeedsFullTreeSync();
602 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
603 LayerTreeDebugState new_debug_state =
604 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
606 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
609 debug_state_ = new_debug_state;
611 rendering_stats_instrumentation_->set_record_rendering_stats(
612 debug_state_.RecordRenderingStats());
615 proxy_->SetDebugState(debug_state);
618 bool LayerTreeHost::UseGpuRasterization() const {
619 if (settings_.gpu_rasterization_forced) {
621 } else if (settings_.gpu_rasterization_enabled) {
622 return has_gpu_rasterization_trigger_ &&
623 content_is_suitable_for_gpu_rasterization_;
629 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
630 if (device_viewport_size == device_viewport_size_)
633 device_viewport_size_ = device_viewport_size;
638 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) {
639 if (overdraw_bottom_height_ == overdraw_bottom_height)
642 overdraw_bottom_height_ = overdraw_bottom_height;
646 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
647 DCHECK(CommitRequested());
648 page_scale_factor_ *= page_scale_delta;
651 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
652 float min_page_scale_factor,
653 float max_page_scale_factor) {
654 if (page_scale_factor == page_scale_factor_ &&
655 min_page_scale_factor == min_page_scale_factor_ &&
656 max_page_scale_factor == max_page_scale_factor_)
659 page_scale_factor_ = page_scale_factor;
660 min_page_scale_factor_ = min_page_scale_factor;
661 max_page_scale_factor_ = max_page_scale_factor;
665 void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
666 DCHECK(bitmap.width() && bitmap.height());
667 DCHECK_EQ(bitmap.bytesPerPixel(), 4);
669 SkBitmap bitmap_copy;
670 if (bitmap.isImmutable()) {
671 bitmap_copy = bitmap;
673 bitmap.copyTo(&bitmap_copy);
674 bitmap_copy.setImmutable();
677 UIResourceBitmap overhang_bitmap(bitmap_copy);
678 overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
679 overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
682 void LayerTreeHost::SetVisible(bool visible) {
683 if (visible_ == visible)
688 proxy_->SetVisible(visible);
691 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
694 base::TimeDelta duration) {
695 pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
696 pending_page_scale_animation_->target_offset = target_offset;
697 pending_page_scale_animation_->use_anchor = use_anchor;
698 pending_page_scale_animation_->scale = scale;
699 pending_page_scale_animation_->duration = duration;
704 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
705 proxy_->NotifyInputThrottledUntilCommit();
708 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
709 if (!proxy_->HasImplThread())
710 static_cast<SingleThreadProxy*>(proxy_.get())->CompositeImmediately(
716 bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() {
717 if (!output_surface_can_be_initialized_)
720 if (output_surface_lost_)
721 proxy_->CreateAndInitializeOutputSurface();
722 return !output_surface_lost_;
725 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
726 DCHECK(!output_surface_lost_);
731 DCHECK(!root_layer()->parent());
733 bool result = UpdateLayers(root_layer(), queue);
735 micro_benchmark_controller_.DidUpdateLayers();
737 return result || next_commit_forces_redraw_;
740 static Layer* FindFirstScrollableLayer(Layer* layer) {
744 if (layer->scrollable())
747 for (size_t i = 0; i < layer->children().size(); ++i) {
748 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
756 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) {
757 if (!layer->SupportsLCDText())
760 lcd_text_metrics_.total_num_cc_layers++;
761 if (layer->draw_properties().can_use_lcd_text) {
762 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
763 if (layer->contents_opaque())
764 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
768 bool LayerTreeHost::UsingSharedMemoryResources() {
769 return GetRendererCapabilities().using_shared_memory_resources;
772 bool LayerTreeHost::UpdateLayers(Layer* root_layer,
773 ResourceUpdateQueue* queue) {
774 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
775 "source_frame_number", source_frame_number());
777 RenderSurfaceLayerList update_list;
781 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
782 Layer* page_scale_layer = page_scale_layer_;
783 if (!page_scale_layer && root_scroll)
784 page_scale_layer = root_scroll->parent();
787 hud_layer_->PrepareForCalculateDrawProperties(
788 device_viewport_size(), device_scale_factor_);
791 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
792 bool can_render_to_separate_surface = true;
793 // TODO(vmpstr): Passing 0 as the current render surface layer list id means
794 // that we won't be able to detect if a layer is part of |update_list|.
795 // Change this if this information is required.
796 int render_surface_layer_list_id = 0;
797 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
799 device_viewport_size(),
801 device_scale_factor_,
804 GetRendererCapabilities().max_texture_size,
805 settings_.can_use_lcd_text,
806 can_render_to_separate_surface,
807 settings_.layer_transforms_should_scale_layer_contents,
809 render_surface_layer_list_id);
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 if (!contents_texture_manager_)
912 contents_texture_manager_->ClearPriorities();
914 size_t memory_for_render_surfaces_metric =
915 CalculateMemoryForRenderSurfaces(render_surface_layer_list);
917 SetPrioritiesForLayers(render_surface_layer_list);
918 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
920 contents_texture_manager_->PrioritizeTextures();
923 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
924 const RenderSurfaceLayerList& update_list) {
925 size_t readback_bytes = 0;
926 size_t max_background_texture_bytes = 0;
927 size_t contents_texture_bytes = 0;
929 // Start iteration at 1 to skip the root surface as it does not have a texture
931 for (size_t i = 1; i < update_list.size(); ++i) {
932 Layer* render_surface_layer = update_list.at(i);
933 RenderSurface* render_surface = render_surface_layer->render_surface();
936 Resource::MemorySizeBytes(render_surface->content_rect().size(),
938 contents_texture_bytes += bytes;
940 if (render_surface_layer->background_filters().IsEmpty())
943 if (bytes > max_background_texture_bytes)
944 max_background_texture_bytes = bytes;
945 if (!readback_bytes) {
946 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
950 return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
953 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
954 ResourceUpdateQueue* queue,
955 bool* did_paint_content,
956 bool* need_more_updates) {
957 // Note: Masks and replicas only exist for layers that own render surfaces. If
958 // we reach this point in code, we already know that at least something will
959 // be drawn into this render surface, so the mask and replica should be
962 Layer* mask_layer = render_surface_layer->mask_layer();
964 *did_paint_content |= mask_layer->Update(queue, NULL);
965 *need_more_updates |= mask_layer->NeedMoreUpdates();
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 *did_paint_content |= replica_mask_layer->Update(queue, NULL);
973 *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
977 void LayerTreeHost::PaintLayerContents(
978 const RenderSurfaceLayerList& render_surface_layer_list,
979 ResourceUpdateQueue* queue,
980 bool* did_paint_content,
981 bool* need_more_updates) {
982 OcclusionTracker<Layer> occlusion_tracker(
983 root_layer_->render_surface()->content_rect());
984 occlusion_tracker.set_minimum_tracking_size(
985 settings_.minimum_occlusion_tracking_size);
987 PrioritizeTextures(render_surface_layer_list);
989 in_paint_layer_contents_ = true;
991 // Iterates front-to-back to allow for testing occlusion and performing
992 // culling during the tree walk.
993 typedef LayerIterator<Layer> LayerIteratorType;
994 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
995 for (LayerIteratorType it =
996 LayerIteratorType::Begin(&render_surface_layer_list);
999 occlusion_tracker.EnterLayer(it);
1001 if (it.represents_target_render_surface()) {
1002 PaintMasksForRenderSurface(
1003 *it, queue, did_paint_content, need_more_updates);
1004 } else if (it.represents_itself() && it->DrawsContent()) {
1005 DCHECK(!it->paint_properties().bounds.IsEmpty());
1006 *did_paint_content |= it->Update(queue, &occlusion_tracker);
1007 *need_more_updates |= it->NeedMoreUpdates();
1008 // Note the '&&' with previous is-suitable state.
1009 // This means that once the layer-tree becomes unsuitable for gpu
1010 // rasterization due to some content, it will continue to be unsuitable
1011 // even if that content is replaced by gpu-friendly content.
1012 // This is to avoid switching back-and-forth between gpu and sw
1013 // rasterization which may be both bad for performance and visually
1015 content_is_suitable_for_gpu_rasterization_ &=
1016 it->IsSuitableForGpuRasterization();
1019 occlusion_tracker.LeaveLayer(it);
1022 in_paint_layer_contents_ = false;
1025 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) {
1026 if (!root_layer_.get())
1029 gfx::Vector2d inner_viewport_scroll_delta;
1030 gfx::Vector2d outer_viewport_scroll_delta;
1032 for (size_t i = 0; i < info.scrolls.size(); ++i) {
1034 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(),
1035 info.scrolls[i].layer_id);
1038 if (layer == outer_viewport_scroll_layer_.get()) {
1039 outer_viewport_scroll_delta += info.scrolls[i].scroll_delta;
1040 } else if (layer == inner_viewport_scroll_layer_.get()) {
1041 inner_viewport_scroll_delta += info.scrolls[i].scroll_delta;
1043 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
1044 info.scrolls[i].scroll_delta);
1048 if (!inner_viewport_scroll_delta.IsZero() ||
1049 !outer_viewport_scroll_delta.IsZero() || info.page_scale_delta != 1.f) {
1050 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1051 // so re-get this layer before doing anything to it.
1053 // Preemptively apply the scroll offset and scale delta here before sending
1054 // it to the client. If the client comes back and sets it to the same
1055 // value, then the layer can early out without needing a full commit.
1056 DCHECK(inner_viewport_scroll_layer_); // We should always have this.
1058 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1059 inner_viewport_scroll_layer_->scroll_offset() +
1060 inner_viewport_scroll_delta);
1061 if (outer_viewport_scroll_layer_) {
1062 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1063 outer_viewport_scroll_layer_->scroll_offset() +
1064 outer_viewport_scroll_delta);
1066 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta);
1068 client_->ApplyScrollAndScale(
1069 inner_viewport_scroll_delta + outer_viewport_scroll_delta,
1070 info.page_scale_delta);
1074 void LayerTreeHost::StartRateLimiter() {
1078 if (!rate_limit_timer_.IsRunning()) {
1079 rate_limit_timer_.Start(FROM_HERE,
1082 &LayerTreeHost::RateLimit);
1086 void LayerTreeHost::StopRateLimiter() {
1087 rate_limit_timer_.Stop();
1090 void LayerTreeHost::RateLimit() {
1091 // Force a no-op command on the compositor context, so that any ratelimiting
1092 // commands will wait for the compositing context, and therefore for the
1094 proxy_->ForceSerializeOnSwapBuffers();
1095 client_->RateLimitSharedMainThreadContext();
1098 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1099 if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
1101 return !proxy_->HasImplThread();
1104 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1105 size_t max_partial_texture_updates = 0;
1106 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
1107 !settings_.impl_side_painting) {
1108 max_partial_texture_updates =
1109 std::min(settings_.max_partial_texture_updates,
1110 proxy_->MaxPartialTextureUpdates());
1112 return max_partial_texture_updates;
1115 bool LayerTreeHost::RequestPartialTextureUpdate() {
1116 if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
1119 partial_texture_update_requests_++;
1123 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1124 if (device_scale_factor == device_scale_factor_)
1126 device_scale_factor_ = device_scale_factor;
1131 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1132 TopControlsState current,
1134 if (!settings_.calculate_top_controls_position)
1137 // Top controls are only used in threaded mode.
1138 proxy_->ImplThreadTaskRunner()->PostTask(
1140 base::Bind(&TopControlsManager::UpdateTopControlsState,
1141 top_controls_manager_weak_ptr_,
1147 scoped_ptr<base::Value> LayerTreeHost::AsValue() const {
1148 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1149 state->Set("proxy", proxy_->AsValue().release());
1150 return state.PassAs<base::Value>();
1153 void LayerTreeHost::AnimateLayers(base::TimeTicks time) {
1154 if (!settings_.accelerated_animation_enabled ||
1155 animation_registrar_->active_animation_controllers().empty())
1158 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1160 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1162 AnimationRegistrar::AnimationControllerMap copy =
1163 animation_registrar_->active_animation_controllers();
1164 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1167 (*iter).second->Animate(monotonic_time);
1168 bool start_ready_animations = true;
1169 (*iter).second->UpdateState(start_ready_animations, NULL);
1173 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
1176 UIResourceId next_id = next_ui_resource_id_++;
1177 DCHECK(ui_resource_client_map_.find(next_id) ==
1178 ui_resource_client_map_.end());
1180 bool resource_lost = false;
1181 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1183 client->GetBitmap(next_id, resource_lost));
1184 ui_resource_request_queue_.push_back(request);
1186 UIResourceClientData data;
1187 data.client = client;
1188 data.size = request.GetBitmap().GetSize();
1190 ui_resource_client_map_[request.GetId()] = data;
1191 return request.GetId();
1194 // Deletes a UI resource. May safely be called more than once.
1195 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
1196 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
1197 if (iter == ui_resource_client_map_.end())
1200 UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
1201 ui_resource_request_queue_.push_back(request);
1202 ui_resource_client_map_.erase(iter);
1205 void LayerTreeHost::RecreateUIResources() {
1206 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
1207 iter != ui_resource_client_map_.end();
1209 UIResourceId uid = iter->first;
1210 const UIResourceClientData& data = iter->second;
1211 bool resource_lost = true;
1212 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1214 data.client->GetBitmap(uid, resource_lost));
1215 ui_resource_request_queue_.push_back(request);
1219 // Returns the size of a resource given its id.
1220 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
1221 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
1222 if (iter == ui_resource_client_map_.end())
1225 const UIResourceClientData& data = iter->second;
1229 void LayerTreeHost::RegisterViewportLayers(
1230 scoped_refptr<Layer> page_scale_layer,
1231 scoped_refptr<Layer> inner_viewport_scroll_layer,
1232 scoped_refptr<Layer> outer_viewport_scroll_layer) {
1233 page_scale_layer_ = page_scale_layer;
1234 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
1235 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1238 bool LayerTreeHost::ScheduleMicroBenchmark(
1239 const std::string& benchmark_name,
1240 scoped_ptr<base::Value> value,
1241 const MicroBenchmark::DoneCallback& callback) {
1242 return micro_benchmark_controller_.ScheduleRun(
1243 benchmark_name, value.Pass(), callback);
1246 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1247 swap_promise_monitor_.insert(monitor);
1250 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1251 swap_promise_monitor_.erase(monitor);
1254 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1255 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1256 for (; it != swap_promise_monitor_.end(); it++)
1257 (*it)->OnSetNeedsCommitOnMain();
1260 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1261 DCHECK(swap_promise);
1262 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
1263 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
1264 swap_promise_list_.push_back(swap_promise.Pass());
1267 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1268 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1269 swap_promise_list_[i]->DidNotSwap(reason);
1270 swap_promise_list_.clear();