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/layer_selection_bound.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
,
53 bool using_shared_memory_resources
)
54 : best_texture_format(best_texture_format
),
55 allow_partial_texture_updates(allow_partial_texture_updates
),
56 max_texture_size(max_texture_size
),
57 using_shared_memory_resources(using_shared_memory_resources
) {}
59 RendererCapabilities::RendererCapabilities()
60 : best_texture_format(RGBA_8888
),
61 allow_partial_texture_updates(false),
63 using_shared_memory_resources(false) {}
65 RendererCapabilities::~RendererCapabilities() {}
67 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateThreaded(
68 LayerTreeHostClient
* client
,
69 SharedBitmapManager
* manager
,
70 const LayerTreeSettings
& settings
,
71 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
) {
72 DCHECK(impl_task_runner
);
73 scoped_ptr
<LayerTreeHost
> layer_tree_host(
74 new LayerTreeHost(client
, manager
, settings
));
75 layer_tree_host
->InitializeThreaded(impl_task_runner
);
76 return layer_tree_host
.Pass();
79 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateSingleThreaded(
80 LayerTreeHostClient
* client
,
81 LayerTreeHostSingleThreadClient
* single_thread_client
,
82 SharedBitmapManager
* manager
,
83 const LayerTreeSettings
& settings
) {
84 scoped_ptr
<LayerTreeHost
> layer_tree_host(
85 new LayerTreeHost(client
, manager
, settings
));
86 layer_tree_host
->InitializeSingleThreaded(single_thread_client
);
87 return layer_tree_host
.Pass();
90 LayerTreeHost::LayerTreeHost(LayerTreeHostClient
* client
,
91 SharedBitmapManager
* manager
,
92 const LayerTreeSettings
& settings
)
93 : micro_benchmark_controller_(this),
94 next_ui_resource_id_(1),
96 needs_full_tree_sync_(true),
98 source_frame_number_(0),
99 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
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 has_gpu_rasterization_trigger_(false),
111 content_is_suitable_for_gpu_rasterization_(true),
112 gpu_rasterization_histogram_recorded_(false),
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();
146 if (settings_
.accelerated_animation_enabled
) {
147 animation_registrar_
->set_supports_scroll_animations(
148 proxy_
->SupportsImplScrolling());
152 LayerTreeHost::~LayerTreeHost() {
153 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
155 overhang_ui_resource_
.reset();
157 if (root_layer_
.get())
158 root_layer_
->SetLayerTreeHost(NULL
);
161 DCHECK(proxy_
->IsMainThread());
165 // We must clear any pointers into the layer tree prior to destroying it.
166 RegisterViewportLayers(NULL
, NULL
, NULL
);
168 if (root_layer_
.get()) {
169 // The layer tree must be destroyed before the layer tree host. We've
170 // made a contract with our animation controllers that the registrar
171 // will outlive them, and we must make good.
176 void LayerTreeHost::SetLayerTreeHostClientReady() {
177 proxy_
->SetLayerTreeHostClientReady();
180 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer
* layer
) {
181 layer
->OnOutputSurfaceCreated();
184 void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success
) {
185 DCHECK(output_surface_lost_
);
187 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
192 // Tolerate a certain number of recreation failures to work around races
193 // in the output-surface-lost machinery.
194 ++num_failed_recreate_attempts_
;
195 if (num_failed_recreate_attempts_
>= 5)
196 LOG(FATAL
) << "Failed to create a fallback OutputSurface.";
197 client_
->DidFailToInitializeOutputSurface();
201 output_surface_lost_
= false;
203 if (!contents_texture_manager_
&& !settings_
.impl_side_painting
) {
204 contents_texture_manager_
=
205 PrioritizedResourceManager::Create(proxy_
.get());
206 surface_memory_placeholder_
=
207 contents_texture_manager_
->CreateTexture(gfx::Size(), RGBA_8888
);
211 LayerTreeHostCommon::CallFunctionForSubtree(
212 root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback
));
215 client_
->DidInitializeOutputSurface();
218 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
219 ResourceProvider
* resource_provider
) {
220 DCHECK(proxy_
->IsImplThread());
221 if (contents_texture_manager_
)
222 contents_texture_manager_
->ClearAllMemory(resource_provider
);
225 void LayerTreeHost::DidBeginMainFrame() {
226 client_
->DidBeginMainFrame();
229 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time
) {
231 client_
->Animate(frame_begin_time
);
235 void LayerTreeHost::DidStopFlinging() {
236 proxy_
->MainThreadHasStoppedFlinging();
239 void LayerTreeHost::Layout() {
243 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl
* host_impl
) {
244 DCHECK(proxy_
->IsImplThread());
245 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
248 // This function commits the LayerTreeHost to an impl tree. When modifying
249 // this function, keep in mind that the function *runs* on the impl thread! Any
250 // code that is logically a main thread operation, e.g. deletion of a Layer,
251 // should be delayed until the LayerTreeHost::CommitComplete, which will run
252 // after the commit, but on the main thread.
253 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl
* host_impl
) {
254 DCHECK(proxy_
->IsImplThread());
256 // If there are linked evicted backings, these backings' resources may be put
257 // into the impl tree, so we can't draw yet. Determine this before clearing
258 // all evicted backings.
259 bool new_impl_tree_has_no_evicted_resources
= false;
260 if (contents_texture_manager_
) {
261 new_impl_tree_has_no_evicted_resources
=
262 !contents_texture_manager_
->LinkedEvictedBackingsExist();
264 // If the memory limit has been increased since this now-finishing
265 // commit began, and the extra now-available memory would have been used,
266 // then request another commit.
267 if (contents_texture_manager_
->MaxMemoryLimitBytes() <
268 host_impl
->memory_allocation_limit_bytes() &&
269 contents_texture_manager_
->MaxMemoryLimitBytes() <
270 contents_texture_manager_
->MaxMemoryNeededBytes()) {
271 host_impl
->SetNeedsCommit();
274 host_impl
->set_max_memory_needed_bytes(
275 contents_texture_manager_
->MaxMemoryNeededBytes());
277 contents_texture_manager_
->UpdateBackingsState(
278 host_impl
->resource_provider());
279 contents_texture_manager_
->ReduceMemory(host_impl
->resource_provider());
282 LayerTreeImpl
* sync_tree
= host_impl
->sync_tree();
284 if (next_commit_forces_redraw_
) {
285 sync_tree
->ForceRedrawNextActivation();
286 next_commit_forces_redraw_
= false;
289 sync_tree
->set_source_frame_number(source_frame_number());
291 if (needs_full_tree_sync_
) {
292 sync_tree
->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
293 root_layer(), sync_tree
->DetachLayerTree(), sync_tree
));
297 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
298 TreeSynchronizer::PushProperties(root_layer(), sync_tree
->root_layer());
301 sync_tree
->set_needs_full_tree_sync(needs_full_tree_sync_
);
302 needs_full_tree_sync_
= false;
304 if (hud_layer_
.get()) {
305 LayerImpl
* hud_impl
= LayerTreeHostCommon::FindLayerInSubtree(
306 sync_tree
->root_layer(), hud_layer_
->id());
307 sync_tree
->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl
*>(hud_impl
));
309 sync_tree
->set_hud_layer(NULL
);
312 sync_tree
->set_background_color(background_color_
);
313 sync_tree
->set_has_transparent_background(has_transparent_background_
);
315 if (page_scale_layer_
&& inner_viewport_scroll_layer_
) {
316 sync_tree
->SetViewportLayersFromIds(
317 page_scale_layer_
->id(),
318 inner_viewport_scroll_layer_
->id(),
319 outer_viewport_scroll_layer_
? outer_viewport_scroll_layer_
->id()
320 : Layer::INVALID_ID
);
322 sync_tree
->ClearViewportLayers();
325 sync_tree
->RegisterSelection(selection_anchor_
, selection_focus_
);
327 float page_scale_delta
=
328 sync_tree
->page_scale_delta() / sync_tree
->sent_page_scale_delta();
329 sync_tree
->SetPageScaleValues(page_scale_factor_
,
330 min_page_scale_factor_
,
331 max_page_scale_factor_
,
333 sync_tree
->set_sent_page_scale_delta(1.f
);
335 sync_tree
->PassSwapPromises(&swap_promise_list_
);
337 host_impl
->SetUseGpuRasterization(UseGpuRasterization());
338 RecordGpuRasterizationHistogram();
340 host_impl
->SetViewportSize(device_viewport_size_
);
341 host_impl
->SetOverdrawBottomHeight(overdraw_bottom_height_
);
342 host_impl
->SetDeviceScaleFactor(device_scale_factor_
);
343 host_impl
->SetDebugState(debug_state_
);
344 if (pending_page_scale_animation_
) {
345 host_impl
->StartPageScaleAnimation(
346 pending_page_scale_animation_
->target_offset
,
347 pending_page_scale_animation_
->use_anchor
,
348 pending_page_scale_animation_
->scale
,
349 pending_page_scale_animation_
->duration
);
350 pending_page_scale_animation_
.reset();
353 if (!ui_resource_request_queue_
.empty()) {
354 sync_tree
->set_ui_resource_request_queue(ui_resource_request_queue_
);
355 ui_resource_request_queue_
.clear();
357 if (overhang_ui_resource_
) {
358 host_impl
->SetOverhangUIResource(
359 overhang_ui_resource_
->id(),
360 GetUIResourceSize(overhang_ui_resource_
->id()));
363 DCHECK(!sync_tree
->ViewportSizeInvalid());
365 if (new_impl_tree_has_no_evicted_resources
) {
366 if (sync_tree
->ContentsTexturesPurged())
367 sync_tree
->ResetContentsTexturesPurged();
370 micro_benchmark_controller_
.ScheduleImplBenchmarks(host_impl
);
373 void LayerTreeHost::WillCommit() {
374 client_
->WillCommit();
377 void LayerTreeHost::UpdateHudLayer() {
378 if (debug_state_
.ShowHudInfo()) {
379 if (!hud_layer_
.get())
380 hud_layer_
= HeadsUpDisplayLayer::Create();
382 if (root_layer_
.get() && !hud_layer_
->parent())
383 root_layer_
->AddChild(hud_layer_
);
384 } else if (hud_layer_
.get()) {
385 hud_layer_
->RemoveFromParent();
390 void LayerTreeHost::CommitComplete() {
391 source_frame_number_
++;
392 client_
->DidCommit();
395 scoped_ptr
<OutputSurface
> LayerTreeHost::CreateOutputSurface() {
396 return client_
->CreateOutputSurface(num_failed_recreate_attempts_
>= 4);
399 scoped_ptr
<LayerTreeHostImpl
> LayerTreeHost::CreateLayerTreeHostImpl(
400 LayerTreeHostImplClient
* client
) {
401 DCHECK(proxy_
->IsImplThread());
402 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
403 LayerTreeHostImpl::Create(settings_
,
406 rendering_stats_instrumentation_
.get(),
407 shared_bitmap_manager_
,
409 host_impl
->SetUseGpuRasterization(UseGpuRasterization());
410 shared_bitmap_manager_
= NULL
;
411 if (settings_
.calculate_top_controls_position
&&
412 host_impl
->top_controls_manager()) {
413 top_controls_manager_weak_ptr_
=
414 host_impl
->top_controls_manager()->AsWeakPtr();
416 input_handler_weak_ptr_
= host_impl
->AsWeakPtr();
417 return host_impl
.Pass();
420 void LayerTreeHost::DidLoseOutputSurface() {
421 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
422 DCHECK(proxy_
->IsMainThread());
424 if (output_surface_lost_
)
427 num_failed_recreate_attempts_
= 0;
428 output_surface_lost_
= true;
432 void LayerTreeHost::FinishAllRendering() {
433 proxy_
->FinishAllRendering();
436 void LayerTreeHost::SetDeferCommits(bool defer_commits
) {
437 proxy_
->SetDeferCommits(defer_commits
);
440 void LayerTreeHost::DidDeferCommit() {}
442 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
443 std::stack
<Layer
*> layer_stack
;
444 layer_stack
.push(root_layer());
445 while (!layer_stack
.empty()) {
446 Layer
* current_layer
= layer_stack
.top();
448 current_layer
->SetNeedsDisplay();
449 for (unsigned int i
= 0; i
< current_layer
->children().size(); i
++) {
450 layer_stack
.push(current_layer
->child_at(i
));
455 const RendererCapabilities
& LayerTreeHost::GetRendererCapabilities() const {
456 return proxy_
->GetRendererCapabilities();
459 void LayerTreeHost::SetNeedsAnimate() {
460 proxy_
->SetNeedsAnimate();
461 NotifySwapPromiseMonitorsOfSetNeedsCommit();
464 void LayerTreeHost::SetNeedsUpdateLayers() {
465 proxy_
->SetNeedsUpdateLayers();
466 NotifySwapPromiseMonitorsOfSetNeedsCommit();
469 void LayerTreeHost::SetNeedsCommit() {
470 if (!prepaint_callback_
.IsCancelled()) {
471 TRACE_EVENT_INSTANT0("cc",
472 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
473 TRACE_EVENT_SCOPE_THREAD
);
474 prepaint_callback_
.Cancel();
476 proxy_
->SetNeedsCommit();
477 NotifySwapPromiseMonitorsOfSetNeedsCommit();
480 void LayerTreeHost::SetNeedsFullTreeSync() {
481 needs_full_tree_sync_
= true;
485 void LayerTreeHost::SetNeedsRedraw() {
486 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_
));
489 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect
& damage_rect
) {
490 proxy_
->SetNeedsRedraw(damage_rect
);
493 bool LayerTreeHost::CommitRequested() const {
494 return proxy_
->CommitRequested();
497 bool LayerTreeHost::BeginMainFrameRequested() const {
498 return proxy_
->BeginMainFrameRequested();
502 void LayerTreeHost::SetNextCommitWaitsForActivation() {
503 proxy_
->SetNextCommitWaitsForActivation();
506 void LayerTreeHost::SetNextCommitForcesRedraw() {
507 next_commit_forces_redraw_
= true;
510 void LayerTreeHost::SetAnimationEvents(
511 scoped_ptr
<AnimationEventsVector
> events
) {
512 DCHECK(proxy_
->IsMainThread());
513 for (size_t event_index
= 0; event_index
< events
->size(); ++event_index
) {
514 int event_layer_id
= (*events
)[event_index
].layer_id
;
516 // Use the map of all controllers, not just active ones, since non-active
517 // controllers may still receive events for impl-only animations.
518 const AnimationRegistrar::AnimationControllerMap
& animation_controllers
=
519 animation_registrar_
->all_animation_controllers();
520 AnimationRegistrar::AnimationControllerMap::const_iterator iter
=
521 animation_controllers
.find(event_layer_id
);
522 if (iter
!= animation_controllers
.end()) {
523 switch ((*events
)[event_index
].type
) {
524 case AnimationEvent::Started
:
525 (*iter
).second
->NotifyAnimationStarted((*events
)[event_index
]);
528 case AnimationEvent::Finished
:
529 (*iter
).second
->NotifyAnimationFinished((*events
)[event_index
]);
532 case AnimationEvent::Aborted
:
533 (*iter
).second
->NotifyAnimationAborted((*events
)[event_index
]);
536 case AnimationEvent::PropertyUpdate
:
537 (*iter
).second
->NotifyAnimationPropertyUpdate((*events
)[event_index
]);
544 void LayerTreeHost::SetRootLayer(scoped_refptr
<Layer
> root_layer
) {
545 if (root_layer_
.get() == root_layer
.get())
548 if (root_layer_
.get())
549 root_layer_
->SetLayerTreeHost(NULL
);
550 root_layer_
= root_layer
;
551 if (root_layer_
.get()) {
552 DCHECK(!root_layer_
->parent());
553 root_layer_
->SetLayerTreeHost(this);
556 if (hud_layer_
.get())
557 hud_layer_
->RemoveFromParent();
559 // Reset gpu rasterization flag.
560 // This flag is sticky until a new tree comes along.
561 content_is_suitable_for_gpu_rasterization_
= true;
562 gpu_rasterization_histogram_recorded_
= false;
564 SetNeedsFullTreeSync();
567 void LayerTreeHost::SetDebugState(const LayerTreeDebugState
& debug_state
) {
568 LayerTreeDebugState new_debug_state
=
569 LayerTreeDebugState::Unite(settings_
.initial_debug_state
, debug_state
);
571 if (LayerTreeDebugState::Equal(debug_state_
, new_debug_state
))
574 debug_state_
= new_debug_state
;
576 rendering_stats_instrumentation_
->set_record_rendering_stats(
577 debug_state_
.RecordRenderingStats());
580 proxy_
->SetDebugState(debug_state
);
583 bool LayerTreeHost::UseGpuRasterization() const {
584 if (settings_
.gpu_rasterization_forced
) {
586 } else if (settings_
.gpu_rasterization_enabled
) {
587 return has_gpu_rasterization_trigger_
&&
588 content_is_suitable_for_gpu_rasterization_
;
594 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger
) {
595 if (has_trigger
== has_gpu_rasterization_trigger_
)
598 has_gpu_rasterization_trigger_
= has_trigger
;
599 TRACE_EVENT_INSTANT1("cc",
600 "LayerTreeHost::SetHasGpuRasterizationTrigger",
601 TRACE_EVENT_SCOPE_THREAD
,
603 has_gpu_rasterization_trigger_
);
606 void LayerTreeHost::SetViewportSize(const gfx::Size
& device_viewport_size
) {
607 if (device_viewport_size
== device_viewport_size_
)
610 device_viewport_size_
= device_viewport_size
;
615 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height
) {
616 if (overdraw_bottom_height_
== overdraw_bottom_height
)
619 overdraw_bottom_height_
= overdraw_bottom_height
;
623 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta
) {
624 DCHECK(CommitRequested());
625 page_scale_factor_
*= page_scale_delta
;
628 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor
,
629 float min_page_scale_factor
,
630 float max_page_scale_factor
) {
631 if (page_scale_factor
== page_scale_factor_
&&
632 min_page_scale_factor
== min_page_scale_factor_
&&
633 max_page_scale_factor
== max_page_scale_factor_
)
636 page_scale_factor_
= page_scale_factor
;
637 min_page_scale_factor_
= min_page_scale_factor
;
638 max_page_scale_factor_
= max_page_scale_factor
;
642 void LayerTreeHost::SetOverhangBitmap(const SkBitmap
& bitmap
) {
643 DCHECK(bitmap
.width() && bitmap
.height());
644 DCHECK_EQ(bitmap
.bytesPerPixel(), 4);
646 SkBitmap bitmap_copy
;
647 if (bitmap
.isImmutable()) {
648 bitmap_copy
= bitmap
;
650 bitmap
.copyTo(&bitmap_copy
);
651 bitmap_copy
.setImmutable();
654 UIResourceBitmap
overhang_bitmap(bitmap_copy
);
655 overhang_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
656 overhang_ui_resource_
= ScopedUIResource::Create(this, overhang_bitmap
);
659 void LayerTreeHost::SetVisible(bool visible
) {
660 if (visible_
== visible
)
665 proxy_
->SetVisible(visible
);
668 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d
& target_offset
,
671 base::TimeDelta duration
) {
672 pending_page_scale_animation_
.reset(new PendingPageScaleAnimation
);
673 pending_page_scale_animation_
->target_offset
= target_offset
;
674 pending_page_scale_animation_
->use_anchor
= use_anchor
;
675 pending_page_scale_animation_
->scale
= scale
;
676 pending_page_scale_animation_
->duration
= duration
;
681 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
682 proxy_
->NotifyInputThrottledUntilCommit();
685 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time
) {
686 DCHECK(!proxy_
->HasImplThread());
687 SingleThreadProxy
* proxy
= static_cast<SingleThreadProxy
*>(proxy_
.get());
689 if (output_surface_lost_
)
690 proxy
->CreateAndInitializeOutputSurface();
691 if (output_surface_lost_
)
694 proxy
->CompositeImmediately(frame_begin_time
);
697 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue
* queue
) {
698 DCHECK(!output_surface_lost_
);
703 DCHECK(!root_layer()->parent());
705 bool result
= UpdateLayers(root_layer(), queue
);
707 micro_benchmark_controller_
.DidUpdateLayers();
709 return result
|| next_commit_forces_redraw_
;
712 static Layer
* FindFirstScrollableLayer(Layer
* layer
) {
716 if (layer
->scrollable())
719 for (size_t i
= 0; i
< layer
->children().size(); ++i
) {
720 Layer
* found
= FindFirstScrollableLayer(layer
->children()[i
].get());
728 void LayerTreeHost::RecordGpuRasterizationHistogram() {
729 // Gpu rasterization is only supported when impl-side painting is enabled.
730 if (gpu_rasterization_histogram_recorded_
|| !settings_
.impl_side_painting
)
733 // Record how widely gpu rasterization is enabled.
734 // This number takes device/gpu whitelisting/backlisting into account.
735 // Note that we do not consider the forced gpu rasterization mode, which is
736 // mostly used for debugging purposes.
737 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
738 settings_
.gpu_rasterization_enabled
);
739 if (settings_
.gpu_rasterization_enabled
) {
740 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
741 has_gpu_rasterization_trigger_
);
742 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
743 content_is_suitable_for_gpu_rasterization_
);
744 // Record how many pages actually get gpu rasterization when enabled.
745 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
746 (has_gpu_rasterization_trigger_
&&
747 content_is_suitable_for_gpu_rasterization_
));
750 gpu_rasterization_histogram_recorded_
= true;
753 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer
* layer
) {
754 if (!layer
->SupportsLCDText())
757 lcd_text_metrics_
.total_num_cc_layers
++;
758 if (layer
->draw_properties().can_use_lcd_text
) {
759 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
++;
760 if (layer
->contents_opaque())
761 lcd_text_metrics_
.total_num_cc_layers_will_use_lcd_text
++;
765 bool LayerTreeHost::UsingSharedMemoryResources() {
766 return GetRendererCapabilities().using_shared_memory_resources
;
769 bool LayerTreeHost::UpdateLayers(Layer
* root_layer
,
770 ResourceUpdateQueue
* queue
) {
771 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
772 "source_frame_number", source_frame_number());
774 RenderSurfaceLayerList update_list
;
778 Layer
* root_scroll
= FindFirstScrollableLayer(root_layer
);
779 Layer
* page_scale_layer
= page_scale_layer_
;
780 if (!page_scale_layer
&& root_scroll
)
781 page_scale_layer
= root_scroll
->parent();
784 hud_layer_
->PrepareForCalculateDrawProperties(
785 device_viewport_size(), device_scale_factor_
);
788 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
789 bool can_render_to_separate_surface
= true;
790 // TODO(vmpstr): Passing 0 as the current render surface layer list id means
791 // that we won't be able to detect if a layer is part of |update_list|.
792 // Change this if this information is required.
793 int render_surface_layer_list_id
= 0;
794 LayerTreeHostCommon::CalcDrawPropsMainInputs
inputs(
796 device_viewport_size(),
798 device_scale_factor_
,
801 GetRendererCapabilities().max_texture_size
,
802 settings_
.can_use_lcd_text
,
803 can_render_to_separate_surface
,
804 settings_
.layer_transforms_should_scale_layer_contents
,
806 render_surface_layer_list_id
);
807 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
809 if (total_frames_used_for_lcd_text_metrics_
<=
810 kTotalFramesToUseForLCDTextMetrics
) {
811 LayerTreeHostCommon::CallFunctionForSubtree(
813 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback
,
814 base::Unretained(this)));
815 total_frames_used_for_lcd_text_metrics_
++;
818 if (total_frames_used_for_lcd_text_metrics_
==
819 kTotalFramesToUseForLCDTextMetrics
) {
820 total_frames_used_for_lcd_text_metrics_
++;
822 UMA_HISTOGRAM_PERCENTAGE(
823 "Renderer4.LCDText.PercentageOfCandidateLayers",
824 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
* 100.0 /
825 lcd_text_metrics_
.total_num_cc_layers
);
826 UMA_HISTOGRAM_PERCENTAGE(
827 "Renderer4.LCDText.PercentageOfAALayers",
828 lcd_text_metrics_
.total_num_cc_layers_will_use_lcd_text
* 100.0 /
829 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
);
833 // Reset partial texture update requests.
834 partial_texture_update_requests_
= 0;
836 bool did_paint_content
= false;
837 bool need_more_updates
= false;
839 update_list
, queue
, &did_paint_content
, &need_more_updates
);
840 if (need_more_updates
) {
841 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
842 prepaint_callback_
.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint
,
843 base::Unretained(this)));
844 static base::TimeDelta prepaint_delay
=
845 base::TimeDelta::FromMilliseconds(100);
846 base::MessageLoop::current()->PostDelayedTask(
847 FROM_HERE
, prepaint_callback_
.callback(), prepaint_delay
);
850 return did_paint_content
;
853 void LayerTreeHost::TriggerPrepaint() {
854 prepaint_callback_
.Cancel();
855 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
859 static void LayerTreeHostReduceMemoryCallback(Layer
* layer
) {
860 layer
->ReduceMemoryUsage();
863 void LayerTreeHost::ReduceMemoryUsage() {
867 LayerTreeHostCommon::CallFunctionForSubtree(
869 base::Bind(&LayerTreeHostReduceMemoryCallback
));
872 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes
) {
873 DCHECK(surface_memory_placeholder_
);
875 // Surfaces have a place holder for their memory since they are managed
876 // independantly but should still be tracked and reduce other memory usage.
877 surface_memory_placeholder_
->SetTextureManager(
878 contents_texture_manager_
.get());
879 surface_memory_placeholder_
->set_request_priority(
880 PriorityCalculator::RenderSurfacePriority());
881 surface_memory_placeholder_
->SetToSelfManagedMemoryPlaceholder(
882 surface_memory_bytes
);
885 void LayerTreeHost::SetPrioritiesForLayers(
886 const RenderSurfaceLayerList
& update_list
) {
887 PriorityCalculator calculator
;
888 typedef LayerIterator
<Layer
> LayerIteratorType
;
889 LayerIteratorType end
= LayerIteratorType::End(&update_list
);
890 for (LayerIteratorType it
= LayerIteratorType::Begin(&update_list
);
893 if (it
.represents_itself()) {
894 it
->SetTexturePriorities(calculator
);
895 } else if (it
.represents_target_render_surface()) {
896 if (it
->mask_layer())
897 it
->mask_layer()->SetTexturePriorities(calculator
);
898 if (it
->replica_layer() && it
->replica_layer()->mask_layer())
899 it
->replica_layer()->mask_layer()->SetTexturePriorities(calculator
);
904 void LayerTreeHost::PrioritizeTextures(
905 const RenderSurfaceLayerList
& render_surface_layer_list
) {
906 if (!contents_texture_manager_
)
909 contents_texture_manager_
->ClearPriorities();
911 size_t memory_for_render_surfaces_metric
=
912 CalculateMemoryForRenderSurfaces(render_surface_layer_list
);
914 SetPrioritiesForLayers(render_surface_layer_list
);
915 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric
);
917 contents_texture_manager_
->PrioritizeTextures();
920 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
921 const RenderSurfaceLayerList
& update_list
) {
922 size_t readback_bytes
= 0;
923 size_t max_background_texture_bytes
= 0;
924 size_t contents_texture_bytes
= 0;
926 // Start iteration at 1 to skip the root surface as it does not have a texture
928 for (size_t i
= 1; i
< update_list
.size(); ++i
) {
929 Layer
* render_surface_layer
= update_list
.at(i
);
930 RenderSurface
* render_surface
= render_surface_layer
->render_surface();
933 Resource::MemorySizeBytes(render_surface
->content_rect().size(),
935 contents_texture_bytes
+= bytes
;
937 if (render_surface_layer
->background_filters().IsEmpty())
940 if (bytes
> max_background_texture_bytes
)
941 max_background_texture_bytes
= bytes
;
942 if (!readback_bytes
) {
943 readback_bytes
= Resource::MemorySizeBytes(device_viewport_size_
,
947 return readback_bytes
+ max_background_texture_bytes
+ contents_texture_bytes
;
950 void LayerTreeHost::PaintMasksForRenderSurface(Layer
* render_surface_layer
,
951 ResourceUpdateQueue
* queue
,
952 bool* did_paint_content
,
953 bool* need_more_updates
) {
954 // Note: Masks and replicas only exist for layers that own render surfaces. If
955 // we reach this point in code, we already know that at least something will
956 // be drawn into this render surface, so the mask and replica should be
959 Layer
* mask_layer
= render_surface_layer
->mask_layer();
961 *did_paint_content
|= mask_layer
->Update(queue
, NULL
);
962 *need_more_updates
|= mask_layer
->NeedMoreUpdates();
965 Layer
* replica_mask_layer
=
966 render_surface_layer
->replica_layer() ?
967 render_surface_layer
->replica_layer()->mask_layer() : NULL
;
968 if (replica_mask_layer
) {
969 *did_paint_content
|= replica_mask_layer
->Update(queue
, NULL
);
970 *need_more_updates
|= replica_mask_layer
->NeedMoreUpdates();
974 void LayerTreeHost::PaintLayerContents(
975 const RenderSurfaceLayerList
& render_surface_layer_list
,
976 ResourceUpdateQueue
* queue
,
977 bool* did_paint_content
,
978 bool* need_more_updates
) {
979 OcclusionTracker
<Layer
> occlusion_tracker(
980 root_layer_
->render_surface()->content_rect());
981 occlusion_tracker
.set_minimum_tracking_size(
982 settings_
.minimum_occlusion_tracking_size
);
984 PrioritizeTextures(render_surface_layer_list
);
986 in_paint_layer_contents_
= true;
988 // Iterates front-to-back to allow for testing occlusion and performing
989 // culling during the tree walk.
990 typedef LayerIterator
<Layer
> LayerIteratorType
;
991 LayerIteratorType end
= LayerIteratorType::End(&render_surface_layer_list
);
992 for (LayerIteratorType it
=
993 LayerIteratorType::Begin(&render_surface_layer_list
);
996 occlusion_tracker
.EnterLayer(it
);
998 if (it
.represents_target_render_surface()) {
999 PaintMasksForRenderSurface(
1000 *it
, queue
, did_paint_content
, need_more_updates
);
1001 } else if (it
.represents_itself()) {
1002 DCHECK(!it
->paint_properties().bounds
.IsEmpty());
1003 *did_paint_content
|= it
->Update(queue
, &occlusion_tracker
);
1004 *need_more_updates
|= it
->NeedMoreUpdates();
1005 // Note the '&&' with previous is-suitable state.
1006 // This means that once the layer-tree becomes unsuitable for gpu
1007 // rasterization due to some content, it will continue to be unsuitable
1008 // even if that content is replaced by gpu-friendly content.
1009 // This is to avoid switching back-and-forth between gpu and sw
1010 // rasterization which may be both bad for performance and visually
1012 content_is_suitable_for_gpu_rasterization_
&=
1013 it
->IsSuitableForGpuRasterization();
1016 occlusion_tracker
.LeaveLayer(it
);
1019 in_paint_layer_contents_
= false;
1022 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet
* info
) {
1023 if (!root_layer_
.get())
1026 ScopedPtrVector
<SwapPromise
>::iterator it
= info
->swap_promises
.begin();
1027 for (; it
!= info
->swap_promises
.end(); ++it
) {
1028 scoped_ptr
<SwapPromise
> swap_promise(info
->swap_promises
.take(it
));
1029 TRACE_EVENT_FLOW_STEP0("input",
1031 TRACE_ID_DONT_MANGLE(swap_promise
->TraceId()),
1032 "Main thread scroll update");
1033 QueueSwapPromise(swap_promise
.Pass());
1036 gfx::Vector2d inner_viewport_scroll_delta
;
1037 gfx::Vector2d outer_viewport_scroll_delta
;
1039 for (size_t i
= 0; i
< info
->scrolls
.size(); ++i
) {
1040 Layer
* layer
= LayerTreeHostCommon::FindLayerInSubtree(
1041 root_layer_
.get(), info
->scrolls
[i
].layer_id
);
1044 if (layer
== outer_viewport_scroll_layer_
.get()) {
1045 outer_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
1046 } else if (layer
== inner_viewport_scroll_layer_
.get()) {
1047 inner_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
1049 layer
->SetScrollOffsetFromImplSide(layer
->scroll_offset() +
1050 info
->scrolls
[i
].scroll_delta
);
1054 if (!inner_viewport_scroll_delta
.IsZero() ||
1055 !outer_viewport_scroll_delta
.IsZero() || info
->page_scale_delta
!= 1.f
) {
1056 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1057 // so re-get this layer before doing anything to it.
1059 // Preemptively apply the scroll offset and scale delta here before sending
1060 // it to the client. If the client comes back and sets it to the same
1061 // value, then the layer can early out without needing a full commit.
1062 DCHECK(inner_viewport_scroll_layer_
); // We should always have this.
1064 inner_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
1065 inner_viewport_scroll_layer_
->scroll_offset() +
1066 inner_viewport_scroll_delta
);
1067 if (outer_viewport_scroll_layer_
) {
1068 outer_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
1069 outer_viewport_scroll_layer_
->scroll_offset() +
1070 outer_viewport_scroll_delta
);
1072 ApplyPageScaleDeltaFromImplSide(info
->page_scale_delta
);
1074 client_
->ApplyScrollAndScale(
1075 inner_viewport_scroll_delta
+ outer_viewport_scroll_delta
,
1076 info
->page_scale_delta
);
1080 void LayerTreeHost::StartRateLimiter() {
1084 if (!rate_limit_timer_
.IsRunning()) {
1085 rate_limit_timer_
.Start(FROM_HERE
,
1088 &LayerTreeHost::RateLimit
);
1092 void LayerTreeHost::StopRateLimiter() {
1093 rate_limit_timer_
.Stop();
1096 void LayerTreeHost::RateLimit() {
1097 // Force a no-op command on the compositor context, so that any ratelimiting
1098 // commands will wait for the compositing context, and therefore for the
1100 proxy_
->ForceSerializeOnSwapBuffers();
1101 client_
->RateLimitSharedMainThreadContext();
1104 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1105 if (!proxy_
->GetRendererCapabilities().allow_partial_texture_updates
)
1107 return !proxy_
->HasImplThread();
1110 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1111 size_t max_partial_texture_updates
= 0;
1112 if (proxy_
->GetRendererCapabilities().allow_partial_texture_updates
&&
1113 !settings_
.impl_side_painting
) {
1114 max_partial_texture_updates
=
1115 std::min(settings_
.max_partial_texture_updates
,
1116 proxy_
->MaxPartialTextureUpdates());
1118 return max_partial_texture_updates
;
1121 bool LayerTreeHost::RequestPartialTextureUpdate() {
1122 if (partial_texture_update_requests_
>= MaxPartialTextureUpdates())
1125 partial_texture_update_requests_
++;
1129 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor
) {
1130 if (device_scale_factor
== device_scale_factor_
)
1132 device_scale_factor_
= device_scale_factor
;
1137 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints
,
1138 TopControlsState current
,
1140 if (!settings_
.calculate_top_controls_position
)
1143 // Top controls are only used in threaded mode.
1144 proxy_
->ImplThreadTaskRunner()->PostTask(
1146 base::Bind(&TopControlsManager::UpdateTopControlsState
,
1147 top_controls_manager_weak_ptr_
,
1153 scoped_ptr
<base::Value
> LayerTreeHost::AsValue() const {
1154 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue());
1155 state
->Set("proxy", proxy_
->AsValue().release());
1156 return state
.PassAs
<base::Value
>();
1159 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time
) {
1160 if (!settings_
.accelerated_animation_enabled
||
1161 animation_registrar_
->active_animation_controllers().empty())
1164 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1166 AnimationRegistrar::AnimationControllerMap copy
=
1167 animation_registrar_
->active_animation_controllers();
1168 for (AnimationRegistrar::AnimationControllerMap::iterator iter
= copy
.begin();
1171 (*iter
).second
->Animate(monotonic_time
);
1172 bool start_ready_animations
= true;
1173 (*iter
).second
->UpdateState(start_ready_animations
, NULL
);
1177 UIResourceId
LayerTreeHost::CreateUIResource(UIResourceClient
* client
) {
1180 UIResourceId next_id
= next_ui_resource_id_
++;
1181 DCHECK(ui_resource_client_map_
.find(next_id
) ==
1182 ui_resource_client_map_
.end());
1184 bool resource_lost
= false;
1185 UIResourceRequest
request(UIResourceRequest::UIResourceCreate
,
1187 client
->GetBitmap(next_id
, resource_lost
));
1188 ui_resource_request_queue_
.push_back(request
);
1190 UIResourceClientData data
;
1191 data
.client
= client
;
1192 data
.size
= request
.GetBitmap().GetSize();
1194 ui_resource_client_map_
[request
.GetId()] = data
;
1195 return request
.GetId();
1198 // Deletes a UI resource. May safely be called more than once.
1199 void LayerTreeHost::DeleteUIResource(UIResourceId uid
) {
1200 UIResourceClientMap::iterator iter
= ui_resource_client_map_
.find(uid
);
1201 if (iter
== ui_resource_client_map_
.end())
1204 UIResourceRequest
request(UIResourceRequest::UIResourceDelete
, uid
);
1205 ui_resource_request_queue_
.push_back(request
);
1206 ui_resource_client_map_
.erase(iter
);
1209 void LayerTreeHost::RecreateUIResources() {
1210 for (UIResourceClientMap::iterator iter
= ui_resource_client_map_
.begin();
1211 iter
!= ui_resource_client_map_
.end();
1213 UIResourceId uid
= iter
->first
;
1214 const UIResourceClientData
& data
= iter
->second
;
1215 bool resource_lost
= true;
1216 UIResourceRequest
request(UIResourceRequest::UIResourceCreate
,
1218 data
.client
->GetBitmap(uid
, resource_lost
));
1219 ui_resource_request_queue_
.push_back(request
);
1223 // Returns the size of a resource given its id.
1224 gfx::Size
LayerTreeHost::GetUIResourceSize(UIResourceId uid
) const {
1225 UIResourceClientMap::const_iterator iter
= ui_resource_client_map_
.find(uid
);
1226 if (iter
== ui_resource_client_map_
.end())
1229 const UIResourceClientData
& data
= iter
->second
;
1233 void LayerTreeHost::RegisterViewportLayers(
1234 scoped_refptr
<Layer
> page_scale_layer
,
1235 scoped_refptr
<Layer
> inner_viewport_scroll_layer
,
1236 scoped_refptr
<Layer
> outer_viewport_scroll_layer
) {
1237 page_scale_layer_
= page_scale_layer
;
1238 inner_viewport_scroll_layer_
= inner_viewport_scroll_layer
;
1239 outer_viewport_scroll_layer_
= outer_viewport_scroll_layer
;
1242 void LayerTreeHost::RegisterSelection(const LayerSelectionBound
& anchor
,
1243 const LayerSelectionBound
& focus
) {
1244 if (selection_anchor_
== anchor
&& selection_focus_
== focus
)
1247 selection_anchor_
= anchor
;
1248 selection_focus_
= focus
;
1252 int LayerTreeHost::ScheduleMicroBenchmark(
1253 const std::string
& benchmark_name
,
1254 scoped_ptr
<base::Value
> value
,
1255 const MicroBenchmark::DoneCallback
& callback
) {
1256 return micro_benchmark_controller_
.ScheduleRun(
1257 benchmark_name
, value
.Pass(), callback
);
1260 bool LayerTreeHost::SendMessageToMicroBenchmark(int id
,
1261 scoped_ptr
<base::Value
> value
) {
1262 return micro_benchmark_controller_
.SendMessage(id
, value
.Pass());
1265 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1266 swap_promise_monitor_
.insert(monitor
);
1269 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1270 swap_promise_monitor_
.erase(monitor
);
1273 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1274 std::set
<SwapPromiseMonitor
*>::iterator it
= swap_promise_monitor_
.begin();
1275 for (; it
!= swap_promise_monitor_
.end(); it
++)
1276 (*it
)->OnSetNeedsCommitOnMain();
1279 void LayerTreeHost::QueueSwapPromise(scoped_ptr
<SwapPromise
> swap_promise
) {
1280 DCHECK(swap_promise
);
1281 if (swap_promise_list_
.size() > kMaxQueuedSwapPromiseNumber
)
1282 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW
);
1283 swap_promise_list_
.push_back(swap_promise
.Pass());
1286 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason
) {
1287 for (size_t i
= 0; i
< swap_promise_list_
.size(); i
++)
1288 swap_promise_list_
[i
]->DidNotSwap(reason
);
1289 swap_promise_list_
.clear();