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/auto_reset.h"
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/location.h"
16 #include "base/metrics/histogram.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/trace_event/trace_event.h"
22 #include "base/trace_event/trace_event_argument.h"
23 #include "cc/animation/animation_host.h"
24 #include "cc/animation/animation_registrar.h"
25 #include "cc/animation/layer_animation_controller.h"
26 #include "cc/base/math_util.h"
27 #include "cc/debug/devtools_instrumentation.h"
28 #include "cc/debug/frame_viewer_instrumentation.h"
29 #include "cc/debug/rendering_stats_instrumentation.h"
30 #include "cc/input/layer_selection_bound.h"
31 #include "cc/input/page_scale_animation.h"
32 #include "cc/input/top_controls_manager.h"
33 #include "cc/layers/heads_up_display_layer.h"
34 #include "cc/layers/heads_up_display_layer_impl.h"
35 #include "cc/layers/layer.h"
36 #include "cc/layers/layer_iterator.h"
37 #include "cc/layers/painted_scrollbar_layer.h"
38 #include "cc/resources/ui_resource_request.h"
39 #include "cc/scheduler/begin_frame_source.h"
40 #include "cc/trees/draw_property_utils.h"
41 #include "cc/trees/layer_tree_host_client.h"
42 #include "cc/trees/layer_tree_host_common.h"
43 #include "cc/trees/layer_tree_host_impl.h"
44 #include "cc/trees/layer_tree_impl.h"
45 #include "cc/trees/single_thread_proxy.h"
46 #include "cc/trees/thread_proxy.h"
47 #include "cc/trees/tree_synchronizer.h"
48 #include "ui/gfx/geometry/size_conversions.h"
49 #include "ui/gfx/geometry/vector2d_conversions.h"
52 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number
;
57 LayerTreeHost::InitParams::InitParams() {
60 LayerTreeHost::InitParams::~InitParams() {
63 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateThreaded(
64 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
,
66 DCHECK(params
->main_task_runner
.get());
67 DCHECK(impl_task_runner
.get());
68 DCHECK(params
->settings
);
69 scoped_ptr
<LayerTreeHost
> layer_tree_host(new LayerTreeHost(params
));
70 layer_tree_host
->InitializeThreaded(
71 params
->main_task_runner
, impl_task_runner
,
72 params
->external_begin_frame_source
.Pass());
73 return layer_tree_host
.Pass();
76 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateSingleThreaded(
77 LayerTreeHostSingleThreadClient
* single_thread_client
,
79 DCHECK(params
->settings
);
80 scoped_ptr
<LayerTreeHost
> layer_tree_host(new LayerTreeHost(params
));
81 layer_tree_host
->InitializeSingleThreaded(
82 single_thread_client
, params
->main_task_runner
,
83 params
->external_begin_frame_source
.Pass());
84 return layer_tree_host
.Pass();
87 LayerTreeHost::LayerTreeHost(InitParams
* params
)
88 : micro_benchmark_controller_(this),
89 next_ui_resource_id_(1),
90 inside_begin_main_frame_(false),
91 needs_full_tree_sync_(true),
92 needs_meta_info_recomputation_(true),
93 client_(params
->client
),
94 source_frame_number_(0),
95 meta_information_sequence_number_(1),
96 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
97 output_surface_lost_(true),
98 settings_(*params
->settings
),
99 debug_state_(settings_
.initial_debug_state
),
100 top_controls_shrink_blink_size_(false),
101 top_controls_height_(0.f
),
102 top_controls_shown_ratio_(0.f
),
103 hide_pinch_scrollbars_near_min_scale_(false),
104 device_scale_factor_(1.f
),
106 page_scale_factor_(1.f
),
107 min_page_scale_factor_(1.f
),
108 max_page_scale_factor_(1.f
),
109 has_gpu_rasterization_trigger_(false),
110 content_is_suitable_for_gpu_rasterization_(true),
111 gpu_rasterization_histogram_recorded_(false),
112 background_color_(SK_ColorWHITE
),
113 has_transparent_background_(false),
114 did_complete_scale_animation_(false),
115 in_paint_layer_contents_(false),
116 id_(s_layer_tree_host_sequence_number
.GetNext() + 1),
117 next_commit_forces_redraw_(false),
118 shared_bitmap_manager_(params
->shared_bitmap_manager
),
119 gpu_memory_buffer_manager_(params
->gpu_memory_buffer_manager
),
120 task_graph_runner_(params
->task_graph_runner
),
121 surface_id_namespace_(0u),
122 next_surface_sequence_(1u) {
123 DCHECK(task_graph_runner_
);
125 if (settings_
.accelerated_animation_enabled
) {
126 if (settings_
.use_compositor_animation_timelines
) {
127 animation_host_
= AnimationHost::Create(ThreadInstance::MAIN
);
128 animation_host_
->SetMutatorHostClient(this);
130 animation_registrar_
= AnimationRegistrar::Create();
134 rendering_stats_instrumentation_
->set_record_rendering_stats(
135 debug_state_
.RecordRenderingStats());
138 void LayerTreeHost::InitializeThreaded(
139 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
140 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
,
141 scoped_ptr
<BeginFrameSource
> external_begin_frame_source
) {
142 InitializeProxy(ThreadProxy::Create(this,
145 external_begin_frame_source
.Pass()));
148 void LayerTreeHost::InitializeSingleThreaded(
149 LayerTreeHostSingleThreadClient
* single_thread_client
,
150 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
151 scoped_ptr
<BeginFrameSource
> external_begin_frame_source
) {
153 SingleThreadProxy::Create(this,
154 single_thread_client
,
156 external_begin_frame_source
.Pass()));
159 void LayerTreeHost::InitializeForTesting(scoped_ptr
<Proxy
> proxy_for_testing
) {
160 InitializeProxy(proxy_for_testing
.Pass());
163 void LayerTreeHost::InitializeProxy(scoped_ptr
<Proxy
> proxy
) {
164 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
166 proxy_
= proxy
.Pass();
168 if (settings_
.accelerated_animation_enabled
) {
170 animation_host_
->SetSupportsScrollAnimations(
171 proxy_
->SupportsImplScrolling());
173 animation_registrar_
->set_supports_scroll_animations(
174 proxy_
->SupportsImplScrolling());
178 LayerTreeHost::~LayerTreeHost() {
179 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
182 animation_host_
->SetMutatorHostClient(nullptr);
184 if (root_layer_
.get())
185 root_layer_
->SetLayerTreeHost(NULL
);
187 DCHECK(swap_promise_monitor_
.empty());
189 BreakSwapPromises(SwapPromise::COMMIT_FAILS
);
192 DCHECK(proxy_
->IsMainThread());
196 // We must clear any pointers into the layer tree prior to destroying it.
197 RegisterViewportLayers(NULL
, NULL
, NULL
, NULL
);
199 if (root_layer_
.get()) {
200 // The layer tree must be destroyed before the layer tree host. We've
201 // made a contract with our animation controllers that the registrar
202 // will outlive them, and we must make good.
207 void LayerTreeHost::SetLayerTreeHostClientReady() {
208 proxy_
->SetLayerTreeHostClientReady();
211 void LayerTreeHost::WillBeginMainFrame() {
212 devtools_instrumentation::WillBeginMainThreadFrame(id(),
213 source_frame_number());
214 client_
->WillBeginMainFrame();
217 void LayerTreeHost::DidBeginMainFrame() {
218 client_
->DidBeginMainFrame();
221 void LayerTreeHost::BeginMainFrameNotExpectedSoon() {
222 client_
->BeginMainFrameNotExpectedSoon();
225 void LayerTreeHost::BeginMainFrame(const BeginFrameArgs
& args
) {
226 inside_begin_main_frame_
= true;
227 client_
->BeginMainFrame(args
);
228 inside_begin_main_frame_
= false;
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());
253 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace
);
255 frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
257 LayerTreeHostCommon::CallFunctionForSubtree(
258 root_layer(), [](Layer
* layer
) { layer
->DidBeginTracing(); });
261 LayerTreeImpl
* sync_tree
= host_impl
->sync_tree();
263 if (next_commit_forces_redraw_
) {
264 sync_tree
->ForceRedrawNextActivation();
265 next_commit_forces_redraw_
= false;
268 sync_tree
->set_source_frame_number(source_frame_number());
270 if (needs_full_tree_sync_
) {
271 sync_tree
->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
272 root_layer(), sync_tree
->DetachLayerTree(), sync_tree
));
274 sync_tree
->set_needs_full_tree_sync(needs_full_tree_sync_
);
275 needs_full_tree_sync_
= false;
277 if (hud_layer_
.get()) {
278 LayerImpl
* hud_impl
= LayerTreeHostCommon::FindLayerInSubtree(
279 sync_tree
->root_layer(), hud_layer_
->id());
280 sync_tree
->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl
*>(hud_impl
));
282 sync_tree
->set_hud_layer(NULL
);
285 sync_tree
->set_background_color(background_color_
);
286 sync_tree
->set_has_transparent_background(has_transparent_background_
);
288 if (page_scale_layer_
.get() && inner_viewport_scroll_layer_
.get()) {
289 sync_tree
->SetViewportLayersFromIds(
290 overscroll_elasticity_layer_
.get() ? overscroll_elasticity_layer_
->id()
292 page_scale_layer_
->id(), inner_viewport_scroll_layer_
->id(),
293 outer_viewport_scroll_layer_
.get() ? outer_viewport_scroll_layer_
->id()
294 : Layer::INVALID_ID
);
295 DCHECK(inner_viewport_scroll_layer_
->IsContainerForFixedPositionLayers());
297 sync_tree
->ClearViewportLayers();
300 sync_tree
->RegisterSelection(selection_
);
302 // Setting property trees must happen before pushing the page scale.
303 sync_tree
->SetPropertyTrees(property_trees_
);
305 sync_tree
->set_hide_pinch_scrollbars_near_min_scale(
306 hide_pinch_scrollbars_near_min_scale_
);
308 sync_tree
->PushPageScaleFromMainThread(
309 page_scale_factor_
, min_page_scale_factor_
, max_page_scale_factor_
);
310 sync_tree
->elastic_overscroll()->PushFromMainThread(elastic_overscroll_
);
311 if (sync_tree
->IsActiveTree())
312 sync_tree
->elastic_overscroll()->PushPendingToActive();
314 sync_tree
->PassSwapPromises(&swap_promise_list_
);
316 sync_tree
->set_top_controls_shrink_blink_size(
317 top_controls_shrink_blink_size_
);
318 sync_tree
->set_top_controls_height(top_controls_height_
);
319 sync_tree
->PushTopControlsFromMainThread(top_controls_shown_ratio_
);
321 host_impl
->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_
);
322 host_impl
->SetContentIsSuitableForGpuRasterization(
323 content_is_suitable_for_gpu_rasterization_
);
324 RecordGpuRasterizationHistogram();
326 host_impl
->SetViewportSize(device_viewport_size_
);
327 host_impl
->SetDeviceScaleFactor(device_scale_factor_
);
328 host_impl
->SetDebugState(debug_state_
);
329 if (pending_page_scale_animation_
) {
330 sync_tree
->SetPendingPageScaleAnimation(
331 pending_page_scale_animation_
.Pass());
334 if (!ui_resource_request_queue_
.empty()) {
335 sync_tree
->set_ui_resource_request_queue(ui_resource_request_queue_
);
336 ui_resource_request_queue_
.clear();
339 DCHECK(!sync_tree
->ViewportSizeInvalid());
341 sync_tree
->set_has_ever_been_drawn(false);
344 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
345 TreeSynchronizer::PushProperties(root_layer(), sync_tree
->root_layer());
347 if (animation_host_
) {
348 DCHECK(host_impl
->animation_host());
349 animation_host_
->PushPropertiesTo(host_impl
->animation_host());
353 // This must happen after synchronizing property trees and after push
354 // properties, which updates property tree indices.
355 sync_tree
->UpdatePropertyTreeScrollingAndAnimationFromMainThread();
357 micro_benchmark_controller_
.ScheduleImplBenchmarks(host_impl
);
360 void LayerTreeHost::WillCommit() {
361 OnCommitForSwapPromises();
362 client_
->WillCommit();
365 void LayerTreeHost::UpdateHudLayer() {
366 if (debug_state_
.ShowHudInfo()) {
367 if (!hud_layer_
.get()) {
368 LayerSettings hud_layer_settings
;
369 hud_layer_settings
.use_compositor_animation_timelines
=
370 settings_
.use_compositor_animation_timelines
;
371 hud_layer_
= HeadsUpDisplayLayer::Create(hud_layer_settings
);
374 if (root_layer_
.get() && !hud_layer_
->parent())
375 root_layer_
->AddChild(hud_layer_
);
376 } else if (hud_layer_
.get()) {
377 hud_layer_
->RemoveFromParent();
382 void LayerTreeHost::CommitComplete() {
383 source_frame_number_
++;
384 client_
->DidCommit();
385 if (did_complete_scale_animation_
) {
386 client_
->DidCompletePageScaleAnimation();
387 did_complete_scale_animation_
= false;
391 void LayerTreeHost::SetOutputSurface(scoped_ptr
<OutputSurface
> surface
) {
392 TRACE_EVENT0("cc", "LayerTreeHost::SetOutputSurface");
393 DCHECK(output_surface_lost_
);
396 proxy_
->SetOutputSurface(surface
.Pass());
399 void LayerTreeHost::RequestNewOutputSurface() {
400 client_
->RequestNewOutputSurface();
403 void LayerTreeHost::DidInitializeOutputSurface() {
404 output_surface_lost_
= false;
405 client_
->DidInitializeOutputSurface();
408 void LayerTreeHost::DidFailToInitializeOutputSurface() {
409 DCHECK(output_surface_lost_
);
410 client_
->DidFailToInitializeOutputSurface();
413 scoped_ptr
<LayerTreeHostImpl
> LayerTreeHost::CreateLayerTreeHostImpl(
414 LayerTreeHostImplClient
* client
) {
415 DCHECK(proxy_
->IsImplThread());
416 scoped_ptr
<LayerTreeHostImpl
> host_impl
= LayerTreeHostImpl::Create(
417 settings_
, client
, proxy_
.get(), rendering_stats_instrumentation_
.get(),
418 shared_bitmap_manager_
, gpu_memory_buffer_manager_
, task_graph_runner_
,
420 host_impl
->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_
);
421 host_impl
->SetContentIsSuitableForGpuRasterization(
422 content_is_suitable_for_gpu_rasterization_
);
423 shared_bitmap_manager_
= NULL
;
424 gpu_memory_buffer_manager_
= NULL
;
425 task_graph_runner_
= NULL
;
426 top_controls_manager_weak_ptr_
=
427 host_impl
->top_controls_manager()->AsWeakPtr();
428 input_handler_weak_ptr_
= host_impl
->AsWeakPtr();
429 return host_impl
.Pass();
432 void LayerTreeHost::DidLoseOutputSurface() {
433 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
434 DCHECK(proxy_
->IsMainThread());
436 if (output_surface_lost_
)
439 output_surface_lost_
= true;
443 void LayerTreeHost::FinishAllRendering() {
444 proxy_
->FinishAllRendering();
447 void LayerTreeHost::SetDeferCommits(bool defer_commits
) {
448 proxy_
->SetDeferCommits(defer_commits
);
451 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
452 std::stack
<Layer
*> layer_stack
;
453 layer_stack
.push(root_layer());
454 while (!layer_stack
.empty()) {
455 Layer
* current_layer
= layer_stack
.top();
457 current_layer
->SetNeedsDisplay();
458 for (unsigned int i
= 0; i
< current_layer
->children().size(); i
++) {
459 layer_stack
.push(current_layer
->child_at(i
));
464 const RendererCapabilities
& LayerTreeHost::GetRendererCapabilities() const {
465 return proxy_
->GetRendererCapabilities();
468 void LayerTreeHost::SetNeedsAnimate() {
469 proxy_
->SetNeedsAnimate();
470 NotifySwapPromiseMonitorsOfSetNeedsCommit();
473 void LayerTreeHost::SetNeedsUpdateLayers() {
474 proxy_
->SetNeedsUpdateLayers();
475 NotifySwapPromiseMonitorsOfSetNeedsCommit();
478 void LayerTreeHost::SetPropertyTreesNeedRebuild() {
479 property_trees_
.needs_rebuild
= true;
480 SetNeedsUpdateLayers();
483 void LayerTreeHost::SetNeedsCommit() {
484 proxy_
->SetNeedsCommit();
485 NotifySwapPromiseMonitorsOfSetNeedsCommit();
488 void LayerTreeHost::SetNeedsFullTreeSync() {
489 needs_full_tree_sync_
= true;
490 needs_meta_info_recomputation_
= true;
492 property_trees_
.needs_rebuild
= true;
496 void LayerTreeHost::SetNeedsMetaInfoRecomputation(bool needs_recomputation
) {
497 needs_meta_info_recomputation_
= needs_recomputation
;
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;
523 proxy_
->SetNeedsUpdateLayers();
526 void LayerTreeHost::SetAnimationEvents(
527 scoped_ptr
<AnimationEventsVector
> events
) {
528 DCHECK(proxy_
->IsMainThread());
530 animation_host_
->SetAnimationEvents(events
.Pass());
532 animation_registrar_
->SetAnimationEvents(events
.Pass());
535 void LayerTreeHost::SetRootLayer(scoped_refptr
<Layer
> root_layer
) {
536 if (root_layer_
.get() == root_layer
.get())
539 if (root_layer_
.get())
540 root_layer_
->SetLayerTreeHost(NULL
);
541 root_layer_
= root_layer
;
542 if (root_layer_
.get()) {
543 DCHECK(!root_layer_
->parent());
544 root_layer_
->SetLayerTreeHost(this);
547 if (hud_layer_
.get())
548 hud_layer_
->RemoveFromParent();
550 // Reset gpu rasterization flag.
551 // This flag is sticky until a new tree comes along.
552 content_is_suitable_for_gpu_rasterization_
= true;
553 gpu_rasterization_histogram_recorded_
= false;
555 SetNeedsFullTreeSync();
558 void LayerTreeHost::SetDebugState(const LayerTreeDebugState
& debug_state
) {
559 LayerTreeDebugState new_debug_state
=
560 LayerTreeDebugState::Unite(settings_
.initial_debug_state
, debug_state
);
562 if (LayerTreeDebugState::Equal(debug_state_
, new_debug_state
))
565 debug_state_
= new_debug_state
;
567 rendering_stats_instrumentation_
->set_record_rendering_stats(
568 debug_state_
.RecordRenderingStats());
571 proxy_
->SetDebugState(debug_state
);
574 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger
) {
575 if (has_trigger
== has_gpu_rasterization_trigger_
)
578 has_gpu_rasterization_trigger_
= has_trigger
;
579 TRACE_EVENT_INSTANT1("cc",
580 "LayerTreeHost::SetHasGpuRasterizationTrigger",
581 TRACE_EVENT_SCOPE_THREAD
,
583 has_gpu_rasterization_trigger_
);
586 void LayerTreeHost::SetViewportSize(const gfx::Size
& device_viewport_size
) {
587 if (device_viewport_size
== device_viewport_size_
)
590 device_viewport_size_
= device_viewport_size
;
592 SetPropertyTreesNeedRebuild();
596 void LayerTreeHost::SetTopControlsHeight(float height
, bool shrink
) {
597 if (top_controls_height_
== height
&&
598 top_controls_shrink_blink_size_
== shrink
)
601 top_controls_height_
= height
;
602 top_controls_shrink_blink_size_
= shrink
;
606 void LayerTreeHost::SetTopControlsShownRatio(float ratio
) {
607 if (top_controls_shown_ratio_
== ratio
)
610 top_controls_shown_ratio_
= ratio
;
614 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta
) {
615 DCHECK(CommitRequested());
616 if (page_scale_delta
== 1.f
)
618 page_scale_factor_
*= page_scale_delta
;
619 SetPropertyTreesNeedRebuild();
622 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor
,
623 float min_page_scale_factor
,
624 float max_page_scale_factor
) {
625 if (page_scale_factor
== page_scale_factor_
&&
626 min_page_scale_factor
== min_page_scale_factor_
&&
627 max_page_scale_factor
== max_page_scale_factor_
)
630 page_scale_factor_
= page_scale_factor
;
631 min_page_scale_factor_
= min_page_scale_factor
;
632 max_page_scale_factor_
= max_page_scale_factor
;
633 SetPropertyTreesNeedRebuild();
637 void LayerTreeHost::SetVisible(bool visible
) {
638 if (visible_
== visible
)
641 proxy_
->SetVisible(visible
);
644 void LayerTreeHost::SetThrottleFrameProduction(bool throttle
) {
645 proxy_
->SetThrottleFrameProduction(throttle
);
648 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d
& target_offset
,
651 base::TimeDelta duration
) {
652 pending_page_scale_animation_
.reset(
653 new PendingPageScaleAnimation(
662 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
663 proxy_
->NotifyInputThrottledUntilCommit();
666 void LayerTreeHost::LayoutAndUpdateLayers() {
667 DCHECK(!proxy_
->HasImplThread());
668 // This function is only valid when not using the scheduler.
669 DCHECK(!settings_
.single_thread_proxy_scheduler
);
670 SingleThreadProxy
* proxy
= static_cast<SingleThreadProxy
*>(proxy_
.get());
672 SetLayerTreeHostClientReady();
673 proxy
->LayoutAndUpdateLayers();
676 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time
) {
677 DCHECK(!proxy_
->HasImplThread());
678 // This function is only valid when not using the scheduler.
679 DCHECK(!settings_
.single_thread_proxy_scheduler
);
680 SingleThreadProxy
* proxy
= static_cast<SingleThreadProxy
*>(proxy_
.get());
682 SetLayerTreeHostClientReady();
683 proxy
->CompositeImmediately(frame_begin_time
);
686 bool LayerTreeHost::UpdateLayers() {
687 DCHECK(!output_surface_lost_
);
690 DCHECK(!root_layer()->parent());
691 bool result
= DoUpdateLayers(root_layer());
692 micro_benchmark_controller_
.DidUpdateLayers();
693 return result
|| next_commit_forces_redraw_
;
696 void LayerTreeHost::DidCompletePageScaleAnimation() {
697 did_complete_scale_animation_
= true;
700 static Layer
* FindFirstScrollableLayer(Layer
* layer
) {
704 if (layer
->scrollable())
707 for (size_t i
= 0; i
< layer
->children().size(); ++i
) {
708 Layer
* found
= FindFirstScrollableLayer(layer
->children()[i
].get());
716 void LayerTreeHost::RecordGpuRasterizationHistogram() {
717 // Gpu rasterization is only supported for Renderer compositors.
718 // Checking for proxy_->HasImplThread() to exclude Browser compositors.
719 if (gpu_rasterization_histogram_recorded_
|| !proxy_
->HasImplThread())
722 // Record how widely gpu rasterization is enabled.
723 // This number takes device/gpu whitelisting/backlisting into account.
724 // Note that we do not consider the forced gpu rasterization mode, which is
725 // mostly used for debugging purposes.
726 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
727 settings_
.gpu_rasterization_enabled
);
728 if (settings_
.gpu_rasterization_enabled
) {
729 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
730 has_gpu_rasterization_trigger_
);
731 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
732 content_is_suitable_for_gpu_rasterization_
);
733 // Record how many pages actually get gpu rasterization when enabled.
734 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
735 (has_gpu_rasterization_trigger_
&&
736 content_is_suitable_for_gpu_rasterization_
));
739 gpu_rasterization_histogram_recorded_
= true;
742 bool LayerTreeHost::UsingSharedMemoryResources() {
743 return GetRendererCapabilities().using_shared_memory_resources
;
746 bool LayerTreeHost::DoUpdateLayers(Layer
* root_layer
) {
747 TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number",
748 source_frame_number());
752 Layer
* root_scroll
= FindFirstScrollableLayer(root_layer
);
753 Layer
* page_scale_layer
= page_scale_layer_
.get();
754 if (!page_scale_layer
&& root_scroll
)
755 page_scale_layer
= root_scroll
->parent();
757 if (hud_layer_
.get()) {
758 hud_layer_
->PrepareForCalculateDrawProperties(device_viewport_size(),
759 device_scale_factor_
);
762 bool can_render_to_separate_surface
= true;
764 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
766 LayerTreeHostCommon::PreCalculateMetaInformation(root_layer
);
768 bool preserves_2d_axis_alignment
= false;
769 gfx::Transform identity_transform
;
770 LayerList update_layer_list
;
772 LayerTreeHostCommon::UpdateRenderSurfaces(
773 root_layer
, can_render_to_separate_surface
, identity_transform
,
774 preserves_2d_axis_alignment
);
776 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
777 "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
778 BuildPropertyTreesAndComputeVisibleRects(
779 root_layer
, page_scale_layer
, inner_viewport_scroll_layer_
.get(),
780 outer_viewport_scroll_layer_
.get(), page_scale_factor_
,
781 device_scale_factor_
, gfx::Rect(device_viewport_size_
),
782 identity_transform
, &property_trees_
, &update_layer_list
);
785 for (const auto& layer
: update_layer_list
)
786 layer
->SavePaintProperties();
788 base::AutoReset
<bool> painting(&in_paint_layer_contents_
, true);
789 bool did_paint_content
= false;
790 for (const auto& layer
: update_layer_list
) {
791 did_paint_content
|= layer
->Update();
792 content_is_suitable_for_gpu_rasterization_
&=
793 layer
->IsSuitableForGpuRasterization();
795 return did_paint_content
;
798 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet
* info
) {
799 ScopedPtrVector
<SwapPromise
>::iterator it
= info
->swap_promises
.begin();
800 for (; it
!= info
->swap_promises
.end(); ++it
) {
801 scoped_ptr
<SwapPromise
> swap_promise(info
->swap_promises
.take(it
));
802 TRACE_EVENT_WITH_FLOW1("input,benchmark",
804 TRACE_ID_DONT_MANGLE(swap_promise
->TraceId()),
805 TRACE_EVENT_FLAG_FLOW_IN
| TRACE_EVENT_FLAG_FLOW_OUT
,
806 "step", "Main thread scroll update");
807 QueueSwapPromise(swap_promise
.Pass());
810 gfx::Vector2dF inner_viewport_scroll_delta
;
811 gfx::Vector2dF outer_viewport_scroll_delta
;
813 if (root_layer_
.get()) {
814 for (size_t i
= 0; i
< info
->scrolls
.size(); ++i
) {
815 Layer
* layer
= LayerTreeHostCommon::FindLayerInSubtree(
816 root_layer_
.get(), info
->scrolls
[i
].layer_id
);
819 if (layer
== outer_viewport_scroll_layer_
.get()) {
820 outer_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
821 } else if (layer
== inner_viewport_scroll_layer_
.get()) {
822 inner_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
824 layer
->SetScrollOffsetFromImplSide(
825 gfx::ScrollOffsetWithDelta(layer
->scroll_offset(),
826 info
->scrolls
[i
].scroll_delta
));
828 SetNeedsUpdateLayers();
832 if (!inner_viewport_scroll_delta
.IsZero() ||
833 !outer_viewport_scroll_delta
.IsZero() || info
->page_scale_delta
!= 1.f
||
834 !info
->elastic_overscroll_delta
.IsZero() || info
->top_controls_delta
) {
835 // Preemptively apply the scroll offset and scale delta here before sending
836 // it to the client. If the client comes back and sets it to the same
837 // value, then the layer can early out without needing a full commit.
838 if (inner_viewport_scroll_layer_
.get()) {
839 inner_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
840 gfx::ScrollOffsetWithDelta(
841 inner_viewport_scroll_layer_
->scroll_offset(),
842 inner_viewport_scroll_delta
));
845 if (outer_viewport_scroll_layer_
.get()) {
846 outer_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
847 gfx::ScrollOffsetWithDelta(
848 outer_viewport_scroll_layer_
->scroll_offset(),
849 outer_viewport_scroll_delta
));
852 ApplyPageScaleDeltaFromImplSide(info
->page_scale_delta
);
853 elastic_overscroll_
+= info
->elastic_overscroll_delta
;
854 // TODO(ccameron): pass the elastic overscroll here so that input events
855 // may be translated appropriately.
856 client_
->ApplyViewportDeltas(
857 inner_viewport_scroll_delta
, outer_viewport_scroll_delta
,
858 info
->elastic_overscroll_delta
, info
->page_scale_delta
,
859 info
->top_controls_delta
);
860 SetNeedsUpdateLayers();
864 void LayerTreeHost::StartRateLimiter() {
865 if (inside_begin_main_frame_
)
868 if (!rate_limit_timer_
.IsRunning()) {
869 rate_limit_timer_
.Start(FROM_HERE
,
872 &LayerTreeHost::RateLimit
);
876 void LayerTreeHost::StopRateLimiter() {
877 rate_limit_timer_
.Stop();
880 void LayerTreeHost::RateLimit() {
881 // Force a no-op command on the compositor context, so that any ratelimiting
882 // commands will wait for the compositing context, and therefore for the
884 proxy_
->ForceSerializeOnSwapBuffers();
885 client_
->RateLimitSharedMainThreadContext();
888 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor
) {
889 if (device_scale_factor
== device_scale_factor_
)
891 device_scale_factor_
= device_scale_factor
;
893 property_trees_
.needs_rebuild
= true;
897 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints
,
898 TopControlsState current
,
900 // Top controls are only used in threaded mode.
901 proxy_
->ImplThreadTaskRunner()->PostTask(
903 base::Bind(&TopControlsManager::UpdateTopControlsState
,
904 top_controls_manager_weak_ptr_
,
910 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time
) {
911 if (!settings_
.accelerated_animation_enabled
)
914 AnimationEventsVector events
;
915 if (animation_host_
) {
916 if (animation_host_
->AnimateLayers(monotonic_time
))
917 animation_host_
->UpdateAnimationState(true, &events
);
919 if (animation_registrar_
->AnimateLayers(monotonic_time
))
920 animation_registrar_
->UpdateAnimationState(true, &events
);
924 property_trees_
.needs_rebuild
= true;
927 UIResourceId
LayerTreeHost::CreateUIResource(UIResourceClient
* client
) {
930 UIResourceId next_id
= next_ui_resource_id_
++;
931 DCHECK(ui_resource_client_map_
.find(next_id
) ==
932 ui_resource_client_map_
.end());
934 bool resource_lost
= false;
935 UIResourceRequest
request(UIResourceRequest::UI_RESOURCE_CREATE
, next_id
,
936 client
->GetBitmap(next_id
, resource_lost
));
937 ui_resource_request_queue_
.push_back(request
);
939 UIResourceClientData data
;
940 data
.client
= client
;
941 data
.size
= request
.GetBitmap().GetSize();
943 ui_resource_client_map_
[request
.GetId()] = data
;
944 return request
.GetId();
947 // Deletes a UI resource. May safely be called more than once.
948 void LayerTreeHost::DeleteUIResource(UIResourceId uid
) {
949 UIResourceClientMap::iterator iter
= ui_resource_client_map_
.find(uid
);
950 if (iter
== ui_resource_client_map_
.end())
953 UIResourceRequest
request(UIResourceRequest::UI_RESOURCE_DELETE
, uid
);
954 ui_resource_request_queue_
.push_back(request
);
955 ui_resource_client_map_
.erase(iter
);
958 void LayerTreeHost::RecreateUIResources() {
959 for (UIResourceClientMap::iterator iter
= ui_resource_client_map_
.begin();
960 iter
!= ui_resource_client_map_
.end();
962 UIResourceId uid
= iter
->first
;
963 const UIResourceClientData
& data
= iter
->second
;
964 bool resource_lost
= true;
965 UIResourceRequest
request(UIResourceRequest::UI_RESOURCE_CREATE
, uid
,
966 data
.client
->GetBitmap(uid
, resource_lost
));
967 ui_resource_request_queue_
.push_back(request
);
971 // Returns the size of a resource given its id.
972 gfx::Size
LayerTreeHost::GetUIResourceSize(UIResourceId uid
) const {
973 UIResourceClientMap::const_iterator iter
= ui_resource_client_map_
.find(uid
);
974 if (iter
== ui_resource_client_map_
.end())
977 const UIResourceClientData
& data
= iter
->second
;
981 void LayerTreeHost::RegisterViewportLayers(
982 scoped_refptr
<Layer
> overscroll_elasticity_layer
,
983 scoped_refptr
<Layer
> page_scale_layer
,
984 scoped_refptr
<Layer
> inner_viewport_scroll_layer
,
985 scoped_refptr
<Layer
> outer_viewport_scroll_layer
) {
986 overscroll_elasticity_layer_
= overscroll_elasticity_layer
;
987 page_scale_layer_
= page_scale_layer
;
988 inner_viewport_scroll_layer_
= inner_viewport_scroll_layer
;
989 outer_viewport_scroll_layer_
= outer_viewport_scroll_layer
;
992 void LayerTreeHost::RegisterSelection(const LayerSelection
& selection
) {
993 if (selection_
== selection
)
996 selection_
= selection
;
1000 int LayerTreeHost::ScheduleMicroBenchmark(
1001 const std::string
& benchmark_name
,
1002 scoped_ptr
<base::Value
> value
,
1003 const MicroBenchmark::DoneCallback
& callback
) {
1004 return micro_benchmark_controller_
.ScheduleRun(
1005 benchmark_name
, value
.Pass(), callback
);
1008 bool LayerTreeHost::SendMessageToMicroBenchmark(int id
,
1009 scoped_ptr
<base::Value
> value
) {
1010 return micro_benchmark_controller_
.SendMessage(id
, value
.Pass());
1013 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1014 swap_promise_monitor_
.insert(monitor
);
1017 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1018 swap_promise_monitor_
.erase(monitor
);
1021 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1022 std::set
<SwapPromiseMonitor
*>::iterator it
= swap_promise_monitor_
.begin();
1023 for (; it
!= swap_promise_monitor_
.end(); it
++)
1024 (*it
)->OnSetNeedsCommitOnMain();
1027 void LayerTreeHost::QueueSwapPromise(scoped_ptr
<SwapPromise
> swap_promise
) {
1028 DCHECK(swap_promise
);
1029 swap_promise_list_
.push_back(swap_promise
.Pass());
1032 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason
) {
1033 for (auto* swap_promise
: swap_promise_list_
)
1034 swap_promise
->DidNotSwap(reason
);
1035 swap_promise_list_
.clear();
1038 void LayerTreeHost::OnCommitForSwapPromises() {
1039 for (auto* swap_promise
: swap_promise_list_
)
1040 swap_promise
->OnCommit();
1043 void LayerTreeHost::set_surface_id_namespace(uint32_t id_namespace
) {
1044 surface_id_namespace_
= id_namespace
;
1047 SurfaceSequence
LayerTreeHost::CreateSurfaceSequence() {
1048 return SurfaceSequence(surface_id_namespace_
, next_surface_sequence_
++);
1051 void LayerTreeHost::SetChildrenNeedBeginFrames(
1052 bool children_need_begin_frames
) const {
1053 proxy_
->SetChildrenNeedBeginFrames(children_need_begin_frames
);
1056 void LayerTreeHost::SendBeginFramesToChildren(
1057 const BeginFrameArgs
& args
) const {
1058 client_
->SendBeginFramesToChildren(args
);
1061 void LayerTreeHost::SetAuthoritativeVSyncInterval(
1062 const base::TimeDelta
& interval
) {
1063 proxy_
->SetAuthoritativeVSyncInterval(interval
);
1066 void LayerTreeHost::RecordFrameTimingEvents(
1067 scoped_ptr
<FrameTimingTracker::CompositeTimingSet
> composite_events
,
1068 scoped_ptr
<FrameTimingTracker::MainFrameTimingSet
> main_frame_events
) {
1069 client_
->RecordFrameTimingEvents(composite_events
.Pass(),
1070 main_frame_events
.Pass());
1073 Layer
* LayerTreeHost::LayerById(int id
) const {
1074 LayerIdMap::const_iterator iter
= layer_id_map_
.find(id
);
1075 return iter
!= layer_id_map_
.end() ? iter
->second
: NULL
;
1078 void LayerTreeHost::RegisterLayer(Layer
* layer
) {
1079 DCHECK(!LayerById(layer
->id()));
1080 DCHECK(!in_paint_layer_contents_
);
1081 layer_id_map_
[layer
->id()] = layer
;
1082 if (animation_host_
)
1083 animation_host_
->RegisterLayer(layer
->id(), LayerTreeType::ACTIVE
);
1086 void LayerTreeHost::UnregisterLayer(Layer
* layer
) {
1087 DCHECK(LayerById(layer
->id()));
1088 DCHECK(!in_paint_layer_contents_
);
1089 if (animation_host_
)
1090 animation_host_
->UnregisterLayer(layer
->id(), LayerTreeType::ACTIVE
);
1091 layer_id_map_
.erase(layer
->id());
1094 bool LayerTreeHost::IsLayerInTree(int layer_id
, LayerTreeType tree_type
) const {
1095 return tree_type
== LayerTreeType::ACTIVE
&& LayerById(layer_id
);
1098 void LayerTreeHost::SetMutatorsNeedCommit() {
1102 void LayerTreeHost::SetLayerFilterMutated(int layer_id
,
1103 LayerTreeType tree_type
,
1104 const FilterOperations
& filters
) {
1105 LayerAnimationValueObserver
* layer
= LayerById(layer_id
);
1107 layer
->OnFilterAnimated(filters
);
1110 void LayerTreeHost::SetLayerOpacityMutated(int layer_id
,
1111 LayerTreeType tree_type
,
1113 LayerAnimationValueObserver
* layer
= LayerById(layer_id
);
1115 layer
->OnOpacityAnimated(opacity
);
1118 void LayerTreeHost::SetLayerTransformMutated(int layer_id
,
1119 LayerTreeType tree_type
,
1120 const gfx::Transform
& transform
) {
1121 LayerAnimationValueObserver
* layer
= LayerById(layer_id
);
1123 layer
->OnTransformAnimated(transform
);
1126 void LayerTreeHost::SetLayerScrollOffsetMutated(
1128 LayerTreeType tree_type
,
1129 const gfx::ScrollOffset
& scroll_offset
) {
1130 LayerAnimationValueObserver
* layer
= LayerById(layer_id
);
1132 layer
->OnScrollOffsetAnimated(scroll_offset
);
1135 void LayerTreeHost::LayerTransformIsPotentiallyAnimatingChanged(
1137 LayerTreeType tree_type
,
1138 bool is_animating
) {
1139 LayerAnimationValueObserver
* layer
= LayerById(layer_id
);
1141 layer
->OnTransformIsPotentiallyAnimatingChanged(is_animating
);
1144 gfx::ScrollOffset
LayerTreeHost::GetScrollOffsetForAnimation(
1145 int layer_id
) const {
1146 LayerAnimationValueProvider
* layer
= LayerById(layer_id
);
1148 return layer
->ScrollOffsetForAnimation();
1151 bool LayerTreeHost::ScrollOffsetAnimationWasInterrupted(
1152 const Layer
* layer
) const {
1153 return animation_host_
1154 ? animation_host_
->ScrollOffsetAnimationWasInterrupted(layer
->id())
1158 bool LayerTreeHost::IsAnimatingFilterProperty(const Layer
* layer
) const {
1159 return animation_host_
1160 ? animation_host_
->IsAnimatingFilterProperty(layer
->id(),
1161 LayerTreeType::ACTIVE
)
1165 bool LayerTreeHost::IsAnimatingOpacityProperty(const Layer
* layer
) const {
1166 return animation_host_
1167 ? animation_host_
->IsAnimatingOpacityProperty(
1168 layer
->id(), LayerTreeType::ACTIVE
)
1172 bool LayerTreeHost::IsAnimatingTransformProperty(const Layer
* layer
) const {
1173 return animation_host_
1174 ? animation_host_
->IsAnimatingTransformProperty(
1175 layer
->id(), LayerTreeType::ACTIVE
)
1179 bool LayerTreeHost::HasPotentiallyRunningFilterAnimation(
1180 const Layer
* layer
) const {
1181 return animation_host_
1182 ? animation_host_
->HasPotentiallyRunningFilterAnimation(
1183 layer
->id(), LayerTreeType::ACTIVE
)
1187 bool LayerTreeHost::HasPotentiallyRunningOpacityAnimation(
1188 const Layer
* layer
) const {
1189 return animation_host_
1190 ? animation_host_
->HasPotentiallyRunningOpacityAnimation(
1191 layer
->id(), LayerTreeType::ACTIVE
)
1195 bool LayerTreeHost::HasPotentiallyRunningTransformAnimation(
1196 const Layer
* layer
) const {
1197 return animation_host_
1198 ? animation_host_
->HasPotentiallyRunningTransformAnimation(
1199 layer
->id(), LayerTreeType::ACTIVE
)
1203 bool LayerTreeHost::HasOnlyTranslationTransforms(const Layer
* layer
) const {
1204 return animation_host_
1205 ? animation_host_
->HasOnlyTranslationTransforms(
1206 layer
->id(), LayerTreeType::ACTIVE
)
1210 bool LayerTreeHost::MaximumTargetScale(const Layer
* layer
,
1211 float* max_scale
) const {
1212 return animation_host_
1213 ? animation_host_
->MaximumTargetScale(
1214 layer
->id(), LayerTreeType::ACTIVE
, max_scale
)
1218 bool LayerTreeHost::AnimationStartScale(const Layer
* layer
,
1219 float* start_scale
) const {
1220 return animation_host_
1221 ? animation_host_
->AnimationStartScale(
1222 layer
->id(), LayerTreeType::ACTIVE
, start_scale
)
1226 bool LayerTreeHost::HasAnyAnimationTargetingProperty(
1228 Animation::TargetProperty property
) const {
1229 return animation_host_
1230 ? animation_host_
->HasAnyAnimationTargetingProperty(layer
->id(),
1235 bool LayerTreeHost::AnimationsPreserveAxisAlignment(const Layer
* layer
) const {
1236 return animation_host_
1237 ? animation_host_
->AnimationsPreserveAxisAlignment(layer
->id())
1241 bool LayerTreeHost::HasAnyAnimation(const Layer
* layer
) const {
1242 return animation_host_
? animation_host_
->HasAnyAnimation(layer
->id())
1246 bool LayerTreeHost::HasActiveAnimation(const Layer
* layer
) const {
1247 return animation_host_
? animation_host_
->HasActiveAnimation(layer
->id())