Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / cc / trees / thread_proxy.cc
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/thread_proxy.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/auto_reset.h"
11 #include "base/bind.h"
12 #include "base/debug/trace_event.h"
13 #include "base/debug/trace_event_synthetic_delay.h"
14 #include "base/metrics/histogram.h"
15 #include "cc/base/swap_promise.h"
16 #include "cc/debug/benchmark_instrumentation.h"
17 #include "cc/debug/devtools_instrumentation.h"
18 #include "cc/input/input_handler.h"
19 #include "cc/output/context_provider.h"
20 #include "cc/output/output_surface.h"
21 #include "cc/quads/draw_quad.h"
22 #include "cc/resources/prioritized_resource_manager.h"
23 #include "cc/scheduler/delay_based_time_source.h"
24 #include "cc/scheduler/frame_rate_controller.h"
25 #include "cc/scheduler/scheduler.h"
26 #include "cc/trees/blocking_task_runner.h"
27 #include "cc/trees/layer_tree_host.h"
28 #include "cc/trees/layer_tree_impl.h"
29 #include "ui/gfx/frame_time.h"
30
31 namespace {
32
33 // Measured in seconds.
34 const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
35
36 class SwapPromiseChecker {
37  public:
38   explicit SwapPromiseChecker(cc::LayerTreeHost* layer_tree_host)
39       : layer_tree_host_(layer_tree_host) {}
40
41   ~SwapPromiseChecker() {
42     layer_tree_host_->BreakSwapPromises(cc::SwapPromise::COMMIT_FAILS);
43   }
44
45  private:
46   cc::LayerTreeHost* layer_tree_host_;
47 };
48
49 }  // namespace
50
51 namespace cc {
52
53 struct ThreadProxy::ReadbackRequest {
54   CompletionEvent completion;
55   bool success;
56   void* pixels;
57   gfx::Rect rect;
58 };
59
60 struct ThreadProxy::CommitPendingRequest {
61   CompletionEvent completion;
62   bool commit_pending;
63 };
64
65 struct ThreadProxy::SchedulerStateRequest {
66   CompletionEvent completion;
67   scoped_ptr<base::Value> state;
68 };
69
70 scoped_ptr<Proxy> ThreadProxy::Create(
71     LayerTreeHost* layer_tree_host,
72     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
73   return make_scoped_ptr(new ThreadProxy(layer_tree_host, impl_task_runner))
74       .PassAs<Proxy>();
75 }
76
77 ThreadProxy::ThreadProxy(
78     LayerTreeHost* layer_tree_host,
79     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
80     : Proxy(impl_task_runner),
81       main_thread_only_vars_unsafe_(this, layer_tree_host->id()),
82       main_thread_or_blocked_vars_unsafe_(layer_tree_host),
83       compositor_thread_vars_unsafe_(this, layer_tree_host->id()) {
84   TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
85   DCHECK(IsMainThread());
86   DCHECK(this->layer_tree_host());
87 }
88
89 ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
90                                             int layer_tree_host_id)
91     : layer_tree_host_id(layer_tree_host_id),
92       animate_requested(false),
93       commit_requested(false),
94       commit_request_sent_to_impl_thread(false),
95       created_offscreen_context_provider(false),
96       started(false),
97       textures_acquired(true),
98       in_composite_and_readback(false),
99       manage_tiles_pending(false),
100       can_cancel_commit(true),
101       defer_commits(false),
102       weak_factory(proxy) {}
103
104 ThreadProxy::MainThreadOnly::~MainThreadOnly() {}
105
106 ThreadProxy::MainThreadOrBlockedMainThread::MainThreadOrBlockedMainThread(
107     LayerTreeHost* host)
108     : layer_tree_host(host),
109       commit_waits_for_activation(false),
110       main_thread_inside_commit(false) {}
111
112 ThreadProxy::MainThreadOrBlockedMainThread::~MainThreadOrBlockedMainThread() {}
113
114 PrioritizedResourceManager*
115 ThreadProxy::MainThreadOrBlockedMainThread::contents_texture_manager() {
116   return layer_tree_host->contents_texture_manager();
117 }
118
119 ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(ThreadProxy* proxy,
120                                                         int layer_tree_host_id)
121     : layer_tree_host_id(layer_tree_host_id),
122       contents_texture_manager(NULL),
123       begin_main_frame_sent_completion_event(NULL),
124       readback_request(NULL),
125       commit_completion_event(NULL),
126       completion_event_for_commit_held_on_tree_activation(NULL),
127       texture_acquisition_completion_event(NULL),
128       next_frame_is_newly_committed_frame(false),
129       inside_draw(false),
130       input_throttled_until_commit(false),
131       animations_frozen_until_next_draw(false),
132       renew_tree_priority_pending(false),
133       weak_factory(proxy) {}
134
135 ThreadProxy::CompositorThreadOnly::~CompositorThreadOnly() {}
136
137 ThreadProxy::~ThreadProxy() {
138   TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
139   DCHECK(IsMainThread());
140   DCHECK(!main().started);
141 }
142
143 bool ThreadProxy::CompositeAndReadback(void* pixels, const gfx::Rect& rect) {
144   TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback");
145   DCHECK(IsMainThread());
146   DCHECK(layer_tree_host());
147
148   if (main().defer_commits) {
149     TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
150     return false;
151   }
152
153   if (!layer_tree_host()->InitializeOutputSurfaceIfNeeded()) {
154     TRACE_EVENT_INSTANT0("cc",
155                          "CompositeAndReadback_EarlyOut_LR_Uninitialized",
156                          TRACE_EVENT_SCOPE_THREAD);
157     return false;
158   }
159
160   // Perform a synchronous commit with an associated readback.
161   ReadbackRequest request;
162   request.rect = rect;
163   request.pixels = pixels;
164   {
165     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
166     CompletionEvent begin_main_frame_sent_completion;
167     Proxy::ImplThreadTaskRunner()->PostTask(
168         FROM_HERE,
169         base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
170                    impl_thread_weak_ptr_,
171                    &begin_main_frame_sent_completion,
172                    &request));
173     begin_main_frame_sent_completion.Wait();
174   }
175
176   main().in_composite_and_readback = true;
177   // This is the forced commit.
178   // Note: The Impl thread also queues a separate BeginMainFrame on the
179   // main thread, which will be called after this CompositeAndReadback
180   // completes, to replace the forced commit.
181   BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
182   main().in_composite_and_readback = false;
183
184   // Composite and readback requires a second commit to undo any changes
185   // that it made.
186   main().can_cancel_commit = false;
187
188   request.completion.Wait();
189   return request.success;
190 }
191
192 void ThreadProxy::ForceCommitForReadbackOnImplThread(
193     CompletionEvent* begin_main_frame_sent_completion,
194     ReadbackRequest* request) {
195   TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
196   DCHECK(IsImplThread());
197   DCHECK(!impl().begin_main_frame_sent_completion_event);
198   DCHECK(!impl().readback_request);
199
200   if (!impl().layer_tree_host_impl) {
201     begin_main_frame_sent_completion->Signal();
202     request->success = false;
203     request->completion.Signal();
204     return;
205   }
206
207   impl().readback_request = request;
208
209   impl().scheduler->SetNeedsForcedCommitForReadback();
210   if (impl().scheduler->CommitPending()) {
211     begin_main_frame_sent_completion->Signal();
212     return;
213   }
214
215   impl().begin_main_frame_sent_completion_event =
216       begin_main_frame_sent_completion;
217 }
218
219 void ThreadProxy::FinishAllRendering() {
220   DCHECK(Proxy::IsMainThread());
221   DCHECK(!main().defer_commits);
222
223   // Make sure all GL drawing is finished on the impl thread.
224   DebugScopedSetMainThreadBlocked main_thread_blocked(this);
225   CompletionEvent completion;
226   Proxy::ImplThreadTaskRunner()->PostTask(
227       FROM_HERE,
228       base::Bind(&ThreadProxy::FinishAllRenderingOnImplThread,
229                  impl_thread_weak_ptr_,
230                  &completion));
231   completion.Wait();
232 }
233
234 bool ThreadProxy::IsStarted() const {
235   DCHECK(Proxy::IsMainThread());
236   return main().started;
237 }
238
239 void ThreadProxy::SetLayerTreeHostClientReady() {
240   TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReady");
241   Proxy::ImplThreadTaskRunner()->PostTask(
242       FROM_HERE,
243       base::Bind(&ThreadProxy::SetLayerTreeHostClientReadyOnImplThread,
244                  impl_thread_weak_ptr_));
245 }
246
247 void ThreadProxy::SetLayerTreeHostClientReadyOnImplThread() {
248   TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReadyOnImplThread");
249   impl().scheduler->SetCanStart();
250 }
251
252 void ThreadProxy::SetVisible(bool visible) {
253   TRACE_EVENT0("cc", "ThreadProxy::SetVisible");
254   DebugScopedSetMainThreadBlocked main_thread_blocked(this);
255
256   CompletionEvent completion;
257   Proxy::ImplThreadTaskRunner()->PostTask(
258       FROM_HERE,
259       base::Bind(&ThreadProxy::SetVisibleOnImplThread,
260                  impl_thread_weak_ptr_,
261                  &completion,
262                  visible));
263   completion.Wait();
264 }
265
266 void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
267                                          bool visible) {
268   TRACE_EVENT0("cc", "ThreadProxy::SetVisibleOnImplThread");
269   impl().layer_tree_host_impl->SetVisible(visible);
270   impl().scheduler->SetVisible(visible);
271   UpdateBackgroundAnimateTicking();
272   completion->Signal();
273 }
274
275 void ThreadProxy::UpdateBackgroundAnimateTicking() {
276   bool should_background_tick =
277       !impl().scheduler->WillDrawIfNeeded() &&
278       impl().layer_tree_host_impl->active_tree()->root_layer();
279   impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
280       should_background_tick);
281   if (should_background_tick)
282     impl().animations_frozen_until_next_draw = false;
283 }
284
285 void ThreadProxy::DoCreateAndInitializeOutputSurface() {
286   TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
287   DCHECK(IsMainThread());
288
289   scoped_ptr<OutputSurface> output_surface =
290       layer_tree_host()->CreateOutputSurface();
291
292   RendererCapabilities capabilities;
293   bool success = !!output_surface;
294   if (!success) {
295     OnOutputSurfaceInitializeAttempted(false, capabilities);
296     return;
297   }
298
299   scoped_refptr<ContextProvider> offscreen_context_provider;
300   if (main().created_offscreen_context_provider) {
301     offscreen_context_provider =
302         layer_tree_host()->client()->OffscreenContextProvider();
303     success = !!offscreen_context_provider.get();
304     if (!success) {
305       OnOutputSurfaceInitializeAttempted(false, capabilities);
306       return;
307     }
308   }
309
310   success = false;
311   {
312     // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
313     // of that call are pushed into the success and capabilities local
314     // variables.
315     CompletionEvent completion;
316     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
317
318     Proxy::ImplThreadTaskRunner()->PostTask(
319         FROM_HERE,
320         base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
321                    impl_thread_weak_ptr_,
322                    &completion,
323                    base::Passed(&output_surface),
324                    offscreen_context_provider,
325                    &success,
326                    &capabilities));
327     completion.Wait();
328   }
329
330   OnOutputSurfaceInitializeAttempted(success, capabilities);
331 }
332
333 void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
334     const RendererCapabilities& capabilities) {
335   main().renderer_capabilities_main_thread_copy = capabilities;
336 }
337
338 void ThreadProxy::OnOutputSurfaceInitializeAttempted(
339     bool success,
340     const RendererCapabilities& capabilities) {
341   DCHECK(IsMainThread());
342   DCHECK(layer_tree_host());
343
344   if (success) {
345     main().renderer_capabilities_main_thread_copy = capabilities;
346   }
347
348   LayerTreeHost::CreateResult result =
349       layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
350   if (result == LayerTreeHost::CreateFailedButTryAgain) {
351     if (!main().output_surface_creation_callback.callback().is_null()) {
352       Proxy::MainThreadTaskRunner()->PostTask(
353           FROM_HERE, main().output_surface_creation_callback.callback());
354     }
355   } else {
356     main().output_surface_creation_callback.Cancel();
357   }
358 }
359
360 void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
361   DCHECK(IsMainThread());
362   if (main().commit_request_sent_to_impl_thread)
363     return;
364   main().commit_request_sent_to_impl_thread = true;
365   Proxy::ImplThreadTaskRunner()->PostTask(
366       FROM_HERE,
367       base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
368                  impl_thread_weak_ptr_));
369 }
370
371 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
372   DCHECK(IsMainThread());
373   DCHECK(!layer_tree_host()->output_surface_lost());
374   return main().renderer_capabilities_main_thread_copy;
375 }
376
377 void ThreadProxy::SetNeedsAnimate() {
378   DCHECK(IsMainThread());
379   if (main().animate_requested)
380     return;
381
382   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
383   main().animate_requested = true;
384   main().can_cancel_commit = false;
385   SendCommitRequestToImplThreadIfNeeded();
386 }
387
388 void ThreadProxy::SetNeedsUpdateLayers() {
389   DCHECK(IsMainThread());
390
391   if (main().commit_request_sent_to_impl_thread)
392     return;
393   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
394
395   SendCommitRequestToImplThreadIfNeeded();
396 }
397
398 void ThreadProxy::SetNeedsCommit() {
399   DCHECK(IsMainThread());
400   // Unconditionally set here to handle SetNeedsCommit calls during a commit.
401   main().can_cancel_commit = false;
402
403   if (main().commit_requested)
404     return;
405   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
406   main().commit_requested = true;
407
408   SendCommitRequestToImplThreadIfNeeded();
409 }
410
411 void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
412   DCHECK(IsImplThread());
413   Proxy::MainThreadTaskRunner()->PostTask(
414       FROM_HERE,
415       base::Bind(&ThreadProxy::SetRendererCapabilitiesMainThreadCopy,
416                  main_thread_weak_ptr_,
417                  impl()
418                      .layer_tree_host_impl->GetRendererCapabilities()
419                      .MainThreadCapabilities()));
420 }
421
422 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
423   TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
424   DCHECK(IsImplThread());
425   CheckOutputSurfaceStatusOnImplThread();
426 }
427
428 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
429   TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
430   DCHECK(IsImplThread());
431   if (!impl().layer_tree_host_impl->IsContextLost())
432     return;
433   if (ContextProvider* offscreen_contexts =
434           impl().layer_tree_host_impl->offscreen_context_provider())
435     offscreen_contexts->VerifyContexts();
436   impl().scheduler->DidLoseOutputSurface();
437 }
438
439 void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
440   TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
441   DCHECK(IsImplThread());
442   Proxy::MainThreadTaskRunner()->PostTask(
443       FROM_HERE,
444       base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
445 }
446
447 void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
448   TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable);
449   DCHECK(IsImplThread());
450   impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable);
451   UpdateBackgroundAnimateTicking();
452 }
453
454 void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
455   TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
456   DCHECK(IsImplThread());
457
458   // Sample the frame time now. This time will be used for updating animations
459   // when we draw.
460   impl().layer_tree_host_impl->CurrentFrameTimeTicks();
461
462   impl().scheduler->BeginImplFrame(args);
463 }
464
465 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
466   TRACE_EVENT1(
467       "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
468   DCHECK(IsImplThread());
469   impl().scheduler->SetCanDraw(can_draw);
470   UpdateBackgroundAnimateTicking();
471 }
472
473 void ThreadProxy::NotifyReadyToActivate() {
474   TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
475   impl().scheduler->NotifyReadyToActivate();
476 }
477
478 void ThreadProxy::SetNeedsCommitOnImplThread() {
479   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
480   DCHECK(IsImplThread());
481   impl().scheduler->SetNeedsCommit();
482 }
483
484 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
485     scoped_ptr<AnimationEventsVector> events,
486     base::Time wall_clock_time) {
487   TRACE_EVENT0("cc",
488                "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
489   DCHECK(IsImplThread());
490   Proxy::MainThreadTaskRunner()->PostTask(
491       FROM_HERE,
492       base::Bind(&ThreadProxy::SetAnimationEvents,
493                  main_thread_weak_ptr_,
494                  base::Passed(&events),
495                  wall_clock_time));
496 }
497
498 bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
499                                                           int priority_cutoff) {
500   DCHECK(IsImplThread());
501
502   if (!impl().contents_texture_manager)
503     return false;
504   if (!impl().layer_tree_host_impl->resource_provider())
505     return false;
506
507   bool reduce_result =
508       impl().contents_texture_manager->ReduceMemoryOnImplThread(
509           limit_bytes,
510           priority_cutoff,
511           impl().layer_tree_host_impl->resource_provider());
512   if (!reduce_result)
513     return false;
514
515   // The texture upload queue may reference textures that were just purged,
516   // clear them from the queue.
517   if (impl().current_resource_update_controller) {
518     impl()
519         .current_resource_update_controller->DiscardUploadsToEvictedResources();
520   }
521   return true;
522 }
523
524 void ThreadProxy::SendManagedMemoryStats() {
525   DCHECK(IsImplThread());
526   if (!impl().layer_tree_host_impl)
527     return;
528   if (!impl().contents_texture_manager)
529     return;
530
531   // If we are using impl-side painting, then SendManagedMemoryStats is called
532   // directly after the tile manager's manage function, and doesn't need to
533   // interact with main thread's layer tree.
534   if (impl().layer_tree_host_impl->settings().impl_side_painting)
535     return;
536
537   impl().layer_tree_host_impl->SendManagedMemoryStats(
538       impl().contents_texture_manager->MemoryVisibleBytes(),
539       impl().contents_texture_manager->MemoryVisibleAndNearbyBytes(),
540       impl().contents_texture_manager->MemoryUseBytes());
541 }
542
543 bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; }
544
545 void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
546   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
547   DCHECK(IsMainThread());
548   Proxy::ImplThreadTaskRunner()->PostTask(
549       FROM_HERE,
550       base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread,
551                  impl_thread_weak_ptr_,
552                  damage_rect));
553 }
554
555 void ThreadProxy::SetNextCommitWaitsForActivation() {
556   DCHECK(IsMainThread());
557   DCHECK(!blocked_main().main_thread_inside_commit);
558   blocked_main().commit_waits_for_activation = true;
559 }
560
561 void ThreadProxy::SetDeferCommits(bool defer_commits) {
562   DCHECK(IsMainThread());
563   DCHECK_NE(main().defer_commits, defer_commits);
564   main().defer_commits = defer_commits;
565
566   if (main().defer_commits)
567     TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
568   else
569     TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
570
571   if (!main().defer_commits && main().pending_deferred_commit)
572     Proxy::MainThreadTaskRunner()->PostTask(
573         FROM_HERE,
574         base::Bind(&ThreadProxy::BeginMainFrame,
575                    main_thread_weak_ptr_,
576                    base::Passed(&main().pending_deferred_commit)));
577 }
578
579 bool ThreadProxy::CommitRequested() const {
580   DCHECK(IsMainThread());
581   return main().commit_requested;
582 }
583
584 bool ThreadProxy::BeginMainFrameRequested() const {
585   DCHECK(IsMainThread());
586   return main().commit_request_sent_to_impl_thread;
587 }
588
589 void ThreadProxy::SetNeedsRedrawOnImplThread() {
590   TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
591   DCHECK(IsImplThread());
592   impl().scheduler->SetNeedsRedraw();
593 }
594
595 void ThreadProxy::SetNeedsManageTilesOnImplThread() {
596   DCHECK(IsImplThread());
597   impl().scheduler->SetNeedsManageTiles();
598 }
599
600 void ThreadProxy::SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) {
601   DCHECK(IsImplThread());
602   impl().layer_tree_host_impl->SetViewportDamage(damage_rect);
603   SetNeedsRedrawOnImplThread();
604 }
605
606 void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread(
607     bool used_incomplete_tile) {
608   DCHECK(IsImplThread());
609   if (used_incomplete_tile) {
610     TRACE_EVENT_INSTANT0("cc",
611                          "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread",
612                          TRACE_EVENT_SCOPE_THREAD);
613   }
614   impl().scheduler->SetSwapUsedIncompleteTile(used_incomplete_tile);
615 }
616
617 void ThreadProxy::DidInitializeVisibleTileOnImplThread() {
618   TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread");
619   DCHECK(IsImplThread());
620   impl().scheduler->SetNeedsRedraw();
621 }
622
623 void ThreadProxy::MainThreadHasStoppedFlinging() {
624   DCHECK(IsMainThread());
625   Proxy::ImplThreadTaskRunner()->PostTask(
626       FROM_HERE,
627       base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread,
628                  impl_thread_weak_ptr_));
629 }
630
631 void ThreadProxy::MainThreadHasStoppedFlingingOnImplThread() {
632   DCHECK(IsImplThread());
633   impl().layer_tree_host_impl->MainThreadHasStoppedFlinging();
634 }
635
636 void ThreadProxy::NotifyInputThrottledUntilCommit() {
637   DCHECK(IsMainThread());
638   Proxy::ImplThreadTaskRunner()->PostTask(
639       FROM_HERE,
640       base::Bind(&ThreadProxy::SetInputThrottledUntilCommitOnImplThread,
641                  impl_thread_weak_ptr_,
642                  true));
643 }
644
645 void ThreadProxy::SetInputThrottledUntilCommitOnImplThread(bool is_throttled) {
646   DCHECK(IsImplThread());
647   if (is_throttled == impl().input_throttled_until_commit)
648     return;
649   impl().input_throttled_until_commit = is_throttled;
650   RenewTreePriority();
651 }
652
653 LayerTreeHost* ThreadProxy::layer_tree_host() {
654   return blocked_main().layer_tree_host;
655 }
656
657 const LayerTreeHost* ThreadProxy::layer_tree_host() const {
658   return blocked_main().layer_tree_host;
659 }
660
661 ThreadProxy::MainThreadOnly& ThreadProxy::main() {
662   DCHECK(IsMainThread());
663   return main_thread_only_vars_unsafe_;
664 }
665 const ThreadProxy::MainThreadOnly& ThreadProxy::main() const {
666   DCHECK(IsMainThread());
667   return main_thread_only_vars_unsafe_;
668 }
669
670 ThreadProxy::MainThreadOrBlockedMainThread& ThreadProxy::blocked_main() {
671   DCHECK(IsMainThread() || IsMainThreadBlocked());
672   return main_thread_or_blocked_vars_unsafe_;
673 }
674
675 const ThreadProxy::MainThreadOrBlockedMainThread& ThreadProxy::blocked_main()
676     const {
677   DCHECK(IsMainThread() || IsMainThreadBlocked());
678   return main_thread_or_blocked_vars_unsafe_;
679 }
680
681 ThreadProxy::CompositorThreadOnly& ThreadProxy::impl() {
682   DCHECK(IsImplThread());
683   return compositor_thread_vars_unsafe_;
684 }
685
686 const ThreadProxy::CompositorThreadOnly& ThreadProxy::impl() const {
687   DCHECK(IsImplThread());
688   return compositor_thread_vars_unsafe_;
689 }
690
691 void ThreadProxy::Start() {
692   DCHECK(IsMainThread());
693   DCHECK(Proxy::HasImplThread());
694
695   // Create LayerTreeHostImpl.
696   DebugScopedSetMainThreadBlocked main_thread_blocked(this);
697   CompletionEvent completion;
698   Proxy::ImplThreadTaskRunner()->PostTask(
699       FROM_HERE,
700       base::Bind(&ThreadProxy::InitializeImplOnImplThread,
701                  base::Unretained(this),
702                  &completion));
703   completion.Wait();
704
705   main_thread_weak_ptr_ = main().weak_factory.GetWeakPtr();
706
707   main().started = true;
708 }
709
710 void ThreadProxy::Stop() {
711   TRACE_EVENT0("cc", "ThreadProxy::Stop");
712   DCHECK(IsMainThread());
713   DCHECK(main().started);
714
715   // Synchronously finishes pending GL operations and deletes the impl.
716   // The two steps are done as separate post tasks, so that tasks posted
717   // by the GL implementation due to the Finish can be executed by the
718   // renderer before shutting it down.
719   {
720     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
721
722     CompletionEvent completion;
723     Proxy::ImplThreadTaskRunner()->PostTask(
724         FROM_HERE,
725         base::Bind(&ThreadProxy::FinishGLOnImplThread,
726                    impl_thread_weak_ptr_,
727                    &completion));
728     completion.Wait();
729   }
730   {
731     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
732
733     CompletionEvent completion;
734     Proxy::ImplThreadTaskRunner()->PostTask(
735         FROM_HERE,
736         base::Bind(&ThreadProxy::LayerTreeHostClosedOnImplThread,
737                    impl_thread_weak_ptr_,
738                    &completion));
739     completion.Wait();
740   }
741
742   main().weak_factory.InvalidateWeakPtrs();
743   blocked_main().layer_tree_host = NULL;
744   main().started = false;
745 }
746
747 void ThreadProxy::ForceSerializeOnSwapBuffers() {
748   DebugScopedSetMainThreadBlocked main_thread_blocked(this);
749   CompletionEvent completion;
750   Proxy::ImplThreadTaskRunner()->PostTask(
751       FROM_HERE,
752       base::Bind(&ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread,
753                  impl_thread_weak_ptr_,
754                  &completion));
755   completion.Wait();
756 }
757
758 void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread(
759     CompletionEvent* completion) {
760   if (impl().layer_tree_host_impl->renderer())
761     impl().layer_tree_host_impl->renderer()->DoNoOp();
762   completion->Signal();
763 }
764
765 void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
766   TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
767   DCHECK(IsImplThread());
768   impl().layer_tree_host_impl->FinishAllRendering();
769   completion->Signal();
770 }
771
772 void ThreadProxy::ScheduledActionSendBeginMainFrame() {
773   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
774   scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
775       new BeginMainFrameAndCommitState);
776   begin_main_frame_state->monotonic_frame_begin_time =
777       impl().layer_tree_host_impl->CurrentPhysicalTimeTicks();
778   begin_main_frame_state->scroll_info =
779       impl().layer_tree_host_impl->ProcessScrollDeltas();
780
781   if (!impl().layer_tree_host_impl->settings().impl_side_painting) {
782     DCHECK_GT(impl().layer_tree_host_impl->memory_allocation_limit_bytes(), 0u);
783   }
784   begin_main_frame_state->memory_allocation_limit_bytes =
785       impl().layer_tree_host_impl->memory_allocation_limit_bytes();
786   begin_main_frame_state->memory_allocation_priority_cutoff =
787       impl().layer_tree_host_impl->memory_allocation_priority_cutoff();
788   begin_main_frame_state->evicted_ui_resources =
789       impl().layer_tree_host_impl->EvictedUIResourcesExist();
790   Proxy::MainThreadTaskRunner()->PostTask(
791       FROM_HERE,
792       base::Bind(&ThreadProxy::BeginMainFrame,
793                  main_thread_weak_ptr_,
794                  base::Passed(&begin_main_frame_state)));
795   devtools_instrumentation::DidRequestMainThreadFrame(
796       impl().layer_tree_host_id);
797   if (impl().begin_main_frame_sent_completion_event) {
798     impl().begin_main_frame_sent_completion_event->Signal();
799     impl().begin_main_frame_sent_completion_event = NULL;
800   }
801   impl().timing_history.DidBeginMainFrame();
802 }
803
804 void ThreadProxy::BeginMainFrame(
805     scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
806   TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
807   TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame");
808   DCHECK(IsMainThread());
809
810   if (!layer_tree_host())
811     return;
812
813   if (main().defer_commits) {
814     main().pending_deferred_commit = begin_main_frame_state.Pass();
815     layer_tree_host()->DidDeferCommit();
816     TRACE_EVENT_INSTANT0(
817         "cc", "EarlyOut_DeferCommits", TRACE_EVENT_SCOPE_THREAD);
818     return;
819   }
820
821   // If the commit finishes, LayerTreeHost will transfer its swap promises to
822   // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
823   // swap promises.
824   SwapPromiseChecker swap_promise_checker(layer_tree_host());
825
826   // Do not notify the impl thread of commit requests that occur during
827   // the apply/animate/layout part of the BeginMainFrameAndCommit process since
828   // those commit requests will get painted immediately. Once we have done
829   // the paint, main().commit_requested will be set to false to allow new commit
830   // requests to be scheduled.
831   main().commit_requested = true;
832   main().commit_request_sent_to_impl_thread = true;
833
834   // On the other hand, the AnimationRequested flag needs to be cleared
835   // here so that any animation requests generated by the apply or animate
836   // callbacks will trigger another frame.
837   main().animate_requested = false;
838
839   if (!main().in_composite_and_readback && !layer_tree_host()->visible()) {
840     main().commit_requested = false;
841     main().commit_request_sent_to_impl_thread = false;
842
843     TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
844     bool did_handle = false;
845     Proxy::ImplThreadTaskRunner()->PostTask(
846         FROM_HERE,
847         base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
848                    impl_thread_weak_ptr_,
849                    did_handle));
850     return;
851   }
852
853   if (begin_main_frame_state) {
854     layer_tree_host()->ApplyScrollAndScale(
855         *begin_main_frame_state->scroll_info);
856   }
857
858   layer_tree_host()->WillBeginMainFrame();
859
860   if (begin_main_frame_state) {
861     layer_tree_host()->UpdateClientAnimations(
862         begin_main_frame_state->monotonic_frame_begin_time);
863     layer_tree_host()->AnimateLayers(
864         begin_main_frame_state->monotonic_frame_begin_time);
865     blocked_main().last_monotonic_frame_begin_time =
866         begin_main_frame_state->monotonic_frame_begin_time;
867   }
868
869   // Unlink any backings that the impl thread has evicted, so that we know to
870   // re-paint them in UpdateLayers.
871   if (blocked_main().contents_texture_manager()) {
872     blocked_main().contents_texture_manager()->UnlinkAndClearEvictedBackings();
873
874     if (begin_main_frame_state) {
875       blocked_main().contents_texture_manager()->SetMaxMemoryLimitBytes(
876           begin_main_frame_state->memory_allocation_limit_bytes);
877       blocked_main().contents_texture_manager()->SetExternalPriorityCutoff(
878           begin_main_frame_state->memory_allocation_priority_cutoff);
879     }
880   }
881
882   // Recreate all UI resources if there were evicted UI resources when the impl
883   // thread initiated the commit.
884   bool evicted_ui_resources = begin_main_frame_state
885                                   ? begin_main_frame_state->evicted_ui_resources
886                                   : false;
887   if (evicted_ui_resources)
888     layer_tree_host()->RecreateUIResources();
889
890   layer_tree_host()->Layout();
891   TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame");
892
893   // Clear the commit flag after updating animations and layout here --- objects
894   // that only layout when painted will trigger another SetNeedsCommit inside
895   // UpdateLayers.
896   main().commit_requested = false;
897   main().commit_request_sent_to_impl_thread = false;
898   bool can_cancel_this_commit = main().can_cancel_commit &&
899                                 !main().in_composite_and_readback &&
900                                 !evicted_ui_resources;
901   main().can_cancel_commit = true;
902
903   scoped_ptr<ResourceUpdateQueue> queue =
904       make_scoped_ptr(new ResourceUpdateQueue);
905
906   bool updated = layer_tree_host()->UpdateLayers(queue.get());
907
908   // Once single buffered layers are committed, they cannot be modified until
909   // they are drawn by the impl thread.
910   main().textures_acquired = false;
911
912   layer_tree_host()->WillCommit();
913
914   if (!updated && can_cancel_this_commit) {
915     TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
916     bool did_handle = true;
917     Proxy::ImplThreadTaskRunner()->PostTask(
918         FROM_HERE,
919         base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
920                    impl_thread_weak_ptr_,
921                    did_handle));
922
923     // Although the commit is internally aborted, this is because it has been
924     // detected to be a no-op.  From the perspective of an embedder, this commit
925     // went through, and input should no longer be throttled, etc.
926     layer_tree_host()->CommitComplete();
927     layer_tree_host()->DidBeginMainFrame();
928     return;
929   }
930
931   // Before calling animate, we set main().animate_requested to false. If it is
932   // true
933   // now, it means SetNeedAnimate was called again, but during a state when
934   // main().commit_request_sent_to_impl_thread = true. We need to force that
935   // call to
936   // happen again now so that the commit request is sent to the impl thread.
937   if (main().animate_requested) {
938     // Forces SetNeedsAnimate to consider posting a commit task.
939     main().animate_requested = false;
940     SetNeedsAnimate();
941   }
942
943   scoped_refptr<ContextProvider> offscreen_context_provider;
944   if (main().renderer_capabilities_main_thread_copy.using_offscreen_context3d &&
945       layer_tree_host()->needs_offscreen_context()) {
946     offscreen_context_provider =
947         layer_tree_host()->client()->OffscreenContextProvider();
948     if (offscreen_context_provider.get())
949       main().created_offscreen_context_provider = true;
950   }
951
952   // Notify the impl thread that the main thread is ready to commit. This will
953   // begin the commit process, which is blocking from the main thread's
954   // point of view, but asynchronously performed on the impl thread,
955   // coordinated by the Scheduler.
956   {
957     TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
958
959     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
960
961     // This CapturePostTasks should be destroyed before CommitComplete() is
962     // called since that goes out to the embedder, and we want the embedder
963     // to receive its callbacks before that.
964     BlockingTaskRunner::CapturePostTasks blocked;
965
966     CompletionEvent completion;
967     Proxy::ImplThreadTaskRunner()->PostTask(
968         FROM_HERE,
969         base::Bind(&ThreadProxy::StartCommitOnImplThread,
970                    impl_thread_weak_ptr_,
971                    &completion,
972                    queue.release(),
973                    offscreen_context_provider));
974     completion.Wait();
975
976     RenderingStatsInstrumentation* stats_instrumentation =
977         layer_tree_host()->rendering_stats_instrumentation();
978     BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
979         stats_instrumentation->main_thread_rendering_stats());
980     stats_instrumentation->AccumulateAndClearMainThreadStats();
981   }
982
983   layer_tree_host()->CommitComplete();
984   layer_tree_host()->DidBeginMainFrame();
985 }
986
987 void ThreadProxy::StartCommitOnImplThread(
988     CompletionEvent* completion,
989     ResourceUpdateQueue* raw_queue,
990     scoped_refptr<ContextProvider> offscreen_context_provider) {
991   scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
992
993   TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
994   DCHECK(!impl().commit_completion_event);
995   DCHECK(IsImplThread() && IsMainThreadBlocked());
996   DCHECK(impl().scheduler);
997   DCHECK(impl().scheduler->CommitPending());
998
999   if (!impl().layer_tree_host_impl) {
1000     TRACE_EVENT_INSTANT0(
1001         "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD);
1002     completion->Signal();
1003     return;
1004   }
1005
1006   if (offscreen_context_provider.get())
1007     offscreen_context_provider->BindToCurrentThread();
1008   impl().layer_tree_host_impl->SetOffscreenContextProvider(
1009       offscreen_context_provider);
1010
1011   if (impl().contents_texture_manager) {
1012     DCHECK_EQ(impl().contents_texture_manager,
1013               blocked_main().contents_texture_manager());
1014   } else {
1015     // Cache this pointer that was created on the main thread side to avoid a
1016     // data race between creating it and using it on the compositor thread.
1017     impl().contents_texture_manager = blocked_main().contents_texture_manager();
1018   }
1019
1020   if (impl().contents_texture_manager) {
1021     if (impl().contents_texture_manager->LinkedEvictedBackingsExist()) {
1022       // Clear any uploads we were making to textures linked to evicted
1023       // resources
1024       queue->ClearUploadsToEvictedResources();
1025       // Some textures in the layer tree are invalid. Kick off another commit
1026       // to fill them again.
1027       SetNeedsCommitOnImplThread();
1028     }
1029
1030     impl().contents_texture_manager->PushTexturePrioritiesToBackings();
1031   }
1032
1033   impl().commit_completion_event = completion;
1034   impl().current_resource_update_controller = ResourceUpdateController::Create(
1035       this,
1036       Proxy::ImplThreadTaskRunner(),
1037       queue.Pass(),
1038       impl().layer_tree_host_impl->resource_provider());
1039   impl().current_resource_update_controller->PerformMoreUpdates(
1040       impl().scheduler->AnticipatedDrawTime());
1041 }
1042
1043 void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
1044   TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread");
1045   DCHECK(IsImplThread());
1046   DCHECK(impl().scheduler);
1047   DCHECK(impl().scheduler->CommitPending());
1048   DCHECK(!impl().layer_tree_host_impl->pending_tree());
1049
1050   if (did_handle)
1051     SetInputThrottledUntilCommitOnImplThread(false);
1052   impl().layer_tree_host_impl->BeginMainFrameAborted(did_handle);
1053   impl().scheduler->BeginMainFrameAborted(did_handle);
1054 }
1055
1056 void ThreadProxy::ScheduledActionCommit() {
1057   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
1058   DCHECK(IsImplThread());
1059   DCHECK(IsMainThreadBlocked());
1060   DCHECK(impl().commit_completion_event);
1061   DCHECK(impl().current_resource_update_controller);
1062
1063   // Complete all remaining texture updates.
1064   impl().current_resource_update_controller->Finalize();
1065   impl().current_resource_update_controller.reset();
1066
1067   if (impl().animations_frozen_until_next_draw) {
1068     impl().animation_freeze_time =
1069         std::max(impl().animation_freeze_time,
1070                  blocked_main().last_monotonic_frame_begin_time);
1071   }
1072
1073   blocked_main().main_thread_inside_commit = true;
1074   impl().layer_tree_host_impl->BeginCommit();
1075   layer_tree_host()->BeginCommitOnImplThread(impl().layer_tree_host_impl.get());
1076   layer_tree_host()->FinishCommitOnImplThread(
1077       impl().layer_tree_host_impl.get());
1078   blocked_main().main_thread_inside_commit = false;
1079
1080   bool hold_commit = layer_tree_host()->settings().impl_side_painting &&
1081                      blocked_main().commit_waits_for_activation;
1082   blocked_main().commit_waits_for_activation = false;
1083
1084   if (hold_commit) {
1085     // For some layer types in impl-side painting, the commit is held until
1086     // the pending tree is activated.  It's also possible that the
1087     // pending tree has already activated if there was no work to be done.
1088     TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
1089     impl().completion_event_for_commit_held_on_tree_activation =
1090         impl().commit_completion_event;
1091     impl().commit_completion_event = NULL;
1092   } else {
1093     impl().commit_completion_event->Signal();
1094     impl().commit_completion_event = NULL;
1095   }
1096
1097   // Delay this step until afer the main thread has been released as it's
1098   // often a good bit of work to update the tree and prepare the new frame.
1099   impl().layer_tree_host_impl->CommitComplete();
1100
1101   SetInputThrottledUntilCommitOnImplThread(false);
1102
1103   UpdateBackgroundAnimateTicking();
1104
1105   impl().next_frame_is_newly_committed_frame = true;
1106
1107   impl().timing_history.DidCommit();
1108
1109   // SetVisible kicks off the next scheduler action, so this must be last.
1110   impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
1111 }
1112
1113 void ThreadProxy::ScheduledActionUpdateVisibleTiles() {
1114   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
1115   DCHECK(IsImplThread());
1116   impl().layer_tree_host_impl->UpdateVisibleTiles();
1117 }
1118
1119 void ThreadProxy::ScheduledActionActivatePendingTree() {
1120   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
1121   DCHECK(IsImplThread());
1122   impl().layer_tree_host_impl->ActivatePendingTree();
1123 }
1124
1125 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
1126   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
1127   DCHECK(IsImplThread());
1128   Proxy::MainThreadTaskRunner()->PostTask(
1129       FROM_HERE,
1130       base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
1131                  main_thread_weak_ptr_));
1132 }
1133
1134 DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
1135     bool forced_draw,
1136     bool swap_requested,
1137     bool readback_requested) {
1138   TRACE_EVENT_SYNTHETIC_DELAY("cc.DrawAndSwap");
1139   DrawSwapReadbackResult result;
1140
1141   DCHECK(IsImplThread());
1142   DCHECK(impl().layer_tree_host_impl.get());
1143
1144   impl().timing_history.DidStartDrawing();
1145   base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
1146   base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
1147
1148   // Advance our animations.
1149   base::TimeTicks monotonic_time;
1150   if (impl().animations_frozen_until_next_draw)
1151     monotonic_time = impl().animation_freeze_time;
1152   else
1153     monotonic_time = impl().layer_tree_host_impl->CurrentFrameTimeTicks();
1154
1155   // TODO(ajuma): Remove wall_clock_time once the legacy implementation of
1156   // animations in Blink is removed.
1157   base::Time wall_clock_time = impl().layer_tree_host_impl->CurrentFrameTime();
1158
1159   // TODO(enne): This should probably happen post-animate.
1160   if (impl().layer_tree_host_impl->pending_tree())
1161     impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties();
1162   impl().layer_tree_host_impl->Animate(monotonic_time, wall_clock_time);
1163
1164   // This method is called on a forced draw, regardless of whether we are able
1165   // to produce a frame, as the calling site on main thread is blocked until its
1166   // request completes, and we signal completion here. If CanDraw() is false, we
1167   // will indicate success=false to the caller, but we must still signal
1168   // completion to avoid deadlock.
1169
1170   // We guard PrepareToDraw() with CanDraw() because it always returns a valid
1171   // frame, so can only be used when such a frame is possible. Since
1172   // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1173   // CanDraw() as well.
1174
1175   bool drawing_for_readback = readback_requested && !!impl().readback_request;
1176   bool can_do_readback =
1177       impl().layer_tree_host_impl->renderer()->CanReadPixels();
1178
1179   LayerTreeHostImpl::FrameData frame;
1180   bool draw_frame = false;
1181
1182   if (impl().layer_tree_host_impl->CanDraw()) {
1183     if (!drawing_for_readback || can_do_readback) {
1184       // If it is for a readback, make sure we draw the portion being read back.
1185       gfx::Rect readback_rect;
1186       if (drawing_for_readback)
1187         readback_rect = impl().readback_request->rect;
1188
1189       result.draw_result =
1190           impl().layer_tree_host_impl->PrepareToDraw(&frame, readback_rect);
1191       draw_frame = forced_draw ||
1192                    result.draw_result == DrawSwapReadbackResult::DRAW_SUCCESS;
1193     } else {
1194       result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CANT_READBACK;
1195     }
1196   } else {
1197     result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CANT_DRAW;
1198   }
1199
1200   if (draw_frame) {
1201     impl().layer_tree_host_impl->DrawLayers(
1202         &frame, impl().scheduler->LastBeginImplFrameTime());
1203     result.draw_result = DrawSwapReadbackResult::DRAW_SUCCESS;
1204     impl().animations_frozen_until_next_draw = false;
1205   } else if (result.draw_result ==
1206                  DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS &&
1207              !impl().layer_tree_host_impl->settings().impl_side_painting) {
1208     // Without impl-side painting, the animated layer that is checkerboarding
1209     // will continue to checkerboard until the next commit. If this layer
1210     // continues to move during the commit, it may continue to checkerboard
1211     // after the commit since the region rasterized during the commit will not
1212     // match the region that is currently visible; eventually this
1213     // checkerboarding will be displayed when we force a draw. To avoid this,
1214     // we freeze animations until we successfully draw.
1215     impl().animations_frozen_until_next_draw = true;
1216     impl().animation_freeze_time = monotonic_time;
1217   } else {
1218     DCHECK_NE(DrawSwapReadbackResult::DRAW_SUCCESS, result.draw_result);
1219   }
1220   impl().layer_tree_host_impl->DidDrawAllLayers(frame);
1221
1222   bool start_ready_animations = draw_frame;
1223   impl().layer_tree_host_impl->UpdateAnimationState(start_ready_animations);
1224
1225   // Check for a pending CompositeAndReadback.
1226   if (drawing_for_readback) {
1227     DCHECK(!swap_requested);
1228     result.did_readback = false;
1229     if (draw_frame) {
1230       if (!impl().layer_tree_host_impl->IsContextLost()) {
1231         impl().layer_tree_host_impl->Readback(impl().readback_request->pixels,
1232                                               impl().readback_request->rect);
1233         result.did_readback = true;
1234       } else {
1235         result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST;
1236       }
1237     }
1238     impl().readback_request->success = result.did_readback;
1239     impl().readback_request->completion.Signal();
1240     impl().readback_request = NULL;
1241   } else if (draw_frame) {
1242     DCHECK(swap_requested);
1243     result.did_swap = impl().layer_tree_host_impl->SwapBuffers(frame);
1244
1245     // We don't know if we have incomplete tiles if we didn't actually swap.
1246     if (result.did_swap) {
1247       DCHECK(!frame.has_no_damage);
1248       SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
1249     }
1250   }
1251
1252   // Tell the main thread that the the newly-commited frame was drawn.
1253   if (impl().next_frame_is_newly_committed_frame) {
1254     impl().next_frame_is_newly_committed_frame = false;
1255     Proxy::MainThreadTaskRunner()->PostTask(
1256         FROM_HERE,
1257         base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
1258   }
1259
1260   if (draw_frame)
1261     CheckOutputSurfaceStatusOnImplThread();
1262
1263   if (result.draw_result == DrawSwapReadbackResult::DRAW_SUCCESS) {
1264     base::TimeDelta draw_duration = impl().timing_history.DidFinishDrawing();
1265
1266     base::TimeDelta draw_duration_overestimate;
1267     base::TimeDelta draw_duration_underestimate;
1268     if (draw_duration > draw_duration_estimate)
1269       draw_duration_underestimate = draw_duration - draw_duration_estimate;
1270     else
1271       draw_duration_overestimate = draw_duration_estimate - draw_duration;
1272     UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
1273                                draw_duration,
1274                                base::TimeDelta::FromMilliseconds(1),
1275                                base::TimeDelta::FromMilliseconds(100),
1276                                50);
1277     UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
1278                                draw_duration_underestimate,
1279                                base::TimeDelta::FromMilliseconds(1),
1280                                base::TimeDelta::FromMilliseconds(100),
1281                                50);
1282     UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
1283                                draw_duration_overestimate,
1284                                base::TimeDelta::FromMilliseconds(1),
1285                                base::TimeDelta::FromMilliseconds(100),
1286                                50);
1287   }
1288
1289   DCHECK_NE(DrawSwapReadbackResult::INVALID_RESULT, result.draw_result);
1290   return result;
1291 }
1292
1293 void ThreadProxy::AcquireLayerTextures() {
1294   // Called when the main thread needs to modify a layer texture that is used
1295   // directly by the compositor.
1296   // This method will block until the next compositor draw if there is a
1297   // previously committed frame that is still undrawn. This is necessary to
1298   // ensure that the main thread does not monopolize access to the textures.
1299   DCHECK(IsMainThread());
1300
1301   if (main().textures_acquired)
1302     return;
1303
1304   TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
1305   DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1306   CompletionEvent completion;
1307   Proxy::ImplThreadTaskRunner()->PostTask(
1308       FROM_HERE,
1309       base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
1310                  impl_thread_weak_ptr_,
1311                  &completion));
1312   // Block until it is safe to write to layer textures from the main thread.
1313   completion.Wait();
1314
1315   main().textures_acquired = true;
1316   main().can_cancel_commit = false;
1317 }
1318
1319 void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
1320     CompletionEvent* completion) {
1321   DCHECK(IsImplThread());
1322   DCHECK(!impl().texture_acquisition_completion_event);
1323
1324   impl().texture_acquisition_completion_event = completion;
1325   impl().scheduler->SetMainThreadNeedsLayerTextures();
1326 }
1327
1328 void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
1329   DCHECK(impl().texture_acquisition_completion_event);
1330   impl().texture_acquisition_completion_event->Signal();
1331   impl().texture_acquisition_completion_event = NULL;
1332 }
1333
1334 void ThreadProxy::ScheduledActionManageTiles() {
1335   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
1336   DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
1337   impl().layer_tree_host_impl->ManageTiles();
1338 }
1339
1340 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
1341   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
1342
1343   // SchedulerStateMachine::DidDrawIfPossibleCompleted isn't set up to
1344   // handle DRAW_ABORTED_CANT_DRAW.  Moreover, the scheduler should
1345   // never generate this call when it can't draw.
1346   DCHECK(impl().layer_tree_host_impl->CanDraw());
1347
1348   bool forced_draw = false;
1349   bool swap_requested = true;
1350   bool readback_requested = false;
1351   return DrawSwapReadbackInternal(
1352       forced_draw, swap_requested, readback_requested);
1353 }
1354
1355 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
1356   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
1357   bool forced_draw = true;
1358   bool swap_requested = true;
1359   bool readback_requested = false;
1360   return DrawSwapReadbackInternal(
1361       forced_draw, swap_requested, readback_requested);
1362 }
1363
1364 DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
1365   TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
1366   bool forced_draw = true;
1367   bool swap_requested = false;
1368   bool readback_requested = true;
1369   return DrawSwapReadbackInternal(
1370       forced_draw, swap_requested, readback_requested);
1371 }
1372
1373 void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
1374   if (impl().current_resource_update_controller)
1375     impl().current_resource_update_controller->PerformMoreUpdates(time);
1376 }
1377
1378 base::TimeDelta ThreadProxy::DrawDurationEstimate() {
1379   return impl().timing_history.DrawDurationEstimate();
1380 }
1381
1382 base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
1383   return impl().timing_history.BeginMainFrameToCommitDurationEstimate();
1384 }
1385
1386 base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
1387   return impl().timing_history.CommitToActivateDurationEstimate();
1388 }
1389
1390 void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
1391                                              base::TimeTicks deadline) {
1392   base::TimeDelta delta = deadline - gfx::FrameTime::Now();
1393   if (delta <= base::TimeDelta())
1394     delta = base::TimeDelta();
1395   Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
1396 }
1397
1398 void ThreadProxy::DidBeginImplFrameDeadline() {
1399   impl().layer_tree_host_impl->ResetCurrentFrameTimeForNextFrame();
1400 }
1401
1402 void ThreadProxy::ReadyToFinalizeTextureUpdates() {
1403   DCHECK(IsImplThread());
1404   impl().scheduler->FinishCommit();
1405 }
1406
1407 void ThreadProxy::DidCommitAndDrawFrame() {
1408   DCHECK(IsMainThread());
1409   if (!layer_tree_host())
1410     return;
1411   layer_tree_host()->DidCommitAndDrawFrame();
1412 }
1413
1414 void ThreadProxy::DidCompleteSwapBuffers() {
1415   DCHECK(IsMainThread());
1416   if (!layer_tree_host())
1417     return;
1418   layer_tree_host()->DidCompleteSwapBuffers();
1419 }
1420
1421 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
1422                                      base::Time wall_clock_time) {
1423   TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
1424   DCHECK(IsMainThread());
1425   if (!layer_tree_host())
1426     return;
1427   layer_tree_host()->SetAnimationEvents(events.Pass(), wall_clock_time);
1428 }
1429
1430 void ThreadProxy::CreateAndInitializeOutputSurface() {
1431   TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
1432   DCHECK(IsMainThread());
1433
1434   // Check that output surface has not been recreated by CompositeAndReadback
1435   // after this task is posted but before it is run.
1436   bool has_initialized_output_surface = true;
1437   {
1438     CompletionEvent completion;
1439     Proxy::ImplThreadTaskRunner()->PostTask(
1440         FROM_HERE,
1441         base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1442                    impl_thread_weak_ptr_,
1443                    &completion,
1444                    &has_initialized_output_surface));
1445     completion.Wait();
1446   }
1447   if (has_initialized_output_surface)
1448     return;
1449
1450   layer_tree_host()->DidLoseOutputSurface();
1451   main().output_surface_creation_callback.Reset(
1452       base::Bind(&ThreadProxy::DoCreateAndInitializeOutputSurface,
1453                  base::Unretained(this)));
1454   main().output_surface_creation_callback.callback().Run();
1455 }
1456
1457 void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1458     CompletionEvent* completion,
1459     bool* has_initialized_output_surface) {
1460   DCHECK(IsImplThread());
1461   *has_initialized_output_surface =
1462       impl().scheduler->HasInitializedOutputSurface();
1463   completion->Signal();
1464 }
1465
1466 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1467   TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1468   DCHECK(IsImplThread());
1469   impl().layer_tree_host_impl =
1470       layer_tree_host()->CreateLayerTreeHostImpl(this);
1471   const LayerTreeSettings& settings = layer_tree_host()->settings();
1472   SchedulerSettings scheduler_settings;
1473   scheduler_settings.deadline_scheduling_enabled =
1474       settings.deadline_scheduling_enabled;
1475   scheduler_settings.impl_side_painting = settings.impl_side_painting;
1476   scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1477       settings.timeout_and_draw_when_animation_checkerboards;
1478   scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
1479       settings.maximum_number_of_failed_draws_before_draw_is_forced_;
1480   scheduler_settings.using_synchronous_renderer_compositor =
1481       settings.using_synchronous_renderer_compositor;
1482   scheduler_settings.throttle_frame_production =
1483       settings.throttle_frame_production;
1484   impl().scheduler =
1485       Scheduler::Create(this, scheduler_settings, impl().layer_tree_host_id);
1486   impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
1487
1488   impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
1489   completion->Signal();
1490 }
1491
1492 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1493     CompletionEvent* completion,
1494     scoped_ptr<OutputSurface> output_surface,
1495     scoped_refptr<ContextProvider> offscreen_context_provider,
1496     bool* success,
1497     RendererCapabilities* capabilities) {
1498   TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
1499   DCHECK(IsImplThread());
1500   DCHECK(IsMainThreadBlocked());
1501   DCHECK(success);
1502   DCHECK(capabilities);
1503
1504   layer_tree_host()->DeleteContentsTexturesOnImplThread(
1505       impl().layer_tree_host_impl->resource_provider());
1506
1507   *success =
1508       impl().layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
1509
1510   if (*success) {
1511     *capabilities = impl()
1512                         .layer_tree_host_impl->GetRendererCapabilities()
1513                         .MainThreadCapabilities();
1514     impl().scheduler->DidCreateAndInitializeOutputSurface();
1515   } else if (offscreen_context_provider.get()) {
1516     if (offscreen_context_provider->BindToCurrentThread())
1517       offscreen_context_provider->VerifyContexts();
1518     offscreen_context_provider = NULL;
1519   }
1520
1521   impl().layer_tree_host_impl->SetOffscreenContextProvider(
1522       offscreen_context_provider);
1523
1524   completion->Signal();
1525 }
1526
1527 void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1528   TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1529   DCHECK(IsImplThread());
1530   if (impl().layer_tree_host_impl->resource_provider())
1531     impl().layer_tree_host_impl->resource_provider()->Finish();
1532   completion->Signal();
1533 }
1534
1535 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
1536   TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1537   DCHECK(IsImplThread());
1538   layer_tree_host()->DeleteContentsTexturesOnImplThread(
1539       impl().layer_tree_host_impl->resource_provider());
1540   impl().current_resource_update_controller.reset();
1541   impl().layer_tree_host_impl->SetNeedsBeginImplFrame(false);
1542   impl().scheduler.reset();
1543   impl().layer_tree_host_impl.reset();
1544   impl().weak_factory.InvalidateWeakPtrs();
1545   impl().contents_texture_manager = NULL;
1546   completion->Signal();
1547 }
1548
1549 size_t ThreadProxy::MaxPartialTextureUpdates() const {
1550   return ResourceUpdateController::MaxPartialTextureUpdates();
1551 }
1552
1553 ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
1554     : memory_allocation_limit_bytes(0),
1555       memory_allocation_priority_cutoff(0),
1556       evicted_ui_resources(false) {}
1557
1558 ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
1559
1560 scoped_ptr<base::Value> ThreadProxy::AsValue() const {
1561   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
1562
1563   CompletionEvent completion;
1564   {
1565     DebugScopedSetMainThreadBlocked main_thread_blocked(
1566         const_cast<ThreadProxy*>(this));
1567     Proxy::ImplThreadTaskRunner()->PostTask(
1568         FROM_HERE,
1569         base::Bind(&ThreadProxy::AsValueOnImplThread,
1570                    impl_thread_weak_ptr_,
1571                    &completion,
1572                    state.get()));
1573     completion.Wait();
1574   }
1575   return state.PassAs<base::Value>();
1576 }
1577
1578 void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion,
1579                                       base::DictionaryValue* state) const {
1580   state->Set("layer_tree_host_impl",
1581              impl().layer_tree_host_impl->AsValue().release());
1582   completion->Signal();
1583 }
1584
1585 bool ThreadProxy::CommitPendingForTesting() {
1586   DCHECK(IsMainThread());
1587   CommitPendingRequest commit_pending_request;
1588   {
1589     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1590     Proxy::ImplThreadTaskRunner()->PostTask(
1591         FROM_HERE,
1592         base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting,
1593                    impl_thread_weak_ptr_,
1594                    &commit_pending_request));
1595     commit_pending_request.completion.Wait();
1596   }
1597   return commit_pending_request.commit_pending;
1598 }
1599
1600 void ThreadProxy::CommitPendingOnImplThreadForTesting(
1601     CommitPendingRequest* request) {
1602   DCHECK(IsImplThread());
1603   if (impl().layer_tree_host_impl->output_surface())
1604     request->commit_pending = impl().scheduler->CommitPending();
1605   else
1606     request->commit_pending = false;
1607   request->completion.Signal();
1608 }
1609
1610 scoped_ptr<base::Value> ThreadProxy::SchedulerStateAsValueForTesting() {
1611   if (IsImplThread())
1612     return impl().scheduler->StateAsValue().Pass();
1613
1614   SchedulerStateRequest scheduler_state_request;
1615   {
1616     DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1617     Proxy::ImplThreadTaskRunner()->PostTask(
1618         FROM_HERE,
1619         base::Bind(&ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting,
1620                    impl_thread_weak_ptr_,
1621                    &scheduler_state_request));
1622     scheduler_state_request.completion.Wait();
1623   }
1624   return scheduler_state_request.state.Pass();
1625 }
1626
1627 void ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting(
1628     SchedulerStateRequest* request) {
1629   DCHECK(IsImplThread());
1630   request->state = impl().scheduler->StateAsValue();
1631   request->completion.Signal();
1632 }
1633
1634 void ThreadProxy::RenewTreePriority() {
1635   DCHECK(IsImplThread());
1636   bool smoothness_takes_priority =
1637       impl().layer_tree_host_impl->pinch_gesture_active() ||
1638       impl().layer_tree_host_impl->IsCurrentlyScrolling() ||
1639       impl().layer_tree_host_impl->page_scale_animation_active();
1640
1641   base::TimeTicks now = impl().layer_tree_host_impl->CurrentPhysicalTimeTicks();
1642
1643   // Update expiration time if smoothness currently takes priority.
1644   if (smoothness_takes_priority) {
1645     impl().smoothness_takes_priority_expiration_time =
1646         now + base::TimeDelta::FromMilliseconds(
1647                   kSmoothnessTakesPriorityExpirationDelay * 1000);
1648   }
1649
1650   // We use the same priority for both trees by default.
1651   TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
1652
1653   // Smoothness takes priority if expiration time is in the future.
1654   if (impl().smoothness_takes_priority_expiration_time > now)
1655     priority = SMOOTHNESS_TAKES_PRIORITY;
1656
1657   // New content always takes priority when the active tree has
1658   // evicted resources or there is an invalid viewport size.
1659   if (impl().layer_tree_host_impl->active_tree()->ContentsTexturesPurged() ||
1660       impl().layer_tree_host_impl->active_tree()->ViewportSizeInvalid() ||
1661       impl().layer_tree_host_impl->EvictedUIResourcesExist() ||
1662       impl().input_throttled_until_commit) {
1663     // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active
1664     // tree might be freed. We need to set RequiresHighResToDraw to ensure that
1665     // high res tiles will be required to activate pending tree.
1666     impl().layer_tree_host_impl->active_tree()->SetRequiresHighResToDraw();
1667     priority = NEW_CONTENT_TAKES_PRIORITY;
1668   }
1669
1670   impl().layer_tree_host_impl->SetTreePriority(priority);
1671   impl().scheduler->SetSmoothnessTakesPriority(priority ==
1672                                                SMOOTHNESS_TAKES_PRIORITY);
1673
1674   // Notify the the client of this compositor via the output surface.
1675   // TODO(epenner): Route this to compositor-thread instead of output-surface
1676   // after GTFO refactor of compositor-thread (http://crbug/170828).
1677   if (impl().layer_tree_host_impl->output_surface()) {
1678     impl()
1679         .layer_tree_host_impl->output_surface()
1680         ->UpdateSmoothnessTakesPriority(priority == SMOOTHNESS_TAKES_PRIORITY);
1681   }
1682
1683   base::TimeDelta delay =
1684       impl().smoothness_takes_priority_expiration_time - now;
1685
1686   // Need to make sure a delayed task is posted when we have smoothness
1687   // takes priority expiration time in the future.
1688   if (delay <= base::TimeDelta())
1689     return;
1690   if (impl().renew_tree_priority_pending)
1691     return;
1692
1693   Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1694       FROM_HERE,
1695       base::Bind(&ThreadProxy::RenewTreePriorityOnImplThread,
1696                  impl_thread_weak_ptr_),
1697       delay);
1698
1699   impl().renew_tree_priority_pending = true;
1700 }
1701
1702 void ThreadProxy::RenewTreePriorityOnImplThread() {
1703   DCHECK(impl().renew_tree_priority_pending);
1704   impl().renew_tree_priority_pending = false;
1705
1706   RenewTreePriority();
1707 }
1708
1709 void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
1710   Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1711       FROM_HERE,
1712       base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
1713                  impl_thread_weak_ptr_),
1714       delay);
1715 }
1716
1717 void ThreadProxy::StartScrollbarAnimationOnImplThread() {
1718   impl().layer_tree_host_impl->StartScrollbarAnimation();
1719 }
1720
1721 void ThreadProxy::DidActivatePendingTree() {
1722   TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
1723   DCHECK(IsImplThread());
1724
1725   if (impl().completion_event_for_commit_held_on_tree_activation &&
1726       !impl().layer_tree_host_impl->pending_tree()) {
1727     TRACE_EVENT_INSTANT0(
1728         "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD);
1729     DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
1730     impl().completion_event_for_commit_held_on_tree_activation->Signal();
1731     impl().completion_event_for_commit_held_on_tree_activation = NULL;
1732   }
1733
1734   UpdateBackgroundAnimateTicking();
1735
1736   impl().timing_history.DidActivatePendingTree();
1737 }
1738
1739 void ThreadProxy::DidManageTiles() {
1740   DCHECK(IsImplThread());
1741   impl().scheduler->DidManageTiles();
1742 }
1743
1744 }  // namespace cc