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