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