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