Enable gaia services for enterprise autotests.
[chromium-blink-merge.git] / cc / trees / layer_tree_host.cc
blob78373c769b6058d8bf647b1e8f5579ff81e33225
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/debug/trace_event_argument.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h"
18 #include "base/stl_util.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "cc/animation/animation_registrar.h"
21 #include "cc/animation/layer_animation_controller.h"
22 #include "cc/base/math_util.h"
23 #include "cc/debug/devtools_instrumentation.h"
24 #include "cc/debug/rendering_stats_instrumentation.h"
25 #include "cc/input/layer_selection_bound.h"
26 #include "cc/input/top_controls_manager.h"
27 #include "cc/layers/heads_up_display_layer.h"
28 #include "cc/layers/heads_up_display_layer_impl.h"
29 #include "cc/layers/layer.h"
30 #include "cc/layers/layer_iterator.h"
31 #include "cc/layers/painted_scrollbar_layer.h"
32 #include "cc/layers/render_surface.h"
33 #include "cc/resources/prioritized_resource_manager.h"
34 #include "cc/resources/ui_resource_request.h"
35 #include "cc/trees/layer_tree_host_client.h"
36 #include "cc/trees/layer_tree_host_common.h"
37 #include "cc/trees/layer_tree_host_impl.h"
38 #include "cc/trees/layer_tree_impl.h"
39 #include "cc/trees/occlusion_tracker.h"
40 #include "cc/trees/single_thread_proxy.h"
41 #include "cc/trees/thread_proxy.h"
42 #include "cc/trees/tree_synchronizer.h"
43 #include "ui/gfx/size_conversions.h"
45 namespace {
46 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
49 namespace cc {
51 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
52 bool allow_partial_texture_updates,
53 int max_texture_size,
54 bool using_shared_memory_resources)
55 : best_texture_format(best_texture_format),
56 allow_partial_texture_updates(allow_partial_texture_updates),
57 max_texture_size(max_texture_size),
58 using_shared_memory_resources(using_shared_memory_resources) {}
60 RendererCapabilities::RendererCapabilities()
61 : best_texture_format(RGBA_8888),
62 allow_partial_texture_updates(false),
63 max_texture_size(0),
64 using_shared_memory_resources(false) {}
66 RendererCapabilities::~RendererCapabilities() {}
68 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
69 LayerTreeHostClient* client,
70 SharedBitmapManager* manager,
71 const LayerTreeSettings& settings,
72 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
73 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
74 DCHECK(main_task_runner.get());
75 DCHECK(impl_task_runner.get());
76 scoped_ptr<LayerTreeHost> layer_tree_host(
77 new LayerTreeHost(client, manager, settings));
78 layer_tree_host->InitializeThreaded(main_task_runner, impl_task_runner);
79 return layer_tree_host.Pass();
82 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
83 LayerTreeHostClient* client,
84 LayerTreeHostSingleThreadClient* single_thread_client,
85 SharedBitmapManager* manager,
86 const LayerTreeSettings& settings,
87 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
88 scoped_ptr<LayerTreeHost> layer_tree_host(
89 new LayerTreeHost(client, manager, settings));
90 layer_tree_host->InitializeSingleThreaded(single_thread_client,
91 main_task_runner);
92 return layer_tree_host.Pass();
95 LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
96 SharedBitmapManager* manager,
97 const LayerTreeSettings& settings)
98 : micro_benchmark_controller_(this),
99 next_ui_resource_id_(1),
100 inside_begin_main_frame_(false),
101 needs_full_tree_sync_(true),
102 client_(client),
103 source_frame_number_(0),
104 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
105 output_surface_lost_(true),
106 num_failed_recreate_attempts_(0),
107 settings_(settings),
108 debug_state_(settings.initial_debug_state),
109 top_controls_layout_height_(0.f),
110 top_controls_content_offset_(0.f),
111 device_scale_factor_(1.f),
112 visible_(true),
113 page_scale_factor_(1.f),
114 min_page_scale_factor_(1.f),
115 max_page_scale_factor_(1.f),
116 has_gpu_rasterization_trigger_(false),
117 content_is_suitable_for_gpu_rasterization_(true),
118 gpu_rasterization_histogram_recorded_(false),
119 background_color_(SK_ColorWHITE),
120 has_transparent_background_(false),
121 partial_texture_update_requests_(0),
122 in_paint_layer_contents_(false),
123 total_frames_used_for_lcd_text_metrics_(0),
124 id_(s_layer_tree_host_sequence_number.GetNext() + 1),
125 next_commit_forces_redraw_(false),
126 shared_bitmap_manager_(manager) {
127 if (settings_.accelerated_animation_enabled)
128 animation_registrar_ = AnimationRegistrar::Create();
129 rendering_stats_instrumentation_->set_record_rendering_stats(
130 debug_state_.RecordRenderingStats());
133 void LayerTreeHost::InitializeThreaded(
134 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
135 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
136 InitializeProxy(
137 ThreadProxy::Create(this, main_task_runner, impl_task_runner));
140 void LayerTreeHost::InitializeSingleThreaded(
141 LayerTreeHostSingleThreadClient* single_thread_client,
142 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
143 InitializeProxy(
144 SingleThreadProxy::Create(this, single_thread_client, main_task_runner));
147 void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
148 InitializeProxy(proxy_for_testing.Pass());
151 void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
152 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
154 proxy_ = proxy.Pass();
155 proxy_->Start();
156 if (settings_.accelerated_animation_enabled) {
157 animation_registrar_->set_supports_scroll_animations(
158 proxy_->SupportsImplScrolling());
162 LayerTreeHost::~LayerTreeHost() {
163 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
165 DCHECK(swap_promise_monitor_.empty());
167 BreakSwapPromises(SwapPromise::COMMIT_FAILS);
169 overhang_ui_resource_.reset();
171 if (root_layer_.get())
172 root_layer_->SetLayerTreeHost(NULL);
174 if (proxy_) {
175 DCHECK(proxy_->IsMainThread());
176 proxy_->Stop();
179 // We must clear any pointers into the layer tree prior to destroying it.
180 RegisterViewportLayers(NULL, NULL, NULL);
182 if (root_layer_.get()) {
183 // The layer tree must be destroyed before the layer tree host. We've
184 // made a contract with our animation controllers that the registrar
185 // will outlive them, and we must make good.
186 root_layer_ = NULL;
190 void LayerTreeHost::SetLayerTreeHostClientReady() {
191 proxy_->SetLayerTreeHostClientReady();
194 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
195 layer->OnOutputSurfaceCreated();
198 void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
199 DCHECK(output_surface_lost_);
200 TRACE_EVENT1("cc",
201 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
202 "success",
203 success);
205 if (!success) {
206 // Tolerate a certain number of recreation failures to work around races
207 // in the output-surface-lost machinery.
208 ++num_failed_recreate_attempts_;
209 if (num_failed_recreate_attempts_ >= 5)
210 LOG(FATAL) << "Failed to create a fallback OutputSurface.";
211 client_->DidFailToInitializeOutputSurface();
212 return;
215 output_surface_lost_ = false;
217 if (!contents_texture_manager_ && !settings_.impl_side_painting) {
218 contents_texture_manager_ =
219 PrioritizedResourceManager::Create(proxy_.get());
220 surface_memory_placeholder_ =
221 contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
224 if (root_layer()) {
225 LayerTreeHostCommon::CallFunctionForSubtree(
226 root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
229 client_->DidInitializeOutputSurface();
232 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
233 ResourceProvider* resource_provider) {
234 DCHECK(proxy_->IsImplThread());
235 if (contents_texture_manager_)
236 contents_texture_manager_->ClearAllMemory(resource_provider);
239 void LayerTreeHost::DidBeginMainFrame() {
240 client_->DidBeginMainFrame();
243 void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) {
244 inside_begin_main_frame_ = true;
245 client_->BeginMainFrame(args);
246 inside_begin_main_frame_ = false;
249 void LayerTreeHost::DidStopFlinging() {
250 proxy_->MainThreadHasStoppedFlinging();
253 void LayerTreeHost::Layout() {
254 client_->Layout();
257 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
258 DCHECK(proxy_->IsImplThread());
259 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
262 // This function commits the LayerTreeHost to an impl tree. When modifying
263 // this function, keep in mind that the function *runs* on the impl thread! Any
264 // code that is logically a main thread operation, e.g. deletion of a Layer,
265 // should be delayed until the LayerTreeHost::CommitComplete, which will run
266 // after the commit, but on the main thread.
267 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
268 DCHECK(proxy_->IsImplThread());
270 // If there are linked evicted backings, these backings' resources may be put
271 // into the impl tree, so we can't draw yet. Determine this before clearing
272 // all evicted backings.
273 bool new_impl_tree_has_no_evicted_resources = false;
274 if (contents_texture_manager_) {
275 new_impl_tree_has_no_evicted_resources =
276 !contents_texture_manager_->LinkedEvictedBackingsExist();
278 // If the memory limit has been increased since this now-finishing
279 // commit began, and the extra now-available memory would have been used,
280 // then request another commit.
281 if (contents_texture_manager_->MaxMemoryLimitBytes() <
282 host_impl->memory_allocation_limit_bytes() &&
283 contents_texture_manager_->MaxMemoryLimitBytes() <
284 contents_texture_manager_->MaxMemoryNeededBytes()) {
285 host_impl->SetNeedsCommit();
288 host_impl->set_max_memory_needed_bytes(
289 contents_texture_manager_->MaxMemoryNeededBytes());
291 contents_texture_manager_->UpdateBackingsState(
292 host_impl->resource_provider());
293 contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
296 LayerTreeImpl* sync_tree = host_impl->sync_tree();
298 if (next_commit_forces_redraw_) {
299 sync_tree->ForceRedrawNextActivation();
300 next_commit_forces_redraw_ = false;
303 sync_tree->set_source_frame_number(source_frame_number());
305 if (needs_full_tree_sync_) {
306 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
307 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
311 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
312 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
315 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
316 needs_full_tree_sync_ = false;
318 if (hud_layer_.get()) {
319 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
320 sync_tree->root_layer(), hud_layer_->id());
321 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
322 } else {
323 sync_tree->set_hud_layer(NULL);
326 sync_tree->set_background_color(background_color_);
327 sync_tree->set_has_transparent_background(has_transparent_background_);
329 if (page_scale_layer_.get() && inner_viewport_scroll_layer_.get()) {
330 sync_tree->SetViewportLayersFromIds(page_scale_layer_->id(),
331 inner_viewport_scroll_layer_->id(),
332 outer_viewport_scroll_layer_.get()
333 ? outer_viewport_scroll_layer_->id()
334 : Layer::INVALID_ID);
335 } else {
336 sync_tree->ClearViewportLayers();
339 sync_tree->RegisterSelection(selection_start_, selection_end_);
341 float page_scale_delta =
342 sync_tree->page_scale_delta() / sync_tree->sent_page_scale_delta();
343 sync_tree->SetPageScaleValues(page_scale_factor_,
344 min_page_scale_factor_,
345 max_page_scale_factor_,
346 page_scale_delta);
347 sync_tree->set_sent_page_scale_delta(1.f);
349 sync_tree->PassSwapPromises(&swap_promise_list_);
351 sync_tree->set_top_controls_layout_height(top_controls_layout_height_);
352 sync_tree->set_top_controls_content_offset(top_controls_content_offset_);
353 sync_tree->set_top_controls_delta(sync_tree->top_controls_delta() -
354 sync_tree->sent_top_controls_delta());
355 sync_tree->set_sent_top_controls_delta(0.f);
357 host_impl->SetUseGpuRasterization(UseGpuRasterization());
358 RecordGpuRasterizationHistogram();
360 host_impl->SetViewportSize(device_viewport_size_);
361 host_impl->SetDeviceScaleFactor(device_scale_factor_);
362 host_impl->SetDebugState(debug_state_);
363 if (pending_page_scale_animation_) {
364 host_impl->StartPageScaleAnimation(
365 pending_page_scale_animation_->target_offset,
366 pending_page_scale_animation_->use_anchor,
367 pending_page_scale_animation_->scale,
368 pending_page_scale_animation_->duration);
369 pending_page_scale_animation_.reset();
372 if (!ui_resource_request_queue_.empty()) {
373 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
374 ui_resource_request_queue_.clear();
376 if (overhang_ui_resource_) {
377 host_impl->SetOverhangUIResource(
378 overhang_ui_resource_->id(),
379 GetUIResourceSize(overhang_ui_resource_->id()));
382 DCHECK(!sync_tree->ViewportSizeInvalid());
384 if (new_impl_tree_has_no_evicted_resources) {
385 if (sync_tree->ContentsTexturesPurged())
386 sync_tree->ResetContentsTexturesPurged();
389 sync_tree->set_has_ever_been_drawn(false);
391 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
394 void LayerTreeHost::WillCommit() {
395 client_->WillCommit();
398 void LayerTreeHost::UpdateHudLayer() {
399 if (debug_state_.ShowHudInfo()) {
400 if (!hud_layer_.get())
401 hud_layer_ = HeadsUpDisplayLayer::Create();
403 if (root_layer_.get() && !hud_layer_->parent())
404 root_layer_->AddChild(hud_layer_);
405 } else if (hud_layer_.get()) {
406 hud_layer_->RemoveFromParent();
407 hud_layer_ = NULL;
411 void LayerTreeHost::CommitComplete() {
412 source_frame_number_++;
413 client_->DidCommit();
416 void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) {
417 proxy_->SetOutputSurface(surface.Pass());
420 void LayerTreeHost::RequestNewOutputSurface() {
421 client_->RequestNewOutputSurface(num_failed_recreate_attempts_ >= 4);
424 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
425 LayerTreeHostImplClient* client) {
426 DCHECK(proxy_->IsImplThread());
427 scoped_ptr<LayerTreeHostImpl> host_impl =
428 LayerTreeHostImpl::Create(settings_,
429 client,
430 proxy_.get(),
431 rendering_stats_instrumentation_.get(),
432 shared_bitmap_manager_,
433 id_);
434 host_impl->SetUseGpuRasterization(UseGpuRasterization());
435 shared_bitmap_manager_ = NULL;
436 if (settings_.calculate_top_controls_position &&
437 host_impl->top_controls_manager()) {
438 top_controls_manager_weak_ptr_ =
439 host_impl->top_controls_manager()->AsWeakPtr();
441 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
442 return host_impl.Pass();
445 void LayerTreeHost::DidLoseOutputSurface() {
446 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
447 DCHECK(proxy_->IsMainThread());
449 if (output_surface_lost_)
450 return;
452 num_failed_recreate_attempts_ = 0;
453 output_surface_lost_ = true;
454 SetNeedsCommit();
457 void LayerTreeHost::FinishAllRendering() {
458 proxy_->FinishAllRendering();
461 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
462 proxy_->SetDeferCommits(defer_commits);
465 void LayerTreeHost::DidDeferCommit() {}
467 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
468 std::stack<Layer*> layer_stack;
469 layer_stack.push(root_layer());
470 while (!layer_stack.empty()) {
471 Layer* current_layer = layer_stack.top();
472 layer_stack.pop();
473 current_layer->SetNeedsDisplay();
474 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
475 layer_stack.push(current_layer->child_at(i));
480 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
481 return proxy_->GetRendererCapabilities();
484 void LayerTreeHost::SetNeedsAnimate() {
485 proxy_->SetNeedsAnimate();
486 NotifySwapPromiseMonitorsOfSetNeedsCommit();
489 void LayerTreeHost::SetNeedsUpdateLayers() {
490 proxy_->SetNeedsUpdateLayers();
491 NotifySwapPromiseMonitorsOfSetNeedsCommit();
494 void LayerTreeHost::SetNeedsCommit() {
495 if (!prepaint_callback_.IsCancelled()) {
496 TRACE_EVENT_INSTANT0("cc",
497 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
498 TRACE_EVENT_SCOPE_THREAD);
499 prepaint_callback_.Cancel();
501 proxy_->SetNeedsCommit();
502 NotifySwapPromiseMonitorsOfSetNeedsCommit();
505 void LayerTreeHost::SetNeedsFullTreeSync() {
506 needs_full_tree_sync_ = true;
507 SetNeedsCommit();
510 void LayerTreeHost::SetNeedsRedraw() {
511 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
514 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
515 proxy_->SetNeedsRedraw(damage_rect);
518 bool LayerTreeHost::CommitRequested() const {
519 return proxy_->CommitRequested();
522 bool LayerTreeHost::BeginMainFrameRequested() const {
523 return proxy_->BeginMainFrameRequested();
527 void LayerTreeHost::SetNextCommitWaitsForActivation() {
528 proxy_->SetNextCommitWaitsForActivation();
531 void LayerTreeHost::SetNextCommitForcesRedraw() {
532 next_commit_forces_redraw_ = true;
535 void LayerTreeHost::SetAnimationEvents(
536 scoped_ptr<AnimationEventsVector> events) {
537 DCHECK(proxy_->IsMainThread());
538 for (size_t event_index = 0; event_index < events->size(); ++event_index) {
539 int event_layer_id = (*events)[event_index].layer_id;
541 // Use the map of all controllers, not just active ones, since non-active
542 // controllers may still receive events for impl-only animations.
543 const AnimationRegistrar::AnimationControllerMap& animation_controllers =
544 animation_registrar_->all_animation_controllers();
545 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
546 animation_controllers.find(event_layer_id);
547 if (iter != animation_controllers.end()) {
548 switch ((*events)[event_index].type) {
549 case AnimationEvent::Started:
550 (*iter).second->NotifyAnimationStarted((*events)[event_index]);
551 break;
553 case AnimationEvent::Finished:
554 (*iter).second->NotifyAnimationFinished((*events)[event_index]);
555 break;
557 case AnimationEvent::Aborted:
558 (*iter).second->NotifyAnimationAborted((*events)[event_index]);
559 break;
561 case AnimationEvent::PropertyUpdate:
562 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
563 break;
569 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
570 if (root_layer_.get() == root_layer.get())
571 return;
573 if (root_layer_.get())
574 root_layer_->SetLayerTreeHost(NULL);
575 root_layer_ = root_layer;
576 if (root_layer_.get()) {
577 DCHECK(!root_layer_->parent());
578 root_layer_->SetLayerTreeHost(this);
581 if (hud_layer_.get())
582 hud_layer_->RemoveFromParent();
584 // Reset gpu rasterization flag.
585 // This flag is sticky until a new tree comes along.
586 content_is_suitable_for_gpu_rasterization_ = true;
587 gpu_rasterization_histogram_recorded_ = false;
589 SetNeedsFullTreeSync();
592 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
593 LayerTreeDebugState new_debug_state =
594 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
596 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
597 return;
599 debug_state_ = new_debug_state;
601 rendering_stats_instrumentation_->set_record_rendering_stats(
602 debug_state_.RecordRenderingStats());
604 SetNeedsCommit();
605 proxy_->SetDebugState(debug_state);
608 bool LayerTreeHost::UseGpuRasterization() const {
609 if (settings_.gpu_rasterization_forced) {
610 return true;
611 } else if (settings_.gpu_rasterization_enabled) {
612 return has_gpu_rasterization_trigger_ &&
613 content_is_suitable_for_gpu_rasterization_;
614 } else {
615 return false;
619 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
620 if (has_trigger == has_gpu_rasterization_trigger_)
621 return;
623 has_gpu_rasterization_trigger_ = has_trigger;
624 TRACE_EVENT_INSTANT1("cc",
625 "LayerTreeHost::SetHasGpuRasterizationTrigger",
626 TRACE_EVENT_SCOPE_THREAD,
627 "has_trigger",
628 has_gpu_rasterization_trigger_);
631 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
632 if (device_viewport_size == device_viewport_size_)
633 return;
635 device_viewport_size_ = device_viewport_size;
637 SetNeedsCommit();
640 void LayerTreeHost::SetTopControlsLayoutHeight(float height) {
641 if (top_controls_layout_height_ == height)
642 return;
644 top_controls_layout_height_ = height;
645 SetNeedsCommit();
648 void LayerTreeHost::SetTopControlsContentOffset(float offset) {
649 if (top_controls_content_offset_ == offset)
650 return;
652 top_controls_content_offset_ = offset;
653 SetNeedsCommit();
656 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
657 DCHECK(CommitRequested());
658 page_scale_factor_ *= page_scale_delta;
661 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
662 float min_page_scale_factor,
663 float max_page_scale_factor) {
664 if (page_scale_factor == page_scale_factor_ &&
665 min_page_scale_factor == min_page_scale_factor_ &&
666 max_page_scale_factor == max_page_scale_factor_)
667 return;
669 page_scale_factor_ = page_scale_factor;
670 min_page_scale_factor_ = min_page_scale_factor;
671 max_page_scale_factor_ = max_page_scale_factor;
672 SetNeedsCommit();
675 void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
676 DCHECK(bitmap.width() && bitmap.height());
677 DCHECK_EQ(bitmap.bytesPerPixel(), 4);
679 SkBitmap bitmap_copy;
680 if (bitmap.isImmutable()) {
681 bitmap_copy = bitmap;
682 } else {
683 bitmap.copyTo(&bitmap_copy);
684 bitmap_copy.setImmutable();
687 UIResourceBitmap overhang_bitmap(bitmap_copy);
688 overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
689 overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
692 void LayerTreeHost::SetVisible(bool visible) {
693 if (visible_ == visible)
694 return;
695 visible_ = visible;
696 if (!visible)
697 ReduceMemoryUsage();
698 proxy_->SetVisible(visible);
701 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
702 bool use_anchor,
703 float scale,
704 base::TimeDelta duration) {
705 pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
706 pending_page_scale_animation_->target_offset = target_offset;
707 pending_page_scale_animation_->use_anchor = use_anchor;
708 pending_page_scale_animation_->scale = scale;
709 pending_page_scale_animation_->duration = duration;
711 SetNeedsCommit();
714 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
715 proxy_->NotifyInputThrottledUntilCommit();
718 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
719 DCHECK(!proxy_->HasImplThread());
720 // This function is only valid when not using the scheduler.
721 DCHECK(!settings_.single_thread_proxy_scheduler);
722 SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
724 SetLayerTreeHostClientReady();
725 if (output_surface_lost_) {
726 RequestNewOutputSurface();
727 // RequestNewOutputSurface could have synchronously created an output
728 // surface, so check again before returning.
729 if (output_surface_lost_)
730 return;
733 proxy->CompositeImmediately(frame_begin_time);
736 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
737 DCHECK(!output_surface_lost_);
739 if (!root_layer())
740 return false;
742 DCHECK(!root_layer()->parent());
744 bool result = UpdateLayers(root_layer(), queue);
746 micro_benchmark_controller_.DidUpdateLayers();
748 return result || next_commit_forces_redraw_;
751 static Layer* FindFirstScrollableLayer(Layer* layer) {
752 if (!layer)
753 return NULL;
755 if (layer->scrollable())
756 return layer;
758 for (size_t i = 0; i < layer->children().size(); ++i) {
759 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
760 if (found)
761 return found;
764 return NULL;
767 void LayerTreeHost::RecordGpuRasterizationHistogram() {
768 // Gpu rasterization is only supported when impl-side painting is enabled.
769 if (gpu_rasterization_histogram_recorded_ || !settings_.impl_side_painting)
770 return;
772 // Record how widely gpu rasterization is enabled.
773 // This number takes device/gpu whitelisting/backlisting into account.
774 // Note that we do not consider the forced gpu rasterization mode, which is
775 // mostly used for debugging purposes.
776 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
777 settings_.gpu_rasterization_enabled);
778 if (settings_.gpu_rasterization_enabled) {
779 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
780 has_gpu_rasterization_trigger_);
781 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
782 content_is_suitable_for_gpu_rasterization_);
783 // Record how many pages actually get gpu rasterization when enabled.
784 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
785 (has_gpu_rasterization_trigger_ &&
786 content_is_suitable_for_gpu_rasterization_));
789 gpu_rasterization_histogram_recorded_ = true;
792 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) {
793 if (!layer->SupportsLCDText())
794 return;
796 lcd_text_metrics_.total_num_cc_layers++;
797 if (layer->draw_properties().can_use_lcd_text) {
798 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
799 if (layer->contents_opaque())
800 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
804 bool LayerTreeHost::UsingSharedMemoryResources() {
805 return GetRendererCapabilities().using_shared_memory_resources;
808 bool LayerTreeHost::UpdateLayers(Layer* root_layer,
809 ResourceUpdateQueue* queue) {
810 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
811 "source_frame_number", source_frame_number());
813 RenderSurfaceLayerList update_list;
815 UpdateHudLayer();
817 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
818 Layer* page_scale_layer = page_scale_layer_.get();
819 if (!page_scale_layer && root_scroll)
820 page_scale_layer = root_scroll->parent();
822 if (hud_layer_.get()) {
823 hud_layer_->PrepareForCalculateDrawProperties(
824 device_viewport_size(), device_scale_factor_);
827 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
828 bool can_render_to_separate_surface = true;
829 // TODO(vmpstr): Passing 0 as the current render surface layer list id means
830 // that we won't be able to detect if a layer is part of |update_list|.
831 // Change this if this information is required.
832 int render_surface_layer_list_id = 0;
833 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
834 root_layer,
835 device_viewport_size(),
836 gfx::Transform(),
837 device_scale_factor_,
838 page_scale_factor_,
839 page_scale_layer,
840 GetRendererCapabilities().max_texture_size,
841 settings_.can_use_lcd_text,
842 can_render_to_separate_surface,
843 settings_.layer_transforms_should_scale_layer_contents,
844 &update_list,
845 render_surface_layer_list_id);
846 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
848 if (total_frames_used_for_lcd_text_metrics_ <=
849 kTotalFramesToUseForLCDTextMetrics) {
850 LayerTreeHostCommon::CallFunctionForSubtree(
851 root_layer,
852 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback,
853 base::Unretained(this)));
854 total_frames_used_for_lcd_text_metrics_++;
857 if (total_frames_used_for_lcd_text_metrics_ ==
858 kTotalFramesToUseForLCDTextMetrics) {
859 total_frames_used_for_lcd_text_metrics_++;
861 UMA_HISTOGRAM_PERCENTAGE(
862 "Renderer4.LCDText.PercentageOfCandidateLayers",
863 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 /
864 lcd_text_metrics_.total_num_cc_layers);
865 UMA_HISTOGRAM_PERCENTAGE(
866 "Renderer4.LCDText.PercentageOfAALayers",
867 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 /
868 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text);
872 // Reset partial texture update requests.
873 partial_texture_update_requests_ = 0;
875 bool did_paint_content = false;
876 bool need_more_updates = false;
877 PaintLayerContents(
878 update_list, queue, &did_paint_content, &need_more_updates);
879 if (need_more_updates) {
880 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
881 prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
882 base::Unretained(this)));
883 static base::TimeDelta prepaint_delay =
884 base::TimeDelta::FromMilliseconds(100);
885 base::MessageLoop::current()->PostDelayedTask(
886 FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
889 return did_paint_content;
892 void LayerTreeHost::TriggerPrepaint() {
893 prepaint_callback_.Cancel();
894 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
895 SetNeedsCommit();
898 static void LayerTreeHostReduceMemoryCallback(Layer* layer) {
899 layer->ReduceMemoryUsage();
902 void LayerTreeHost::ReduceMemoryUsage() {
903 if (!root_layer())
904 return;
906 LayerTreeHostCommon::CallFunctionForSubtree(
907 root_layer(),
908 base::Bind(&LayerTreeHostReduceMemoryCallback));
911 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
912 DCHECK(surface_memory_placeholder_);
914 // Surfaces have a place holder for their memory since they are managed
915 // independantly but should still be tracked and reduce other memory usage.
916 surface_memory_placeholder_->SetTextureManager(
917 contents_texture_manager_.get());
918 surface_memory_placeholder_->set_request_priority(
919 PriorityCalculator::RenderSurfacePriority());
920 surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
921 surface_memory_bytes);
924 void LayerTreeHost::SetPrioritiesForLayers(
925 const RenderSurfaceLayerList& update_list) {
926 PriorityCalculator calculator;
927 typedef LayerIterator<Layer> LayerIteratorType;
928 LayerIteratorType end = LayerIteratorType::End(&update_list);
929 for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
930 it != end;
931 ++it) {
932 if (it.represents_itself()) {
933 it->SetTexturePriorities(calculator);
934 } else if (it.represents_target_render_surface()) {
935 if (it->mask_layer())
936 it->mask_layer()->SetTexturePriorities(calculator);
937 if (it->replica_layer() && it->replica_layer()->mask_layer())
938 it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
943 void LayerTreeHost::PrioritizeTextures(
944 const RenderSurfaceLayerList& render_surface_layer_list) {
945 if (!contents_texture_manager_)
946 return;
948 contents_texture_manager_->ClearPriorities();
950 size_t memory_for_render_surfaces_metric =
951 CalculateMemoryForRenderSurfaces(render_surface_layer_list);
953 SetPrioritiesForLayers(render_surface_layer_list);
954 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
956 contents_texture_manager_->PrioritizeTextures();
959 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
960 const RenderSurfaceLayerList& update_list) {
961 size_t readback_bytes = 0;
962 size_t max_background_texture_bytes = 0;
963 size_t contents_texture_bytes = 0;
965 // Start iteration at 1 to skip the root surface as it does not have a texture
966 // cost.
967 for (size_t i = 1; i < update_list.size(); ++i) {
968 Layer* render_surface_layer = update_list.at(i);
969 RenderSurface* render_surface = render_surface_layer->render_surface();
971 size_t bytes =
972 Resource::MemorySizeBytes(render_surface->content_rect().size(),
973 RGBA_8888);
974 contents_texture_bytes += bytes;
976 if (render_surface_layer->background_filters().IsEmpty())
977 continue;
979 if (bytes > max_background_texture_bytes)
980 max_background_texture_bytes = bytes;
981 if (!readback_bytes) {
982 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
983 RGBA_8888);
986 return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
989 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
990 ResourceUpdateQueue* queue,
991 bool* did_paint_content,
992 bool* need_more_updates) {
993 // Note: Masks and replicas only exist for layers that own render surfaces. If
994 // we reach this point in code, we already know that at least something will
995 // be drawn into this render surface, so the mask and replica should be
996 // painted.
998 Layer* mask_layer = render_surface_layer->mask_layer();
999 if (mask_layer) {
1000 *did_paint_content |= mask_layer->Update(queue, NULL);
1001 *need_more_updates |= mask_layer->NeedMoreUpdates();
1004 Layer* replica_mask_layer =
1005 render_surface_layer->replica_layer() ?
1006 render_surface_layer->replica_layer()->mask_layer() : NULL;
1007 if (replica_mask_layer) {
1008 *did_paint_content |= replica_mask_layer->Update(queue, NULL);
1009 *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
1013 void LayerTreeHost::PaintLayerContents(
1014 const RenderSurfaceLayerList& render_surface_layer_list,
1015 ResourceUpdateQueue* queue,
1016 bool* did_paint_content,
1017 bool* need_more_updates) {
1018 OcclusionTracker<Layer> occlusion_tracker(
1019 root_layer_->render_surface()->content_rect());
1020 occlusion_tracker.set_minimum_tracking_size(
1021 settings_.minimum_occlusion_tracking_size);
1023 PrioritizeTextures(render_surface_layer_list);
1025 in_paint_layer_contents_ = true;
1027 // Iterates front-to-back to allow for testing occlusion and performing
1028 // culling during the tree walk.
1029 typedef LayerIterator<Layer> LayerIteratorType;
1030 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1031 for (LayerIteratorType it =
1032 LayerIteratorType::Begin(&render_surface_layer_list);
1033 it != end;
1034 ++it) {
1035 occlusion_tracker.EnterLayer(it);
1037 if (it.represents_target_render_surface()) {
1038 PaintMasksForRenderSurface(
1039 *it, queue, did_paint_content, need_more_updates);
1040 } else if (it.represents_itself()) {
1041 DCHECK(!it->paint_properties().bounds.IsEmpty());
1042 *did_paint_content |= it->Update(queue, &occlusion_tracker);
1043 *need_more_updates |= it->NeedMoreUpdates();
1044 // Note the '&&' with previous is-suitable state.
1045 // This means that once the layer-tree becomes unsuitable for gpu
1046 // rasterization due to some content, it will continue to be unsuitable
1047 // even if that content is replaced by gpu-friendly content.
1048 // This is to avoid switching back-and-forth between gpu and sw
1049 // rasterization which may be both bad for performance and visually
1050 // jarring.
1051 content_is_suitable_for_gpu_rasterization_ &=
1052 it->IsSuitableForGpuRasterization();
1055 occlusion_tracker.LeaveLayer(it);
1058 in_paint_layer_contents_ = false;
1061 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
1062 if (!root_layer_.get())
1063 return;
1065 ScopedPtrVector<SwapPromise>::iterator it = info->swap_promises.begin();
1066 for (; it != info->swap_promises.end(); ++it) {
1067 scoped_ptr<SwapPromise> swap_promise(info->swap_promises.take(it));
1068 TRACE_EVENT_FLOW_STEP0("input",
1069 "LatencyInfo.Flow",
1070 TRACE_ID_DONT_MANGLE(swap_promise->TraceId()),
1071 "Main thread scroll update");
1072 QueueSwapPromise(swap_promise.Pass());
1075 gfx::Vector2d inner_viewport_scroll_delta;
1076 gfx::Vector2d outer_viewport_scroll_delta;
1078 for (size_t i = 0; i < info->scrolls.size(); ++i) {
1079 Layer* layer = LayerTreeHostCommon::FindLayerInSubtree(
1080 root_layer_.get(), info->scrolls[i].layer_id);
1081 if (!layer)
1082 continue;
1083 if (layer == outer_viewport_scroll_layer_.get()) {
1084 outer_viewport_scroll_delta += info->scrolls[i].scroll_delta;
1085 } else if (layer == inner_viewport_scroll_layer_.get()) {
1086 inner_viewport_scroll_delta += info->scrolls[i].scroll_delta;
1087 } else {
1088 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
1089 info->scrolls[i].scroll_delta);
1093 if (!inner_viewport_scroll_delta.IsZero() ||
1094 !outer_viewport_scroll_delta.IsZero() ||
1095 info->page_scale_delta != 1.f ||
1096 info->top_controls_delta) {
1097 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1098 // so re-get this layer before doing anything to it.
1100 // Preemptively apply the scroll offset and scale delta here before sending
1101 // it to the client. If the client comes back and sets it to the same
1102 // value, then the layer can early out without needing a full commit.
1103 DCHECK(inner_viewport_scroll_layer_.get()); // We should always have this.
1105 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1106 inner_viewport_scroll_layer_->scroll_offset() +
1107 inner_viewport_scroll_delta);
1108 if (outer_viewport_scroll_layer_.get()) {
1109 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
1110 outer_viewport_scroll_layer_->scroll_offset() +
1111 outer_viewport_scroll_delta);
1113 ApplyPageScaleDeltaFromImplSide(info->page_scale_delta);
1115 client_->ApplyViewportDeltas(
1116 inner_viewport_scroll_delta + outer_viewport_scroll_delta,
1117 info->page_scale_delta,
1118 info->top_controls_delta);
1122 void LayerTreeHost::StartRateLimiter() {
1123 if (inside_begin_main_frame_)
1124 return;
1126 if (!rate_limit_timer_.IsRunning()) {
1127 rate_limit_timer_.Start(FROM_HERE,
1128 base::TimeDelta(),
1129 this,
1130 &LayerTreeHost::RateLimit);
1134 void LayerTreeHost::StopRateLimiter() {
1135 rate_limit_timer_.Stop();
1138 void LayerTreeHost::RateLimit() {
1139 // Force a no-op command on the compositor context, so that any ratelimiting
1140 // commands will wait for the compositing context, and therefore for the
1141 // SwapBuffers.
1142 proxy_->ForceSerializeOnSwapBuffers();
1143 client_->RateLimitSharedMainThreadContext();
1146 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1147 if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
1148 return false;
1149 return !proxy_->HasImplThread();
1152 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1153 size_t max_partial_texture_updates = 0;
1154 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
1155 !settings_.impl_side_painting) {
1156 max_partial_texture_updates =
1157 std::min(settings_.max_partial_texture_updates,
1158 proxy_->MaxPartialTextureUpdates());
1160 return max_partial_texture_updates;
1163 bool LayerTreeHost::RequestPartialTextureUpdate() {
1164 if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
1165 return false;
1167 partial_texture_update_requests_++;
1168 return true;
1171 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1172 if (device_scale_factor == device_scale_factor_)
1173 return;
1174 device_scale_factor_ = device_scale_factor;
1176 SetNeedsCommit();
1179 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1180 TopControlsState current,
1181 bool animate) {
1182 if (!settings_.calculate_top_controls_position)
1183 return;
1185 // Top controls are only used in threaded mode.
1186 proxy_->ImplThreadTaskRunner()->PostTask(
1187 FROM_HERE,
1188 base::Bind(&TopControlsManager::UpdateTopControlsState,
1189 top_controls_manager_weak_ptr_,
1190 constraints,
1191 current,
1192 animate));
1195 void LayerTreeHost::AsValueInto(base::debug::TracedValue* state) const {
1196 state->BeginDictionary("proxy");
1197 proxy_->AsValueInto(state);
1198 state->EndDictionary();
1201 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
1202 if (!settings_.accelerated_animation_enabled ||
1203 animation_registrar_->active_animation_controllers().empty())
1204 return;
1206 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1208 AnimationRegistrar::AnimationControllerMap copy =
1209 animation_registrar_->active_animation_controllers();
1210 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1211 iter != copy.end();
1212 ++iter) {
1213 (*iter).second->Animate(monotonic_time);
1214 bool start_ready_animations = true;
1215 (*iter).second->UpdateState(start_ready_animations, NULL);
1219 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
1220 DCHECK(client);
1222 UIResourceId next_id = next_ui_resource_id_++;
1223 DCHECK(ui_resource_client_map_.find(next_id) ==
1224 ui_resource_client_map_.end());
1226 bool resource_lost = false;
1227 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1228 next_id,
1229 client->GetBitmap(next_id, resource_lost));
1230 ui_resource_request_queue_.push_back(request);
1232 UIResourceClientData data;
1233 data.client = client;
1234 data.size = request.GetBitmap().GetSize();
1236 ui_resource_client_map_[request.GetId()] = data;
1237 return request.GetId();
1240 // Deletes a UI resource. May safely be called more than once.
1241 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
1242 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
1243 if (iter == ui_resource_client_map_.end())
1244 return;
1246 UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
1247 ui_resource_request_queue_.push_back(request);
1248 ui_resource_client_map_.erase(iter);
1251 void LayerTreeHost::RecreateUIResources() {
1252 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
1253 iter != ui_resource_client_map_.end();
1254 ++iter) {
1255 UIResourceId uid = iter->first;
1256 const UIResourceClientData& data = iter->second;
1257 bool resource_lost = true;
1258 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1259 uid,
1260 data.client->GetBitmap(uid, resource_lost));
1261 ui_resource_request_queue_.push_back(request);
1265 // Returns the size of a resource given its id.
1266 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
1267 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
1268 if (iter == ui_resource_client_map_.end())
1269 return gfx::Size();
1271 const UIResourceClientData& data = iter->second;
1272 return data.size;
1275 void LayerTreeHost::RegisterViewportLayers(
1276 scoped_refptr<Layer> page_scale_layer,
1277 scoped_refptr<Layer> inner_viewport_scroll_layer,
1278 scoped_refptr<Layer> outer_viewport_scroll_layer) {
1279 page_scale_layer_ = page_scale_layer;
1280 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
1281 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1284 void LayerTreeHost::RegisterSelection(const LayerSelectionBound& start,
1285 const LayerSelectionBound& end) {
1286 if (selection_start_ == start && selection_end_ == end)
1287 return;
1289 selection_start_ = start;
1290 selection_end_ = end;
1291 SetNeedsCommit();
1294 int LayerTreeHost::ScheduleMicroBenchmark(
1295 const std::string& benchmark_name,
1296 scoped_ptr<base::Value> value,
1297 const MicroBenchmark::DoneCallback& callback) {
1298 return micro_benchmark_controller_.ScheduleRun(
1299 benchmark_name, value.Pass(), callback);
1302 bool LayerTreeHost::SendMessageToMicroBenchmark(int id,
1303 scoped_ptr<base::Value> value) {
1304 return micro_benchmark_controller_.SendMessage(id, value.Pass());
1307 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1308 swap_promise_monitor_.insert(monitor);
1311 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1312 swap_promise_monitor_.erase(monitor);
1315 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1316 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1317 for (; it != swap_promise_monitor_.end(); it++)
1318 (*it)->OnSetNeedsCommitOnMain();
1321 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1322 DCHECK(swap_promise);
1323 swap_promise_list_.push_back(swap_promise.Pass());
1326 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1327 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1328 swap_promise_list_[i]->DidNotSwap(reason);
1329 swap_promise_list_.clear();
1332 } // namespace cc