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