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/debug/trace_event_argument.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h"
18 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "cc/animation/animation_registrar.h"
21 #include "cc/animation/layer_animation_controller.h"
22 #include "cc/base/math_util.h"
23 #include "cc/debug/devtools_instrumentation.h"
24 #include "cc/debug/rendering_stats_instrumentation.h"
25 #include "cc/input/layer_selection_bound.h"
26 #include "cc/input/top_controls_manager.h"
27 #include "cc/layers/heads_up_display_layer.h"
28 #include "cc/layers/heads_up_display_layer_impl.h"
29 #include "cc/layers/layer.h"
30 #include "cc/layers/layer_iterator.h"
31 #include "cc/layers/painted_scrollbar_layer.h"
32 #include "cc/layers/render_surface.h"
33 #include "cc/resources/prioritized_resource_manager.h"
34 #include "cc/resources/ui_resource_request.h"
35 #include "cc/trees/layer_tree_host_client.h"
36 #include "cc/trees/layer_tree_host_common.h"
37 #include "cc/trees/layer_tree_host_impl.h"
38 #include "cc/trees/layer_tree_impl.h"
39 #include "cc/trees/occlusion_tracker.h"
40 #include "cc/trees/single_thread_proxy.h"
41 #include "cc/trees/thread_proxy.h"
42 #include "cc/trees/tree_synchronizer.h"
43 #include "ui/gfx/size_conversions.h"
46 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
51 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
52 bool allow_partial_texture_updates,
54 bool using_shared_memory_resources)
55 : best_texture_format(best_texture_format),
56 allow_partial_texture_updates(allow_partial_texture_updates),
57 max_texture_size(max_texture_size),
58 using_shared_memory_resources(using_shared_memory_resources) {}
60 RendererCapabilities::RendererCapabilities()
61 : best_texture_format(RGBA_8888),
62 allow_partial_texture_updates(false),
64 using_shared_memory_resources(false) {}
66 RendererCapabilities::~RendererCapabilities() {}
68 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
69 LayerTreeHostClient* client,
70 SharedBitmapManager* manager,
71 const LayerTreeSettings& settings,
72 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
73 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
74 DCHECK(main_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(main_task_runner, 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_refptr<base::SingleThreadTaskRunner> main_task_runner) {
88 scoped_ptr<LayerTreeHost> layer_tree_host(
89 new LayerTreeHost(client, manager, settings));
90 layer_tree_host->InitializeSingleThreaded(single_thread_client,
92 return layer_tree_host.Pass();
95 LayerTreeHost::LayerTreeHost(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),
103 source_frame_number_(0),
104 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
105 output_surface_lost_(true),
106 num_failed_recreate_attempts_(0),
108 debug_state_(settings.initial_debug_state),
109 overdraw_bottom_height_(0.f),
110 device_scale_factor_(1.f),
112 page_scale_factor_(1.f),
113 min_page_scale_factor_(1.f),
114 max_page_scale_factor_(1.f),
115 has_gpu_rasterization_trigger_(false),
116 content_is_suitable_for_gpu_rasterization_(true),
117 gpu_rasterization_histogram_recorded_(false),
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> main_task_runner,
134 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
136 ThreadProxy::Create(this, main_task_runner, impl_task_runner));
139 void LayerTreeHost::InitializeSingleThreaded(
140 LayerTreeHostSingleThreadClient* single_thread_client,
141 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
143 SingleThreadProxy::Create(this, single_thread_client, main_task_runner));
146 void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
147 InitializeProxy(proxy_for_testing.Pass());
150 void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
151 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
153 proxy_ = proxy.Pass();
155 if (settings_.accelerated_animation_enabled) {
156 animation_registrar_->set_supports_scroll_animations(
157 proxy_->SupportsImplScrolling());
161 LayerTreeHost::~LayerTreeHost() {
162 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
164 CHECK(swap_promise_monitor_.empty());
166 BreakSwapPromises(SwapPromise::COMMIT_FAILS);
168 overhang_ui_resource_.reset();
170 if (root_layer_.get())
171 root_layer_->SetLayerTreeHost(NULL);
174 DCHECK(proxy_->IsMainThread());
178 // We must clear any pointers into the layer tree prior to destroying it.
179 RegisterViewportLayers(NULL, NULL, NULL);
181 if (root_layer_.get()) {
182 // The layer tree must be destroyed before the layer tree host. We've
183 // made a contract with our animation controllers that the registrar
184 // will outlive them, and we must make good.
189 void LayerTreeHost::SetLayerTreeHostClientReady() {
190 proxy_->SetLayerTreeHostClientReady();
193 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
194 layer->OnOutputSurfaceCreated();
197 void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
198 DCHECK(output_surface_lost_);
200 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
205 // Tolerate a certain number of recreation failures to work around races
206 // in the output-surface-lost machinery.
207 ++num_failed_recreate_attempts_;
208 if (num_failed_recreate_attempts_ >= 5)
209 LOG(FATAL) << "Failed to create a fallback OutputSurface.";
210 client_->DidFailToInitializeOutputSurface();
214 output_surface_lost_ = false;
216 if (!contents_texture_manager_ && !settings_.impl_side_painting) {
217 contents_texture_manager_ =
218 PrioritizedResourceManager::Create(proxy_.get());
219 surface_memory_placeholder_ =
220 contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
224 LayerTreeHostCommon::CallFunctionForSubtree(
225 root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
228 client_->DidInitializeOutputSurface();
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::DidBeginMainFrame() {
239 client_->DidBeginMainFrame();
242 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
244 client_->Animate(frame_begin_time);
248 void LayerTreeHost::DidStopFlinging() {
249 proxy_->MainThreadHasStoppedFlinging();
252 void LayerTreeHost::Layout() {
256 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
257 DCHECK(proxy_->IsImplThread());
258 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
261 // This function commits the LayerTreeHost to an impl tree. When modifying
262 // this function, keep in mind that the function *runs* on the impl thread! Any
263 // code that is logically a main thread operation, e.g. deletion of a Layer,
264 // should be delayed until the LayerTreeHost::CommitComplete, which will run
265 // after the commit, but on the main thread.
266 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
267 DCHECK(proxy_->IsImplThread());
269 // If there are linked evicted backings, these backings' resources may be put
270 // into the impl tree, so we can't draw yet. Determine this before clearing
271 // all evicted backings.
272 bool new_impl_tree_has_no_evicted_resources = false;
273 if (contents_texture_manager_) {
274 new_impl_tree_has_no_evicted_resources =
275 !contents_texture_manager_->LinkedEvictedBackingsExist();
277 // If the memory limit has been increased since this now-finishing
278 // commit began, and the extra now-available memory would have been used,
279 // then request another commit.
280 if (contents_texture_manager_->MaxMemoryLimitBytes() <
281 host_impl->memory_allocation_limit_bytes() &&
282 contents_texture_manager_->MaxMemoryLimitBytes() <
283 contents_texture_manager_->MaxMemoryNeededBytes()) {
284 host_impl->SetNeedsCommit();
287 host_impl->set_max_memory_needed_bytes(
288 contents_texture_manager_->MaxMemoryNeededBytes());
290 contents_texture_manager_->UpdateBackingsState(
291 host_impl->resource_provider());
292 contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
295 LayerTreeImpl* sync_tree = host_impl->sync_tree();
297 if (next_commit_forces_redraw_) {
298 sync_tree->ForceRedrawNextActivation();
299 next_commit_forces_redraw_ = false;
302 sync_tree->set_source_frame_number(source_frame_number());
304 if (needs_full_tree_sync_) {
305 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
306 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
310 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
311 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
314 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
315 needs_full_tree_sync_ = false;
317 if (hud_layer_.get()) {
318 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
319 sync_tree->root_layer(), hud_layer_->id());
320 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
322 sync_tree->set_hud_layer(NULL);
325 sync_tree->set_background_color(background_color_);
326 sync_tree->set_has_transparent_background(has_transparent_background_);
328 if (page_scale_layer_ && inner_viewport_scroll_layer_) {
329 sync_tree->SetViewportLayersFromIds(
330 page_scale_layer_->id(),
331 inner_viewport_scroll_layer_->id(),
332 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
333 : Layer::INVALID_ID);
335 sync_tree->ClearViewportLayers();
338 sync_tree->RegisterSelection(selection_start_, selection_end_);
340 float page_scale_delta =
341 sync_tree->page_scale_delta() / sync_tree->sent_page_scale_delta();
342 sync_tree->SetPageScaleValues(page_scale_factor_,
343 min_page_scale_factor_,
344 max_page_scale_factor_,
346 sync_tree->set_sent_page_scale_delta(1.f);
348 sync_tree->PassSwapPromises(&swap_promise_list_);
350 host_impl->SetUseGpuRasterization(UseGpuRasterization());
351 RecordGpuRasterizationHistogram();
353 host_impl->SetViewportSize(device_viewport_size_);
354 host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_);
355 host_impl->SetDeviceScaleFactor(device_scale_factor_);
356 host_impl->SetDebugState(debug_state_);
357 if (pending_page_scale_animation_) {
358 host_impl->StartPageScaleAnimation(
359 pending_page_scale_animation_->target_offset,
360 pending_page_scale_animation_->use_anchor,
361 pending_page_scale_animation_->scale,
362 pending_page_scale_animation_->duration);
363 pending_page_scale_animation_.reset();
366 if (!ui_resource_request_queue_.empty()) {
367 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
368 ui_resource_request_queue_.clear();
370 if (overhang_ui_resource_) {
371 host_impl->SetOverhangUIResource(
372 overhang_ui_resource_->id(),
373 GetUIResourceSize(overhang_ui_resource_->id()));
376 DCHECK(!sync_tree->ViewportSizeInvalid());
378 if (new_impl_tree_has_no_evicted_resources) {
379 if (sync_tree->ContentsTexturesPurged())
380 sync_tree->ResetContentsTexturesPurged();
383 sync_tree->set_has_ever_been_drawn(false);
385 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
388 void LayerTreeHost::WillCommit() {
389 client_->WillCommit();
392 void LayerTreeHost::UpdateHudLayer() {
393 if (debug_state_.ShowHudInfo()) {
394 if (!hud_layer_.get())
395 hud_layer_ = HeadsUpDisplayLayer::Create();
397 if (root_layer_.get() && !hud_layer_->parent())
398 root_layer_->AddChild(hud_layer_);
399 } else if (hud_layer_.get()) {
400 hud_layer_->RemoveFromParent();
405 void LayerTreeHost::CommitComplete() {
406 source_frame_number_++;
407 client_->DidCommit();
410 scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() {
411 return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4);
414 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
415 LayerTreeHostImplClient* client) {
416 DCHECK(proxy_->IsImplThread());
417 scoped_ptr<LayerTreeHostImpl> host_impl =
418 LayerTreeHostImpl::Create(settings_,
421 rendering_stats_instrumentation_.get(),
422 shared_bitmap_manager_,
424 host_impl->SetUseGpuRasterization(UseGpuRasterization());
425 shared_bitmap_manager_ = NULL;
426 if (settings_.calculate_top_controls_position &&
427 host_impl->top_controls_manager()) {
428 top_controls_manager_weak_ptr_ =
429 host_impl->top_controls_manager()->AsWeakPtr();
431 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
432 return host_impl.Pass();
435 void LayerTreeHost::DidLoseOutputSurface() {
436 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
437 DCHECK(proxy_->IsMainThread());
439 if (output_surface_lost_)
442 num_failed_recreate_attempts_ = 0;
443 output_surface_lost_ = true;
447 void LayerTreeHost::FinishAllRendering() {
448 proxy_->FinishAllRendering();
451 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
452 proxy_->SetDeferCommits(defer_commits);
455 void LayerTreeHost::DidDeferCommit() {}
457 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
458 std::stack<Layer*> layer_stack;
459 layer_stack.push(root_layer());
460 while (!layer_stack.empty()) {
461 Layer* current_layer = layer_stack.top();
463 current_layer->SetNeedsDisplay();
464 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
465 layer_stack.push(current_layer->child_at(i));
470 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
471 return proxy_->GetRendererCapabilities();
474 void LayerTreeHost::SetNeedsAnimate() {
475 proxy_->SetNeedsAnimate();
476 NotifySwapPromiseMonitorsOfSetNeedsCommit();
479 void LayerTreeHost::SetNeedsUpdateLayers() {
480 proxy_->SetNeedsUpdateLayers();
481 NotifySwapPromiseMonitorsOfSetNeedsCommit();
484 void LayerTreeHost::SetNeedsCommit() {
485 if (!prepaint_callback_.IsCancelled()) {
486 TRACE_EVENT_INSTANT0("cc",
487 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
488 TRACE_EVENT_SCOPE_THREAD);
489 prepaint_callback_.Cancel();
491 proxy_->SetNeedsCommit();
492 NotifySwapPromiseMonitorsOfSetNeedsCommit();
495 void LayerTreeHost::SetNeedsFullTreeSync() {
496 needs_full_tree_sync_ = true;
500 void LayerTreeHost::SetNeedsRedraw() {
501 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
504 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
505 proxy_->SetNeedsRedraw(damage_rect);
508 bool LayerTreeHost::CommitRequested() const {
509 return proxy_->CommitRequested();
512 bool LayerTreeHost::BeginMainFrameRequested() const {
513 return proxy_->BeginMainFrameRequested();
517 void LayerTreeHost::SetNextCommitWaitsForActivation() {
518 proxy_->SetNextCommitWaitsForActivation();
521 void LayerTreeHost::SetNextCommitForcesRedraw() {
522 next_commit_forces_redraw_ = true;
525 void LayerTreeHost::SetAnimationEvents(
526 scoped_ptr<AnimationEventsVector> events) {
527 DCHECK(proxy_->IsMainThread());
528 for (size_t event_index = 0; event_index < events->size(); ++event_index) {
529 int event_layer_id = (*events)[event_index].layer_id;
531 // Use the map of all controllers, not just active ones, since non-active
532 // controllers may still receive events for impl-only animations.
533 const AnimationRegistrar::AnimationControllerMap& animation_controllers =
534 animation_registrar_->all_animation_controllers();
535 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
536 animation_controllers.find(event_layer_id);
537 if (iter != animation_controllers.end()) {
538 switch ((*events)[event_index].type) {
539 case AnimationEvent::Started:
540 (*iter).second->NotifyAnimationStarted((*events)[event_index]);
543 case AnimationEvent::Finished:
544 (*iter).second->NotifyAnimationFinished((*events)[event_index]);
547 case AnimationEvent::Aborted:
548 (*iter).second->NotifyAnimationAborted((*events)[event_index]);
551 case AnimationEvent::PropertyUpdate:
552 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
559 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
560 if (root_layer_.get() == root_layer.get())
563 if (root_layer_.get())
564 root_layer_->SetLayerTreeHost(NULL);
565 root_layer_ = root_layer;
566 if (root_layer_.get()) {
567 DCHECK(!root_layer_->parent());
568 root_layer_->SetLayerTreeHost(this);
571 if (hud_layer_.get())
572 hud_layer_->RemoveFromParent();
574 // Reset gpu rasterization flag.
575 // This flag is sticky until a new tree comes along.
576 content_is_suitable_for_gpu_rasterization_ = true;
577 gpu_rasterization_histogram_recorded_ = false;
579 SetNeedsFullTreeSync();
582 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
583 LayerTreeDebugState new_debug_state =
584 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
586 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
589 debug_state_ = new_debug_state;
591 rendering_stats_instrumentation_->set_record_rendering_stats(
592 debug_state_.RecordRenderingStats());
595 proxy_->SetDebugState(debug_state);
598 bool LayerTreeHost::UseGpuRasterization() const {
599 if (settings_.gpu_rasterization_forced) {
601 } else if (settings_.gpu_rasterization_enabled) {
602 return has_gpu_rasterization_trigger_ &&
603 content_is_suitable_for_gpu_rasterization_;
609 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
610 if (has_trigger == has_gpu_rasterization_trigger_)
613 has_gpu_rasterization_trigger_ = has_trigger;
614 TRACE_EVENT_INSTANT1("cc",
615 "LayerTreeHost::SetHasGpuRasterizationTrigger",
616 TRACE_EVENT_SCOPE_THREAD,
618 has_gpu_rasterization_trigger_);
621 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
622 if (device_viewport_size == device_viewport_size_)
625 device_viewport_size_ = device_viewport_size;
630 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) {
631 if (overdraw_bottom_height_ == overdraw_bottom_height)
634 overdraw_bottom_height_ = overdraw_bottom_height;
638 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
639 DCHECK(CommitRequested());
640 page_scale_factor_ *= page_scale_delta;
643 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
644 float min_page_scale_factor,
645 float max_page_scale_factor) {
646 if (page_scale_factor == page_scale_factor_ &&
647 min_page_scale_factor == min_page_scale_factor_ &&
648 max_page_scale_factor == max_page_scale_factor_)
651 page_scale_factor_ = page_scale_factor;
652 min_page_scale_factor_ = min_page_scale_factor;
653 max_page_scale_factor_ = max_page_scale_factor;
657 void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
658 DCHECK(bitmap.width() && bitmap.height());
659 DCHECK_EQ(bitmap.bytesPerPixel(), 4);
661 SkBitmap bitmap_copy;
662 if (bitmap.isImmutable()) {
663 bitmap_copy = bitmap;
665 bitmap.copyTo(&bitmap_copy);
666 bitmap_copy.setImmutable();
669 UIResourceBitmap overhang_bitmap(bitmap_copy);
670 overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
671 overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
674 void LayerTreeHost::SetVisible(bool visible) {
675 if (visible_ == visible)
680 proxy_->SetVisible(visible);
683 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
686 base::TimeDelta duration) {
687 pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
688 pending_page_scale_animation_->target_offset = target_offset;
689 pending_page_scale_animation_->use_anchor = use_anchor;
690 pending_page_scale_animation_->scale = scale;
691 pending_page_scale_animation_->duration = duration;
696 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
697 proxy_->NotifyInputThrottledUntilCommit();
700 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
701 DCHECK(!proxy_->HasImplThread());
702 SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
704 if (output_surface_lost_)
705 proxy->CreateAndInitializeOutputSurface();
706 if (output_surface_lost_)
709 proxy->CompositeImmediately(frame_begin_time);
712 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
713 DCHECK(!output_surface_lost_);
718 DCHECK(!root_layer()->parent());
720 bool result = UpdateLayers(root_layer(), queue);
722 micro_benchmark_controller_.DidUpdateLayers();
724 return result || next_commit_forces_redraw_;
727 static Layer* FindFirstScrollableLayer(Layer* layer) {
731 if (layer->scrollable())
734 for (size_t i = 0; i < layer->children().size(); ++i) {
735 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
743 void LayerTreeHost::RecordGpuRasterizationHistogram() {
744 // Gpu rasterization is only supported when impl-side painting is enabled.
745 if (gpu_rasterization_histogram_recorded_ || !settings_.impl_side_painting)
748 // Record how widely gpu rasterization is enabled.
749 // This number takes device/gpu whitelisting/backlisting into account.
750 // Note that we do not consider the forced gpu rasterization mode, which is
751 // mostly used for debugging purposes.
752 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
753 settings_.gpu_rasterization_enabled);
754 if (settings_.gpu_rasterization_enabled) {
755 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
756 has_gpu_rasterization_trigger_);
757 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
758 content_is_suitable_for_gpu_rasterization_);
759 // Record how many pages actually get gpu rasterization when enabled.
760 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
761 (has_gpu_rasterization_trigger_ &&
762 content_is_suitable_for_gpu_rasterization_));
765 gpu_rasterization_histogram_recorded_ = true;
768 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) {
769 if (!layer->SupportsLCDText())
772 lcd_text_metrics_.total_num_cc_layers++;
773 if (layer->draw_properties().can_use_lcd_text) {
774 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
775 if (layer->contents_opaque())
776 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
780 bool LayerTreeHost::UsingSharedMemoryResources() {
781 return GetRendererCapabilities().using_shared_memory_resources;
784 bool LayerTreeHost::UpdateLayers(Layer* root_layer,
785 ResourceUpdateQueue* queue) {
786 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
787 "source_frame_number", source_frame_number());
789 RenderSurfaceLayerList update_list;
793 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
794 Layer* page_scale_layer = page_scale_layer_;
795 if (!page_scale_layer && root_scroll)
796 page_scale_layer = root_scroll->parent();
799 hud_layer_->PrepareForCalculateDrawProperties(
800 device_viewport_size(), device_scale_factor_);
803 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
804 bool can_render_to_separate_surface = true;
805 // TODO(vmpstr): Passing 0 as the current render surface layer list id means
806 // that we won't be able to detect if a layer is part of |update_list|.
807 // Change this if this information is required.
808 int render_surface_layer_list_id = 0;
809 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
811 device_viewport_size(),
813 device_scale_factor_,
816 GetRendererCapabilities().max_texture_size,
817 settings_.can_use_lcd_text,
818 can_render_to_separate_surface,
819 settings_.layer_transforms_should_scale_layer_contents,
821 render_surface_layer_list_id);
822 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
824 if (total_frames_used_for_lcd_text_metrics_ <=
825 kTotalFramesToUseForLCDTextMetrics) {
826 LayerTreeHostCommon::CallFunctionForSubtree(
828 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback,
829 base::Unretained(this)));
830 total_frames_used_for_lcd_text_metrics_++;
833 if (total_frames_used_for_lcd_text_metrics_ ==
834 kTotalFramesToUseForLCDTextMetrics) {
835 total_frames_used_for_lcd_text_metrics_++;
837 UMA_HISTOGRAM_PERCENTAGE(
838 "Renderer4.LCDText.PercentageOfCandidateLayers",
839 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 /
840 lcd_text_metrics_.total_num_cc_layers);
841 UMA_HISTOGRAM_PERCENTAGE(
842 "Renderer4.LCDText.PercentageOfAALayers",
843 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 /
844 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text);
848 // Reset partial texture update requests.
849 partial_texture_update_requests_ = 0;
851 bool did_paint_content = false;
852 bool need_more_updates = false;
854 update_list, queue, &did_paint_content, &need_more_updates);
855 if (need_more_updates) {
856 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
857 prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
858 base::Unretained(this)));
859 static base::TimeDelta prepaint_delay =
860 base::TimeDelta::FromMilliseconds(100);
861 base::MessageLoop::current()->PostDelayedTask(
862 FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
865 return did_paint_content;
868 void LayerTreeHost::TriggerPrepaint() {
869 prepaint_callback_.Cancel();
870 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
874 static void LayerTreeHostReduceMemoryCallback(Layer* layer) {
875 layer->ReduceMemoryUsage();
878 void LayerTreeHost::ReduceMemoryUsage() {
882 LayerTreeHostCommon::CallFunctionForSubtree(
884 base::Bind(&LayerTreeHostReduceMemoryCallback));
887 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
888 DCHECK(surface_memory_placeholder_);
890 // Surfaces have a place holder for their memory since they are managed
891 // independantly but should still be tracked and reduce other memory usage.
892 surface_memory_placeholder_->SetTextureManager(
893 contents_texture_manager_.get());
894 surface_memory_placeholder_->set_request_priority(
895 PriorityCalculator::RenderSurfacePriority());
896 surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
897 surface_memory_bytes);
900 void LayerTreeHost::SetPrioritiesForLayers(
901 const RenderSurfaceLayerList& update_list) {
902 PriorityCalculator calculator;
903 typedef LayerIterator<Layer> LayerIteratorType;
904 LayerIteratorType end = LayerIteratorType::End(&update_list);
905 for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
908 if (it.represents_itself()) {
909 it->SetTexturePriorities(calculator);
910 } else if (it.represents_target_render_surface()) {
911 if (it->mask_layer())
912 it->mask_layer()->SetTexturePriorities(calculator);
913 if (it->replica_layer() && it->replica_layer()->mask_layer())
914 it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
919 void LayerTreeHost::PrioritizeTextures(
920 const RenderSurfaceLayerList& render_surface_layer_list) {
921 if (!contents_texture_manager_)
924 contents_texture_manager_->ClearPriorities();
926 size_t memory_for_render_surfaces_metric =
927 CalculateMemoryForRenderSurfaces(render_surface_layer_list);
929 SetPrioritiesForLayers(render_surface_layer_list);
930 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
932 contents_texture_manager_->PrioritizeTextures();
935 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
936 const RenderSurfaceLayerList& update_list) {
937 size_t readback_bytes = 0;
938 size_t max_background_texture_bytes = 0;
939 size_t contents_texture_bytes = 0;
941 // Start iteration at 1 to skip the root surface as it does not have a texture
943 for (size_t i = 1; i < update_list.size(); ++i) {
944 Layer* render_surface_layer = update_list.at(i);
945 RenderSurface* render_surface = render_surface_layer->render_surface();
948 Resource::MemorySizeBytes(render_surface->content_rect().size(),
950 contents_texture_bytes += bytes;
952 if (render_surface_layer->background_filters().IsEmpty())
955 if (bytes > max_background_texture_bytes)
956 max_background_texture_bytes = bytes;
957 if (!readback_bytes) {
958 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
962 return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
965 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
966 ResourceUpdateQueue* queue,
967 bool* did_paint_content,
968 bool* need_more_updates) {
969 // Note: Masks and replicas only exist for layers that own render surfaces. If
970 // we reach this point in code, we already know that at least something will
971 // be drawn into this render surface, so the mask and replica should be
974 Layer* mask_layer = render_surface_layer->mask_layer();
976 *did_paint_content |= mask_layer->Update(queue, NULL);
977 *need_more_updates |= mask_layer->NeedMoreUpdates();
980 Layer* replica_mask_layer =
981 render_surface_layer->replica_layer() ?
982 render_surface_layer->replica_layer()->mask_layer() : NULL;
983 if (replica_mask_layer) {
984 *did_paint_content |= replica_mask_layer->Update(queue, NULL);
985 *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
989 void LayerTreeHost::PaintLayerContents(
990 const RenderSurfaceLayerList& render_surface_layer_list,
991 ResourceUpdateQueue* queue,
992 bool* did_paint_content,
993 bool* need_more_updates) {
994 OcclusionTracker<Layer> occlusion_tracker(
995 root_layer_->render_surface()->content_rect());
996 occlusion_tracker.set_minimum_tracking_size(
997 settings_.minimum_occlusion_tracking_size);
999 PrioritizeTextures(render_surface_layer_list);
1001 in_paint_layer_contents_ = true;
1003 // Iterates front-to-back to allow for testing occlusion and performing
1004 // culling during the tree walk.
1005 typedef LayerIterator<Layer> LayerIteratorType;
1006 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1007 for (LayerIteratorType it =
1008 LayerIteratorType::Begin(&render_surface_layer_list);
1011 occlusion_tracker.EnterLayer(it);
1013 if (it.represents_target_render_surface()) {
1014 PaintMasksForRenderSurface(
1015 *it, queue, did_paint_content, need_more_updates);
1016 } else if (it.represents_itself()) {
1017 DCHECK(!it->paint_properties().bounds.IsEmpty());
1018 *did_paint_content |= it->Update(queue, &occlusion_tracker);
1019 *need_more_updates |= it->NeedMoreUpdates();
1020 // Note the '&&' with previous is-suitable state.
1021 // This means that once the layer-tree becomes unsuitable for gpu
1022 // rasterization due to some content, it will continue to be unsuitable
1023 // even if that content is replaced by gpu-friendly content.
1024 // This is to avoid switching back-and-forth between gpu and sw
1025 // rasterization which may be both bad for performance and visually
1027 content_is_suitable_for_gpu_rasterization_ &=
1028 it->IsSuitableForGpuRasterization();
1031 occlusion_tracker.LeaveLayer(it);
1034 in_paint_layer_contents_ = false;
1037 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
1038 if (!root_layer_.get())
1041 ScopedPtrVector<SwapPromise>::iterator it = info->swap_promises.begin();
1042 for (; it != info->swap_promises.end(); ++it) {
1043 scoped_ptr<SwapPromise> swap_promise(info->swap_promises.take(it));
1044 TRACE_EVENT_FLOW_STEP0("input",
1046 TRACE_ID_DONT_MANGLE(swap_promise->TraceId()),
1047 "Main thread scroll update");
1048 QueueSwapPromise(swap_promise.Pass());
1051 gfx::Vector2d inner_viewport_scroll_delta;
1052 gfx::Vector2d outer_viewport_scroll_delta;
1054 for (size_t i = 0; i < info->scrolls.size(); ++i) {
1055 Layer* layer = LayerTreeHostCommon::FindLayerInSubtree(
1056 root_layer_.get(), info->scrolls[i].layer_id);
1059 if (layer == outer_viewport_scroll_layer_.get()) {
1060 outer_viewport_scroll_delta += info->scrolls[i].scroll_delta;
1061 } else if (layer == inner_viewport_scroll_layer_.get()) {
1062 inner_viewport_scroll_delta += info->scrolls[i].scroll_delta;
1064 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
1065 info->scrolls[i].scroll_delta);
1069 if (!inner_viewport_scroll_delta.IsZero() ||
1070 !outer_viewport_scroll_delta.IsZero() || info->page_scale_delta != 1.f) {
1071 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1072 // so re-get this layer before doing anything to it.
1074 // Preemptively apply the scroll offset and scale delta here before sending
1075 // it to the client. If the client comes back and sets it to the same
1076 // value, then the layer can early out without needing a full commit.
1077 DCHECK(inner_viewport_scroll_layer_); // We should always have this.
1079 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1080 inner_viewport_scroll_layer_->scroll_offset() +
1081 inner_viewport_scroll_delta);
1082 if (outer_viewport_scroll_layer_) {
1083 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1084 outer_viewport_scroll_layer_->scroll_offset() +
1085 outer_viewport_scroll_delta);
1087 ApplyPageScaleDeltaFromImplSide(info->page_scale_delta);
1089 client_->ApplyScrollAndScale(
1090 inner_viewport_scroll_delta + outer_viewport_scroll_delta,
1091 info->page_scale_delta);
1095 void LayerTreeHost::StartRateLimiter() {
1099 if (!rate_limit_timer_.IsRunning()) {
1100 rate_limit_timer_.Start(FROM_HERE,
1103 &LayerTreeHost::RateLimit);
1107 void LayerTreeHost::StopRateLimiter() {
1108 rate_limit_timer_.Stop();
1111 void LayerTreeHost::RateLimit() {
1112 // Force a no-op command on the compositor context, so that any ratelimiting
1113 // commands will wait for the compositing context, and therefore for the
1115 proxy_->ForceSerializeOnSwapBuffers();
1116 client_->RateLimitSharedMainThreadContext();
1119 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1120 if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
1122 return !proxy_->HasImplThread();
1125 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1126 size_t max_partial_texture_updates = 0;
1127 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
1128 !settings_.impl_side_painting) {
1129 max_partial_texture_updates =
1130 std::min(settings_.max_partial_texture_updates,
1131 proxy_->MaxPartialTextureUpdates());
1133 return max_partial_texture_updates;
1136 bool LayerTreeHost::RequestPartialTextureUpdate() {
1137 if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
1140 partial_texture_update_requests_++;
1144 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1145 if (device_scale_factor == device_scale_factor_)
1147 device_scale_factor_ = device_scale_factor;
1152 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1153 TopControlsState current,
1155 if (!settings_.calculate_top_controls_position)
1158 // Top controls are only used in threaded mode.
1159 proxy_->ImplThreadTaskRunner()->PostTask(
1161 base::Bind(&TopControlsManager::UpdateTopControlsState,
1162 top_controls_manager_weak_ptr_,
1168 void LayerTreeHost::AsValueInto(base::debug::TracedValue* state) const {
1169 state->BeginDictionary("proxy");
1170 proxy_->AsValueInto(state);
1171 state->EndDictionary();
1174 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
1175 if (!settings_.accelerated_animation_enabled ||
1176 animation_registrar_->active_animation_controllers().empty())
1179 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1181 AnimationRegistrar::AnimationControllerMap copy =
1182 animation_registrar_->active_animation_controllers();
1183 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1186 (*iter).second->Animate(monotonic_time);
1187 bool start_ready_animations = true;
1188 (*iter).second->UpdateState(start_ready_animations, NULL);
1192 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
1195 UIResourceId next_id = next_ui_resource_id_++;
1196 DCHECK(ui_resource_client_map_.find(next_id) ==
1197 ui_resource_client_map_.end());
1199 bool resource_lost = false;
1200 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1202 client->GetBitmap(next_id, resource_lost));
1203 ui_resource_request_queue_.push_back(request);
1205 UIResourceClientData data;
1206 data.client = client;
1207 data.size = request.GetBitmap().GetSize();
1209 ui_resource_client_map_[request.GetId()] = data;
1210 return request.GetId();
1213 // Deletes a UI resource. May safely be called more than once.
1214 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
1215 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
1216 if (iter == ui_resource_client_map_.end())
1219 UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
1220 ui_resource_request_queue_.push_back(request);
1221 ui_resource_client_map_.erase(iter);
1224 void LayerTreeHost::RecreateUIResources() {
1225 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
1226 iter != ui_resource_client_map_.end();
1228 UIResourceId uid = iter->first;
1229 const UIResourceClientData& data = iter->second;
1230 bool resource_lost = true;
1231 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1233 data.client->GetBitmap(uid, resource_lost));
1234 ui_resource_request_queue_.push_back(request);
1238 // Returns the size of a resource given its id.
1239 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
1240 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
1241 if (iter == ui_resource_client_map_.end())
1244 const UIResourceClientData& data = iter->second;
1248 void LayerTreeHost::RegisterViewportLayers(
1249 scoped_refptr<Layer> page_scale_layer,
1250 scoped_refptr<Layer> inner_viewport_scroll_layer,
1251 scoped_refptr<Layer> outer_viewport_scroll_layer) {
1252 page_scale_layer_ = page_scale_layer;
1253 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
1254 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1257 void LayerTreeHost::RegisterSelection(const LayerSelectionBound& start,
1258 const LayerSelectionBound& end) {
1259 if (selection_start_ == start && selection_end_ == end)
1262 selection_start_ = start;
1263 selection_end_ = end;
1267 int LayerTreeHost::ScheduleMicroBenchmark(
1268 const std::string& benchmark_name,
1269 scoped_ptr<base::Value> value,
1270 const MicroBenchmark::DoneCallback& callback) {
1271 return micro_benchmark_controller_.ScheduleRun(
1272 benchmark_name, value.Pass(), callback);
1275 bool LayerTreeHost::SendMessageToMicroBenchmark(int id,
1276 scoped_ptr<base::Value> value) {
1277 return micro_benchmark_controller_.SendMessage(id, value.Pass());
1280 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1281 swap_promise_monitor_.insert(monitor);
1284 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1285 swap_promise_monitor_.erase(monitor);
1288 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1289 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1290 for (; it != swap_promise_monitor_.end(); it++)
1291 (*it)->OnSetNeedsCommitOnMain();
1294 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1295 DCHECK(swap_promise);
1296 swap_promise_list_.push_back(swap_promise.Pass());
1299 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1300 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1301 swap_promise_list_[i]->DidNotSwap(reason);
1302 swap_promise_list_.clear();