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