1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
11 #include "base/atomic_sequence_num.h"
12 #include "base/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/geometry/size_conversions.h"
46 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number
;
51 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format
,
52 bool allow_partial_texture_updates
,
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),
64 using_shared_memory_resources(false) {}
66 RendererCapabilities::~RendererCapabilities() {}
68 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateThreaded(
69 LayerTreeHostClient
* client
,
70 SharedBitmapManager
* shared_bitmap_manager
,
71 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
72 const LayerTreeSettings
& settings
,
73 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
,
74 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
) {
75 DCHECK(main_task_runner
.get());
76 DCHECK(impl_task_runner
.get());
77 scoped_ptr
<LayerTreeHost
> layer_tree_host(new LayerTreeHost(
78 client
, shared_bitmap_manager
, gpu_memory_buffer_manager
, settings
));
79 layer_tree_host
->InitializeThreaded(main_task_runner
, impl_task_runner
);
80 return layer_tree_host
.Pass();
83 scoped_ptr
<LayerTreeHost
> LayerTreeHost::CreateSingleThreaded(
84 LayerTreeHostClient
* client
,
85 LayerTreeHostSingleThreadClient
* single_thread_client
,
86 SharedBitmapManager
* shared_bitmap_manager
,
87 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
88 const LayerTreeSettings
& settings
,
89 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
) {
90 scoped_ptr
<LayerTreeHost
> layer_tree_host(new LayerTreeHost(
91 client
, shared_bitmap_manager
, gpu_memory_buffer_manager
, settings
));
92 layer_tree_host
->InitializeSingleThreaded(single_thread_client
,
94 return layer_tree_host
.Pass();
97 LayerTreeHost::LayerTreeHost(
98 LayerTreeHostClient
* client
,
99 SharedBitmapManager
* shared_bitmap_manager
,
100 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
101 const LayerTreeSettings
& settings
)
102 : micro_benchmark_controller_(this),
103 next_ui_resource_id_(1),
104 inside_begin_main_frame_(false),
105 needs_full_tree_sync_(true),
107 source_frame_number_(0),
108 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
109 output_surface_lost_(true),
110 num_failed_recreate_attempts_(0),
112 debug_state_(settings
.initial_debug_state
),
113 top_controls_layout_height_(0.f
),
114 top_controls_content_offset_(0.f
),
115 device_scale_factor_(1.f
),
117 page_scale_factor_(1.f
),
118 min_page_scale_factor_(1.f
),
119 max_page_scale_factor_(1.f
),
120 has_gpu_rasterization_trigger_(false),
121 content_is_suitable_for_gpu_rasterization_(true),
122 gpu_rasterization_histogram_recorded_(false),
123 background_color_(SK_ColorWHITE
),
124 has_transparent_background_(false),
125 partial_texture_update_requests_(0),
126 in_paint_layer_contents_(false),
127 total_frames_used_for_lcd_text_metrics_(0),
128 id_(s_layer_tree_host_sequence_number
.GetNext() + 1),
129 next_commit_forces_redraw_(false),
130 shared_bitmap_manager_(shared_bitmap_manager
),
131 gpu_memory_buffer_manager_(gpu_memory_buffer_manager
) {
132 if (settings_
.accelerated_animation_enabled
)
133 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
) {
142 ThreadProxy::Create(this, main_task_runner
, impl_task_runner
));
145 void LayerTreeHost::InitializeSingleThreaded(
146 LayerTreeHostSingleThreadClient
* single_thread_client
,
147 scoped_refptr
<base::SingleThreadTaskRunner
> main_task_runner
) {
149 SingleThreadProxy::Create(this, single_thread_client
, main_task_runner
));
152 void LayerTreeHost::InitializeForTesting(scoped_ptr
<Proxy
> proxy_for_testing
) {
153 InitializeProxy(proxy_for_testing
.Pass());
156 void LayerTreeHost::InitializeProxy(scoped_ptr
<Proxy
> proxy
) {
157 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
159 proxy_
= proxy
.Pass();
161 if (settings_
.accelerated_animation_enabled
) {
162 animation_registrar_
->set_supports_scroll_animations(
163 proxy_
->SupportsImplScrolling());
167 LayerTreeHost::~LayerTreeHost() {
168 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
170 DCHECK(swap_promise_monitor_
.empty());
172 BreakSwapPromises(SwapPromise::COMMIT_FAILS
);
174 overhang_ui_resource_
= nullptr;
176 if (root_layer_
.get())
177 root_layer_
->SetLayerTreeHost(NULL
);
180 DCHECK(proxy_
->IsMainThread());
184 // We must clear any pointers into the layer tree prior to destroying it.
185 RegisterViewportLayers(NULL
, NULL
, NULL
);
187 if (root_layer_
.get()) {
188 // The layer tree must be destroyed before the layer tree host. We've
189 // made a contract with our animation controllers that the registrar
190 // will outlive them, and we must make good.
195 void LayerTreeHost::SetLayerTreeHostClientReady() {
196 proxy_
->SetLayerTreeHostClientReady();
199 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer
* layer
) {
200 layer
->OnOutputSurfaceCreated();
203 void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success
) {
204 DCHECK(output_surface_lost_
);
206 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
211 // Tolerate a certain number of recreation failures to work around races
212 // in the output-surface-lost machinery.
213 ++num_failed_recreate_attempts_
;
214 if (num_failed_recreate_attempts_
>= 5)
215 LOG(FATAL
) << "Failed to create a fallback OutputSurface.";
216 client_
->DidFailToInitializeOutputSurface();
220 output_surface_lost_
= false;
222 if (!contents_texture_manager_
&& !settings_
.impl_side_painting
) {
223 contents_texture_manager_
=
224 PrioritizedResourceManager::Create(proxy_
.get());
225 surface_memory_placeholder_
=
226 contents_texture_manager_
->CreateTexture(gfx::Size(), RGBA_8888
);
230 LayerTreeHostCommon::CallFunctionForSubtree(
231 root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback
));
234 client_
->DidInitializeOutputSurface();
237 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
238 ResourceProvider
* resource_provider
) {
239 DCHECK(proxy_
->IsImplThread());
240 if (contents_texture_manager_
)
241 contents_texture_manager_
->ClearAllMemory(resource_provider
);
244 void LayerTreeHost::DidBeginMainFrame() {
245 client_
->DidBeginMainFrame();
248 void LayerTreeHost::BeginMainFrame(const BeginFrameArgs
& args
) {
249 inside_begin_main_frame_
= true;
250 client_
->BeginMainFrame(args
);
251 inside_begin_main_frame_
= false;
254 void LayerTreeHost::DidStopFlinging() {
255 proxy_
->MainThreadHasStoppedFlinging();
258 void LayerTreeHost::Layout() {
262 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl
* host_impl
) {
263 DCHECK(proxy_
->IsImplThread());
264 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
267 // This function commits the LayerTreeHost to an impl tree. When modifying
268 // this function, keep in mind that the function *runs* on the impl thread! Any
269 // code that is logically a main thread operation, e.g. deletion of a Layer,
270 // should be delayed until the LayerTreeHost::CommitComplete, which will run
271 // after the commit, but on the main thread.
272 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl
* host_impl
) {
273 DCHECK(proxy_
->IsImplThread());
275 // If there are linked evicted backings, these backings' resources may be put
276 // into the impl tree, so we can't draw yet. Determine this before clearing
277 // all evicted backings.
278 bool new_impl_tree_has_no_evicted_resources
= false;
279 if (contents_texture_manager_
) {
280 new_impl_tree_has_no_evicted_resources
=
281 !contents_texture_manager_
->LinkedEvictedBackingsExist();
283 // If the memory limit has been increased since this now-finishing
284 // commit began, and the extra now-available memory would have been used,
285 // then request another commit.
286 if (contents_texture_manager_
->MaxMemoryLimitBytes() <
287 host_impl
->memory_allocation_limit_bytes() &&
288 contents_texture_manager_
->MaxMemoryLimitBytes() <
289 contents_texture_manager_
->MaxMemoryNeededBytes()) {
290 host_impl
->SetNeedsCommit();
293 host_impl
->set_max_memory_needed_bytes(
294 contents_texture_manager_
->MaxMemoryNeededBytes());
296 contents_texture_manager_
->UpdateBackingsState(
297 host_impl
->resource_provider());
298 contents_texture_manager_
->ReduceMemory(host_impl
->resource_provider());
301 LayerTreeImpl
* sync_tree
= host_impl
->sync_tree();
303 if (next_commit_forces_redraw_
) {
304 sync_tree
->ForceRedrawNextActivation();
305 next_commit_forces_redraw_
= false;
308 sync_tree
->set_source_frame_number(source_frame_number());
310 if (needs_full_tree_sync_
) {
311 sync_tree
->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
312 root_layer(), sync_tree
->DetachLayerTree(), sync_tree
));
316 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
317 TreeSynchronizer::PushProperties(root_layer(), sync_tree
->root_layer());
320 sync_tree
->set_needs_full_tree_sync(needs_full_tree_sync_
);
321 needs_full_tree_sync_
= false;
323 if (hud_layer_
.get()) {
324 LayerImpl
* hud_impl
= LayerTreeHostCommon::FindLayerInSubtree(
325 sync_tree
->root_layer(), hud_layer_
->id());
326 sync_tree
->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl
*>(hud_impl
));
328 sync_tree
->set_hud_layer(NULL
);
331 sync_tree
->set_background_color(background_color_
);
332 sync_tree
->set_has_transparent_background(has_transparent_background_
);
334 if (page_scale_layer_
.get() && inner_viewport_scroll_layer_
.get()) {
335 sync_tree
->SetViewportLayersFromIds(page_scale_layer_
->id(),
336 inner_viewport_scroll_layer_
->id(),
337 outer_viewport_scroll_layer_
.get()
338 ? outer_viewport_scroll_layer_
->id()
339 : Layer::INVALID_ID
);
341 sync_tree
->ClearViewportLayers();
344 sync_tree
->RegisterSelection(selection_start_
, selection_end_
);
346 float page_scale_delta
=
347 sync_tree
->page_scale_delta() / sync_tree
->sent_page_scale_delta();
348 sync_tree
->SetPageScaleValues(page_scale_factor_
,
349 min_page_scale_factor_
,
350 max_page_scale_factor_
,
352 sync_tree
->set_sent_page_scale_delta(1.f
);
354 sync_tree
->PassSwapPromises(&swap_promise_list_
);
356 sync_tree
->set_top_controls_layout_height(top_controls_layout_height_
);
357 sync_tree
->set_top_controls_content_offset(top_controls_content_offset_
);
358 sync_tree
->set_top_controls_delta(sync_tree
->top_controls_delta() -
359 sync_tree
->sent_top_controls_delta());
360 sync_tree
->set_sent_top_controls_delta(0.f
);
362 host_impl
->SetUseGpuRasterization(UseGpuRasterization());
363 RecordGpuRasterizationHistogram();
365 host_impl
->SetViewportSize(device_viewport_size_
);
366 host_impl
->SetDeviceScaleFactor(device_scale_factor_
);
367 host_impl
->SetDebugState(debug_state_
);
368 if (pending_page_scale_animation_
) {
369 sync_tree
->SetPageScaleAnimation(
370 pending_page_scale_animation_
->target_offset
,
371 pending_page_scale_animation_
->use_anchor
,
372 pending_page_scale_animation_
->scale
,
373 pending_page_scale_animation_
->duration
);
374 pending_page_scale_animation_
= nullptr;
377 if (!ui_resource_request_queue_
.empty()) {
378 sync_tree
->set_ui_resource_request_queue(ui_resource_request_queue_
);
379 ui_resource_request_queue_
.clear();
381 if (overhang_ui_resource_
) {
382 host_impl
->SetOverhangUIResource(
383 overhang_ui_resource_
->id(),
384 GetUIResourceSize(overhang_ui_resource_
->id()));
387 DCHECK(!sync_tree
->ViewportSizeInvalid());
389 if (new_impl_tree_has_no_evicted_resources
) {
390 if (sync_tree
->ContentsTexturesPurged())
391 sync_tree
->ResetContentsTexturesPurged();
394 sync_tree
->set_has_ever_been_drawn(false);
396 micro_benchmark_controller_
.ScheduleImplBenchmarks(host_impl
);
399 void LayerTreeHost::WillCommit() {
400 client_
->WillCommit();
403 void LayerTreeHost::UpdateHudLayer() {
404 if (debug_state_
.ShowHudInfo()) {
405 if (!hud_layer_
.get())
406 hud_layer_
= HeadsUpDisplayLayer::Create();
408 if (root_layer_
.get() && !hud_layer_
->parent())
409 root_layer_
->AddChild(hud_layer_
);
410 } else if (hud_layer_
.get()) {
411 hud_layer_
->RemoveFromParent();
416 void LayerTreeHost::CommitComplete() {
417 source_frame_number_
++;
418 client_
->DidCommit();
421 void LayerTreeHost::SetOutputSurface(scoped_ptr
<OutputSurface
> surface
) {
422 proxy_
->SetOutputSurface(surface
.Pass());
425 void LayerTreeHost::RequestNewOutputSurface() {
426 client_
->RequestNewOutputSurface(num_failed_recreate_attempts_
>= 4);
429 scoped_ptr
<LayerTreeHostImpl
> LayerTreeHost::CreateLayerTreeHostImpl(
430 LayerTreeHostImplClient
* client
) {
431 DCHECK(proxy_
->IsImplThread());
432 scoped_ptr
<LayerTreeHostImpl
> host_impl
=
433 LayerTreeHostImpl::Create(settings_
,
436 rendering_stats_instrumentation_
.get(),
437 shared_bitmap_manager_
,
438 gpu_memory_buffer_manager_
,
440 host_impl
->SetUseGpuRasterization(UseGpuRasterization());
441 shared_bitmap_manager_
= NULL
;
442 gpu_memory_buffer_manager_
= NULL
;
443 if (settings_
.calculate_top_controls_position
&&
444 host_impl
->top_controls_manager()) {
445 top_controls_manager_weak_ptr_
=
446 host_impl
->top_controls_manager()->AsWeakPtr();
448 input_handler_weak_ptr_
= host_impl
->AsWeakPtr();
449 return host_impl
.Pass();
452 void LayerTreeHost::DidLoseOutputSurface() {
453 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
454 DCHECK(proxy_
->IsMainThread());
456 if (output_surface_lost_
)
459 num_failed_recreate_attempts_
= 0;
460 output_surface_lost_
= true;
464 void LayerTreeHost::FinishAllRendering() {
465 proxy_
->FinishAllRendering();
468 void LayerTreeHost::SetDeferCommits(bool defer_commits
) {
469 proxy_
->SetDeferCommits(defer_commits
);
472 void LayerTreeHost::DidDeferCommit() {}
474 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
475 std::stack
<Layer
*> layer_stack
;
476 layer_stack
.push(root_layer());
477 while (!layer_stack
.empty()) {
478 Layer
* current_layer
= layer_stack
.top();
480 current_layer
->SetNeedsDisplay();
481 for (unsigned int i
= 0; i
< current_layer
->children().size(); i
++) {
482 layer_stack
.push(current_layer
->child_at(i
));
487 const RendererCapabilities
& LayerTreeHost::GetRendererCapabilities() const {
488 return proxy_
->GetRendererCapabilities();
491 void LayerTreeHost::SetNeedsAnimate() {
492 proxy_
->SetNeedsAnimate();
493 NotifySwapPromiseMonitorsOfSetNeedsCommit();
496 void LayerTreeHost::SetNeedsUpdateLayers() {
497 proxy_
->SetNeedsUpdateLayers();
498 NotifySwapPromiseMonitorsOfSetNeedsCommit();
501 void LayerTreeHost::SetNeedsCommit() {
502 if (!prepaint_callback_
.IsCancelled()) {
503 TRACE_EVENT_INSTANT0("cc",
504 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
505 TRACE_EVENT_SCOPE_THREAD
);
506 prepaint_callback_
.Cancel();
508 proxy_
->SetNeedsCommit();
509 NotifySwapPromiseMonitorsOfSetNeedsCommit();
512 void LayerTreeHost::SetNeedsFullTreeSync() {
513 needs_full_tree_sync_
= true;
517 void LayerTreeHost::SetNeedsRedraw() {
518 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_
));
521 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect
& damage_rect
) {
522 proxy_
->SetNeedsRedraw(damage_rect
);
525 bool LayerTreeHost::CommitRequested() const {
526 return proxy_
->CommitRequested();
529 bool LayerTreeHost::BeginMainFrameRequested() const {
530 return proxy_
->BeginMainFrameRequested();
534 void LayerTreeHost::SetNextCommitWaitsForActivation() {
535 proxy_
->SetNextCommitWaitsForActivation();
538 void LayerTreeHost::SetNextCommitForcesRedraw() {
539 next_commit_forces_redraw_
= true;
542 void LayerTreeHost::SetAnimationEvents(
543 scoped_ptr
<AnimationEventsVector
> events
) {
544 DCHECK(proxy_
->IsMainThread());
545 for (size_t event_index
= 0; event_index
< events
->size(); ++event_index
) {
546 int event_layer_id
= (*events
)[event_index
].layer_id
;
548 // Use the map of all controllers, not just active ones, since non-active
549 // controllers may still receive events for impl-only animations.
550 const AnimationRegistrar::AnimationControllerMap
& animation_controllers
=
551 animation_registrar_
->all_animation_controllers();
552 AnimationRegistrar::AnimationControllerMap::const_iterator iter
=
553 animation_controllers
.find(event_layer_id
);
554 if (iter
!= animation_controllers
.end()) {
555 switch ((*events
)[event_index
].type
) {
556 case AnimationEvent::Started
:
557 (*iter
).second
->NotifyAnimationStarted((*events
)[event_index
]);
560 case AnimationEvent::Finished
:
561 (*iter
).second
->NotifyAnimationFinished((*events
)[event_index
]);
564 case AnimationEvent::Aborted
:
565 (*iter
).second
->NotifyAnimationAborted((*events
)[event_index
]);
568 case AnimationEvent::PropertyUpdate
:
569 (*iter
).second
->NotifyAnimationPropertyUpdate((*events
)[event_index
]);
576 void LayerTreeHost::SetRootLayer(scoped_refptr
<Layer
> root_layer
) {
577 if (root_layer_
.get() == root_layer
.get())
580 if (root_layer_
.get())
581 root_layer_
->SetLayerTreeHost(NULL
);
582 root_layer_
= root_layer
;
583 if (root_layer_
.get()) {
584 DCHECK(!root_layer_
->parent());
585 root_layer_
->SetLayerTreeHost(this);
588 if (hud_layer_
.get())
589 hud_layer_
->RemoveFromParent();
591 // Reset gpu rasterization flag.
592 // This flag is sticky until a new tree comes along.
593 content_is_suitable_for_gpu_rasterization_
= true;
594 gpu_rasterization_histogram_recorded_
= false;
596 SetNeedsFullTreeSync();
599 void LayerTreeHost::SetDebugState(const LayerTreeDebugState
& debug_state
) {
600 LayerTreeDebugState new_debug_state
=
601 LayerTreeDebugState::Unite(settings_
.initial_debug_state
, debug_state
);
603 if (LayerTreeDebugState::Equal(debug_state_
, new_debug_state
))
606 debug_state_
= new_debug_state
;
608 rendering_stats_instrumentation_
->set_record_rendering_stats(
609 debug_state_
.RecordRenderingStats());
612 proxy_
->SetDebugState(debug_state
);
615 bool LayerTreeHost::UseGpuRasterization() const {
616 if (settings_
.gpu_rasterization_forced
) {
618 } else if (settings_
.gpu_rasterization_enabled
) {
619 return has_gpu_rasterization_trigger_
&&
620 content_is_suitable_for_gpu_rasterization_
;
626 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger
) {
627 if (has_trigger
== has_gpu_rasterization_trigger_
)
630 has_gpu_rasterization_trigger_
= has_trigger
;
631 TRACE_EVENT_INSTANT1("cc",
632 "LayerTreeHost::SetHasGpuRasterizationTrigger",
633 TRACE_EVENT_SCOPE_THREAD
,
635 has_gpu_rasterization_trigger_
);
638 void LayerTreeHost::SetViewportSize(const gfx::Size
& device_viewport_size
) {
639 if (device_viewport_size
== device_viewport_size_
)
642 device_viewport_size_
= device_viewport_size
;
647 void LayerTreeHost::SetTopControlsLayoutHeight(float height
) {
648 if (top_controls_layout_height_
== height
)
651 top_controls_layout_height_
= height
;
655 void LayerTreeHost::SetTopControlsContentOffset(float offset
) {
656 if (top_controls_content_offset_
== offset
)
659 top_controls_content_offset_
= offset
;
663 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta
) {
664 DCHECK(CommitRequested());
665 page_scale_factor_
*= page_scale_delta
;
668 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor
,
669 float min_page_scale_factor
,
670 float max_page_scale_factor
) {
671 if (page_scale_factor
== page_scale_factor_
&&
672 min_page_scale_factor
== min_page_scale_factor_
&&
673 max_page_scale_factor
== max_page_scale_factor_
)
676 page_scale_factor_
= page_scale_factor
;
677 min_page_scale_factor_
= min_page_scale_factor
;
678 max_page_scale_factor_
= max_page_scale_factor
;
682 void LayerTreeHost::SetOverhangBitmap(const SkBitmap
& bitmap
) {
683 DCHECK(bitmap
.width() && bitmap
.height());
684 DCHECK_EQ(bitmap
.bytesPerPixel(), 4);
686 SkBitmap bitmap_copy
;
687 if (bitmap
.isImmutable()) {
688 bitmap_copy
= bitmap
;
690 bitmap
.copyTo(&bitmap_copy
);
691 bitmap_copy
.setImmutable();
694 UIResourceBitmap
overhang_bitmap(bitmap_copy
);
695 overhang_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
696 overhang_ui_resource_
= ScopedUIResource::Create(this, overhang_bitmap
);
699 void LayerTreeHost::SetVisible(bool visible
) {
700 if (visible_
== visible
)
705 proxy_
->SetVisible(visible
);
708 void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d
& target_offset
,
711 base::TimeDelta duration
) {
712 pending_page_scale_animation_
.reset(new PendingPageScaleAnimation
);
713 pending_page_scale_animation_
->target_offset
= target_offset
;
714 pending_page_scale_animation_
->use_anchor
= use_anchor
;
715 pending_page_scale_animation_
->scale
= scale
;
716 pending_page_scale_animation_
->duration
= duration
;
721 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
722 proxy_
->NotifyInputThrottledUntilCommit();
725 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time
) {
726 DCHECK(!proxy_
->HasImplThread());
727 // This function is only valid when not using the scheduler.
728 DCHECK(!settings_
.single_thread_proxy_scheduler
);
729 SingleThreadProxy
* proxy
= static_cast<SingleThreadProxy
*>(proxy_
.get());
731 SetLayerTreeHostClientReady();
732 proxy
->CompositeImmediately(frame_begin_time
);
735 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue
* queue
) {
736 DCHECK(!output_surface_lost_
);
741 DCHECK(!root_layer()->parent());
743 bool result
= UpdateLayers(root_layer(), queue
);
745 micro_benchmark_controller_
.DidUpdateLayers();
747 return result
|| next_commit_forces_redraw_
;
750 static Layer
* FindFirstScrollableLayer(Layer
* layer
) {
754 if (layer
->scrollable())
757 for (size_t i
= 0; i
< layer
->children().size(); ++i
) {
758 Layer
* found
= FindFirstScrollableLayer(layer
->children()[i
].get());
766 void LayerTreeHost::RecordGpuRasterizationHistogram() {
767 // Gpu rasterization is only supported when impl-side painting is enabled.
768 if (gpu_rasterization_histogram_recorded_
|| !settings_
.impl_side_painting
)
771 // Record how widely gpu rasterization is enabled.
772 // This number takes device/gpu whitelisting/backlisting into account.
773 // Note that we do not consider the forced gpu rasterization mode, which is
774 // mostly used for debugging purposes.
775 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
776 settings_
.gpu_rasterization_enabled
);
777 if (settings_
.gpu_rasterization_enabled
) {
778 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered",
779 has_gpu_rasterization_trigger_
);
780 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
781 content_is_suitable_for_gpu_rasterization_
);
782 // Record how many pages actually get gpu rasterization when enabled.
783 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed",
784 (has_gpu_rasterization_trigger_
&&
785 content_is_suitable_for_gpu_rasterization_
));
788 gpu_rasterization_histogram_recorded_
= true;
791 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer
* layer
) {
792 if (!layer
->SupportsLCDText())
795 lcd_text_metrics_
.total_num_cc_layers
++;
796 if (layer
->draw_properties().can_use_lcd_text
) {
797 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
++;
798 if (layer
->contents_opaque())
799 lcd_text_metrics_
.total_num_cc_layers_will_use_lcd_text
++;
803 bool LayerTreeHost::UsingSharedMemoryResources() {
804 return GetRendererCapabilities().using_shared_memory_resources
;
807 bool LayerTreeHost::UpdateLayers(Layer
* root_layer
,
808 ResourceUpdateQueue
* queue
) {
809 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
810 "source_frame_number", source_frame_number());
812 RenderSurfaceLayerList update_list
;
816 Layer
* root_scroll
= FindFirstScrollableLayer(root_layer
);
817 Layer
* page_scale_layer
= page_scale_layer_
.get();
818 if (!page_scale_layer
&& root_scroll
)
819 page_scale_layer
= root_scroll
->parent();
821 if (hud_layer_
.get()) {
822 hud_layer_
->PrepareForCalculateDrawProperties(
823 device_viewport_size(), device_scale_factor_
);
826 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
827 bool can_render_to_separate_surface
= true;
828 // TODO(vmpstr): Passing 0 as the current render surface layer list id means
829 // that we won't be able to detect if a layer is part of |update_list|.
830 // Change this if this information is required.
831 int render_surface_layer_list_id
= 0;
832 LayerTreeHostCommon::CalcDrawPropsMainInputs
inputs(
834 device_viewport_size(),
836 device_scale_factor_
,
839 GetRendererCapabilities().max_texture_size
,
840 settings_
.can_use_lcd_text
,
841 can_render_to_separate_surface
,
842 settings_
.layer_transforms_should_scale_layer_contents
,
844 render_surface_layer_list_id
);
845 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
847 if (total_frames_used_for_lcd_text_metrics_
<=
848 kTotalFramesToUseForLCDTextMetrics
) {
849 LayerTreeHostCommon::CallFunctionForSubtree(
851 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback
,
852 base::Unretained(this)));
853 total_frames_used_for_lcd_text_metrics_
++;
856 if (total_frames_used_for_lcd_text_metrics_
==
857 kTotalFramesToUseForLCDTextMetrics
) {
858 total_frames_used_for_lcd_text_metrics_
++;
860 UMA_HISTOGRAM_PERCENTAGE(
861 "Renderer4.LCDText.PercentageOfCandidateLayers",
862 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
* 100.0 /
863 lcd_text_metrics_
.total_num_cc_layers
);
864 UMA_HISTOGRAM_PERCENTAGE(
865 "Renderer4.LCDText.PercentageOfAALayers",
866 lcd_text_metrics_
.total_num_cc_layers_will_use_lcd_text
* 100.0 /
867 lcd_text_metrics_
.total_num_cc_layers_can_use_lcd_text
);
871 // Reset partial texture update requests.
872 partial_texture_update_requests_
= 0;
874 bool did_paint_content
= false;
875 bool need_more_updates
= false;
877 update_list
, queue
, &did_paint_content
, &need_more_updates
);
878 if (need_more_updates
) {
879 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
880 prepaint_callback_
.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint
,
881 base::Unretained(this)));
882 static base::TimeDelta prepaint_delay
=
883 base::TimeDelta::FromMilliseconds(100);
884 base::MessageLoop::current()->PostDelayedTask(
885 FROM_HERE
, prepaint_callback_
.callback(), prepaint_delay
);
888 return did_paint_content
;
891 void LayerTreeHost::TriggerPrepaint() {
892 prepaint_callback_
.Cancel();
893 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
897 static void LayerTreeHostReduceMemoryCallback(Layer
* layer
) {
898 layer
->ReduceMemoryUsage();
901 void LayerTreeHost::ReduceMemoryUsage() {
905 LayerTreeHostCommon::CallFunctionForSubtree(
907 base::Bind(&LayerTreeHostReduceMemoryCallback
));
910 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes
) {
911 DCHECK(surface_memory_placeholder_
);
913 // Surfaces have a place holder for their memory since they are managed
914 // independantly but should still be tracked and reduce other memory usage.
915 surface_memory_placeholder_
->SetTextureManager(
916 contents_texture_manager_
.get());
917 surface_memory_placeholder_
->set_request_priority(
918 PriorityCalculator::RenderSurfacePriority());
919 surface_memory_placeholder_
->SetToSelfManagedMemoryPlaceholder(
920 surface_memory_bytes
);
923 void LayerTreeHost::SetPrioritiesForLayers(
924 const RenderSurfaceLayerList
& update_list
) {
925 PriorityCalculator calculator
;
926 typedef LayerIterator
<Layer
> LayerIteratorType
;
927 LayerIteratorType end
= LayerIteratorType::End(&update_list
);
928 for (LayerIteratorType it
= LayerIteratorType::Begin(&update_list
);
931 if (it
.represents_itself()) {
932 it
->SetTexturePriorities(calculator
);
933 } else if (it
.represents_target_render_surface()) {
934 if (it
->mask_layer())
935 it
->mask_layer()->SetTexturePriorities(calculator
);
936 if (it
->replica_layer() && it
->replica_layer()->mask_layer())
937 it
->replica_layer()->mask_layer()->SetTexturePriorities(calculator
);
942 void LayerTreeHost::PrioritizeTextures(
943 const RenderSurfaceLayerList
& render_surface_layer_list
) {
944 if (!contents_texture_manager_
)
947 contents_texture_manager_
->ClearPriorities();
949 size_t memory_for_render_surfaces_metric
=
950 CalculateMemoryForRenderSurfaces(render_surface_layer_list
);
952 SetPrioritiesForLayers(render_surface_layer_list
);
953 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric
);
955 contents_texture_manager_
->PrioritizeTextures();
958 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
959 const RenderSurfaceLayerList
& update_list
) {
960 size_t readback_bytes
= 0;
961 size_t max_background_texture_bytes
= 0;
962 size_t contents_texture_bytes
= 0;
964 // Start iteration at 1 to skip the root surface as it does not have a texture
966 for (size_t i
= 1; i
< update_list
.size(); ++i
) {
967 Layer
* render_surface_layer
= update_list
.at(i
);
968 RenderSurface
* render_surface
= render_surface_layer
->render_surface();
971 Resource::MemorySizeBytes(render_surface
->content_rect().size(),
973 contents_texture_bytes
+= bytes
;
975 if (render_surface_layer
->background_filters().IsEmpty())
978 if (bytes
> max_background_texture_bytes
)
979 max_background_texture_bytes
= bytes
;
980 if (!readback_bytes
) {
981 readback_bytes
= Resource::MemorySizeBytes(device_viewport_size_
,
985 return readback_bytes
+ max_background_texture_bytes
+ contents_texture_bytes
;
988 void LayerTreeHost::PaintMasksForRenderSurface(Layer
* render_surface_layer
,
989 ResourceUpdateQueue
* queue
,
990 bool* did_paint_content
,
991 bool* need_more_updates
) {
992 // Note: Masks and replicas only exist for layers that own render surfaces. If
993 // we reach this point in code, we already know that at least something will
994 // be drawn into this render surface, so the mask and replica should be
997 Layer
* mask_layer
= render_surface_layer
->mask_layer();
999 *did_paint_content
|= mask_layer
->Update(queue
, NULL
);
1000 *need_more_updates
|= mask_layer
->NeedMoreUpdates();
1003 Layer
* replica_mask_layer
=
1004 render_surface_layer
->replica_layer() ?
1005 render_surface_layer
->replica_layer()->mask_layer() : NULL
;
1006 if (replica_mask_layer
) {
1007 *did_paint_content
|= replica_mask_layer
->Update(queue
, NULL
);
1008 *need_more_updates
|= replica_mask_layer
->NeedMoreUpdates();
1012 void LayerTreeHost::PaintLayerContents(
1013 const RenderSurfaceLayerList
& render_surface_layer_list
,
1014 ResourceUpdateQueue
* queue
,
1015 bool* did_paint_content
,
1016 bool* need_more_updates
) {
1017 OcclusionTracker
<Layer
> occlusion_tracker(
1018 root_layer_
->render_surface()->content_rect());
1019 occlusion_tracker
.set_minimum_tracking_size(
1020 settings_
.minimum_occlusion_tracking_size
);
1022 PrioritizeTextures(render_surface_layer_list
);
1024 in_paint_layer_contents_
= true;
1026 // Iterates front-to-back to allow for testing occlusion and performing
1027 // culling during the tree walk.
1028 typedef LayerIterator
<Layer
> LayerIteratorType
;
1029 LayerIteratorType end
= LayerIteratorType::End(&render_surface_layer_list
);
1030 for (LayerIteratorType it
=
1031 LayerIteratorType::Begin(&render_surface_layer_list
);
1034 occlusion_tracker
.EnterLayer(it
);
1036 if (it
.represents_target_render_surface()) {
1037 PaintMasksForRenderSurface(
1038 *it
, queue
, did_paint_content
, need_more_updates
);
1039 } else if (it
.represents_itself()) {
1040 DCHECK(!it
->paint_properties().bounds
.IsEmpty());
1041 *did_paint_content
|= it
->Update(queue
, &occlusion_tracker
);
1042 *need_more_updates
|= it
->NeedMoreUpdates();
1043 // Note the '&&' with previous is-suitable state.
1044 // This means that once the layer-tree becomes unsuitable for gpu
1045 // rasterization due to some content, it will continue to be unsuitable
1046 // even if that content is replaced by gpu-friendly content.
1047 // This is to avoid switching back-and-forth between gpu and sw
1048 // rasterization which may be both bad for performance and visually
1050 content_is_suitable_for_gpu_rasterization_
&=
1051 it
->IsSuitableForGpuRasterization();
1054 occlusion_tracker
.LeaveLayer(it
);
1057 in_paint_layer_contents_
= false;
1060 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet
* info
) {
1061 ScopedPtrVector
<SwapPromise
>::iterator it
= info
->swap_promises
.begin();
1062 for (; it
!= info
->swap_promises
.end(); ++it
) {
1063 scoped_ptr
<SwapPromise
> swap_promise(info
->swap_promises
.take(it
));
1064 TRACE_EVENT_FLOW_STEP0("input",
1066 TRACE_ID_DONT_MANGLE(swap_promise
->TraceId()),
1067 "Main thread scroll update");
1068 QueueSwapPromise(swap_promise
.Pass());
1071 gfx::Vector2d inner_viewport_scroll_delta
;
1072 gfx::Vector2d outer_viewport_scroll_delta
;
1074 if (root_layer_
.get()) {
1075 for (size_t i
= 0; i
< info
->scrolls
.size(); ++i
) {
1076 Layer
* layer
= LayerTreeHostCommon::FindLayerInSubtree(
1077 root_layer_
.get(), info
->scrolls
[i
].layer_id
);
1080 if (layer
== outer_viewport_scroll_layer_
.get()) {
1081 outer_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
1082 } else if (layer
== inner_viewport_scroll_layer_
.get()) {
1083 inner_viewport_scroll_delta
+= info
->scrolls
[i
].scroll_delta
;
1085 layer
->SetScrollOffsetFromImplSide(
1086 gfx::ScrollOffsetWithDelta(layer
->scroll_offset(),
1087 info
->scrolls
[i
].scroll_delta
));
1092 if (!inner_viewport_scroll_delta
.IsZero() ||
1093 !outer_viewport_scroll_delta
.IsZero() ||
1094 info
->page_scale_delta
!= 1.f
||
1095 info
->top_controls_delta
) {
1096 // Preemptively apply the scroll offset and scale delta here before sending
1097 // it to the client. If the client comes back and sets it to the same
1098 // value, then the layer can early out without needing a full commit.
1099 if (inner_viewport_scroll_layer_
.get()) {
1100 inner_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
1101 gfx::ScrollOffsetWithDelta(
1102 inner_viewport_scroll_layer_
->scroll_offset(),
1103 inner_viewport_scroll_delta
));
1106 if (outer_viewport_scroll_layer_
.get()) {
1107 outer_viewport_scroll_layer_
->SetScrollOffsetFromImplSide(
1108 gfx::ScrollOffsetWithDelta(
1109 outer_viewport_scroll_layer_
->scroll_offset(),
1110 outer_viewport_scroll_delta
));
1113 ApplyPageScaleDeltaFromImplSide(info
->page_scale_delta
);
1114 if (!settings_
.use_pinch_virtual_viewport
) {
1115 client_
->ApplyViewportDeltas(
1116 inner_viewport_scroll_delta
+ outer_viewport_scroll_delta
,
1117 info
->page_scale_delta
,
1118 info
->top_controls_delta
);
1120 client_
->ApplyViewportDeltas(
1121 inner_viewport_scroll_delta
,
1122 outer_viewport_scroll_delta
,
1123 info
->page_scale_delta
,
1124 info
->top_controls_delta
);
1129 void LayerTreeHost::StartRateLimiter() {
1130 if (inside_begin_main_frame_
)
1133 if (!rate_limit_timer_
.IsRunning()) {
1134 rate_limit_timer_
.Start(FROM_HERE
,
1137 &LayerTreeHost::RateLimit
);
1141 void LayerTreeHost::StopRateLimiter() {
1142 rate_limit_timer_
.Stop();
1145 void LayerTreeHost::RateLimit() {
1146 // Force a no-op command on the compositor context, so that any ratelimiting
1147 // commands will wait for the compositing context, and therefore for the
1149 proxy_
->ForceSerializeOnSwapBuffers();
1150 client_
->RateLimitSharedMainThreadContext();
1153 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1154 if (!proxy_
->GetRendererCapabilities().allow_partial_texture_updates
)
1156 return !proxy_
->HasImplThread();
1159 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1160 size_t max_partial_texture_updates
= 0;
1161 if (proxy_
->GetRendererCapabilities().allow_partial_texture_updates
&&
1162 !settings_
.impl_side_painting
) {
1163 max_partial_texture_updates
=
1164 std::min(settings_
.max_partial_texture_updates
,
1165 proxy_
->MaxPartialTextureUpdates());
1167 return max_partial_texture_updates
;
1170 bool LayerTreeHost::RequestPartialTextureUpdate() {
1171 if (partial_texture_update_requests_
>= MaxPartialTextureUpdates())
1174 partial_texture_update_requests_
++;
1178 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor
) {
1179 if (device_scale_factor
== device_scale_factor_
)
1181 device_scale_factor_
= device_scale_factor
;
1186 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints
,
1187 TopControlsState current
,
1189 if (!settings_
.calculate_top_controls_position
)
1192 // Top controls are only used in threaded mode.
1193 proxy_
->ImplThreadTaskRunner()->PostTask(
1195 base::Bind(&TopControlsManager::UpdateTopControlsState
,
1196 top_controls_manager_weak_ptr_
,
1202 void LayerTreeHost::AsValueInto(base::debug::TracedValue
* state
) const {
1203 state
->BeginDictionary("proxy");
1204 proxy_
->AsValueInto(state
);
1205 state
->EndDictionary();
1208 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time
) {
1209 if (!settings_
.accelerated_animation_enabled
||
1210 animation_registrar_
->active_animation_controllers().empty())
1213 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1215 AnimationRegistrar::AnimationControllerMap copy
=
1216 animation_registrar_
->active_animation_controllers();
1217 for (AnimationRegistrar::AnimationControllerMap::iterator iter
= copy
.begin();
1220 (*iter
).second
->Animate(monotonic_time
);
1221 bool start_ready_animations
= true;
1222 (*iter
).second
->UpdateState(start_ready_animations
, NULL
);
1226 UIResourceId
LayerTreeHost::CreateUIResource(UIResourceClient
* client
) {
1229 UIResourceId next_id
= next_ui_resource_id_
++;
1230 DCHECK(ui_resource_client_map_
.find(next_id
) ==
1231 ui_resource_client_map_
.end());
1233 bool resource_lost
= false;
1234 UIResourceRequest
request(UIResourceRequest::UIResourceCreate
,
1236 client
->GetBitmap(next_id
, resource_lost
));
1237 ui_resource_request_queue_
.push_back(request
);
1239 UIResourceClientData data
;
1240 data
.client
= client
;
1241 data
.size
= request
.GetBitmap().GetSize();
1243 ui_resource_client_map_
[request
.GetId()] = data
;
1244 return request
.GetId();
1247 // Deletes a UI resource. May safely be called more than once.
1248 void LayerTreeHost::DeleteUIResource(UIResourceId uid
) {
1249 UIResourceClientMap::iterator iter
= ui_resource_client_map_
.find(uid
);
1250 if (iter
== ui_resource_client_map_
.end())
1253 UIResourceRequest
request(UIResourceRequest::UIResourceDelete
, uid
);
1254 ui_resource_request_queue_
.push_back(request
);
1255 ui_resource_client_map_
.erase(iter
);
1258 void LayerTreeHost::RecreateUIResources() {
1259 for (UIResourceClientMap::iterator iter
= ui_resource_client_map_
.begin();
1260 iter
!= ui_resource_client_map_
.end();
1262 UIResourceId uid
= iter
->first
;
1263 const UIResourceClientData
& data
= iter
->second
;
1264 bool resource_lost
= true;
1265 UIResourceRequest
request(UIResourceRequest::UIResourceCreate
,
1267 data
.client
->GetBitmap(uid
, resource_lost
));
1268 ui_resource_request_queue_
.push_back(request
);
1272 // Returns the size of a resource given its id.
1273 gfx::Size
LayerTreeHost::GetUIResourceSize(UIResourceId uid
) const {
1274 UIResourceClientMap::const_iterator iter
= ui_resource_client_map_
.find(uid
);
1275 if (iter
== ui_resource_client_map_
.end())
1278 const UIResourceClientData
& data
= iter
->second
;
1282 void LayerTreeHost::RegisterViewportLayers(
1283 scoped_refptr
<Layer
> page_scale_layer
,
1284 scoped_refptr
<Layer
> inner_viewport_scroll_layer
,
1285 scoped_refptr
<Layer
> outer_viewport_scroll_layer
) {
1286 page_scale_layer_
= page_scale_layer
;
1287 inner_viewport_scroll_layer_
= inner_viewport_scroll_layer
;
1288 outer_viewport_scroll_layer_
= outer_viewport_scroll_layer
;
1291 void LayerTreeHost::RegisterSelection(const LayerSelectionBound
& start
,
1292 const LayerSelectionBound
& end
) {
1293 if (selection_start_
== start
&& selection_end_
== end
)
1296 selection_start_
= start
;
1297 selection_end_
= end
;
1301 int LayerTreeHost::ScheduleMicroBenchmark(
1302 const std::string
& benchmark_name
,
1303 scoped_ptr
<base::Value
> value
,
1304 const MicroBenchmark::DoneCallback
& callback
) {
1305 return micro_benchmark_controller_
.ScheduleRun(
1306 benchmark_name
, value
.Pass(), callback
);
1309 bool LayerTreeHost::SendMessageToMicroBenchmark(int id
,
1310 scoped_ptr
<base::Value
> value
) {
1311 return micro_benchmark_controller_
.SendMessage(id
, value
.Pass());
1314 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1315 swap_promise_monitor_
.insert(monitor
);
1318 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor
* monitor
) {
1319 swap_promise_monitor_
.erase(monitor
);
1322 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1323 std::set
<SwapPromiseMonitor
*>::iterator it
= swap_promise_monitor_
.begin();
1324 for (; it
!= swap_promise_monitor_
.end(); it
++)
1325 (*it
)->OnSetNeedsCommitOnMain();
1328 void LayerTreeHost::QueueSwapPromise(scoped_ptr
<SwapPromise
> swap_promise
) {
1329 DCHECK(swap_promise
);
1330 swap_promise_list_
.push_back(swap_promise
.Pass());
1333 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason
) {
1334 for (size_t i
= 0; i
< swap_promise_list_
.size(); i
++)
1335 swap_promise_list_
[i
]->DidNotSwap(reason
);
1336 swap_promise_list_
.clear();