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.
4
5 #include "cc/trees/layer_tree_host.h"
6
7 #include <algorithm>
8 #include <stack>
9 #include <string>
10
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/overdraw_metrics.h"
24 #include "cc/debug/rendering_stats_instrumentation.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"
43
44 namespace {
45 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
46 }
47
48 namespace cc {
49
RendererCapabilities(ResourceFormat best_texture_format,bool allow_partial_texture_updates,bool using_offscreen_context3d,int max_texture_size,bool using_shared_memory_resources)50 RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
51 bool allow_partial_texture_updates,
52 bool using_offscreen_context3d,
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 using_offscreen_context3d(using_offscreen_context3d),
58 max_texture_size(max_texture_size),
59 using_shared_memory_resources(using_shared_memory_resources) {}
60
RendererCapabilities()61 RendererCapabilities::RendererCapabilities()
62 : best_texture_format(RGBA_8888),
63 allow_partial_texture_updates(false),
64 using_offscreen_context3d(false),
65 max_texture_size(0),
66 using_shared_memory_resources(false) {}
67
~RendererCapabilities()68 RendererCapabilities::~RendererCapabilities() {}
69
CreateThreaded(LayerTreeHostClient * client,SharedBitmapManager * manager,const LayerTreeSettings & settings,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)70 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
71 LayerTreeHostClient* client,
72 SharedBitmapManager* manager,
73 const LayerTreeSettings& settings,
74 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
75 DCHECK(impl_task_runner);
76 scoped_ptr<LayerTreeHost> layer_tree_host(
77 new LayerTreeHost(client, manager, settings));
78 if (!layer_tree_host->InitializeThreaded(impl_task_runner))
79 return scoped_ptr<LayerTreeHost>();
80 return layer_tree_host.Pass();
81 }
82
CreateSingleThreaded(LayerTreeHostClient * client,LayerTreeHostSingleThreadClient * single_thread_client,SharedBitmapManager * manager,const LayerTreeSettings & settings)83 scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded(
84 LayerTreeHostClient* client,
85 LayerTreeHostSingleThreadClient* single_thread_client,
86 SharedBitmapManager* manager,
87 const LayerTreeSettings& settings) {
88 scoped_ptr<LayerTreeHost> layer_tree_host(
89 new LayerTreeHost(client, manager, settings));
90 if (!layer_tree_host->InitializeSingleThreaded(single_thread_client))
91 return scoped_ptr<LayerTreeHost>();
92 return layer_tree_host.Pass();
93 }
94
95
LayerTreeHost(LayerTreeHostClient * client,SharedBitmapManager * manager,const LayerTreeSettings & settings)96 LayerTreeHost::LayerTreeHost(
97 LayerTreeHostClient* client,
98 SharedBitmapManager* manager,
99 const LayerTreeSettings& settings)
100 : micro_benchmark_controller_(this),
101 next_ui_resource_id_(1),
102 animating_(false),
103 needs_full_tree_sync_(true),
104 needs_filter_context_(false),
105 client_(client),
106 source_frame_number_(0),
107 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
108 output_surface_can_be_initialized_(true),
109 output_surface_lost_(true),
110 num_failed_recreate_attempts_(0),
111 settings_(settings),
112 debug_state_(settings.initial_debug_state),
113 overdraw_bottom_height_(0.f),
114 device_scale_factor_(1.f),
115 visible_(true),
116 page_scale_factor_(1.f),
117 min_page_scale_factor_(1.f),
118 max_page_scale_factor_(1.f),
119 trigger_idle_updates_(true),
120 background_color_(SK_ColorWHITE),
121 has_transparent_background_(false),
122 partial_texture_update_requests_(0),
123 in_paint_layer_contents_(false),
124 total_frames_used_for_lcd_text_metrics_(0),
125 id_(s_layer_tree_host_sequence_number.GetNext() + 1),
126 next_commit_forces_redraw_(false),
127 shared_bitmap_manager_(manager) {
128 if (settings_.accelerated_animation_enabled)
129 animation_registrar_ = AnimationRegistrar::Create();
130 rendering_stats_instrumentation_->set_record_rendering_stats(
131 debug_state_.RecordRenderingStats());
132 }
133
InitializeThreaded(scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)134 bool LayerTreeHost::InitializeThreaded(
135 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
136 return InitializeProxy(ThreadProxy::Create(this, impl_task_runner));
137 }
138
InitializeSingleThreaded(LayerTreeHostSingleThreadClient * single_thread_client)139 bool LayerTreeHost::InitializeSingleThreaded(
140 LayerTreeHostSingleThreadClient* single_thread_client) {
141 return InitializeProxy(
142 SingleThreadProxy::Create(this, single_thread_client));
143 }
144
InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing)145 bool LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) {
146 return InitializeProxy(proxy_for_testing.Pass());
147 }
148
InitializeProxy(scoped_ptr<Proxy> proxy)149 bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
150 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
151
152 scoped_ptr<OutputSurface> output_surface(CreateOutputSurface());
153 if (!output_surface)
154 return false;
155
156 proxy_ = proxy.Pass();
157 proxy_->Start(output_surface.Pass());
158 return true;
159 }
160
~LayerTreeHost()161 LayerTreeHost::~LayerTreeHost() {
162 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
163
164 overhang_ui_resource_.reset();
165
166 if (root_layer_.get())
167 root_layer_->SetLayerTreeHost(NULL);
168
169 if (proxy_) {
170 DCHECK(proxy_->IsMainThread());
171 proxy_->Stop();
172 }
173
174 if (root_layer_.get()) {
175 // The layer tree must be destroyed before the layer tree host. We've
176 // made a contract with our animation controllers that the registrar
177 // will outlive them, and we must make good.
178 root_layer_ = NULL;
179 }
180 }
181
SetLayerTreeHostClientReady()182 void LayerTreeHost::SetLayerTreeHostClientReady() {
183 proxy_->SetLayerTreeHostClientReady();
184 }
185
LayerTreeHostOnOutputSurfaceCreatedCallback(Layer * layer)186 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
187 layer->OnOutputSurfaceCreated();
188 }
189
190 LayerTreeHost::CreateResult
OnCreateAndInitializeOutputSurfaceAttempted(bool success)191 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
192 TRACE_EVENT1("cc",
193 "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
194 "success",
195 success);
196
197 DCHECK(output_surface_lost_);
198 if (success) {
199 output_surface_lost_ = false;
200
201 if (!contents_texture_manager_ && !settings_.impl_side_painting) {
202 contents_texture_manager_ =
203 PrioritizedResourceManager::Create(proxy_.get());
204 surface_memory_placeholder_ =
205 contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
206 }
207
208 if (root_layer()) {
209 LayerTreeHostCommon::CallFunctionForSubtree(
210 root_layer(),
211 base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
212 }
213
214 client_->DidInitializeOutputSurface(true);
215 return CreateSucceeded;
216 }
217
218 // Failure path.
219
220 client_->DidFailToInitializeOutputSurface();
221
222 // Tolerate a certain number of recreation failures to work around races
223 // in the output-surface-lost machinery.
224 ++num_failed_recreate_attempts_;
225 if (num_failed_recreate_attempts_ >= 5) {
226 // We have tried too many times to recreate the output surface. Tell the
227 // host to fall back to software rendering.
228 output_surface_can_be_initialized_ = false;
229 client_->DidInitializeOutputSurface(false);
230 return CreateFailedAndGaveUp;
231 }
232
233 return CreateFailedButTryAgain;
234 }
235
DeleteContentsTexturesOnImplThread(ResourceProvider * resource_provider)236 void LayerTreeHost::DeleteContentsTexturesOnImplThread(
237 ResourceProvider* resource_provider) {
238 DCHECK(proxy_->IsImplThread());
239 if (contents_texture_manager_)
240 contents_texture_manager_->ClearAllMemory(resource_provider);
241 }
242
AcquireLayerTextures()243 void LayerTreeHost::AcquireLayerTextures() {
244 DCHECK(proxy_->IsMainThread());
245 proxy_->AcquireLayerTextures();
246 }
247
DidBeginMainFrame()248 void LayerTreeHost::DidBeginMainFrame() {
249 client_->DidBeginMainFrame();
250 }
251
UpdateClientAnimations(base::TimeTicks frame_begin_time)252 void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
253 animating_ = true;
254 client_->Animate((frame_begin_time - base::TimeTicks()).InSecondsF());
255 animating_ = false;
256 }
257
DidStopFlinging()258 void LayerTreeHost::DidStopFlinging() {
259 proxy_->MainThreadHasStoppedFlinging();
260 }
261
Layout()262 void LayerTreeHost::Layout() {
263 client_->Layout();
264 }
265
BeginCommitOnImplThread(LayerTreeHostImpl * host_impl)266 void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
267 DCHECK(proxy_->IsImplThread());
268 TRACE_EVENT0("cc", "LayerTreeHost::CommitTo");
269 }
270
271 // This function commits the LayerTreeHost to an impl tree. When modifying
272 // this function, keep in mind that the function *runs* on the impl thread! Any
273 // code that is logically a main thread operation, e.g. deletion of a Layer,
274 // should be delayed until the LayerTreeHost::CommitComplete, which will run
275 // after the commit, but on the main thread.
FinishCommitOnImplThread(LayerTreeHostImpl * host_impl)276 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
277 DCHECK(proxy_->IsImplThread());
278
279 // If there are linked evicted backings, these backings' resources may be put
280 // into the impl tree, so we can't draw yet. Determine this before clearing
281 // all evicted backings.
282 bool new_impl_tree_has_no_evicted_resources = false;
283 if (contents_texture_manager_) {
284 new_impl_tree_has_no_evicted_resources =
285 !contents_texture_manager_->LinkedEvictedBackingsExist();
286
287 // If the memory limit has been increased since this now-finishing
288 // commit began, and the extra now-available memory would have been used,
289 // then request another commit.
290 if (contents_texture_manager_->MaxMemoryLimitBytes() <
291 host_impl->memory_allocation_limit_bytes() &&
292 contents_texture_manager_->MaxMemoryLimitBytes() <
293 contents_texture_manager_->MaxMemoryNeededBytes()) {
294 host_impl->SetNeedsCommit();
295 }
296
297 host_impl->set_max_memory_needed_bytes(
298 contents_texture_manager_->MaxMemoryNeededBytes());
299
300 contents_texture_manager_->UpdateBackingsState(
301 host_impl->resource_provider());
302 }
303
304 // In impl-side painting, synchronize to the pending tree so that it has
305 // time to raster before being displayed. If no pending tree is needed,
306 // synchronization can happen directly to the active tree and
307 // unlinked contents resources can be reclaimed immediately.
308 LayerTreeImpl* sync_tree;
309 if (settings_.impl_side_painting) {
310 // Commits should not occur while there is already a pending tree.
311 DCHECK(!host_impl->pending_tree());
312 host_impl->CreatePendingTree();
313 sync_tree = host_impl->pending_tree();
314 if (next_commit_forces_redraw_)
315 sync_tree->ForceRedrawNextActivation();
316 } else {
317 if (next_commit_forces_redraw_)
318 host_impl->SetFullRootLayerDamage();
319 contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
320 sync_tree = host_impl->active_tree();
321 }
322
323 next_commit_forces_redraw_ = false;
324
325 sync_tree->set_source_frame_number(source_frame_number());
326
327 if (needs_full_tree_sync_)
328 sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
329 root_layer(), sync_tree->DetachLayerTree(), sync_tree));
330 {
331 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
332 TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
333 }
334
335 sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
336 needs_full_tree_sync_ = false;
337
338 if (hud_layer_.get()) {
339 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree(
340 sync_tree->root_layer(), hud_layer_->id());
341 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
342 } else {
343 sync_tree->set_hud_layer(NULL);
344 }
345
346 sync_tree->set_background_color(background_color_);
347 sync_tree->set_has_transparent_background(has_transparent_background_);
348
349 sync_tree->FindRootScrollLayer();
350
351 // TODO(wjmaclean) For now, not all LTH clients will register viewports, so
352 // only set them when available..
353 if (page_scale_layer_) {
354 DCHECK(inner_viewport_scroll_layer_);
355 sync_tree->SetViewportLayersFromIds(
356 page_scale_layer_->id(),
357 inner_viewport_scroll_layer_->id(),
358 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
359 : Layer::INVALID_ID);
360 } else {
361 sync_tree->ClearViewportLayers();
362 }
363
364 float page_scale_delta, sent_page_scale_delta;
365 if (settings_.impl_side_painting) {
366 // Update the delta from the active tree, which may have
367 // adjusted its delta prior to the pending tree being created.
368 // This code is equivalent to that in LayerTreeImpl::SetPageScaleDelta.
369 DCHECK_EQ(1.f, sync_tree->sent_page_scale_delta());
370 page_scale_delta = host_impl->active_tree()->page_scale_delta();
371 sent_page_scale_delta = host_impl->active_tree()->sent_page_scale_delta();
372 } else {
373 page_scale_delta = sync_tree->page_scale_delta();
374 sent_page_scale_delta = sync_tree->sent_page_scale_delta();
375 sync_tree->set_sent_page_scale_delta(1.f);
376 }
377
378 sync_tree->SetPageScaleFactorAndLimits(page_scale_factor_,
379 min_page_scale_factor_,
380 max_page_scale_factor_);
381 sync_tree->SetPageScaleDelta(page_scale_delta / sent_page_scale_delta);
382
383 sync_tree->PassSwapPromises(&swap_promise_list_);
384
385 host_impl->SetViewportSize(device_viewport_size_);
386 host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_);
387 host_impl->SetDeviceScaleFactor(device_scale_factor_);
388 host_impl->SetDebugState(debug_state_);
389 if (pending_page_scale_animation_) {
390 host_impl->StartPageScaleAnimation(
391 pending_page_scale_animation_->target_offset,
392 pending_page_scale_animation_->use_anchor,
393 pending_page_scale_animation_->scale,
394 pending_page_scale_animation_->duration);
395 pending_page_scale_animation_.reset();
396 }
397
398 if (!ui_resource_request_queue_.empty()) {
399 sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
400 ui_resource_request_queue_.clear();
401 // Process any ui resource requests in the queue. For impl-side-painting,
402 // the queue is processed in LayerTreeHostImpl::ActivatePendingTree.
403 if (!settings_.impl_side_painting)
404 sync_tree->ProcessUIResourceRequestQueue();
405 }
406 if (overhang_ui_resource_) {
407 host_impl->SetOverhangUIResource(
408 overhang_ui_resource_->id(),
409 GetUIResourceSize(overhang_ui_resource_->id()));
410 }
411
412 DCHECK(!sync_tree->ViewportSizeInvalid());
413
414 if (new_impl_tree_has_no_evicted_resources) {
415 if (sync_tree->ContentsTexturesPurged())
416 sync_tree->ResetContentsTexturesPurged();
417 }
418
419 if (!settings_.impl_side_painting) {
420 // If we're not in impl-side painting, the tree is immediately
421 // considered active.
422 sync_tree->DidBecomeActive();
423 devtools_instrumentation::didActivateLayerTree(id_, source_frame_number_);
424 }
425
426 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
427
428 source_frame_number_++;
429 }
430
WillCommit()431 void LayerTreeHost::WillCommit() {
432 client_->WillCommit();
433 }
434
UpdateHudLayer()435 void LayerTreeHost::UpdateHudLayer() {
436 if (debug_state_.ShowHudInfo()) {
437 if (!hud_layer_.get())
438 hud_layer_ = HeadsUpDisplayLayer::Create();
439
440 if (root_layer_.get() && !hud_layer_->parent())
441 root_layer_->AddChild(hud_layer_);
442 } else if (hud_layer_.get()) {
443 hud_layer_->RemoveFromParent();
444 hud_layer_ = NULL;
445 }
446 }
447
CommitComplete()448 void LayerTreeHost::CommitComplete() {
449 client_->DidCommit();
450 }
451
CreateOutputSurface()452 scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() {
453 return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4);
454 }
455
CreateLayerTreeHostImpl(LayerTreeHostImplClient * client)456 scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
457 LayerTreeHostImplClient* client) {
458 DCHECK(proxy_->IsImplThread());
459 scoped_ptr<LayerTreeHostImpl> host_impl =
460 LayerTreeHostImpl::Create(settings_,
461 client,
462 proxy_.get(),
463 rendering_stats_instrumentation_.get(),
464 shared_bitmap_manager_,
465 id_);
466 shared_bitmap_manager_ = NULL;
467 if (settings_.calculate_top_controls_position &&
468 host_impl->top_controls_manager()) {
469 top_controls_manager_weak_ptr_ =
470 host_impl->top_controls_manager()->AsWeakPtr();
471 }
472 input_handler_weak_ptr_ = host_impl->AsWeakPtr();
473 return host_impl.Pass();
474 }
475
DidLoseOutputSurface()476 void LayerTreeHost::DidLoseOutputSurface() {
477 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface");
478 DCHECK(proxy_->IsMainThread());
479
480 if (output_surface_lost_)
481 return;
482
483 num_failed_recreate_attempts_ = 0;
484 output_surface_lost_ = true;
485 SetNeedsCommit();
486 }
487
CompositeAndReadback(void * pixels,gfx::Rect rect_in_device_viewport)488 bool LayerTreeHost::CompositeAndReadback(void* pixels,
489 gfx::Rect rect_in_device_viewport) {
490 trigger_idle_updates_ = false;
491 bool ret = proxy_->CompositeAndReadback(pixels, rect_in_device_viewport);
492 trigger_idle_updates_ = true;
493 return ret;
494 }
495
FinishAllRendering()496 void LayerTreeHost::FinishAllRendering() {
497 proxy_->FinishAllRendering();
498 }
499
SetDeferCommits(bool defer_commits)500 void LayerTreeHost::SetDeferCommits(bool defer_commits) {
501 proxy_->SetDeferCommits(defer_commits);
502 }
503
DidDeferCommit()504 void LayerTreeHost::DidDeferCommit() {}
505
SetNeedsDisplayOnAllLayers()506 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
507 std::stack<Layer*> layer_stack;
508 layer_stack.push(root_layer());
509 while (!layer_stack.empty()) {
510 Layer* current_layer = layer_stack.top();
511 layer_stack.pop();
512 current_layer->SetNeedsDisplay();
513 for (unsigned int i = 0; i < current_layer->children().size(); i++) {
514 layer_stack.push(current_layer->child_at(i));
515 }
516 }
517 }
518
CollectRenderingStats(RenderingStats * stats) const519 void LayerTreeHost::CollectRenderingStats(RenderingStats* stats) const {
520 CHECK(debug_state_.RecordRenderingStats());
521 *stats = rendering_stats_instrumentation_->GetRenderingStats();
522 }
523
GetRendererCapabilities() const524 const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
525 return proxy_->GetRendererCapabilities();
526 }
527
SetNeedsAnimate()528 void LayerTreeHost::SetNeedsAnimate() {
529 proxy_->SetNeedsAnimate();
530 NotifySwapPromiseMonitorsOfSetNeedsCommit();
531 }
532
SetNeedsUpdateLayers()533 void LayerTreeHost::SetNeedsUpdateLayers() {
534 proxy_->SetNeedsUpdateLayers();
535 NotifySwapPromiseMonitorsOfSetNeedsCommit();
536 }
537
SetNeedsCommit()538 void LayerTreeHost::SetNeedsCommit() {
539 if (!prepaint_callback_.IsCancelled()) {
540 TRACE_EVENT_INSTANT0("cc",
541 "LayerTreeHost::SetNeedsCommit::cancel prepaint",
542 TRACE_EVENT_SCOPE_THREAD);
543 prepaint_callback_.Cancel();
544 }
545 proxy_->SetNeedsCommit();
546 NotifySwapPromiseMonitorsOfSetNeedsCommit();
547 }
548
SetNeedsFullTreeSync()549 void LayerTreeHost::SetNeedsFullTreeSync() {
550 needs_full_tree_sync_ = true;
551 SetNeedsCommit();
552 }
553
SetNeedsRedraw()554 void LayerTreeHost::SetNeedsRedraw() {
555 SetNeedsRedrawRect(gfx::Rect(device_viewport_size_));
556 }
557
SetNeedsRedrawRect(gfx::Rect damage_rect)558 void LayerTreeHost::SetNeedsRedrawRect(gfx::Rect damage_rect) {
559 proxy_->SetNeedsRedraw(damage_rect);
560 }
561
CommitRequested() const562 bool LayerTreeHost::CommitRequested() const {
563 return proxy_->CommitRequested();
564 }
565
BeginMainFrameRequested() const566 bool LayerTreeHost::BeginMainFrameRequested() const {
567 return proxy_->BeginMainFrameRequested();
568 }
569
570
SetNextCommitWaitsForActivation()571 void LayerTreeHost::SetNextCommitWaitsForActivation() {
572 proxy_->SetNextCommitWaitsForActivation();
573 }
574
SetNextCommitForcesRedraw()575 void LayerTreeHost::SetNextCommitForcesRedraw() {
576 next_commit_forces_redraw_ = true;
577 }
578
SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,base::Time wall_clock_time)579 void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
580 base::Time wall_clock_time) {
581 DCHECK(proxy_->IsMainThread());
582 for (size_t event_index = 0; event_index < events->size(); ++event_index) {
583 int event_layer_id = (*events)[event_index].layer_id;
584
585 // Use the map of all controllers, not just active ones, since non-active
586 // controllers may still receive events for impl-only animations.
587 const AnimationRegistrar::AnimationControllerMap& animation_controllers =
588 animation_registrar_->all_animation_controllers();
589 AnimationRegistrar::AnimationControllerMap::const_iterator iter =
590 animation_controllers.find(event_layer_id);
591 if (iter != animation_controllers.end()) {
592 switch ((*events)[event_index].type) {
593 case AnimationEvent::Started:
594 (*iter).second->NotifyAnimationStarted((*events)[event_index],
595 wall_clock_time.ToDoubleT());
596 break;
597
598 case AnimationEvent::Finished:
599 (*iter).second->NotifyAnimationFinished((*events)[event_index],
600 wall_clock_time.ToDoubleT());
601 break;
602
603 case AnimationEvent::Aborted:
604 (*iter).second->NotifyAnimationAborted((*events)[event_index]);
605 break;
606
607 case AnimationEvent::PropertyUpdate:
608 (*iter).second->NotifyAnimationPropertyUpdate((*events)[event_index]);
609 break;
610 }
611 }
612 }
613 }
614
SetRootLayer(scoped_refptr<Layer> root_layer)615 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
616 if (root_layer_.get() == root_layer.get())
617 return;
618
619 if (root_layer_.get())
620 root_layer_->SetLayerTreeHost(NULL);
621 root_layer_ = root_layer;
622 if (root_layer_.get()) {
623 DCHECK(!root_layer_->parent());
624 root_layer_->SetLayerTreeHost(this);
625 }
626
627 if (hud_layer_.get())
628 hud_layer_->RemoveFromParent();
629
630 SetNeedsFullTreeSync();
631 }
632
SetDebugState(const LayerTreeDebugState & debug_state)633 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
634 LayerTreeDebugState new_debug_state =
635 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
636
637 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
638 return;
639
640 debug_state_ = new_debug_state;
641
642 rendering_stats_instrumentation_->set_record_rendering_stats(
643 debug_state_.RecordRenderingStats());
644
645 SetNeedsCommit();
646 }
647
SetViewportSize(gfx::Size device_viewport_size)648 void LayerTreeHost::SetViewportSize(gfx::Size device_viewport_size) {
649 if (device_viewport_size == device_viewport_size_)
650 return;
651
652 device_viewport_size_ = device_viewport_size;
653
654 SetNeedsCommit();
655 }
656
SetOverdrawBottomHeight(float overdraw_bottom_height)657 void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) {
658 if (overdraw_bottom_height_ == overdraw_bottom_height)
659 return;
660
661 overdraw_bottom_height_ = overdraw_bottom_height;
662 SetNeedsCommit();
663 }
664
ApplyPageScaleDeltaFromImplSide(float page_scale_delta)665 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
666 DCHECK(CommitRequested());
667 page_scale_factor_ *= page_scale_delta;
668 }
669
SetPageScaleFactorAndLimits(float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)670 void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
671 float min_page_scale_factor,
672 float max_page_scale_factor) {
673 if (page_scale_factor == page_scale_factor_ &&
674 min_page_scale_factor == min_page_scale_factor_ &&
675 max_page_scale_factor == max_page_scale_factor_)
676 return;
677
678 page_scale_factor_ = page_scale_factor;
679 min_page_scale_factor_ = min_page_scale_factor;
680 max_page_scale_factor_ = max_page_scale_factor;
681 SetNeedsCommit();
682 }
683
SetOverhangBitmap(const SkBitmap & bitmap)684 void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
685 DCHECK(bitmap.width() && bitmap.height());
686 DCHECK_EQ(bitmap.bytesPerPixel(), 4);
687
688 SkBitmap bitmap_copy;
689 if (bitmap.isImmutable()) {
690 bitmap_copy = bitmap;
691 } else {
692 bitmap.copyTo(&bitmap_copy, bitmap.config());
693 bitmap_copy.setImmutable();
694 }
695
696 UIResourceBitmap overhang_bitmap(bitmap_copy);
697 overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
698 overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
699 }
700
SetVisible(bool visible)701 void LayerTreeHost::SetVisible(bool visible) {
702 if (visible_ == visible)
703 return;
704 visible_ = visible;
705 if (!visible)
706 ReduceMemoryUsage();
707 proxy_->SetVisible(visible);
708 }
709
StartPageScaleAnimation(gfx::Vector2d target_offset,bool use_anchor,float scale,base::TimeDelta duration)710 void LayerTreeHost::StartPageScaleAnimation(gfx::Vector2d target_offset,
711 bool use_anchor,
712 float scale,
713 base::TimeDelta duration) {
714 pending_page_scale_animation_.reset(new PendingPageScaleAnimation);
715 pending_page_scale_animation_->target_offset = target_offset;
716 pending_page_scale_animation_->use_anchor = use_anchor;
717 pending_page_scale_animation_->scale = scale;
718 pending_page_scale_animation_->duration = duration;
719
720 SetNeedsCommit();
721 }
722
NotifyInputThrottledUntilCommit()723 void LayerTreeHost::NotifyInputThrottledUntilCommit() {
724 proxy_->NotifyInputThrottledUntilCommit();
725 }
726
Composite(base::TimeTicks frame_begin_time)727 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
728 if (!proxy_->HasImplThread())
729 static_cast<SingleThreadProxy*>(proxy_.get())->CompositeImmediately(
730 frame_begin_time);
731 else
732 SetNeedsCommit();
733 }
734
InitializeOutputSurfaceIfNeeded()735 bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() {
736 if (!output_surface_can_be_initialized_)
737 return false;
738
739 if (output_surface_lost_)
740 proxy_->CreateAndInitializeOutputSurface();
741 return !output_surface_lost_;
742 }
743
UpdateLayers(ResourceUpdateQueue * queue)744 bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
745 DCHECK(!output_surface_lost_);
746
747 if (!root_layer())
748 return false;
749
750 DCHECK(!root_layer()->parent());
751
752 bool result = UpdateLayers(root_layer(), queue);
753
754 micro_benchmark_controller_.DidUpdateLayers();
755
756 return result;
757 }
758
FindFirstScrollableLayer(Layer * layer)759 static Layer* FindFirstScrollableLayer(Layer* layer) {
760 if (!layer)
761 return NULL;
762
763 if (layer->scrollable())
764 return layer;
765
766 for (size_t i = 0; i < layer->children().size(); ++i) {
767 Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
768 if (found)
769 return found;
770 }
771
772 return NULL;
773 }
774
CalculateLCDTextMetricsCallback(Layer * layer)775 void LayerTreeHost::CalculateLCDTextMetricsCallback(Layer* layer) {
776 if (!layer->SupportsLCDText())
777 return;
778
779 lcd_text_metrics_.total_num_cc_layers++;
780 if (layer->draw_properties().can_use_lcd_text) {
781 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text++;
782 if (layer->contents_opaque())
783 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text++;
784 }
785 }
786
UsingSharedMemoryResources()787 bool LayerTreeHost::UsingSharedMemoryResources() {
788 return GetRendererCapabilities().using_shared_memory_resources;
789 }
790
UpdateLayers(Layer * root_layer,ResourceUpdateQueue * queue)791 bool LayerTreeHost::UpdateLayers(Layer* root_layer,
792 ResourceUpdateQueue* queue) {
793 TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
794 "source_frame_number", source_frame_number());
795
796 RenderSurfaceLayerList update_list;
797 {
798 UpdateHudLayer();
799
800 Layer* root_scroll = FindFirstScrollableLayer(root_layer);
801 Layer* page_scale_layer = page_scale_layer_;
802 if (!page_scale_layer && root_scroll)
803 page_scale_layer = root_scroll->parent();
804
805 if (hud_layer_) {
806 hud_layer_->PrepareForCalculateDrawProperties(
807 device_viewport_size(), device_scale_factor_);
808 }
809
810 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
811 bool can_render_to_separate_surface = true;
812 LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
813 root_layer,
814 device_viewport_size(),
815 gfx::Transform(),
816 device_scale_factor_,
817 page_scale_factor_,
818 page_scale_layer,
819 GetRendererCapabilities().max_texture_size,
820 settings_.can_use_lcd_text,
821 can_render_to_separate_surface,
822 settings_.layer_transforms_should_scale_layer_contents,
823 &update_list);
824 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
825
826 if (total_frames_used_for_lcd_text_metrics_ <=
827 kTotalFramesToUseForLCDTextMetrics) {
828 LayerTreeHostCommon::CallFunctionForSubtree(
829 root_layer,
830 base::Bind(&LayerTreeHost::CalculateLCDTextMetricsCallback,
831 base::Unretained(this)));
832 total_frames_used_for_lcd_text_metrics_++;
833 }
834
835 if (total_frames_used_for_lcd_text_metrics_ ==
836 kTotalFramesToUseForLCDTextMetrics) {
837 total_frames_used_for_lcd_text_metrics_++;
838
839 UMA_HISTOGRAM_PERCENTAGE(
840 "Renderer4.LCDText.PercentageOfCandidateLayers",
841 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text * 100.0 /
842 lcd_text_metrics_.total_num_cc_layers);
843 UMA_HISTOGRAM_PERCENTAGE(
844 "Renderer4.LCDText.PercentageOfAALayers",
845 lcd_text_metrics_.total_num_cc_layers_will_use_lcd_text * 100.0 /
846 lcd_text_metrics_.total_num_cc_layers_can_use_lcd_text);
847 }
848 }
849
850 // Reset partial texture update requests.
851 partial_texture_update_requests_ = 0;
852
853 bool did_paint_content = false;
854 bool need_more_updates = false;
855 PaintLayerContents(
856 update_list, queue, &did_paint_content, &need_more_updates);
857 if (trigger_idle_updates_ && need_more_updates) {
858 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
859 prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
860 base::Unretained(this)));
861 static base::TimeDelta prepaint_delay =
862 base::TimeDelta::FromMilliseconds(100);
863 base::MessageLoop::current()->PostDelayedTask(
864 FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
865 }
866
867 return did_paint_content;
868 }
869
TriggerPrepaint()870 void LayerTreeHost::TriggerPrepaint() {
871 prepaint_callback_.Cancel();
872 TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
873 SetNeedsCommit();
874 }
875
LayerTreeHostReduceMemoryCallback(Layer * layer)876 static void LayerTreeHostReduceMemoryCallback(Layer* layer) {
877 layer->ReduceMemoryUsage();
878 }
879
ReduceMemoryUsage()880 void LayerTreeHost::ReduceMemoryUsage() {
881 if (!root_layer())
882 return;
883
884 LayerTreeHostCommon::CallFunctionForSubtree(
885 root_layer(),
886 base::Bind(&LayerTreeHostReduceMemoryCallback));
887 }
888
SetPrioritiesForSurfaces(size_t surface_memory_bytes)889 void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
890 DCHECK(surface_memory_placeholder_);
891
892 // Surfaces have a place holder for their memory since they are managed
893 // independantly but should still be tracked and reduce other memory usage.
894 surface_memory_placeholder_->SetTextureManager(
895 contents_texture_manager_.get());
896 surface_memory_placeholder_->set_request_priority(
897 PriorityCalculator::RenderSurfacePriority());
898 surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
899 surface_memory_bytes);
900 }
901
SetPrioritiesForLayers(const RenderSurfaceLayerList & update_list)902 void LayerTreeHost::SetPrioritiesForLayers(
903 const RenderSurfaceLayerList& update_list) {
904 typedef LayerIterator<Layer,
905 RenderSurfaceLayerList,
906 RenderSurface,
907 LayerIteratorActions::FrontToBack> LayerIteratorType;
908
909 PriorityCalculator calculator;
910 LayerIteratorType end = LayerIteratorType::End(&update_list);
911 for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
912 it != end;
913 ++it) {
914 if (it.represents_itself()) {
915 it->SetTexturePriorities(calculator);
916 } else if (it.represents_target_render_surface()) {
917 if (it->mask_layer())
918 it->mask_layer()->SetTexturePriorities(calculator);
919 if (it->replica_layer() && it->replica_layer()->mask_layer())
920 it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
921 }
922 }
923 }
924
PrioritizeTextures(const RenderSurfaceLayerList & render_surface_layer_list,OverdrawMetrics * metrics)925 void LayerTreeHost::PrioritizeTextures(
926 const RenderSurfaceLayerList& render_surface_layer_list,
927 OverdrawMetrics* metrics) {
928 if (!contents_texture_manager_)
929 return;
930
931 contents_texture_manager_->ClearPriorities();
932
933 size_t memory_for_render_surfaces_metric =
934 CalculateMemoryForRenderSurfaces(render_surface_layer_list);
935
936 SetPrioritiesForLayers(render_surface_layer_list);
937 SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
938
939 metrics->DidUseContentsTextureMemoryBytes(
940 contents_texture_manager_->MemoryAboveCutoffBytes());
941 metrics->DidUseRenderSurfaceTextureMemoryBytes(
942 memory_for_render_surfaces_metric);
943
944 contents_texture_manager_->PrioritizeTextures();
945 }
946
CalculateMemoryForRenderSurfaces(const RenderSurfaceLayerList & update_list)947 size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
948 const RenderSurfaceLayerList& update_list) {
949 size_t readback_bytes = 0;
950 size_t max_background_texture_bytes = 0;
951 size_t contents_texture_bytes = 0;
952
953 // Start iteration at 1 to skip the root surface as it does not have a texture
954 // cost.
955 for (size_t i = 1; i < update_list.size(); ++i) {
956 Layer* render_surface_layer = update_list.at(i);
957 RenderSurface* render_surface = render_surface_layer->render_surface();
958
959 size_t bytes =
960 Resource::MemorySizeBytes(render_surface->content_rect().size(),
961 RGBA_8888);
962 contents_texture_bytes += bytes;
963
964 if (render_surface_layer->background_filters().IsEmpty())
965 continue;
966
967 if (bytes > max_background_texture_bytes)
968 max_background_texture_bytes = bytes;
969 if (!readback_bytes) {
970 readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
971 RGBA_8888);
972 }
973 }
974 return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
975 }
976
PaintMasksForRenderSurface(Layer * render_surface_layer,ResourceUpdateQueue * queue,bool * did_paint_content,bool * need_more_updates)977 void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
978 ResourceUpdateQueue* queue,
979 bool* did_paint_content,
980 bool* need_more_updates) {
981 // Note: Masks and replicas only exist for layers that own render surfaces. If
982 // we reach this point in code, we already know that at least something will
983 // be drawn into this render surface, so the mask and replica should be
984 // painted.
985
986 Layer* mask_layer = render_surface_layer->mask_layer();
987 if (mask_layer) {
988 *did_paint_content |= mask_layer->Update(queue, NULL);
989 *need_more_updates |= mask_layer->NeedMoreUpdates();
990 }
991
992 Layer* replica_mask_layer =
993 render_surface_layer->replica_layer() ?
994 render_surface_layer->replica_layer()->mask_layer() : NULL;
995 if (replica_mask_layer) {
996 *did_paint_content |= replica_mask_layer->Update(queue, NULL);
997 *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
998 }
999 }
1000
PaintLayerContents(const RenderSurfaceLayerList & render_surface_layer_list,ResourceUpdateQueue * queue,bool * did_paint_content,bool * need_more_updates)1001 void LayerTreeHost::PaintLayerContents(
1002 const RenderSurfaceLayerList& render_surface_layer_list,
1003 ResourceUpdateQueue* queue,
1004 bool* did_paint_content,
1005 bool* need_more_updates) {
1006 // Use FrontToBack to allow for testing occlusion and performing culling
1007 // during the tree walk.
1008 typedef LayerIterator<Layer,
1009 RenderSurfaceLayerList,
1010 RenderSurface,
1011 LayerIteratorActions::FrontToBack> LayerIteratorType;
1012
1013 bool record_metrics_for_frame =
1014 settings_.show_overdraw_in_tracing &&
1015 base::debug::TraceLog::GetInstance() &&
1016 base::debug::TraceLog::GetInstance()->IsEnabled();
1017 OcclusionTracker occlusion_tracker(
1018 root_layer_->render_surface()->content_rect(), record_metrics_for_frame);
1019 occlusion_tracker.set_minimum_tracking_size(
1020 settings_.minimum_occlusion_tracking_size);
1021
1022 PrioritizeTextures(render_surface_layer_list,
1023 occlusion_tracker.overdraw_metrics());
1024
1025 in_paint_layer_contents_ = true;
1026
1027 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1028 for (LayerIteratorType it =
1029 LayerIteratorType::Begin(&render_surface_layer_list);
1030 it != end;
1031 ++it) {
1032 occlusion_tracker.EnterLayer(it);
1033
1034 if (it.represents_target_render_surface()) {
1035 PaintMasksForRenderSurface(
1036 *it, queue, did_paint_content, need_more_updates);
1037 } else if (it.represents_itself() && it->DrawsContent()) {
1038 DCHECK(!it->paint_properties().bounds.IsEmpty());
1039 *did_paint_content |= it->Update(queue, &occlusion_tracker);
1040 *need_more_updates |= it->NeedMoreUpdates();
1041 }
1042
1043 occlusion_tracker.LeaveLayer(it);
1044 }
1045
1046 in_paint_layer_contents_ = false;
1047
1048 occlusion_tracker.overdraw_metrics()->RecordMetrics(this);
1049 }
1050
ApplyScrollAndScale(const ScrollAndScaleSet & info)1051 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) {
1052 if (!root_layer_.get())
1053 return;
1054
1055 gfx::Vector2d root_scroll_delta;
1056 Layer* root_scroll_layer = FindFirstScrollableLayer(root_layer_.get());
1057
1058 for (size_t i = 0; i < info.scrolls.size(); ++i) {
1059 Layer* layer =
1060 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(),
1061 info.scrolls[i].layer_id);
1062 if (!layer)
1063 continue;
1064 if (layer == root_scroll_layer) {
1065 root_scroll_delta += info.scrolls[i].scroll_delta;
1066 } else {
1067 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() +
1068 info.scrolls[i].scroll_delta);
1069 }
1070 }
1071
1072 if (!root_scroll_delta.IsZero() || info.page_scale_delta != 1.f) {
1073 // SetScrollOffsetFromImplSide above could have destroyed the tree,
1074 // so re-get this layer before doing anything to it.
1075 root_scroll_layer = FindFirstScrollableLayer(root_layer_.get());
1076
1077 // Preemptively apply the scroll offset and scale delta here before sending
1078 // it to the client. If the client comes back and sets it to the same
1079 // value, then the layer can early out without needing a full commit.
1080 if (root_scroll_layer) {
1081 root_scroll_layer->SetScrollOffsetFromImplSide(
1082 root_scroll_layer->scroll_offset() + root_scroll_delta);
1083 }
1084 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta);
1085 client_->ApplyScrollAndScale(root_scroll_delta, info.page_scale_delta);
1086 }
1087 }
1088
StartRateLimiter()1089 void LayerTreeHost::StartRateLimiter() {
1090 if (animating_)
1091 return;
1092
1093 if (!rate_limit_timer_.IsRunning()) {
1094 rate_limit_timer_.Start(FROM_HERE,
1095 base::TimeDelta(),
1096 this,
1097 &LayerTreeHost::RateLimit);
1098 }
1099 }
1100
StopRateLimiter()1101 void LayerTreeHost::StopRateLimiter() {
1102 rate_limit_timer_.Stop();
1103 }
1104
RateLimit()1105 void LayerTreeHost::RateLimit() {
1106 // Force a no-op command on the compositor context, so that any ratelimiting
1107 // commands will wait for the compositing context, and therefore for the
1108 // SwapBuffers.
1109 proxy_->ForceSerializeOnSwapBuffers();
1110 client_->RateLimitSharedMainThreadContext();
1111 }
1112
AlwaysUsePartialTextureUpdates()1113 bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
1114 if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
1115 return false;
1116 return !proxy_->HasImplThread();
1117 }
1118
MaxPartialTextureUpdates() const1119 size_t LayerTreeHost::MaxPartialTextureUpdates() const {
1120 size_t max_partial_texture_updates = 0;
1121 if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
1122 !settings_.impl_side_painting) {
1123 max_partial_texture_updates =
1124 std::min(settings_.max_partial_texture_updates,
1125 proxy_->MaxPartialTextureUpdates());
1126 }
1127 return max_partial_texture_updates;
1128 }
1129
RequestPartialTextureUpdate()1130 bool LayerTreeHost::RequestPartialTextureUpdate() {
1131 if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
1132 return false;
1133
1134 partial_texture_update_requests_++;
1135 return true;
1136 }
1137
SetDeviceScaleFactor(float device_scale_factor)1138 void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
1139 if (device_scale_factor == device_scale_factor_)
1140 return;
1141 device_scale_factor_ = device_scale_factor;
1142
1143 SetNeedsCommit();
1144 }
1145
UpdateTopControlsState(TopControlsState constraints,TopControlsState current,bool animate)1146 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints,
1147 TopControlsState current,
1148 bool animate) {
1149 if (!settings_.calculate_top_controls_position)
1150 return;
1151
1152 // Top controls are only used in threaded mode.
1153 proxy_->ImplThreadTaskRunner()->PostTask(
1154 FROM_HERE,
1155 base::Bind(&TopControlsManager::UpdateTopControlsState,
1156 top_controls_manager_weak_ptr_,
1157 constraints,
1158 current,
1159 animate));
1160 }
1161
AsValue() const1162 scoped_ptr<base::Value> LayerTreeHost::AsValue() const {
1163 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1164 state->Set("proxy", proxy_->AsValue().release());
1165 return state.PassAs<base::Value>();
1166 }
1167
AnimateLayers(base::TimeTicks time)1168 void LayerTreeHost::AnimateLayers(base::TimeTicks time) {
1169 if (!settings_.accelerated_animation_enabled ||
1170 animation_registrar_->active_animation_controllers().empty())
1171 return;
1172
1173 TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
1174
1175 double monotonic_time = (time - base::TimeTicks()).InSecondsF();
1176
1177 AnimationRegistrar::AnimationControllerMap copy =
1178 animation_registrar_->active_animation_controllers();
1179 for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
1180 iter != copy.end();
1181 ++iter) {
1182 (*iter).second->Animate(monotonic_time);
1183 bool start_ready_animations = true;
1184 (*iter).second->UpdateState(start_ready_animations, NULL);
1185 }
1186 }
1187
CreateUIResource(UIResourceClient * client)1188 UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
1189 DCHECK(client);
1190
1191 UIResourceId next_id = next_ui_resource_id_++;
1192 DCHECK(ui_resource_client_map_.find(next_id) ==
1193 ui_resource_client_map_.end());
1194
1195 bool resource_lost = false;
1196 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1197 next_id,
1198 client->GetBitmap(next_id, resource_lost));
1199 ui_resource_request_queue_.push_back(request);
1200
1201 UIResourceClientData data;
1202 data.client = client;
1203 data.size = request.GetBitmap().GetSize();
1204
1205 ui_resource_client_map_[request.GetId()] = data;
1206 return request.GetId();
1207 }
1208
1209 // Deletes a UI resource. May safely be called more than once.
DeleteUIResource(UIResourceId uid)1210 void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
1211 UIResourceClientMap::iterator iter = ui_resource_client_map_.find(uid);
1212 if (iter == ui_resource_client_map_.end())
1213 return;
1214
1215 UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
1216 ui_resource_request_queue_.push_back(request);
1217 ui_resource_client_map_.erase(iter);
1218 }
1219
RecreateUIResources()1220 void LayerTreeHost::RecreateUIResources() {
1221 for (UIResourceClientMap::iterator iter = ui_resource_client_map_.begin();
1222 iter != ui_resource_client_map_.end();
1223 ++iter) {
1224 UIResourceId uid = iter->first;
1225 const UIResourceClientData& data = iter->second;
1226 bool resource_lost = true;
1227 UIResourceRequest request(UIResourceRequest::UIResourceCreate,
1228 uid,
1229 data.client->GetBitmap(uid, resource_lost));
1230 ui_resource_request_queue_.push_back(request);
1231 }
1232 }
1233
1234 // Returns the size of a resource given its id.
GetUIResourceSize(UIResourceId uid) const1235 gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
1236 UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
1237 if (iter == ui_resource_client_map_.end())
1238 return gfx::Size();
1239
1240 const UIResourceClientData& data = iter->second;
1241 return data.size;
1242 }
1243
RegisterViewportLayers(scoped_refptr<Layer> page_scale_layer,scoped_refptr<Layer> inner_viewport_scroll_layer,scoped_refptr<Layer> outer_viewport_scroll_layer)1244 void LayerTreeHost::RegisterViewportLayers(
1245 scoped_refptr<Layer> page_scale_layer,
1246 scoped_refptr<Layer> inner_viewport_scroll_layer,
1247 scoped_refptr<Layer> outer_viewport_scroll_layer) {
1248 page_scale_layer_ = page_scale_layer;
1249 inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
1250 outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
1251 }
1252
ScheduleMicroBenchmark(const std::string & benchmark_name,scoped_ptr<base::Value> value,const MicroBenchmark::DoneCallback & callback)1253 bool LayerTreeHost::ScheduleMicroBenchmark(
1254 const std::string& benchmark_name,
1255 scoped_ptr<base::Value> value,
1256 const MicroBenchmark::DoneCallback& callback) {
1257 return micro_benchmark_controller_.ScheduleRun(
1258 benchmark_name, value.Pass(), callback);
1259 }
1260
InsertSwapPromiseMonitor(SwapPromiseMonitor * monitor)1261 void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1262 swap_promise_monitor_.insert(monitor);
1263 }
1264
RemoveSwapPromiseMonitor(SwapPromiseMonitor * monitor)1265 void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
1266 swap_promise_monitor_.erase(monitor);
1267 }
1268
NotifySwapPromiseMonitorsOfSetNeedsCommit()1269 void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
1270 std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
1271 for (; it != swap_promise_monitor_.end(); it++)
1272 (*it)->OnSetNeedsCommitOnMain();
1273 }
1274
QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise)1275 void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
1276 DCHECK(swap_promise);
1277 if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
1278 BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW);
1279 swap_promise_list_.push_back(swap_promise.Pass());
1280 }
1281
BreakSwapPromises(SwapPromise::DidNotSwapReason reason)1282 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1283 for (size_t i = 0; i < swap_promise_list_.size(); i++)
1284 swap_promise_list_[i]->DidNotSwap(reason);
1285 swap_promise_list_.clear();
1286 }
1287
1288 } // namespace cc
1289