Add ICU message format support
[chromium-blink-merge.git] / cc / trees / layer_tree_host.cc
blob4d72eb246854c54d69d5c89b806c73be7d989a0b
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"
7 #include <algorithm>
8 #include <stack>
9 #include <string>
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/layers/render_surface.h"
39 #include "cc/resources/ui_resource_request.h"
40 #include "cc/scheduler/begin_frame_source.h"
41 #include "cc/trees/draw_property_utils.h"
42 #include "cc/trees/layer_tree_host_client.h"
43 #include "cc/trees/layer_tree_host_common.h"
44 #include "cc/trees/layer_tree_host_impl.h"
45 #include "cc/trees/layer_tree_impl.h"
46 #include "cc/trees/single_thread_proxy.h"
47 #include "cc/trees/thread_proxy.h"
48 #include "cc/trees/tree_synchronizer.h"
49 #include "ui/gfx/geometry/size_conversions.h"
50 #include "ui/gfx/geometry/vector2d_conversions.h"
52 namespace {
53 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
56 namespace cc {
58 LayerTreeHost::InitParams::InitParams() {
61 LayerTreeHost::InitParams::~InitParams() {
64 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
65 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
66 InitParams* params) {
67 DCHECK(params->main_task_runner.get());
68 DCHECK(impl_task_runner.get());
69 DCHECK(params->settings);
70 scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(params));
71 layer_tree_host->InitializeThreaded(
72 params->main_task_runner, impl_task_runner,
73 params->external_begin_frame_source.Pass());
74 return layer_tree_host.Pass();
77 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
78 LayerTreeHostSingleThreadClient* single_thread_client,
79 InitParams* params) {
80 DCHECK(params->settings);
81 scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(params));
82 layer_tree_host->InitializeSingleThreaded(
83 single_thread_client, params->main_task_runner,
84 params->external_begin_frame_source.Pass());
85 return layer_tree_host.Pass();
88 LayerTreeHost::LayerTreeHost(InitParams* params)
89 : micro_benchmark_controller_(this),
90 next_ui_resource_id_(1),
91 inside_begin_main_frame_(false),
92 needs_full_tree_sync_(true),
93 needs_meta_info_recomputation_(true),
94 client_(params->client),
95 source_frame_number_(0),
96 meta_information_sequence_number_(1),
97 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
98 output_surface_lost_(true),
99 settings_(*params->settings),
100 debug_state_(settings_.initial_debug_state),
101 top_controls_shrink_blink_size_(false),
102 top_controls_height_(0.f),
103 top_controls_shown_ratio_(0.f),
104 hide_pinch_scrollbars_near_min_scale_(false),
105 device_scale_factor_(1.f),
106 visible_(true),
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 did_complete_scale_animation_(false),
116 in_paint_layer_contents_(false),
117 id_(s_layer_tree_host_sequence_number.GetNext() + 1),
118 next_commit_forces_redraw_(false),
119 shared_bitmap_manager_(params->shared_bitmap_manager),
120 gpu_memory_buffer_manager_(params->gpu_memory_buffer_manager),
121 task_graph_runner_(params->task_graph_runner),
122 surface_id_namespace_(0u),
123 next_surface_sequence_(1u) {
124 DCHECK(task_graph_runner_);
126 if (settings_.accelerated_animation_enabled) {
127 if (settings_.use_compositor_animation_timelines) {
128 animation_host_ = AnimationHost::Create(ThreadInstance::MAIN);
129 animation_host_->SetMutatorHostClient(this);
130 } else {
131 animation_registrar_ = AnimationRegistrar::Create();
135 rendering_stats_instrumentation_->set_record_rendering_stats(
136 debug_state_.RecordRenderingStats());
139 void LayerTreeHost::InitializeThreaded(
140 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
141 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
142 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
143 InitializeProxy(ThreadProxy::Create(this,
144 main_task_runner,
145 impl_task_runner,
146 external_begin_frame_source.Pass()));
149 void LayerTreeHost::InitializeSingleThreaded(
150 LayerTreeHostSingleThreadClient* single_thread_client,
151 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
152 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
153 InitializeProxy(
154 SingleThreadProxy::Create(this,
155 single_thread_client,
156 main_task_runner,
157 external_begin_frame_source.Pass()));
160 void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
161 InitializeProxy(proxy_for_testing.Pass());
164 void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
165 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
167 proxy_ = proxy.Pass();
168 proxy_->Start();
169 if (settings_.accelerated_animation_enabled) {
170 if (animation_host_)
171 animation_host_->SetSupportsScrollAnimations(
172 proxy_->SupportsImplScrolling());
173 else
174 animation_registrar_->set_supports_scroll_animations(
175 proxy_->SupportsImplScrolling());
179 LayerTreeHost::~LayerTreeHost() {
180 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
182 if (animation_host_)
183 animation_host_->SetMutatorHostClient(nullptr);
185 if (root_layer_.get())
186 root_layer_->SetLayerTreeHost(NULL);
188 DCHECK(swap_promise_monitor_.empty());
190 BreakSwapPromises(SwapPromise::COMMIT_FAILS);
192 if (proxy_) {
193 DCHECK(proxy_->IsMainThread());
194 proxy_->Stop();
197 // We must clear any pointers into the layer tree prior to destroying it.
198 RegisterViewportLayers(NULL, NULL, NULL, NULL);
200 if (root_layer_.get()) {
201 // The layer tree must be destroyed before the layer tree host. We've
202 // made a contract with our animation controllers that the registrar
203 // will outlive them, and we must make good.
204 root_layer_ = NULL;
208 void LayerTreeHost::SetLayerTreeHostClientReady() {
209 proxy_->SetLayerTreeHostClientReady();
212 void LayerTreeHost::WillBeginMainFrame() {
213 devtools_instrumentation::WillBeginMainThreadFrame(id(),
214 source_frame_number());
215 client_->WillBeginMainFrame();
218 void LayerTreeHost::DidBeginMainFrame() {
219 client_->DidBeginMainFrame();
222 void LayerTreeHost::BeginMainFrameNotExpectedSoon() {
223 client_->BeginMainFrameNotExpectedSoon();
226 void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) {
227 inside_begin_main_frame_ = true;
228 client_->BeginMainFrame(args);
229 inside_begin_main_frame_ = false;
232 void LayerTreeHost::DidStopFlinging() {
233 proxy_->MainThreadHasStoppedFlinging();
236 void LayerTreeHost::Layout() {
237 client_->Layout();
240 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
241 DCHECK(proxy_->IsImplThread());
242 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
245 // This function commits the LayerTreeHost to an impl tree. When modifying
246 // this function, keep in mind that the function *runs* on the impl thread! Any
247 // code that is logically a main thread operation, e.g. deletion of a Layer,
248 // should be delayed until the LayerTreeHost::CommitComplete, which will run
249 // after the commit, but on the main thread.
250 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
251 DCHECK(proxy_->IsImplThread());
253 bool is_new_trace;
254 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
255 if (is_new_trace &&
256 frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
257 root_layer()) {
258 LayerTreeHostCommon::CallFunctionForSubtree(
259 root_layer(), [](Layer* layer) { layer->DidBeginTracing(); });
262 LayerTreeImpl* sync_tree = host_impl->sync_tree();
264 if (next_commit_forces_redraw_) {
265 sync_tree->ForceRedrawNextActivation();
266 next_commit_forces_redraw_ = false;
269 sync_tree->set_source_frame_number(source_frame_number());
271 if (needs_full_tree_sync_) {
272 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
273 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
275 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
276 needs_full_tree_sync_ = false;
278 if (hud_layer_.get()) {
279 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
280 sync_tree->root_layer(), hud_layer_->id());
281 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
282 } else {
283 sync_tree->set_hud_layer(NULL);
286 sync_tree->set_background_color(background_color_);
287 sync_tree->set_has_transparent_background(has_transparent_background_);
289 if (page_scale_layer_.get() && inner_viewport_scroll_layer_.get()) {
290 sync_tree->SetViewportLayersFromIds(
291 overscroll_elasticity_layer_.get() ? overscroll_elasticity_layer_->id()
292 : Layer::INVALID_ID,
293 page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
294 outer_viewport_scroll_layer_.get() ? outer_viewport_scroll_layer_->id()
295 : Layer::INVALID_ID);
296 DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers());
297 } else {
298 sync_tree->ClearViewportLayers();
301 sync_tree->RegisterSelection(selection_);
303 // Setting property trees must happen before pushing the page scale.
304 sync_tree->SetPropertyTrees(property_trees_);
306 sync_tree->set_hide_pinch_scrollbars_near_min_scale(
307 hide_pinch_scrollbars_near_min_scale_);
309 sync_tree->PushPageScaleFromMainThread(
310 page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
311 sync_tree->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
312 if (sync_tree->IsActiveTree())
313 sync_tree->elastic_overscroll()->PushPendingToActive();
315 sync_tree->PassSwapPromises(&swap_promise_list_);
317 sync_tree->set_top_controls_shrink_blink_size(
318 top_controls_shrink_blink_size_);
319 sync_tree->set_top_controls_height(top_controls_height_);
320 sync_tree->PushTopControlsFromMainThread(top_controls_shown_ratio_);
322 host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_);
323 host_impl->SetContentIsSuitableForGpuRasterization(
324 content_is_suitable_for_gpu_rasterization_);
325 RecordGpuRasterizationHistogram();
327 host_impl->SetViewportSize(device_viewport_size_);
328 host_impl->SetDeviceScaleFactor(device_scale_factor_);
329 host_impl->SetDebugState(debug_state_);
330 if (pending_page_scale_animation_) {
331 sync_tree->SetPendingPageScaleAnimation(
332 pending_page_scale_animation_.Pass());
335 if (!ui_resource_request_queue_.empty()) {
336 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
337 ui_resource_request_queue_.clear();
340 DCHECK(!sync_tree->ViewportSizeInvalid());
342 sync_tree->set_has_ever_been_drawn(false);
345 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
346 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
348 if (animation_host_) {
349 DCHECK(host_impl->animation_host());
350 animation_host_->PushPropertiesTo(host_impl->animation_host());
354 // This must happen after synchronizing property trees and after push
355 // properties, which updates property tree indices.
356 sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread();
358 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
361 void LayerTreeHost::WillCommit() {
362 OnCommitForSwapPromises();
363 client_->WillCommit();
366 void LayerTreeHost::UpdateHudLayer() {
367 if (debug_state_.ShowHudInfo()) {
368 if (!hud_layer_.get()) {
369 LayerSettings hud_layer_settings;
370 hud_layer_settings.use_compositor_animation_timelines =
371 settings_.use_compositor_animation_timelines;
372 hud_layer_ = HeadsUpDisplayLayer::Create(hud_layer_settings);
375 if (root_layer_.get() && !hud_layer_->parent())
376 root_layer_->AddChild(hud_layer_);
377 } else if (hud_layer_.get()) {
378 hud_layer_->RemoveFromParent();
379 hud_layer_ = NULL;
383 void LayerTreeHost::CommitComplete() {
384 source_frame_number_++;
385 client_->DidCommit();
386 if (did_complete_scale_animation_) {
387 client_->DidCompletePageScaleAnimation();
388 did_complete_scale_animation_ = false;
392 void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) {
393 TRACE_EVENT0("cc", "LayerTreeHost::SetOutputSurface");
394 DCHECK(output_surface_lost_);
395 DCHECK(surface);
397 proxy_->SetOutputSurface(surface.Pass());
400 void LayerTreeHost::RequestNewOutputSurface() {
401 client_->RequestNewOutputSurface();
404 void LayerTreeHost::DidInitializeOutputSurface() {
405 output_surface_lost_ = false;
406 if (root_layer()) {
407 LayerTreeHostCommon::CallFunctionForSubtree(
408 root_layer(), [](Layer* layer) { layer->OnOutputSurfaceCreated(); });
410 client_->DidInitializeOutputSurface();
413 void LayerTreeHost::DidFailToInitializeOutputSurface() {
414 DCHECK(output_surface_lost_);
415 client_->DidFailToInitializeOutputSurface();
418 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
419 LayerTreeHostImplClient* client) {
420 DCHECK(proxy_->IsImplThread());
421 scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
422 settings_, client, proxy_.get(), rendering_stats_instrumentation_.get(),
423 shared_bitmap_manager_, gpu_memory_buffer_manager_, task_graph_runner_,
424 id_);
425 host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_);
426 host_impl->SetContentIsSuitableForGpuRasterization(
427 content_is_suitable_for_gpu_rasterization_);
428 shared_bitmap_manager_ = NULL;
429 gpu_memory_buffer_manager_ = NULL;
430 task_graph_runner_ = NULL;
431 top_controls_manager_weak_ptr_ =
432 host_impl->top_controls_manager()->AsWeakPtr();
433 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
434 return host_impl.Pass();
437 void LayerTreeHost::DidLoseOutputSurface() {
438 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
439 DCHECK(proxy_->IsMainThread());
441 if (output_surface_lost_)
442 return;
444 output_surface_lost_ = true;
445 SetNeedsCommit();
448 void LayerTreeHost::FinishAllRendering() {
449 proxy_->FinishAllRendering();
452 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
453 proxy_->SetDeferCommits(defer_commits);
456 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
457 std::stack<Layer*> layer_stack;
458 layer_stack.push(root_layer());
459 while (!layer_stack.empty()) {
460 Layer* current_layer = layer_stack.top();
461 layer_stack.pop();
462 current_layer->SetNeedsDisplay();
463 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
464 layer_stack.push(current_layer->child_at(i));
469 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
470 return proxy_->GetRendererCapabilities();
473 void LayerTreeHost::SetNeedsAnimate() {
474 proxy_->SetNeedsAnimate();
475 NotifySwapPromiseMonitorsOfSetNeedsCommit();
478 void LayerTreeHost::SetNeedsUpdateLayers() {
479 proxy_->SetNeedsUpdateLayers();
480 NotifySwapPromiseMonitorsOfSetNeedsCommit();
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;
493 SetNeedsCommit();
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;
525 void LayerTreeHost::SetAnimationEvents(
526 scoped_ptr<AnimationEventsVector> events) {
527 DCHECK(proxy_->IsMainThread());
528 if (animation_host_)
529 animation_host_->SetAnimationEvents(events.Pass());
530 else
531 animation_registrar_->SetAnimationEvents(events.Pass());
534 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
535 if (root_layer_.get() == root_layer.get())
536 return;
538 if (root_layer_.get())
539 root_layer_->SetLayerTreeHost(NULL);
540 root_layer_ = root_layer;
541 if (root_layer_.get()) {
542 DCHECK(!root_layer_->parent());
543 root_layer_->SetLayerTreeHost(this);
546 if (hud_layer_.get())
547 hud_layer_->RemoveFromParent();
549 // Reset gpu rasterization flag.
550 // This flag is sticky until a new tree comes along.
551 content_is_suitable_for_gpu_rasterization_ = true;
552 gpu_rasterization_histogram_recorded_ = false;
554 SetNeedsFullTreeSync();
557 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
558 LayerTreeDebugState new_debug_state =
559 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
561 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
562 return;
564 debug_state_ = new_debug_state;
566 rendering_stats_instrumentation_->set_record_rendering_stats(
567 debug_state_.RecordRenderingStats());
569 SetNeedsCommit();
570 proxy_->SetDebugState(debug_state);
573 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
574 if (has_trigger == has_gpu_rasterization_trigger_)
575 return;
577 has_gpu_rasterization_trigger_ = has_trigger;
578 TRACE_EVENT_INSTANT1("cc",
579 "LayerTreeHost::SetHasGpuRasterizationTrigger",
580 TRACE_EVENT_SCOPE_THREAD,
581 "has_trigger",
582 has_gpu_rasterization_trigger_);
585 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
586 if (device_viewport_size == device_viewport_size_)
587 return;
589 device_viewport_size_ = device_viewport_size;
591 property_trees_.needs_rebuild = true;
592 SetNeedsCommit();
595 void LayerTreeHost::SetTopControlsHeight(float height, bool shrink) {
596 if (top_controls_height_ == height &&
597 top_controls_shrink_blink_size_ == shrink)
598 return;
600 top_controls_height_ = height;
601 top_controls_shrink_blink_size_ = shrink;
602 SetNeedsCommit();
605 void LayerTreeHost::SetTopControlsShownRatio(float ratio) {
606 if (top_controls_shown_ratio_ == ratio)
607 return;
609 top_controls_shown_ratio_ = ratio;
610 SetNeedsCommit();
613 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
614 DCHECK(CommitRequested());
615 if (page_scale_delta == 1.f)
616 return;
617 page_scale_factor_ *= page_scale_delta;
618 property_trees_.needs_rebuild = true;
621 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
622 float min_page_scale_factor,
623 float max_page_scale_factor) {
624 if (page_scale_factor == page_scale_factor_ &&
625 min_page_scale_factor == min_page_scale_factor_ &&
626 max_page_scale_factor == max_page_scale_factor_)
627 return;
629 page_scale_factor_ = page_scale_factor;
630 min_page_scale_factor_ = min_page_scale_factor;
631 max_page_scale_factor_ = max_page_scale_factor;
632 property_trees_.needs_rebuild = true;
633 SetNeedsCommit();
636 void LayerTreeHost::SetVisible(bool visible) {
637 if (visible_ == visible)
638 return;
639 visible_ = visible;
640 if (!visible)
641 ReduceMemoryUsage();
642 proxy_->SetVisible(visible);
645 void LayerTreeHost::SetThrottleFrameProduction(bool throttle) {
646 proxy_->SetThrottleFrameProduction(throttle);
649 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
650 bool use_anchor,
651 float scale,
652 base::TimeDelta duration) {
653 pending_page_scale_animation_.reset(
654 new PendingPageScaleAnimation(
655 target_offset,
656 use_anchor,
657 scale,
658 duration));
660 SetNeedsCommit();
663 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
664 proxy_->NotifyInputThrottledUntilCommit();
667 void LayerTreeHost::LayoutAndUpdateLayers() {
668 DCHECK(!proxy_->HasImplThread());
669 // This function is only valid when not using the scheduler.
670 DCHECK(!settings_.single_thread_proxy_scheduler);
671 SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
673 SetLayerTreeHostClientReady();
674 proxy->LayoutAndUpdateLayers();
677 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
678 DCHECK(!proxy_->HasImplThread());
679 // This function is only valid when not using the scheduler.
680 DCHECK(!settings_.single_thread_proxy_scheduler);
681 SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
683 SetLayerTreeHostClientReady();
684 proxy->CompositeImmediately(frame_begin_time);
687 bool LayerTreeHost::UpdateLayers() {
688 DCHECK(!output_surface_lost_);
689 if (!root_layer())
690 return false;
691 DCHECK(!root_layer()->parent());
692 bool result = DoUpdateLayers(root_layer());
693 micro_benchmark_controller_.DidUpdateLayers();
694 return result || next_commit_forces_redraw_;
697 void LayerTreeHost::DidCompletePageScaleAnimation() {
698 did_complete_scale_animation_ = true;
701 static Layer* FindFirstScrollableLayer(Layer* layer) {
702 if (!layer)
703 return NULL;
705 if (layer->scrollable())
706 return layer;
708 for (size_t i = 0; i < layer->children().size(); ++i) {
709 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
710 if (found)
711 return found;
714 return NULL;
717 void LayerTreeHost::RecordGpuRasterizationHistogram() {
718 // Gpu rasterization is only supported for Renderer compositors.
719 // Checking for proxy_->HasImplThread() to exclude Browser compositors.
720 if (gpu_rasterization_histogram_recorded_ || !proxy_->HasImplThread())
721 return;
723 // Record how widely gpu rasterization is enabled.
724 // This number takes device/gpu whitelisting/backlisting into account.
725 // Note that we do not consider the forced gpu rasterization mode, which is
726 // mostly used for debugging purposes.
727 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
728 settings_.gpu_rasterization_enabled);
729 if (settings_.gpu_rasterization_enabled) {
730 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
731 has_gpu_rasterization_trigger_);
732 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
733 content_is_suitable_for_gpu_rasterization_);
734 // Record how many pages actually get gpu rasterization when enabled.
735 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
736 (has_gpu_rasterization_trigger_ &&
737 content_is_suitable_for_gpu_rasterization_));
740 gpu_rasterization_histogram_recorded_ = true;
743 bool LayerTreeHost::UsingSharedMemoryResources() {
744 return GetRendererCapabilities().using_shared_memory_resources;
747 bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
748 TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number",
749 source_frame_number());
751 UpdateHudLayer();
753 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
754 Layer* page_scale_layer = page_scale_layer_.get();
755 if (!page_scale_layer && root_scroll)
756 page_scale_layer = root_scroll->parent();
758 if (hud_layer_.get()) {
759 hud_layer_->PrepareForCalculateDrawProperties(device_viewport_size(),
760 device_scale_factor_);
763 bool can_render_to_separate_surface = true;
765 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
767 LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
769 bool preserves_2d_axis_alignment = false;
770 gfx::Transform identity_transform;
771 LayerList update_layer_list;
773 LayerTreeHostCommon::UpdateRenderSurfaces(
774 root_layer, can_render_to_separate_surface, identity_transform,
775 preserves_2d_axis_alignment);
777 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
778 "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
779 BuildPropertyTreesAndComputeVisibleRects(
780 root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(),
781 outer_viewport_scroll_layer_.get(), page_scale_factor_,
782 device_scale_factor_, gfx::Rect(device_viewport_size_),
783 identity_transform, &property_trees_, &update_layer_list);
786 for (const auto& layer : update_layer_list)
787 layer->SavePaintProperties();
789 base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
790 bool did_paint_content = false;
791 for (const auto& layer : update_layer_list) {
792 // TODO(enne): temporarily clobber draw properties visible rect.
793 layer->draw_properties().visible_layer_rect =
794 layer->visible_rect_from_property_trees();
795 did_paint_content |= layer->Update();
796 content_is_suitable_for_gpu_rasterization_ &=
797 layer->IsSuitableForGpuRasterization();
799 return did_paint_content;
802 void LayerTreeHost::ReduceMemoryUsage() {
803 if (!root_layer())
804 return;
806 LayerTreeHostCommon::CallFunctionForSubtree(
807 root_layer(), [](Layer* layer) { layer->ReduceMemoryUsage(); });
810 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
811 ScopedPtrVector<SwapPromise>::iterator it = info->swap_promises.begin();
812 for (; it != info->swap_promises.end(); ++it) {
813 scoped_ptr<SwapPromise> swap_promise(info->swap_promises.take(it));
814 TRACE_EVENT_FLOW_STEP0("input",
815 "LatencyInfo.Flow",
816 TRACE_ID_DONT_MANGLE(swap_promise->TraceId()),
817 "Main thread scroll update");
818 QueueSwapPromise(swap_promise.Pass());
821 gfx::Vector2dF inner_viewport_scroll_delta;
822 gfx::Vector2dF outer_viewport_scroll_delta;
824 if (root_layer_.get()) {
825 for (size_t i = 0; i < info->scrolls.size(); ++i) {
826 Layer* layer = LayerTreeHostCommon::FindLayerInSubtree(
827 root_layer_.get(), info->scrolls[i].layer_id);
828 if (!layer)
829 continue;
830 if (layer == outer_viewport_scroll_layer_.get()) {
831 outer_viewport_scroll_delta += info->scrolls[i].scroll_delta;
832 } else if (layer == inner_viewport_scroll_layer_.get()) {
833 inner_viewport_scroll_delta += info->scrolls[i].scroll_delta;
834 } else {
835 layer->SetScrollOffsetFromImplSide(
836 gfx::ScrollOffsetWithDelta(layer->scroll_offset(),
837 info->scrolls[i].scroll_delta));
842 if (!inner_viewport_scroll_delta.IsZero() ||
843 !outer_viewport_scroll_delta.IsZero() || info->page_scale_delta != 1.f ||
844 !info->elastic_overscroll_delta.IsZero() || info->top_controls_delta) {
845 // Preemptively apply the scroll offset and scale delta here before sending
846 // it to the client. If the client comes back and sets it to the same
847 // value, then the layer can early out without needing a full commit.
848 if (inner_viewport_scroll_layer_.get()) {
849 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
850 gfx::ScrollOffsetWithDelta(
851 inner_viewport_scroll_layer_->scroll_offset(),
852 inner_viewport_scroll_delta));
855 if (outer_viewport_scroll_layer_.get()) {
856 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
857 gfx::ScrollOffsetWithDelta(
858 outer_viewport_scroll_layer_->scroll_offset(),
859 outer_viewport_scroll_delta));
862 ApplyPageScaleDeltaFromImplSide(info->page_scale_delta);
863 elastic_overscroll_ += info->elastic_overscroll_delta;
864 // TODO(ccameron): pass the elastic overscroll here so that input events
865 // may be translated appropriately.
866 client_->ApplyViewportDeltas(
867 inner_viewport_scroll_delta, outer_viewport_scroll_delta,
868 info->elastic_overscroll_delta, info->page_scale_delta,
869 info->top_controls_delta);
873 void LayerTreeHost::StartRateLimiter() {
874 if (inside_begin_main_frame_)
875 return;
877 if (!rate_limit_timer_.IsRunning()) {
878 rate_limit_timer_.Start(FROM_HERE,
879 base::TimeDelta(),
880 this,
881 &LayerTreeHost::RateLimit);
885 void LayerTreeHost::StopRateLimiter() {
886 rate_limit_timer_.Stop();
889 void LayerTreeHost::RateLimit() {
890 // Force a no-op command on the compositor context, so that any ratelimiting
891 // commands will wait for the compositing context, and therefore for the
892 // SwapBuffers.
893 proxy_->ForceSerializeOnSwapBuffers();
894 client_->RateLimitSharedMainThreadContext();
897 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
898 if (device_scale_factor == device_scale_factor_)
899 return;
900 device_scale_factor_ = device_scale_factor;
902 property_trees_.needs_rebuild = true;
903 SetNeedsCommit();
906 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
907 TopControlsState current,
908 bool animate) {
909 // Top controls are only used in threaded mode.
910 proxy_->ImplThreadTaskRunner()->PostTask(
911 FROM_HERE,
912 base::Bind(&TopControlsManager::UpdateTopControlsState,
913 top_controls_manager_weak_ptr_,
914 constraints,
915 current,
916 animate));
919 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
920 if (!settings_.accelerated_animation_enabled)
921 return;
923 AnimationEventsVector events;
924 if (animation_host_) {
925 if (animation_host_->AnimateLayers(monotonic_time))
926 animation_host_->UpdateAnimationState(true, &events);
927 } else {
928 if (animation_registrar_->AnimateLayers(monotonic_time))
929 animation_registrar_->UpdateAnimationState(true, &events);
932 if (!events.empty())
933 property_trees_.needs_rebuild = true;
936 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
937 DCHECK(client);
939 UIResourceId next_id = next_ui_resource_id_++;
940 DCHECK(ui_resource_client_map_.find(next_id) ==
941 ui_resource_client_map_.end());
943 bool resource_lost = false;
944 UIResourceRequest request(UIResourceRequest::UI_RESOURCE_CREATE, next_id,
945 client->GetBitmap(next_id, resource_lost));
946 ui_resource_request_queue_.push_back(request);
948 UIResourceClientData data;
949 data.client = client;
950 data.size = request.GetBitmap().GetSize();
952 ui_resource_client_map_[request.GetId()] = data;
953 return request.GetId();
956 // Deletes a UI resource. May safely be called more than once.
957 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
958 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
959 if (iter == ui_resource_client_map_.end())
960 return;
962 UIResourceRequest request(UIResourceRequest::UI_RESOURCE_DELETE, uid);
963 ui_resource_request_queue_.push_back(request);
964 ui_resource_client_map_.erase(iter);
967 void LayerTreeHost::RecreateUIResources() {
968 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
969 iter != ui_resource_client_map_.end();
970 ++iter) {
971 UIResourceId uid = iter->first;
972 const UIResourceClientData& data = iter->second;
973 bool resource_lost = true;
974 UIResourceRequest request(UIResourceRequest::UI_RESOURCE_CREATE, uid,
975 data.client->GetBitmap(uid, resource_lost));
976 ui_resource_request_queue_.push_back(request);
980 // Returns the size of a resource given its id.
981 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
982 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
983 if (iter == ui_resource_client_map_.end())
984 return gfx::Size();
986 const UIResourceClientData& data = iter->second;
987 return data.size;
990 void LayerTreeHost::RegisterViewportLayers(
991 scoped_refptr<Layer> overscroll_elasticity_layer,
992 scoped_refptr<Layer> page_scale_layer,
993 scoped_refptr<Layer> inner_viewport_scroll_layer,
994 scoped_refptr<Layer> outer_viewport_scroll_layer) {
995 overscroll_elasticity_layer_ = overscroll_elasticity_layer;
996 page_scale_layer_ = page_scale_layer;
997 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
998 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1001 void LayerTreeHost::RegisterSelection(const LayerSelection& selection) {
1002 if (selection_ == selection)
1003 return;
1005 selection_ = selection;
1006 SetNeedsCommit();
1009 int LayerTreeHost::ScheduleMicroBenchmark(
1010 const std::string& benchmark_name,
1011 scoped_ptr<base::Value> value,
1012 const MicroBenchmark::DoneCallback& callback) {
1013 return micro_benchmark_controller_.ScheduleRun(
1014 benchmark_name, value.Pass(), callback);
1017 bool LayerTreeHost::SendMessageToMicroBenchmark(int id,
1018 scoped_ptr<base::Value> value) {
1019 return micro_benchmark_controller_.SendMessage(id, value.Pass());
1022 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1023 swap_promise_monitor_.insert(monitor);
1026 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1027 swap_promise_monitor_.erase(monitor);
1030 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1031 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1032 for (; it != swap_promise_monitor_.end(); it++)
1033 (*it)->OnSetNeedsCommitOnMain();
1036 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1037 DCHECK(swap_promise);
1038 swap_promise_list_.push_back(swap_promise.Pass());
1041 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1042 for (auto* swap_promise : swap_promise_list_)
1043 swap_promise->DidNotSwap(reason);
1044 swap_promise_list_.clear();
1047 void LayerTreeHost::OnCommitForSwapPromises() {
1048 for (auto* swap_promise : swap_promise_list_)
1049 swap_promise->OnCommit();
1052 void LayerTreeHost::set_surface_id_namespace(uint32_t id_namespace) {
1053 surface_id_namespace_ = id_namespace;
1056 SurfaceSequence LayerTreeHost::CreateSurfaceSequence() {
1057 return SurfaceSequence(surface_id_namespace_, next_surface_sequence_++);
1060 void LayerTreeHost::SetChildrenNeedBeginFrames(
1061 bool children_need_begin_frames) const {
1062 proxy_->SetChildrenNeedBeginFrames(children_need_begin_frames);
1065 void LayerTreeHost::SendBeginFramesToChildren(
1066 const BeginFrameArgs& args) const {
1067 client_->SendBeginFramesToChildren(args);
1070 void LayerTreeHost::SetAuthoritativeVSyncInterval(
1071 const base::TimeDelta& interval) {
1072 proxy_->SetAuthoritativeVSyncInterval(interval);
1075 void LayerTreeHost::RecordFrameTimingEvents(
1076 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
1077 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
1078 client_->RecordFrameTimingEvents(composite_events.Pass(),
1079 main_frame_events.Pass());
1082 Layer* LayerTreeHost::LayerById(int id) const {
1083 LayerIdMap::const_iterator iter = layer_id_map_.find(id);
1084 return iter != layer_id_map_.end() ? iter->second : NULL;
1087 void LayerTreeHost::RegisterLayer(Layer* layer) {
1088 DCHECK(!LayerById(layer->id()));
1089 DCHECK(!in_paint_layer_contents_);
1090 layer_id_map_[layer->id()] = layer;
1091 if (animation_host_)
1092 animation_host_->RegisterLayer(layer->id(), LayerTreeType::ACTIVE);
1095 void LayerTreeHost::UnregisterLayer(Layer* layer) {
1096 DCHECK(LayerById(layer->id()));
1097 DCHECK(!in_paint_layer_contents_);
1098 if (animation_host_)
1099 animation_host_->UnregisterLayer(layer->id(), LayerTreeType::ACTIVE);
1100 layer_id_map_.erase(layer->id());
1103 bool LayerTreeHost::IsLayerInTree(int layer_id, LayerTreeType tree_type) const {
1104 return tree_type == LayerTreeType::ACTIVE;
1107 void LayerTreeHost::SetMutatorsNeedCommit() {
1108 SetNeedsCommit();
1111 void LayerTreeHost::SetLayerFilterMutated(int layer_id,
1112 LayerTreeType tree_type,
1113 const FilterOperations& filters) {
1114 LayerAnimationValueObserver* layer = LayerById(layer_id);
1115 DCHECK(layer);
1116 layer->OnFilterAnimated(filters);
1119 void LayerTreeHost::SetLayerOpacityMutated(int layer_id,
1120 LayerTreeType tree_type,
1121 float opacity) {
1122 LayerAnimationValueObserver* layer = LayerById(layer_id);
1123 DCHECK(layer);
1124 layer->OnOpacityAnimated(opacity);
1127 void LayerTreeHost::SetLayerTransformMutated(int layer_id,
1128 LayerTreeType tree_type,
1129 const gfx::Transform& transform) {
1130 LayerAnimationValueObserver* layer = LayerById(layer_id);
1131 DCHECK(layer);
1132 layer->OnTransformAnimated(transform);
1135 void LayerTreeHost::SetLayerScrollOffsetMutated(
1136 int layer_id,
1137 LayerTreeType tree_type,
1138 const gfx::ScrollOffset& scroll_offset) {
1139 LayerAnimationValueObserver* layer = LayerById(layer_id);
1140 DCHECK(layer);
1141 layer->OnScrollOffsetAnimated(scroll_offset);
1144 void LayerTreeHost::LayerTransformIsPotentiallyAnimatingChanged(
1145 int layer_id,
1146 LayerTreeType tree_type,
1147 bool is_animating) {
1148 LayerAnimationValueObserver* layer = LayerById(layer_id);
1149 DCHECK(layer);
1150 layer->OnTransformIsPotentiallyAnimatingChanged(is_animating);
1153 gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
1154 int layer_id) const {
1155 LayerAnimationValueProvider* layer = LayerById(layer_id);
1156 DCHECK(layer);
1157 return layer->ScrollOffsetForAnimation();
1160 bool LayerTreeHost::ScrollOffsetAnimationWasInterrupted(
1161 const Layer* layer) const {
1162 return animation_host_
1163 ? animation_host_->ScrollOffsetAnimationWasInterrupted(layer->id())
1164 : false;
1167 bool LayerTreeHost::IsAnimatingFilterProperty(const Layer* layer) const {
1168 return animation_host_
1169 ? animation_host_->IsAnimatingFilterProperty(layer->id(),
1170 LayerTreeType::ACTIVE)
1171 : false;
1174 bool LayerTreeHost::IsAnimatingOpacityProperty(const Layer* layer) const {
1175 return animation_host_
1176 ? animation_host_->IsAnimatingOpacityProperty(
1177 layer->id(), LayerTreeType::ACTIVE)
1178 : false;
1181 bool LayerTreeHost::IsAnimatingTransformProperty(const Layer* layer) const {
1182 return animation_host_
1183 ? animation_host_->IsAnimatingTransformProperty(
1184 layer->id(), LayerTreeType::ACTIVE)
1185 : false;
1188 bool LayerTreeHost::HasPotentiallyRunningFilterAnimation(
1189 const Layer* layer) const {
1190 return animation_host_
1191 ? animation_host_->HasPotentiallyRunningFilterAnimation(
1192 layer->id(), LayerTreeType::ACTIVE)
1193 : false;
1196 bool LayerTreeHost::HasPotentiallyRunningOpacityAnimation(
1197 const Layer* layer) const {
1198 return animation_host_
1199 ? animation_host_->HasPotentiallyRunningOpacityAnimation(
1200 layer->id(), LayerTreeType::ACTIVE)
1201 : false;
1204 bool LayerTreeHost::HasPotentiallyRunningTransformAnimation(
1205 const Layer* layer) const {
1206 return animation_host_
1207 ? animation_host_->HasPotentiallyRunningTransformAnimation(
1208 layer->id(), LayerTreeType::ACTIVE)
1209 : false;
1212 bool LayerTreeHost::HasAnyAnimationTargetingProperty(
1213 const Layer* layer,
1214 Animation::TargetProperty property) const {
1215 return animation_host_
1216 ? animation_host_->HasAnyAnimationTargetingProperty(layer->id(),
1217 property)
1218 : false;
1221 bool LayerTreeHost::AnimationsPreserveAxisAlignment(const Layer* layer) const {
1222 return animation_host_
1223 ? animation_host_->AnimationsPreserveAxisAlignment(layer->id())
1224 : true;
1227 bool LayerTreeHost::HasAnyAnimation(const Layer* layer) const {
1228 return animation_host_ ? animation_host_->HasAnyAnimation(layer->id())
1229 : false;
1232 bool LayerTreeHost::HasActiveAnimation(const Layer* layer) const {
1233 return animation_host_ ? animation_host_->HasActiveAnimation(layer->id())
1234 : false;
1237 } // namespace cc