thread_proxy.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/thread_proxy.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string>
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/metrics/histogram.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/benchmark_instrumentation.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/draw_quad.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/prioritized_resource_manager.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/delay_based_time_source.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/frame_rate_controller.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/scheduler.h"
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "cc/trees/blocking_task_runner.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Measured in seconds.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst size_t kDurationHistorySize = 60;
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst double kCommitAndActivationDurationEstimationPercentile = 50.0;
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const double kDrawDurationEstimationPercentile = 100.0;
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const int kDrawDurationEstimatePaddingInMicroseconds = 0;
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::ReadbackRequest {
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool success;
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void* pixels;
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect rect;
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::CommitPendingRequest {
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool commit_pending;
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::SchedulerStateRequest {
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<base::Value> state;
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<Proxy> ThreadProxy::Create(
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LayerTreeHost* layer_tree_host,
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ThreadProxy(layer_tree_host, impl_task_runner)).PassAs<Proxy>();
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochThreadProxy::ThreadProxy(
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LayerTreeHost* layer_tree_host,
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : Proxy(impl_task_runner),
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      animate_requested_(false),
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_requested_(false),
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_request_sent_to_impl_thread_(false),
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      created_offscreen_context_provider_(false),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_(layer_tree_host),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      started_(false),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      textures_acquired_(true),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_composite_and_readback_(false),
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manage_tiles_pending_(false),
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      commit_waits_for_activation_(false),
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      inside_commit_(false),
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_sent_completion_event_on_impl_thread_(NULL),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      readback_request_on_impl_thread_(NULL),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_completion_event_on_impl_thread_(NULL),
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      completion_event_for_commit_held_on_tree_activation_(NULL),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texture_acquisition_completion_event_on_impl_thread_(NULL),
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      next_frame_is_newly_committed_frame_on_impl_thread_(false),
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      throttle_frame_production_(
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          layer_tree_host->settings().throttle_frame_production),
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_impl_frame_scheduling_enabled_(
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          layer_tree_host->settings().begin_impl_frame_scheduling_enabled),
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      using_synchronous_renderer_compositor_(
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          layer_tree_host->settings().using_synchronous_renderer_compositor),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inside_draw_(false),
89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      can_cancel_commit_(true),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      defer_commits_(false),
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      input_throttled_until_commit_(false),
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      renew_tree_priority_on_impl_thread_pending_(false),
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      draw_duration_history_(kDurationHistorySize),
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_to_commit_duration_history_(kDurationHistorySize),
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      commit_to_activate_duration_history_(kDurationHistorySize),
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_on_impl_thread_(this),
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(layer_tree_host_);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThreadProxy::~ThreadProxy() {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!started_);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback");
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_);
113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (defer_commits_) {
115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return false;
117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Perform a synchronous commit with an associated readback.
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ReadbackRequest request;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.rect = rect;
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.pixels = pixels;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent begin_main_frame_sent_completion;
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Proxy::ImplThreadTaskRunner()
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ->PostTask(FROM_HERE,
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              impl_thread_weak_ptr_,
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                              &begin_main_frame_sent_completion,
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              &request));
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion.Wait();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = true;
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is the forced commit.
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Note: The Impl thread also queues a separate BeginMainFrame on the
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // main thread, which will be called after this CompositeAndReadback
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // completes, to replace the forced commit.
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = false;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Composite and readback requires a second commit to undo any changes
149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // that it made.
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.completion.Wait();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return request.success;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::ForceCommitForReadbackOnImplThread(
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent* begin_main_frame_sent_completion,
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ReadbackRequest* request) {
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsImplThread());
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!begin_main_frame_sent_completion_event_on_impl_thread_);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!readback_request_on_impl_thread_);
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->success = false;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->completion.Signal();
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  readback_request_on_impl_thread_ = request;
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (scheduler_on_impl_thread_->CommitPending()) {
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_completion_event_on_impl_thread_ =
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_sent_completion;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRendering() {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!defer_commits_);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure all GL drawing is finished on the impl thread.
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::FinishAllRenderingOnImplThread,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsStarted() const {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return started_;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReady() {
204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReady");
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetLayerTreeHostClientReadyOnImplThread,
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_));
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReadyOnImplThread() {
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReadyOnImplThread");
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanStart();
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisible(bool visible) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisible");
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetVisibleOnImplThread,
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 &completion,
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 visible));
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool visible) {
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisibleOnImplThread");
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetVisible(visible);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(visible);
235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::UpdateBackgroundAnimateTicking() {
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      !scheduler_on_impl_thread_->WillDrawIfNeeded() &&
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->root_layer());
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::DoCreateAndInitializeOutputSurface() {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!output_surface)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_surface = layer_tree_host_->CreateOutputSurface();
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RendererCapabilities capabilities;
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool success = !!output_surface;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!success) {
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnOutputSurfaceInitializeAttempted(false, capabilities);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<ContextProvider> offscreen_context_provider;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (created_offscreen_context_provider_) {
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        layer_tree_host_->client()->OffscreenContextProvider();
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    success = !!offscreen_context_provider.get();
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!success) {
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OnOutputSurfaceInitializeAttempted(false, capabilities);
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  success = false;
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // of that call are pushed into the success and capabilities local
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // variables.
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Passed(&output_surface),
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   offscreen_context_provider,
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &success,
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &capabilities));
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnOutputSurfaceInitializeAttempted(success, capabilities);
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::OnOutputSurfaceInitializeAttempted(
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RendererCapabilities& capabilities) {
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(layer_tree_host_);
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (success) {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    renderer_capabilities_main_thread_copy_ = capabilities;
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LayerTreeHost::CreateResult result =
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (result == LayerTreeHost::CreateFailedButTryAgain) {
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!output_surface_creation_callback_.callback().is_null()) {
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Proxy::MainThreadTaskRunner()->PostTask(
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          FROM_HERE, output_surface_creation_callback_.callback());
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_surface_creation_callback_.Cancel();
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
316558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
317558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (commit_request_sent_to_impl_thread_)
319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
320558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  commit_request_sent_to_impl_thread_ = true;
321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
322558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                 impl_thread_weak_ptr_));
325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!layer_tree_host_->output_surface_lost());
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return renderer_capabilities_main_thread_copy_;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsAnimate() {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = true;
340558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
342558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SetNeedsUpdateLayers() {
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (commit_request_sent_to_impl_thread_)
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
351558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommit() {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Unconditionally set here to handle SetNeedsCommit calls during a commit.
357558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (commit_requested_)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CheckOutputSurfaceStatusOnImplThread();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->IsContextLost())
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (cc::ContextProvider* offscreen_contexts =
379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          layer_tree_host_impl_->offscreen_context_provider())
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts->VerifyContexts();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->DidLoseOutputSurface();
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame",
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               "enable", enable);
3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(enable);
39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
4021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Sample the frame time now. This time will be used for updating animations
40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // when we draw.
40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_impl_->CurrentFrameTimeTicks();
40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginImplFrame(args);
40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT1(
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanDraw(can_draw);
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::NotifyReadyToActivate() {
420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scheduler_on_impl_thread_->NotifyReadyToActivate();
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommitOnImplThread() {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsCommit();
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AnimationEventsVector> events,
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time wall_clock_time) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc",
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetAnimationEvents,
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 main_thread_weak_ptr_,
440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 base::Passed(&events),
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 wall_clock_time));
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          int priority_cutoff) {
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_->contents_texture_manager())
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!layer_tree_host_impl_->resource_provider())
4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool reduce_result = layer_tree_host_->contents_texture_manager()->
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ReduceMemoryOnImplThread(limit_bytes,
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               priority_cutoff,
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               layer_tree_host_impl_->resource_provider());
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reduce_result)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The texture upload queue may reference textures that were just purged,
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clear them from the queue.
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_resource_update_controller_on_impl_thread_->
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DiscardUploadsToEvictedResources();
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SendManagedMemoryStats() {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_->contents_texture_manager())
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are using impl-side painting, then SendManagedMemoryStats is called
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly after the tile manager's manage function, and doesn't need to
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // interact with main thread's layer tree.
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_->settings().impl_side_painting)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SendManagedMemoryStats(
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->contents_texture_manager()->MemoryVisibleBytes(),
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->contents_texture_manager()->
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          MemoryVisibleAndNearbyBytes(),
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->contents_texture_manager()->MemoryUseBytes());
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsInsideDraw() { return inside_draw_; }
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread,
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 damage_rect));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::SetNextCommitWaitsForActivation() {
502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(IsMainThread());
503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!inside_commit_);
504424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = true;
505424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetDeferCommits(bool defer_commits) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(defer_commits_, defer_commits);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  defer_commits_ = defer_commits;
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!defer_commits_ && pending_deferred_commit_)
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
5201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrame,
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   main_thread_weak_ptr_,
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Passed(&pending_deferred_commit_)));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitRequested() const {
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_requested_;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ThreadProxy::BeginMainFrameRequested() const {
5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(IsMainThread());
5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return commit_request_sent_to_impl_thread_;
5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawOnImplThread() {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::SetNeedsManageTilesOnImplThread() {
542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsImplThread());
543d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsManageTiles();
544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->SetViewportDamage(damage_rect);
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetNeedsRedrawOnImplThread();
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread(
55358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool used_incomplete_tile) {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (used_incomplete_tile) {
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TRACE_EVENT_INSTANT0(
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "cc",
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread",
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        TRACE_EVENT_SCOPE_THREAD);
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
56158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetSwapUsedIncompleteTile(
56258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    used_incomplete_tile);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidInitializeVisibleTileOnImplThread() {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread");
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlinging() {
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 impl_thread_weak_ptr_));
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlingingOnImplThread() {
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  layer_tree_host_impl_->MainThreadHasStoppedFlinging();
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::NotifyInputThrottledUntilCommit() {
585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsMainThread());
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostTask(
587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&ThreadProxy::SetInputThrottledUntilCommitOnImplThread,
589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 impl_thread_weak_ptr_,
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 true));
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::SetInputThrottledUntilCommitOnImplThread(
594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool is_throttled) {
595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_throttled == input_throttled_until_commit_)
597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  input_throttled_until_commit_ = is_throttled;
599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RenewTreePriority();
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(Proxy::HasImplThread());
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(first_output_surface);
606424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create LayerTreeHostImpl.
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::InitializeImplOnImplThread,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 &completion));
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  first_output_surface_ = first_output_surface.Pass();
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = true;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::Stop() {
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::Stop");
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(started_);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Synchronously finishes pending GL operations and deletes the impl.
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The two steps are done as separate post tasks, so that tasks posted
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // by the GL implementation due to the Finish can be executed by the
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // renderer before shutting it down.
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::FinishGLOnImplThread,
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion));
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::LayerTreeHostClosedOnImplThread,
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion));
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!layer_tree_host_impl_.get());  // verify that the impl deleted.
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_ = NULL;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = false;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffers() {
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread,
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread(
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->renderer())
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->renderer()->DoNoOp();
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->FinishAllRendering();
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::ScheduledActionSendBeginMainFrame() {
6888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new BeginMainFrameAndCommitState);
6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->monotonic_frame_begin_time =
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      layer_tree_host_impl_->CurrentPhysicalTimeTicks();
6931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->scroll_info =
69490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      layer_tree_host_impl_->ProcessScrollDeltas();
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!layer_tree_host_impl_->settings().impl_side_painting) {
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u);
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
6991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_limit_bytes =
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->memory_allocation_limit_bytes();
7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_priority_cutoff =
70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_host_impl_->memory_allocation_priority_cutoff();
7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->evicted_ui_resources =
70458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist();
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
7071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&ThreadProxy::BeginMainFrame,
70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 main_thread_weak_ptr_,
7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 base::Passed(&begin_main_frame_state)));
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_sent_completion_event_on_impl_thread_) {
7121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_->Signal();
7131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_ = NULL;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_time_ = base::TimeTicks::HighResNow();
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrame(
7191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_)
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_) {
7271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_deferred_commit_ = begin_main_frame_state.Pass();
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->DidDeferCommit();
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not notify the impl thread of commit requests that occur during
7341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the apply/animate/layout part of the BeginMainFrameAndCommit process since
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those commit requests will get painted immediately. Once we have done
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the paint, commit_requested_ will be set to false to allow new commit
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // requests to be scheduled.
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = true;
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On the other hand, the AnimationRequested flag needs to be cleared
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // here so that any animation requests generated by the apply or animate
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callbacks will trigger another frame.
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = false;
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!in_composite_and_readback_ && !layer_tree_host_->visible()) {
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_requested_ = false;
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_request_sent_to_impl_thread_ = false;
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NotVisible");
751558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = false;
752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
755558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
756558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_state)
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    layer_tree_host_->ApplyScrollAndScale(*begin_main_frame_state->scroll_info);
762558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_->WillBeginMainFrame();
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_state) {
766b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    layer_tree_host_->UpdateClientAnimations(
7671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
768b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    layer_tree_host_->AnimateLayers(
7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Unlink any backings that the impl thread has evicted, so that we know to
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // re-paint them in UpdateLayers.
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_->contents_texture_manager()) {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->contents_texture_manager()->
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UnlinkAndClearEvictedBackings();
77768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (begin_main_frame_state) {
77968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
7801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_limit_bytes);
78168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_host_->contents_texture_manager()->SetExternalPriorityCutoff(
7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_priority_cutoff);
78368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Recreate all UI resources if there were evicted UI resources when the impl
78758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // thread initiated the commit.
7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool evicted_ui_resources = begin_main_frame_state
7891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  ? begin_main_frame_state->evicted_ui_resources
7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  : false;
79158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (evicted_ui_resources)
79258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_->RecreateUIResources();
79358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->Layout();
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear the commit flag after updating animations and layout here --- objects
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that only layout when painted will trigger another SetNeedsCommit inside
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UpdateLayers.
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = false;
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = false;
801558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool can_cancel_this_commit =
80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      can_cancel_commit_ &&
80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !in_composite_and_readback_ &&
80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !evicted_ui_resources;
805558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = true;
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue =
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new ResourceUpdateQueue);
80968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
81068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool updated = layer_tree_host_->UpdateLayers(queue.get());
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Once single buffered layers are committed, they cannot be modified until
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they are drawn by the impl thread.
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = false;
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->WillCommit();
817558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
818558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!updated && can_cancel_this_commit) {
819558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
820558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = true;
821558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
822558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        FROM_HERE,
8231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
824558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
825558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
826558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
827558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Although the commit is internally aborted, this is because it has been
828558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // detected to be a no-op.  From the perspective of an embedder, this commit
829558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // went through, and input should no longer be throttled, etc.
830558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    layer_tree_host_->CommitComplete();
8311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    layer_tree_host_->DidBeginMainFrame();
832558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
833558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
834558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
835558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Before calling animate, we set animate_requested_ to false. If it is true
836558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // now, it means SetNeedAnimate was called again, but during a state when
837558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // commit_request_sent_to_impl_thread_ = true. We need to force that call to
838558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // happen again now so that the commit request is sent to the impl thread.
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_) {
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Forces SetNeedsAnimate to consider posting a commit task.
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    animate_requested_ = false;
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetNeedsAnimate();
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<cc::ContextProvider> offscreen_context_provider;
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renderer_capabilities_main_thread_copy_.using_offscreen_context3d &&
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->needs_offscreen_context()) {
8484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        layer_tree_host_->client()->OffscreenContextProvider();
850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (offscreen_context_provider.get())
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      created_offscreen_context_provider_ = true;
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Notify the impl thread that the main thread is ready to commit. This will
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // begin the commit process, which is blocking from the main thread's
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // point of view, but asynchronously performed on the impl thread,
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // coordinated by the Scheduler.
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
8591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
863424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // This CapturePostTasks should be destroyed before CommitComplete() is
864424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // called since that goes out to the embedder, and we want the embedder
865424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // to receive its callbacks before that.
866424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    BlockingTaskRunner::CapturePostTasks blocked;
867424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
87190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(&ThreadProxy::StartCommitOnImplThread,
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion,
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   queue.release(),
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   offscreen_context_provider));
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderingStatsInstrumentation* stats_instrumentation =
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        layer_tree_host_->rendering_stats_instrumentation();
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        stats_instrumentation->main_thread_rendering_stats());
8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    stats_instrumentation->AccumulateAndClearMainThreadStats();
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
8861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_->DidBeginMainFrame();
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
88990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::StartCommitOnImplThread(
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceUpdateQueue* raw_queue,
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<cc::ContextProvider> offscreen_context_provider) {
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!commit_completion_event_on_impl_thread_);
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread() && IsMainThreadBlocked());
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion->Signal();
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (offscreen_context_provider.get())
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_context_provider->BindToCurrentThread();
909424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
910424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (layer_tree_host_->contents_texture_manager()) {
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer_tree_host_->contents_texture_manager()->
914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            LinkedEvictedBackingsExist()) {
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Clear any uploads we were making to textures linked to evicted
916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // resources
917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      queue->ClearUploadsToEvictedResources();
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Some textures in the layer tree are invalid. Kick off another commit
919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // to fill them again.
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetNeedsCommitOnImplThread();
921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    layer_tree_host_->contents_texture_manager()->
924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        PushTexturePrioritiesToBackings();
925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_completion_event_on_impl_thread_ = completion;
928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_ =
929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ResourceUpdateController::Create(
930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          this,
931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          Proxy::ImplThreadTaskRunner(),
932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          queue.Pass(),
933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          layer_tree_host_impl_->resource_provider());
934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scheduler_on_impl_thread_->AnticipatedDrawTime());
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
9391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread");
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
943558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!layer_tree_host_impl_->pending_tree());
944558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
945558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // If the begin frame data was handled, then scroll and scale set was applied
946558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // by the main thread, so the active tree needs to be updated as if these sent
947558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // values were applied and committed.
948a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (did_handle) {
9493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    layer_tree_host_impl_->active_tree()
9503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ->ApplySentScrollAndScaleDeltasFromAbortedCommit();
9513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    layer_tree_host_impl_->active_tree()->ResetContentsTexturesPurged();
952a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetInputThrottledUntilCommitOnImplThread(false);
953a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
9548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionCommit() {
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(commit_completion_event_on_impl_thread_);
961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(current_resource_update_controller_on_impl_thread_);
962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Complete all remaining texture updates.
964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->Finalize();
965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_.reset();
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
967424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = true;
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->BeginCommit();
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->CommitComplete();
972424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = false;
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
974a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetInputThrottledUntilCommitOnImplThread(false);
975a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
976424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_frame_is_newly_committed_frame_on_impl_thread_ = true;
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_->settings().impl_side_painting &&
981424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      commit_waits_for_activation_) {
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For some layer types in impl-side painting, the commit is held until
9837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the pending tree is activated.  It's also possible that the
9847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // pending tree has already activated if there was no work to be done.
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ =
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        commit_completion_event_on_impl_thread_;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_->Signal();
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
994424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = false;
995424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
9967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_complete_time_ = base::TimeTicks::HighResNow();
9971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_to_commit_duration_history_.InsertSample(
9981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      commit_complete_time_ - begin_main_frame_sent_time_);
9997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetVisible kicks off the next scheduler action, so this must be last.
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1004ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ThreadProxy::ScheduledActionUpdateVisibleTiles() {
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1006ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
1007ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  layer_tree_host_impl_->UpdateVisibleTiles();
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1010424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::ScheduledActionActivatePendingTree() {
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1012424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
1013424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->ActivatePendingTree();
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 main_thread_weak_ptr_));
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
102658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool forced_draw,
102758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool swap_requested,
102858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool readback_requested) {
102958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DrawSwapReadbackResult result;
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_draw = false;
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_swap = false;
103258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.did_readback = false;
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_.get());
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->renderer());
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->renderer())
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::HighResNow();
104368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
104468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::AutoReset<bool> mark_inside(&inside_draw_, true);
104568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
104668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Advance our animations.
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks monotonic_time =
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->CurrentFrameTimeTicks();
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
10504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(enne): This should probably happen post-animate.
10524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (layer_tree_host_impl_->pending_tree())
10534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
10557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called on a forced draw, regardless of whether we are able
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to produce a frame, as the calling site on main thread is blocked until its
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // request completes, and we signal completion here. If CanDraw() is false, we
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will indicate success=false to the caller, but we must still signal
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // completion to avoid deadlock.
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We guard PrepareToDraw() with CanDraw() because it always returns a valid
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame, so can only be used when such a frame is possible. Since
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CanDraw() as well.
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool drawing_for_readback =
106858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      readback_requested && !!readback_request_on_impl_thread_;
1069b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostImpl::FrameData frame;
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool draw_frame = false;
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1074b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (layer_tree_host_impl_->CanDraw() &&
1075b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      (!drawing_for_readback || can_do_readback)) {
1076b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // If it is for a readback, make sure we draw the portion being read back.
1077b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    gfx::Rect readback_rect;
1078b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (drawing_for_readback)
1079b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      readback_rect = readback_request_on_impl_thread_->rect;
1080b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        forced_draw)
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      draw_frame = true;
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_frame) {
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->DrawLayers(
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &frame,
10898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        scheduler_on_impl_thread_->LastBeginImplFrameTime());
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_draw = true;
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->DidDrawAllLayers(frame);
109368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
109468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool start_ready_animations = draw_frame;
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for a pending CompositeAndReadback.
109858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (drawing_for_readback) {
109958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!swap_requested);
110058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result.did_readback = false;
110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (draw_frame && !layer_tree_host_impl_->IsContextLost()) {
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      readback_request_on_impl_thread_->rect);
110458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      result.did_readback = true;
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
110658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    readback_request_on_impl_thread_->success = result.did_readback;
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_->completion.Signal();
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_ = NULL;
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (draw_frame) {
111058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(swap_requested);
1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We don't know if we have incomplete tiles if we didn't actually swap.
111458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (result.did_swap) {
111558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DCHECK(!frame.has_no_damage);
111658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
111758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the main thread that the the newly-commited frame was drawn.
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (next_frame_is_newly_committed_frame_on_impl_thread_) {
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_frame_is_newly_committed_frame_on_impl_thread_ = false;
1123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
1124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (draw_frame) {
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckOutputSurfaceStatusOnImplThread();
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_time;
11327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    draw_duration_history_.InsertSample(draw_duration);
11337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_overestimate;
11347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_underestimate;
11357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (draw_duration > draw_duration_estimate)
11367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_underestimate = draw_duration - draw_duration_estimate;
11377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else
11387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_overestimate = draw_duration_estimate - draw_duration;
11397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
11407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration,
11417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
11427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
11437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
11447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
11457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_underestimate,
11467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
11477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
11487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
11497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
11507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_overestimate,
11517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
11527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
11537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
11547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
11557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTextures() {
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when the main thread needs to modify a layer texture that is used
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly by the compositor.
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method will block until the next compositor draw if there is a
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // previously committed frame that is still undrawn. This is necessary to
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ensure that the main thread does not monopolize access to the textures.
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (textures_acquired_)
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
1173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Block until it is safe to write to layer textures from the main thread.
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = true;
1182558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!texture_acquisition_completion_event_on_impl_thread_);
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = completion;
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture_acquisition_completion_event_on_impl_thread_);
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_->Signal();
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = NULL;
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::ScheduledActionManageTiles() {
1201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
1202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  layer_tree_host_impl_->ManageTiles();
1204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
120658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
120758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
120858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = false;
120958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
121058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
121158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
121258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
121358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
121458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
121558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
121658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
121758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
121858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
121958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
122058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
122158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
122558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
122658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
122758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = false;
122858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = true;
122958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
123058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_)
123568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
123668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        time);
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TimeDelta ThreadProxy::DrawDurationEstimate() {
12407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta historical_estimate =
12417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_history_.Percentile(kDrawDurationEstimationPercentile);
12427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
12437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kDrawDurationEstimatePaddingInMicroseconds);
12447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return historical_estimate + padding;
12457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
12467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
12481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return begin_main_frame_to_commit_duration_history_.Percentile(
12497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
12507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
12517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
12537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return commit_to_activate_duration_history_.Percentile(
12547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
12557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
12567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
12588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                             base::TimeTicks deadline) {
12591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeDelta delta = deadline - gfx::FrameTime::Now();
126068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (delta <= base::TimeDelta())
126168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delta = base::TimeDelta();
126268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
126368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
126468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::DidBeginImplFrameDeadline() {
12668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
12678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
12688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ReadyToFinalizeTextureUpdates() {
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
127190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler_on_impl_thread_->FinishCommit();
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCommitAndDrawFrame() {
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_)
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->DidCommitAndDrawFrame();
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCompleteSwapBuffers() {
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_)
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->DidCompleteSwapBuffers();
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     base::Time wall_clock_time) {
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_)
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::CreateAndInitializeOutputSurface() {
1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check that output surface has not been recreated by CompositeAndReadback
1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after this task is posted but before it is run.
1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_initialized_output_surface_on_impl_thread = true;
1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
1306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &has_initialized_output_surface_on_impl_thread));
1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
1313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_initialized_output_surface_on_impl_thread)
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->DidLoseOutputSurface();
1318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.Reset(base::Bind(
1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &ThreadProxy::DoCreateAndInitializeOutputSurface,
1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Unretained(this)));
1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.callback().Run();
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent* completion,
1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* has_initialized_output_surface) {
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *has_initialized_output_surface =
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scheduler_on_impl_thread_->HasInitializedOutputSurface();
1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
133390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const LayerTreeSettings& settings = layer_tree_host_->settings();
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings scheduler_settings;
133968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scheduler_settings.deadline_scheduling_enabled =
134068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      settings.deadline_scheduling_enabled;
1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.impl_side_painting = settings.impl_side_painting;
1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      settings.timeout_and_draw_when_animation_checkerboards;
134458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
134558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings.maximum_number_of_failed_draws_before_draw_is_forced_;
13467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scheduler_settings.using_synchronous_renderer_compositor =
13477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      settings.using_synchronous_renderer_compositor;
1348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduler_settings.throttle_frame_production =
1349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      settings.throttle_frame_production;
13507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::InitializeOutputSurfaceOnImplThread(
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<OutputSurface> output_surface,
1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<ContextProvider> offscreen_context_provider,
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* success,
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RendererCapabilities* capabilities) {
1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThreadBlocked());
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(success);
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(capabilities);
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->DeleteContentsTexturesOnImplThread(
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (*success) {
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *capabilities = layer_tree_host_impl_->GetRendererCapabilities();
1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
1377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (offscreen_context_provider.get()) {
1378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (offscreen_context_provider->BindToCurrentThread())
1379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider->VerifyContexts();
1380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    offscreen_context_provider = NULL;
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
1384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
1385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->resource_provider())
1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_impl_->resource_provider()->Finish();
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->DeleteContentsTexturesOnImplThread(
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
14024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  current_resource_update_controller_on_impl_thread_.reset();
14031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(false);
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_.reset();
1405a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  layer_tree_host_impl_.reset();
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_on_impl_thread_.InvalidateWeakPtrs();
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t ThreadProxy::MaxPartialTextureUpdates() const {
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ResourceUpdateController::MaxPartialTextureUpdates();
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
141568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : memory_allocation_limit_bytes(0),
141668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_allocation_priority_cutoff(0),
141768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      evicted_ui_resources(false) {}
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::AsValue() const {
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const_cast<ThreadProxy*>(this));
1428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&ThreadProxy::AsValueOnImplThread,
1431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   impl_thread_weak_ptr_,
1432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   &completion,
1433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   state.get()));
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return state.PassAs<base::Value>();
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion,
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::DictionaryValue* state) const {
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->Set("layer_tree_host_impl",
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             layer_tree_host_impl_->AsValue().release());
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitPendingForTesting() {
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommitPendingRequest commit_pending_request;
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting,
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &commit_pending_request));
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_pending_request.completion.Wait();
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_pending_request.commit_pending;
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CommitPendingOnImplThreadForTesting(
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommitPendingRequest* request) {
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface())
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = scheduler_on_impl_thread_->CommitPending();
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = false;
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request->completion.Signal();
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::SchedulerStateAsValueForTesting() {
14727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsImplThread())
1473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return scheduler_on_impl_thread_->StateAsValue().Pass();
14747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
14757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SchedulerStateRequest scheduler_state_request;
14767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
14777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
14803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting,
14817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   impl_thread_weak_ptr_,
14827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   &scheduler_state_request));
14837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scheduler_state_request.completion.Wait();
14847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
14853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scheduler_state_request.state.Pass();
14867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
14877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
14883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting(
14897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SchedulerStateRequest* request) {
14907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(IsImplThread());
1491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->state = scheduler_on_impl_thread_->StateAsValue();
14927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  request->completion.Signal();
14937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
14947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriority() {
1496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool smoothness_takes_priority =
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->pinch_gesture_active() ||
14994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      layer_tree_host_impl_->IsCurrentlyScrolling() ||
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->page_scale_animation_active();
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeTicks now = layer_tree_host_impl_->CurrentPhysicalTimeTicks();
15037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update expiration time if smoothness currently takes priority.
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (smoothness_takes_priority) {
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    smoothness_takes_priority_expiration_time_ =
15077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        now + base::TimeDelta::FromMilliseconds(
15087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  kSmoothnessTakesPriorityExpirationDelay * 1000);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We use the same priority for both trees by default.
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Smoothness takes priority if expiration time is in the future.
15157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (smoothness_takes_priority_expiration_time_ > now)
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = SMOOTHNESS_TAKES_PRIORITY;
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // New content always takes priority when the active tree has
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // evicted resources or there is an invalid viewport size.
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->active_tree()->ContentsTexturesPurged() ||
1521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->ViewportSizeInvalid() ||
152258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist() ||
1523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      input_throttled_until_commit_)
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = NEW_CONTENT_TAKES_PRIORITY;
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetTreePriority(priority);
15271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scheduler_on_impl_thread_->SetSmoothnessTakesPriority(
15281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      priority == SMOOTHNESS_TAKES_PRIORITY);
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the the client of this compositor via the output surface.
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(epenner): Route this to compositor-thread instead of output-surface
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after GTFO refactor of compositor-thread (http://crbug/170828).
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface()) {
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->output_surface()->
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UpdateSmoothnessTakesPriority(priority == SMOOTHNESS_TAKES_PRIORITY);
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta delay = smoothness_takes_priority_expiration_time_ - now;
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Need to make sure a delayed task is posted when we have smoothness
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // takes priority expiration time in the future.
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delay <= base::TimeDelta())
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renew_tree_priority_on_impl_thread_pending_)
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::RenewTreePriorityOnImplThread,
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_on_impl_thread_.GetWeakPtr()),
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = true;
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriorityOnImplThread() {
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(renew_tree_priority_on_impl_thread_pending_);
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = false;
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenewTreePriority();
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
1564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_),
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::StartScrollbarAnimationOnImplThread() {
15727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layer_tree_host_impl_->StartScrollbarAnimation();
1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1575a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ThreadProxy::DidActivatePendingTree() {
1576a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(IsImplThread());
1577a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
1578a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1579a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (completion_event_for_commit_held_on_tree_activation_ &&
1580a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !layer_tree_host_impl_->pending_tree()) {
1581a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1582a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         TRACE_EVENT_SCOPE_THREAD);
1583a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1584a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_->Signal();
1585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ = NULL;
1586a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
15877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
1589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
15907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_to_activate_duration_history_.InsertSample(
15917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::TimeTicks::HighResNow() - commit_complete_time_);
1592a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1593a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1595