Use md5_check in proguard.py to detect when it's not really necessary
[chromium-blink-merge.git] / cc / trees / layer_tree_host.cc
blob3dfb248c4927c894032fdcd5a0517108c6d94f2a
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/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"
51 namespace {
52 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
55 namespace cc {
57 LayerTreeHost::InitParams::InitParams() {
60 LayerTreeHost::InitParams::~InitParams() {
63 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
64 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
65 InitParams* params) {
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,
78 InitParams* params) {
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),
105 visible_(true),
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);
129 } else {
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,
143 main_task_runner,
144 impl_task_runner,
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) {
152 InitializeProxy(
153 SingleThreadProxy::Create(this,
154 single_thread_client,
155 main_task_runner,
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();
167 proxy_->Start();
168 if (settings_.accelerated_animation_enabled) {
169 if (animation_host_)
170 animation_host_->SetSupportsScrollAnimations(
171 proxy_->SupportsImplScrolling());
172 else
173 animation_registrar_->set_supports_scroll_animations(
174 proxy_->SupportsImplScrolling());
178 LayerTreeHost::~LayerTreeHost() {
179 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
181 if (animation_host_)
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);
191 if (proxy_) {
192 DCHECK(proxy_->IsMainThread());
193 proxy_->Stop();
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.
203 root_layer_ = NULL;
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() {
236 client_->Layout();
239 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
240 DCHECK(proxy_->IsImplThread());
241 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
244 // This function commits the LayerTreeHost to an impl tree. When modifying
245 // this function, keep in mind that the function *runs* on the impl thread! Any
246 // code that is logically a main thread operation, e.g. deletion of a Layer,
247 // should be delayed until the LayerTreeHost::CommitComplete, which will run
248 // after the commit, but on the main thread.
249 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
250 DCHECK(proxy_->IsImplThread());
252 bool is_new_trace;
253 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
254 if (is_new_trace &&
255 frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
256 root_layer()) {
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));
281 } else {
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()
291 : Layer::INVALID_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());
296 } else {
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();
378 hud_layer_ = NULL;
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_);
394 DCHECK(surface);
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_,
419 id_);
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_)
437 return;
439 output_surface_lost_ = true;
440 SetNeedsCommit();
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();
456 layer_stack.pop();
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;
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;
523 proxy_->SetNeedsUpdateLayers();
526 void LayerTreeHost::SetAnimationEvents(
527 scoped_ptr<AnimationEventsVector> events) {
528 DCHECK(proxy_->IsMainThread());
529 if (animation_host_)
530 animation_host_->SetAnimationEvents(events.Pass());
531 else
532 animation_registrar_->SetAnimationEvents(events.Pass());
535 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
536 if (root_layer_.get() == root_layer.get())
537 return;
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))
563 return;
565 debug_state_ = new_debug_state;
567 rendering_stats_instrumentation_->set_record_rendering_stats(
568 debug_state_.RecordRenderingStats());
570 SetNeedsCommit();
571 proxy_->SetDebugState(debug_state);
574 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
575 if (has_trigger == has_gpu_rasterization_trigger_)
576 return;
578 has_gpu_rasterization_trigger_ = has_trigger;
579 TRACE_EVENT_INSTANT1("cc",
580 "LayerTreeHost::SetHasGpuRasterizationTrigger",
581 TRACE_EVENT_SCOPE_THREAD,
582 "has_trigger",
583 has_gpu_rasterization_trigger_);
586 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
587 if (device_viewport_size == device_viewport_size_)
588 return;
590 device_viewport_size_ = device_viewport_size;
592 SetPropertyTreesNeedRebuild();
593 SetNeedsCommit();
596 void LayerTreeHost::SetTopControlsHeight(float height, bool shrink) {
597 if (top_controls_height_ == height &&
598 top_controls_shrink_blink_size_ == shrink)
599 return;
601 top_controls_height_ = height;
602 top_controls_shrink_blink_size_ = shrink;
603 SetNeedsCommit();
606 void LayerTreeHost::SetTopControlsShownRatio(float ratio) {
607 if (top_controls_shown_ratio_ == ratio)
608 return;
610 top_controls_shown_ratio_ = ratio;
611 SetNeedsCommit();
614 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
615 DCHECK(CommitRequested());
616 if (page_scale_delta == 1.f)
617 return;
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_)
628 return;
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();
634 SetNeedsCommit();
637 void LayerTreeHost::SetVisible(bool visible) {
638 if (visible_ == visible)
639 return;
640 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,
649 bool use_anchor,
650 float scale,
651 base::TimeDelta duration) {
652 pending_page_scale_animation_.reset(
653 new PendingPageScaleAnimation(
654 target_offset,
655 use_anchor,
656 scale,
657 duration));
659 SetNeedsCommit();
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_);
688 if (!root_layer())
689 return false;
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) {
701 if (!layer)
702 return NULL;
704 if (layer->scrollable())
705 return layer;
707 for (size_t i = 0; i < layer->children().size(); ++i) {
708 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
709 if (found)
710 return found;
713 return NULL;
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())
720 return;
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());
750 UpdateHudLayer();
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",
803 "LatencyInfo.Flow",
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);
817 if (!layer)
818 continue;
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;
823 } else {
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_)
866 return;
868 if (!rate_limit_timer_.IsRunning()) {
869 rate_limit_timer_.Start(FROM_HERE,
870 base::TimeDelta(),
871 this,
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
883 // SwapBuffers.
884 proxy_->ForceSerializeOnSwapBuffers();
885 client_->RateLimitSharedMainThreadContext();
888 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
889 if (device_scale_factor == device_scale_factor_)
890 return;
891 device_scale_factor_ = device_scale_factor;
893 property_trees_.needs_rebuild = true;
894 SetNeedsCommit();
897 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
898 TopControlsState current,
899 bool animate) {
900 // Top controls are only used in threaded mode.
901 proxy_->ImplThreadTaskRunner()->PostTask(
902 FROM_HERE,
903 base::Bind(&TopControlsManager::UpdateTopControlsState,
904 top_controls_manager_weak_ptr_,
905 constraints,
906 current,
907 animate));
910 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
911 if (!settings_.accelerated_animation_enabled)
912 return;
914 AnimationEventsVector events;
915 if (animation_host_) {
916 if (animation_host_->AnimateLayers(monotonic_time))
917 animation_host_->UpdateAnimationState(true, &events);
918 } else {
919 if (animation_registrar_->AnimateLayers(monotonic_time))
920 animation_registrar_->UpdateAnimationState(true, &events);
923 if (!events.empty())
924 property_trees_.needs_rebuild = true;
927 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
928 DCHECK(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())
951 return;
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();
961 ++iter) {
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())
975 return gfx::Size();
977 const UIResourceClientData& data = iter->second;
978 return data.size;
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)
994 return;
996 selection_ = selection;
997 SetNeedsCommit();
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() {
1099 SetNeedsCommit();
1102 void LayerTreeHost::SetLayerFilterMutated(int layer_id,
1103 LayerTreeType tree_type,
1104 const FilterOperations& filters) {
1105 LayerAnimationValueObserver* layer = LayerById(layer_id);
1106 DCHECK(layer);
1107 layer->OnFilterAnimated(filters);
1110 void LayerTreeHost::SetLayerOpacityMutated(int layer_id,
1111 LayerTreeType tree_type,
1112 float opacity) {
1113 LayerAnimationValueObserver* layer = LayerById(layer_id);
1114 DCHECK(layer);
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);
1122 DCHECK(layer);
1123 layer->OnTransformAnimated(transform);
1126 void LayerTreeHost::SetLayerScrollOffsetMutated(
1127 int layer_id,
1128 LayerTreeType tree_type,
1129 const gfx::ScrollOffset& scroll_offset) {
1130 LayerAnimationValueObserver* layer = LayerById(layer_id);
1131 DCHECK(layer);
1132 layer->OnScrollOffsetAnimated(scroll_offset);
1135 void LayerTreeHost::LayerTransformIsPotentiallyAnimatingChanged(
1136 int layer_id,
1137 LayerTreeType tree_type,
1138 bool is_animating) {
1139 LayerAnimationValueObserver* layer = LayerById(layer_id);
1140 DCHECK(layer);
1141 layer->OnTransformIsPotentiallyAnimatingChanged(is_animating);
1144 gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
1145 int layer_id) const {
1146 LayerAnimationValueProvider* layer = LayerById(layer_id);
1147 DCHECK(layer);
1148 return layer->ScrollOffsetForAnimation();
1151 bool LayerTreeHost::ScrollOffsetAnimationWasInterrupted(
1152 const Layer* layer) const {
1153 return animation_host_
1154 ? animation_host_->ScrollOffsetAnimationWasInterrupted(layer->id())
1155 : false;
1158 bool LayerTreeHost::IsAnimatingFilterProperty(const Layer* layer) const {
1159 return animation_host_
1160 ? animation_host_->IsAnimatingFilterProperty(layer->id(),
1161 LayerTreeType::ACTIVE)
1162 : false;
1165 bool LayerTreeHost::IsAnimatingOpacityProperty(const Layer* layer) const {
1166 return animation_host_
1167 ? animation_host_->IsAnimatingOpacityProperty(
1168 layer->id(), LayerTreeType::ACTIVE)
1169 : false;
1172 bool LayerTreeHost::IsAnimatingTransformProperty(const Layer* layer) const {
1173 return animation_host_
1174 ? animation_host_->IsAnimatingTransformProperty(
1175 layer->id(), LayerTreeType::ACTIVE)
1176 : false;
1179 bool LayerTreeHost::HasPotentiallyRunningFilterAnimation(
1180 const Layer* layer) const {
1181 return animation_host_
1182 ? animation_host_->HasPotentiallyRunningFilterAnimation(
1183 layer->id(), LayerTreeType::ACTIVE)
1184 : false;
1187 bool LayerTreeHost::HasPotentiallyRunningOpacityAnimation(
1188 const Layer* layer) const {
1189 return animation_host_
1190 ? animation_host_->HasPotentiallyRunningOpacityAnimation(
1191 layer->id(), LayerTreeType::ACTIVE)
1192 : false;
1195 bool LayerTreeHost::HasPotentiallyRunningTransformAnimation(
1196 const Layer* layer) const {
1197 return animation_host_
1198 ? animation_host_->HasPotentiallyRunningTransformAnimation(
1199 layer->id(), LayerTreeType::ACTIVE)
1200 : false;
1203 bool LayerTreeHost::HasOnlyTranslationTransforms(const Layer* layer) const {
1204 return animation_host_
1205 ? animation_host_->HasOnlyTranslationTransforms(
1206 layer->id(), LayerTreeType::ACTIVE)
1207 : false;
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)
1215 : false;
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)
1223 : false;
1226 bool LayerTreeHost::HasAnyAnimationTargetingProperty(
1227 const Layer* layer,
1228 Animation::TargetProperty property) const {
1229 return animation_host_
1230 ? animation_host_->HasAnyAnimationTargetingProperty(layer->id(),
1231 property)
1232 : false;
1235 bool LayerTreeHost::AnimationsPreserveAxisAlignment(const Layer* layer) const {
1236 return animation_host_
1237 ? animation_host_->AnimationsPreserveAxisAlignment(layer->id())
1238 : true;
1241 bool LayerTreeHost::HasAnyAnimation(const Layer* layer) const {
1242 return animation_host_ ? animation_host_->HasAnyAnimation(layer->id())
1243 : false;
1246 bool LayerTreeHost::HasActiveAnimation(const Layer* layer) const {
1247 return animation_host_ ? animation_host_->HasActiveAnimation(layer->id())
1248 : false;
1251 } // namespace cc