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"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "cc/base/swap_promise.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/benchmark_instrumentation.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/draw_quad.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/prioritized_resource_manager.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/delay_based_time_source.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/frame_rate_controller.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/scheduler.h"
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "cc/trees/blocking_task_runner.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Measured in seconds.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst size_t kDurationHistorySize = 60;
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst double kCommitAndActivationDurationEstimationPercentile = 50.0;
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const double kDrawDurationEstimationPercentile = 100.0;
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const int kDrawDurationEstimatePaddingInMicroseconds = 0;
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SwapPromiseChecker {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit SwapPromiseChecker(cc::LayerTreeHost* layer_tree_host)
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        : layer_tree_host_(layer_tree_host) {}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ~SwapPromiseChecker() {
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host_->BreakSwapPromises(cc::SwapPromise::COMMIT_FAILS);
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cc::LayerTreeHost* layer_tree_host_;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::ReadbackRequest {
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool success;
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void* pixels;
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Rect rect;
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::CommitPendingRequest {
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool commit_pending;
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct ThreadProxy::SchedulerStateRequest {
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CompletionEvent completion;
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<base::Value> state;
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<Proxy> ThreadProxy::Create(
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LayerTreeHost* layer_tree_host,
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ThreadProxy(layer_tree_host, impl_task_runner)).PassAs<Proxy>();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochThreadProxy::ThreadProxy(
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LayerTreeHost* layer_tree_host,
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : Proxy(impl_task_runner),
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      animate_requested_(false),
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_requested_(false),
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_request_sent_to_impl_thread_(false),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      created_offscreen_context_provider_(false),
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host_unsafe_(layer_tree_host),
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_unsafe_(NULL),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      started_(false),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      textures_acquired_(true),
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_composite_and_readback_(false),
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manage_tiles_pending_(false),
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      commit_waits_for_activation_(false),
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      inside_commit_(false),
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_sent_completion_event_on_impl_thread_(NULL),
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      readback_request_on_impl_thread_(NULL),
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      commit_completion_event_on_impl_thread_(NULL),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      completion_event_for_commit_held_on_tree_activation_(NULL),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texture_acquisition_completion_event_on_impl_thread_(NULL),
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      next_frame_is_newly_committed_frame_on_impl_thread_(false),
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      throttle_frame_production_(
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          layer_tree_host->settings().throttle_frame_production),
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_impl_frame_scheduling_enabled_(
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          layer_tree_host->settings().begin_impl_frame_scheduling_enabled),
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      using_synchronous_renderer_compositor_(
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          layer_tree_host->settings().using_synchronous_renderer_compositor),
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inside_draw_(false),
108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      can_cancel_commit_(true),
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      defer_commits_(false),
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      input_throttled_until_commit_(false),
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      renew_tree_priority_on_impl_thread_pending_(false),
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      draw_duration_history_(kDurationHistorySize),
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_to_commit_duration_history_(kDurationHistorySize),
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      commit_to_activate_duration_history_(kDurationHistorySize),
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_on_impl_thread_(this),
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      weak_factory_(this),
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      layer_tree_host_id_(layer_tree_host->id()) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(this->layer_tree_host());
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThreadProxy::~ThreadProxy() {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!started_);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback");
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(layer_tree_host());
133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (defer_commits_) {
135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit");
136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return false;
137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host()->InitializeOutputSurfaceIfNeeded()) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized");
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Perform a synchronous commit with an associated readback.
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ReadbackRequest request;
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.rect = rect;
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.pixels = pixels;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent begin_main_frame_sent_completion;
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Proxy::ImplThreadTaskRunner()
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ->PostTask(FROM_HERE,
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              impl_thread_weak_ptr_,
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                              &begin_main_frame_sent_completion,
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              &request));
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion.Wait();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = true;
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is the forced commit.
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Note: The Impl thread also queues a separate BeginMainFrame on the
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // main thread, which will be called after this CompositeAndReadback
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // completes, to replace the forced commit.
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_composite_and_readback_ = false;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Composite and readback requires a second commit to undo any changes
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // that it made.
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request.completion.Wait();
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return request.success;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::ForceCommitForReadbackOnImplThread(
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompletionEvent* begin_main_frame_sent_completion,
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ReadbackRequest* request) {
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(IsImplThread());
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!begin_main_frame_sent_completion_event_on_impl_thread_);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!readback_request_on_impl_thread_);
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->success = false;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->completion.Signal();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  readback_request_on_impl_thread_ = request;
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (scheduler_on_impl_thread_->CommitPending()) {
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion->Signal();
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_completion_event_on_impl_thread_ =
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      begin_main_frame_sent_completion;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRendering() {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!defer_commits_);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure all GL drawing is finished on the impl thread.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::FinishAllRenderingOnImplThread,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsStarted() const {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(Proxy::IsMainThread());
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return started_;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReady() {
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReady");
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetLayerTreeHostClientReadyOnImplThread,
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_));
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ThreadProxy::SetLayerTreeHostClientReadyOnImplThread() {
232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReadyOnImplThread");
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanStart();
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisible(bool visible) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisible");
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetVisibleOnImplThread,
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 &completion,
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 visible));
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool visible) {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetVisibleOnImplThread");
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetVisible(visible);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(visible);
255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::UpdateBackgroundAnimateTicking() {
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      !scheduler_on_impl_thread_->WillDrawIfNeeded() &&
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->root_layer());
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::DoCreateAndInitializeOutputSurface() {
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface");
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!output_surface)
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    output_surface = layer_tree_host()->CreateOutputSurface();
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RendererCapabilities capabilities;
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool success = !!output_surface;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!success) {
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnOutputSurfaceInitializeAttempted(false, capabilities);
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<ContextProvider> offscreen_context_provider;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (created_offscreen_context_provider_) {
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->client()->OffscreenContextProvider();
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    success = !!offscreen_context_provider.get();
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!success) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OnOutputSurfaceInitializeAttempted(false, capabilities);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  success = false;
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // of that call are pushed into the success and capabilities local
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // variables.
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Passed(&output_surface),
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   offscreen_context_provider,
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &success,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &capabilities));
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnOutputSurfaceInitializeAttempted(success, capabilities);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
314a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.orgvoid ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
315a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org    const RendererCapabilities& capabilities) {
316a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org  renderer_capabilities_main_thread_copy_ = capabilities;
317a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org}
318a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::OnOutputSurfaceInitializeAttempted(
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success,
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RendererCapabilities& capabilities) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(layer_tree_host());
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (success) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    renderer_capabilities_main_thread_copy_ = capabilities;
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LayerTreeHost::CreateResult result =
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (result == LayerTreeHost::CreateFailedButTryAgain) {
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!output_surface_creation_callback_.callback().is_null()) {
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Proxy::MainThreadTaskRunner()->PostTask(
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          FROM_HERE, output_surface_creation_callback_.callback());
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_surface_creation_callback_.Cancel();
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
342558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
343558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (commit_request_sent_to_impl_thread_)
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  commit_request_sent_to_impl_thread_ = true;
346558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                 impl_thread_weak_ptr_));
350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
351558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!layer_tree_host()->output_surface_lost());
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return renderer_capabilities_main_thread_copy_;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsAnimate() {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = true;
365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
367558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThreadProxy::SetNeedsUpdateLayers() {
370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(IsMainThread());
3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (commit_request_sent_to_impl_thread_)
3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommit() {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
381558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Unconditionally set here to handle SetNeedsCommit calls during a commit.
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (commit_requested_)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
389558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  SendCommitRequestToImplThreadIfNeeded();
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.orgvoid ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
393a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org  DCHECK(IsImplThread());
394a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org  Proxy::MainThreadTaskRunner()->PostTask(
395a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org      FROM_HERE,
396a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org      base::Bind(&ThreadProxy::SetRendererCapabilitiesMainThreadCopy,
397a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org                 main_thread_weak_ptr_,
398a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org                 layer_tree_host_impl_->GetRendererCapabilities()
399a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org                     .MainThreadCapabilities()));
400a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org}
401a1a4478c1f45e01b398ca4776fc933a77b33e3ceboliu@chromium.org
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CheckOutputSurfaceStatusOnImplThread();
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread");
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->IsContextLost())
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (ContextProvider* offscreen_contexts =
414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          layer_tree_host_impl_->offscreen_context_provider())
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts->VerifyContexts();
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->DidLoseOutputSurface();
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame",
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               "enable", enable);
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(enable);
43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Sample the frame time now. This time will be used for updating animations
44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // when we draw.
44168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_impl_->CurrentFrameTimeTicks();
44268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginImplFrame(args);
44468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT1(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetCanDraw(can_draw);
451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::NotifyReadyToActivate() {
455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scheduler_on_impl_thread_->NotifyReadyToActivate();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsCommitOnImplThread() {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsCommit();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AnimationEventsVector> events,
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time wall_clock_time) {
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc",
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetAnimationEvents,
474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 main_thread_weak_ptr_,
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 base::Passed(&events),
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 wall_clock_time));
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          int priority_cutoff) {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!contents_texture_manager_on_impl_thread())
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!layer_tree_host_impl_->resource_provider())
4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool reduce_result = contents_texture_manager_on_impl_thread()->
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ReduceMemoryOnImplThread(limit_bytes,
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               priority_cutoff,
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               layer_tree_host_impl_->resource_provider());
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reduce_result)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The texture upload queue may reference textures that were just purged,
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clear them from the queue.
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_resource_update_controller_on_impl_thread_->
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DiscardUploadsToEvictedResources();
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SendManagedMemoryStats() {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!contents_texture_manager_on_impl_thread())
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are using impl-side painting, then SendManagedMemoryStats is called
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly after the tile manager's manage function, and doesn't need to
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // interact with main thread's layer tree.
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (layer_tree_host_impl_->settings().impl_side_painting)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SendManagedMemoryStats(
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->MemoryVisibleBytes(),
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          MemoryVisibleAndNearbyBytes(),
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_impl_thread()->MemoryUseBytes());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::IsInsideDraw() { return inside_draw_; }
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread,
532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 impl_thread_weak_ptr_,
533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 damage_rect));
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::SetNextCommitWaitsForActivation() {
537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(IsMainThread());
538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!inside_commit_);
539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = true;
540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetDeferCommits(bool defer_commits) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(defer_commits_, defer_commits);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  defer_commits_ = defer_commits;
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!defer_commits_ && pending_deferred_commit_)
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrame,
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   main_thread_weak_ptr_,
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Passed(&pending_deferred_commit_)));
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitRequested() const {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_requested_;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ThreadProxy::BeginMainFrameRequested() const {
5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(IsMainThread());
5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return commit_request_sent_to_impl_thread_;
5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawOnImplThread() {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
576d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::SetNeedsManageTilesOnImplThread() {
577d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(IsImplThread());
578d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsManageTiles();
579d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
580d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->SetViewportDamage(damage_rect);
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetNeedsRedrawOnImplThread();
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread(
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool used_incomplete_tile) {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (used_incomplete_tile) {
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TRACE_EVENT_INSTANT0(
59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "cc",
59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread",
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        TRACE_EVENT_SCOPE_THREAD);
59558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
59658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_on_impl_thread_->SetSwapUsedIncompleteTile(
59758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    used_incomplete_tile);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidInitializeVisibleTileOnImplThread() {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread");
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetNeedsRedraw();
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlinging() {
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThread());
608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread,
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 impl_thread_weak_ptr_));
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::MainThreadHasStoppedFlingingOnImplThread() {
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
61690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  layer_tree_host_impl_->MainThreadHasStoppedFlinging();
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::NotifyInputThrottledUntilCommit() {
620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsMainThread());
621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostTask(
622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&ThreadProxy::SetInputThrottledUntilCommitOnImplThread,
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 impl_thread_weak_ptr_,
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 true));
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ThreadProxy::SetInputThrottledUntilCommitOnImplThread(
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool is_throttled) {
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_throttled == input_throttled_until_commit_)
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  input_throttled_until_commit_ = is_throttled;
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RenewTreePriority();
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)LayerTreeHost* ThreadProxy::layer_tree_host() {
638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host_unsafe_;
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const LayerTreeHost* ThreadProxy::layer_tree_host() const {
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host_unsafe_;
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PrioritizedResourceManager*
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ThreadProxy::contents_texture_manager_on_main_thread() {
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsMainThread() || IsMainThreadBlocked());
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return layer_tree_host()->contents_texture_manager();
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PrioritizedResourceManager*
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ThreadProxy::contents_texture_manager_on_impl_thread() {
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsImplThread());
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return contents_texture_manager_unsafe_;
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(Proxy::HasImplThread());
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(first_output_surface);
663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create LayerTreeHostImpl.
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::InitializeImplOnImplThread,
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this),
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 &completion));
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  first_output_surface_ = first_output_surface.Pass();
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = true;
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::Stop() {
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::Stop");
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(started_);
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Synchronously finishes pending GL operations and deletes the impl.
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The two steps are done as separate post tasks, so that tasks posted
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // by the GL implementation due to the Finish can be executed by the
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // renderer before shutting it down.
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::FinishGLOnImplThread,
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion));
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::LayerTreeHostClosedOnImplThread,
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion));
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!layer_tree_host_impl_.get());  // verify that the impl deleted.
715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  contents_texture_manager_unsafe_ = NULL;
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host_unsafe_ = NULL;
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  started_ = false;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffers() {
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread,
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread(
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->renderer())
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->renderer()->DoNoOp();
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->FinishAllRendering();
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::ScheduledActionSendBeginMainFrame() {
7468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new BeginMainFrameAndCommitState);
7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->monotonic_frame_begin_time =
7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      layer_tree_host_impl_->CurrentPhysicalTimeTicks();
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->scroll_info =
75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      layer_tree_host_impl_->ProcessScrollDeltas();
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!layer_tree_host_impl_->settings().impl_side_painting) {
755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u);
756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_limit_bytes =
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->memory_allocation_limit_bytes();
7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->memory_allocation_priority_cutoff =
76068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      layer_tree_host_impl_->memory_allocation_priority_cutoff();
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_state->evicted_ui_resources =
76258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist();
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
7651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&ThreadProxy::BeginMainFrame,
76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 main_thread_weak_ptr_,
7671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 base::Passed(&begin_main_frame_state)));
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_sent_completion_event_on_impl_thread_) {
7701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_->Signal();
7711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    begin_main_frame_sent_completion_event_on_impl_thread_ = NULL;
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_sent_time_ = base::TimeTicks::HighResNow();
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrame(
7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (defer_commits_) {
7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_deferred_commit_ = begin_main_frame_state.Pass();
786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->DidDeferCommit();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the commit finishes, LayerTreeHost will transfer its swap promises to
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // swap promises.
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SwapPromiseChecker swap_promise_checker(layer_tree_host());
795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not notify the impl thread of commit requests that occur during
7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the apply/animate/layout part of the BeginMainFrameAndCommit process since
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those commit requests will get painted immediately. Once we have done
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the paint, commit_requested_ will be set to false to allow new commit
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // requests to be scheduled.
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = true;
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = true;
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On the other hand, the AnimationRequested flag needs to be cleared
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // here so that any animation requests generated by the apply or animate
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // callbacks will trigger another frame.
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  animate_requested_ = false;
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!in_composite_and_readback_ && !layer_tree_host()->visible()) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_requested_ = false;
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_request_sent_to_impl_thread_ = false;
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NotVisible");
814558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = false;
815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
8171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
818558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
819558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (begin_main_frame_state) {
824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->ApplyScrollAndScale(
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        *begin_main_frame_state->scroll_info);
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
827558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->WillBeginMainFrame();
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (begin_main_frame_state) {
831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->UpdateClientAnimations(
8321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->AnimateLayers(
8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        begin_main_frame_state->monotonic_frame_begin_time);
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Unlink any backings that the impl thread has evicted, so that we know to
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // re-paint them in UpdateLayers.
839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_on_main_thread()) {
840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_on_main_thread()->
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UnlinkAndClearEvictedBackings();
84268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (begin_main_frame_state) {
844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_main_thread()->SetMaxMemoryLimitBytes(
8451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_limit_bytes);
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      contents_texture_manager_on_main_thread()->SetExternalPriorityCutoff(
8471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          begin_main_frame_state->memory_allocation_priority_cutoff);
84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Recreate all UI resources if there were evicted UI resources when the impl
85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // thread initiated the commit.
8531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool evicted_ui_resources = begin_main_frame_state
8541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  ? begin_main_frame_state->evicted_ui_resources
8551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                  : false;
85658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (evicted_ui_resources)
857f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->RecreateUIResources();
85858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->Layout();
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear the commit flag after updating animations and layout here --- objects
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that only layout when painted will trigger another SetNeedsCommit inside
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UpdateLayers.
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_requested_ = false;
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_request_sent_to_impl_thread_ = false;
866558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool can_cancel_this_commit =
86758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      can_cancel_commit_ &&
86858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !in_composite_and_readback_ &&
86958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !evicted_ui_resources;
870558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = true;
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue =
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new ResourceUpdateQueue);
87468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool updated = layer_tree_host()->UpdateLayers(queue.get());
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Once single buffered layers are committed, they cannot be modified until
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they are drawn by the impl thread.
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = false;
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->WillCommit();
882558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
883558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!updated && can_cancel_this_commit) {
884558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    TRACE_EVENT0("cc", "EarlyOut_NoUpdates");
885558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool did_handle = true;
886558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
887558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        FROM_HERE,
8881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
889558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   impl_thread_weak_ptr_,
890558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                   did_handle));
891558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
892558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Although the commit is internally aborted, this is because it has been
893558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // detected to be a no-op.  From the perspective of an embedder, this commit
894558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // went through, and input should no longer be throttled, etc.
895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->CommitComplete();
896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->DidBeginMainFrame();
897558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
898558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
899558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
900558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Before calling animate, we set animate_requested_ to false. If it is true
901558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // now, it means SetNeedAnimate was called again, but during a state when
902558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // commit_request_sent_to_impl_thread_ = true. We need to force that call to
903558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // happen again now so that the commit request is sent to the impl thread.
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (animate_requested_) {
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Forces SetNeedsAnimate to consider posting a commit task.
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    animate_requested_ = false;
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetNeedsAnimate();
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
910a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<ContextProvider> offscreen_context_provider;
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renderer_capabilities_main_thread_copy_.using_offscreen_context3d &&
912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->needs_offscreen_context()) {
9134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    offscreen_context_provider =
914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->client()->OffscreenContextProvider();
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (offscreen_context_provider.get())
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      created_offscreen_context_provider_ = true;
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
91990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Notify the impl thread that the main thread is ready to commit. This will
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // begin the commit process, which is blocking from the main thread's
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // point of view, but asynchronously performed on the impl thread,
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // coordinated by the Scheduler.
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
9241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
928424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // This CapturePostTasks should be destroyed before CommitComplete() is
929424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // called since that goes out to the embedder, and we want the embedder
930424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // to receive its callbacks before that.
931424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    BlockingTaskRunner::CapturePostTasks blocked;
932424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent completion;
934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
93690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(&ThreadProxy::StartCommitOnImplThread,
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &completion,
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   queue.release(),
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   offscreen_context_provider));
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderingStatsInstrumentation* stats_instrumentation =
944f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        layer_tree_host()->rendering_stats_instrumentation();
9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        stats_instrumentation->main_thread_rendering_stats());
9473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    stats_instrumentation->AccumulateAndClearMainThreadStats();
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->CommitComplete();
951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidBeginMainFrame();
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
95490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::StartCommitOnImplThread(
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceUpdateQueue* raw_queue,
957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_refptr<ContextProvider> offscreen_context_provider) {
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!commit_completion_event_on_impl_thread_);
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread() && IsMainThreadBlocked());
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_) {
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TRACE_EVENT0("cc", "EarlyOut_NoLayerTree");
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion->Signal();
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (offscreen_context_provider.get())
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_context_provider->BindToCurrentThread();
974424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
975424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_unsafe_) {
978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_EQ(contents_texture_manager_unsafe_,
979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              contents_texture_manager_on_main_thread());
980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Cache this pointer that was created on the main thread side to avoid a
982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // data race between creating it and using it on the compositor thread.
983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_unsafe_ =
984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        contents_texture_manager_on_main_thread();
985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (contents_texture_manager_on_main_thread()) {
988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (contents_texture_manager_on_main_thread()->
989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            LinkedEvictedBackingsExist()) {
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Clear any uploads we were making to textures linked to evicted
991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // resources
992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      queue->ClearUploadsToEvictedResources();
993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Some textures in the layer tree are invalid. Kick off another commit
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // to fill them again.
995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetNeedsCommitOnImplThread();
996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    contents_texture_manager_on_main_thread()->
999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        PushTexturePrioritiesToBackings();
1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  commit_completion_event_on_impl_thread_ = completion;
1003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_ =
1004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ResourceUpdateController::Create(
1005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          this,
1006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          Proxy::ImplThreadTaskRunner(),
1007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          queue.Pass(),
1008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          layer_tree_host_impl_->resource_provider());
1009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
1010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scheduler_on_impl_thread_->AnticipatedDrawTime());
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
10141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread");
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_);
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scheduler_on_impl_thread_->CommitPending());
1018558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!layer_tree_host_impl_->pending_tree());
1019558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1020d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (did_handle)
1021a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetInputThrottledUntilCommitOnImplThread(false);
1022d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  layer_tree_host_impl_->BeginMainFrameAborted(did_handle);
10238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionCommit() {
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(commit_completion_event_on_impl_thread_);
1030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(current_resource_update_controller_on_impl_thread_);
1031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Complete all remaining texture updates.
1033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_->Finalize();
1034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  current_resource_update_controller_on_impl_thread_.reset();
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1036424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = true;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->BeginCommit();
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->BeginCommitOnImplThread(layer_tree_host_impl_.get());
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->FinishCommitOnImplThread(layer_tree_host_impl_.get());
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->CommitComplete();
1041424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  inside_commit_ = false;
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1043a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetInputThrottledUntilCommitOnImplThread(false);
1044a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1045424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_frame_is_newly_committed_frame_on_impl_thread_ = true;
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (layer_tree_host()->settings().impl_side_painting &&
1050424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      commit_waits_for_activation_) {
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For some layer types in impl-side painting, the commit is held until
10527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // the pending tree is activated.  It's also possible that the
10537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // pending tree has already activated if there was no work to be done.
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ =
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        commit_completion_event_on_impl_thread_;
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_->Signal();
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_completion_event_on_impl_thread_ = NULL;
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1063424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  commit_waits_for_activation_ = false;
1064424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
10657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_complete_time_ = base::TimeTicks::HighResNow();
10661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  begin_main_frame_to_commit_duration_history_.InsertSample(
10671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      commit_complete_time_ - begin_main_frame_sent_time_);
10687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetVisible kicks off the next scheduler action, so this must be last.
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1073ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ThreadProxy::ScheduledActionUpdateVisibleTiles() {
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1075ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles");
1076ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  layer_tree_host_impl_->UpdateVisibleTiles();
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1079424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ThreadProxy::ScheduledActionActivatePendingTree() {
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1081424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree");
1082424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->ActivatePendingTree();
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
10873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::MainThreadTaskRunner()->PostTask(
1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 main_thread_weak_ptr_));
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
109558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool forced_draw,
109658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool swap_requested,
109758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool readback_requested) {
109858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DrawSwapReadbackResult result;
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_draw = false;
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.did_swap = false;
110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result.did_readback = false;
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_.get());
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_)
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->renderer());
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_tree_host_impl_->renderer())
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::HighResNow();
111268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
111368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::AutoReset<bool> mark_inside(&inside_draw_, true);
111468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
111568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Advance our animations.
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks monotonic_time =
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->CurrentFrameTimeTicks();
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time wall_clock_time = layer_tree_host_impl_->CurrentFrameTime();
11194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(enne): This should probably happen post-animate.
11214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (layer_tree_host_impl_->pending_tree())
11224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->Animate(monotonic_time, wall_clock_time);
11247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called on a forced draw, regardless of whether we are able
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to produce a frame, as the calling site on main thread is blocked until its
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // request completes, and we signal completion here. If CanDraw() is false, we
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will indicate success=false to the caller, but we must still signal
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // completion to avoid deadlock.
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We guard PrepareToDraw() with CanDraw() because it always returns a valid
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame, so can only be used when such a frame is possible. Since
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CanDraw() as well.
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool drawing_for_readback =
113758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      readback_requested && !!readback_request_on_impl_thread_;
1138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostImpl::FrameData frame;
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool draw_frame = false;
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (layer_tree_host_impl_->CanDraw() &&
1144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      (!drawing_for_readback || can_do_readback)) {
1145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // If it is for a readback, make sure we draw the portion being read back.
1146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    gfx::Rect readback_rect;
1147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (drawing_for_readback)
1148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      readback_rect = readback_request_on_impl_thread_->rect;
1149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        forced_draw)
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      draw_frame = true;
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_frame) {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->DrawLayers(
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &frame,
11588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        scheduler_on_impl_thread_->LastBeginImplFrameTime());
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_draw = true;
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->DidDrawAllLayers(frame);
116268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
116368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool start_ready_animations = draw_frame;
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for a pending CompositeAndReadback.
116758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (drawing_for_readback) {
116858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!swap_requested);
116958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result.did_readback = false;
117058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (draw_frame && !layer_tree_host_impl_->IsContextLost()) {
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels,
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      readback_request_on_impl_thread_->rect);
117358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      result.did_readback = true;
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
117558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    readback_request_on_impl_thread_->success = result.did_readback;
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_->completion.Signal();
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    readback_request_on_impl_thread_ = NULL;
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (draw_frame) {
117958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(swap_requested);
1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
118258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We don't know if we have incomplete tiles if we didn't actually swap.
118358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (result.did_swap) {
118458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DCHECK(!frame.has_no_damage);
118558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      SetSwapUsedIncompleteTileOnImplThread(frame.contains_incomplete_tile);
118658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the main thread that the the newly-commited frame was drawn.
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (next_frame_is_newly_committed_frame_on_impl_thread_) {
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_frame_is_newly_committed_frame_on_impl_thread_ = false;
1192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::MainThreadTaskRunner()->PostTask(
1193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (draw_frame) {
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CheckOutputSurfaceStatusOnImplThread();
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_time;
12017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    draw_duration_history_.InsertSample(draw_duration);
12027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_overestimate;
12037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::TimeDelta draw_duration_underestimate;
12047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (draw_duration > draw_duration_estimate)
12057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_underestimate = draw_duration - draw_duration_estimate;
12067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else
12077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_overestimate = draw_duration_estimate - draw_duration;
12087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
12097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration,
12107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
12147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_underestimate,
12157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
12197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               draw_duration_overestimate,
12207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
12217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(100),
12227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               50);
12237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
12247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTextures() {
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when the main thread needs to modify a layer texture that is used
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directly by the compositor.
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method will block until the next compositor draw if there is a
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // previously committed frame that is still undrawn. This is necessary to
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ensure that the main thread does not monopolize access to the textures.
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (textures_acquired_)
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::AcquireLayerTextures");
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DebugScopedSetMainThreadBlocked main_thread_blocked(this);
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
1242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostTask(
1243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread,
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_,
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 &completion));
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Block until it is safe to write to layer textures from the main thread.
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion.Wait();
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_acquired_ = true;
1251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  can_cancel_commit_ = false;
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread(
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion) {
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!texture_acquisition_completion_event_on_impl_thread_);
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = completion;
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture_acquisition_completion_event_on_impl_thread_);
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_->Signal();
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_acquisition_completion_event_on_impl_thread_ = NULL;
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ThreadProxy::ScheduledActionManageTiles() {
1270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionManageTiles");
1271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  layer_tree_host_impl_->ManageTiles();
1273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
127558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
127658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
127758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = false;
127858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
127958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
128058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
128158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
128258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
128358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = true;
128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = false;
128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
129058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
129358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() {
129458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback");
129558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool forced_draw = true;
129658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool swap_requested = false;
129758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool readback_requested = true;
129858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return DrawSwapReadbackInternal(
129958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      forced_draw, swap_requested, readback_requested);
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (current_resource_update_controller_on_impl_thread_)
130468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    current_resource_update_controller_on_impl_thread_->PerformMoreUpdates(
130568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        time);
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TimeDelta ThreadProxy::DrawDurationEstimate() {
13097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta historical_estimate =
13107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      draw_duration_history_.Percentile(kDrawDurationEstimationPercentile);
13117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
13127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kDrawDurationEstimatePaddingInMicroseconds);
13137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return historical_estimate + padding;
13147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
13157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
13168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
13171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return begin_main_frame_to_commit_duration_history_.Percentile(
13187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
13197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
13227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return commit_to_activate_duration_history_.Percentile(
13237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      kCommitAndActivationDurationEstimationPercentile);
13247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
13278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                             base::TimeTicks deadline) {
13281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeDelta delta = deadline - gfx::FrameTime::Now();
132968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (delta <= base::TimeDelta())
133068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delta = base::TimeDelta();
133168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
133268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
133368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ThreadProxy::DidBeginImplFrameDeadline() {
13358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
13368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
13378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::ReadyToFinalizeTextureUpdates() {
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
134090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler_on_impl_thread_->FinishCommit();
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCommitAndDrawFrame() {
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidCommitAndDrawFrame();
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::DidCompleteSwapBuffers() {
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidCompleteSwapBuffers();
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events,
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     base::Time wall_clock_time) {
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!layer_tree_host())
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->SetAnimationEvents(events.Pass(), wall_clock_time);
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::CreateAndInitializeOutputSurface() {
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface");
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check that output surface has not been recreated by CompositeAndReadback
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after this task is posted but before it is run.
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_initialized_output_surface_on_impl_thread = true;
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent completion;
1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread,
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   impl_thread_weak_ptr_,
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &completion,
1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &has_initialized_output_surface_on_impl_thread));
1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    completion.Wait();
1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_initialized_output_surface_on_impl_thread)
1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DidLoseOutputSurface();
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.Reset(base::Bind(
1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &ThreadProxy::DoCreateAndInitializeOutputSurface,
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Unretained(this)));
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_surface_creation_callback_.callback().Run();
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::HasInitializedOutputSurfaceOnImplThread(
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CompletionEvent* completion,
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* has_initialized_output_surface) {
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *has_initialized_output_surface =
1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scheduler_on_impl_thread_->HasInitializedOutputSurface();
1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host_impl_ = layer_tree_host()->CreateLayerTreeHostImpl(this);
1406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const LayerTreeSettings& settings = layer_tree_host()->settings();
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings scheduler_settings;
140868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scheduler_settings.deadline_scheduling_enabled =
140968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      settings.deadline_scheduling_enabled;
1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.impl_side_painting = settings.impl_side_painting;
1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      settings.timeout_and_draw_when_animation_checkerboards;
141358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
141458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings.maximum_number_of_failed_draws_before_draw_is_forced_;
14157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scheduler_settings.using_synchronous_renderer_compositor =
14167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      settings.using_synchronous_renderer_compositor;
1417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduler_settings.throttle_frame_production =
1418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      settings.throttle_frame_production;
1419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings,
1420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      layer_tree_host_id_);
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::InitializeOutputSurfaceOnImplThread(
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompletionEvent* completion,
1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<OutputSurface> output_surface,
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<ContextProvider> offscreen_context_provider,
1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool* success,
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RendererCapabilities* capabilities) {
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsMainThreadBlocked());
1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(success);
1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(capabilities);
1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DeleteContentsTexturesOnImplThread(
1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (*success) {
144587f58e12eeb69005db1f255eab8e88bab8977eecboliu@chromium.org    *capabilities = layer_tree_host_impl_->GetRendererCapabilities()
144687f58e12eeb69005db1f255eab8e88bab8977eecboliu@chromium.org                        .MainThreadCapabilities();
1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
1448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (offscreen_context_provider.get()) {
1449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (offscreen_context_provider->BindToCurrentThread())
1450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider->VerifyContexts();
1451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    offscreen_context_provider = NULL;
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  layer_tree_host_impl_->SetOffscreenContextProvider(
1455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      offscreen_context_provider);
1456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) {
1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsImplThread());
1463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (layer_tree_host_impl_->resource_provider())
1464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_impl_->resource_provider()->Finish();
1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  completion->Signal();
1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
1471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layer_tree_host()->DeleteContentsTexturesOnImplThread(
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->resource_provider());
14734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  current_resource_update_controller_on_impl_thread_.reset();
14741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  layer_tree_host_impl_->SetNeedsBeginImplFrame(false);
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_on_impl_thread_.reset();
1476a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  layer_tree_host_impl_.reset();
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_on_impl_thread_.InvalidateWeakPtrs();
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t ThreadProxy::MaxPartialTextureUpdates() const {
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ResourceUpdateController::MaxPartialTextureUpdates();
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
148668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : memory_allocation_limit_bytes(0),
148768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_allocation_priority_cutoff(0),
148868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      evicted_ui_resources(false) {}
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::AsValue() const {
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompletionEvent completion;
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const_cast<ThreadProxy*>(this));
1499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
1501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&ThreadProxy::AsValueOnImplThread,
1502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   impl_thread_weak_ptr_,
1503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   &completion,
1504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   state.get()));
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    completion.Wait();
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return state.PassAs<base::Value>();
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion,
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::DictionaryValue* state) const {
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->Set("layer_tree_host_impl",
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             layer_tree_host_impl_->AsValue().release());
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  completion->Signal();
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThreadProxy::CommitPendingForTesting() {
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsMainThread());
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommitPendingRequest commit_pending_request;
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting,
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   impl_thread_weak_ptr_,
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &commit_pending_request));
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    commit_pending_request.completion.Wait();
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commit_pending_request.commit_pending;
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::CommitPendingOnImplThreadForTesting(
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommitPendingRequest* request) {
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsImplThread());
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface())
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = scheduler_on_impl_thread_->CommitPending();
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request->commit_pending = false;
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request->completion.Signal();
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::Value> ThreadProxy::SchedulerStateAsValueForTesting() {
15437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsImplThread())
1544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return scheduler_on_impl_thread_->StateAsValue().Pass();
15457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SchedulerStateRequest scheduler_state_request;
15477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
15487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Proxy::ImplThreadTaskRunner()->PostTask(
1550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
15513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting,
15527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   impl_thread_weak_ptr_,
15537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   &scheduler_state_request));
15547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scheduler_state_request.completion.Wait();
15557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
15563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scheduler_state_request.state.Pass();
15577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
15587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThreadProxy::SchedulerStateAsValueOnImplThreadForTesting(
15607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SchedulerStateRequest* request) {
15617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(IsImplThread());
1562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->state = scheduler_on_impl_thread_->StateAsValue();
15637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  request->completion.Signal();
15647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
15657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriority() {
1567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(IsImplThread());
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool smoothness_takes_priority =
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->pinch_gesture_active() ||
15704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      layer_tree_host_impl_->IsCurrentlyScrolling() ||
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_impl_->page_scale_animation_active();
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeTicks now = layer_tree_host_impl_->CurrentPhysicalTimeTicks();
15747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update expiration time if smoothness currently takes priority.
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (smoothness_takes_priority) {
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    smoothness_takes_priority_expiration_time_ =
15787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        now + base::TimeDelta::FromMilliseconds(
15797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  kSmoothnessTakesPriorityExpirationDelay * 1000);
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We use the same priority for both trees by default.
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Smoothness takes priority if expiration time is in the future.
15867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (smoothness_takes_priority_expiration_time_ > now)
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = SMOOTHNESS_TAKES_PRIORITY;
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // New content always takes priority when the active tree has
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // evicted resources or there is an invalid viewport size.
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->active_tree()->ContentsTexturesPurged() ||
1592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      layer_tree_host_impl_->active_tree()->ViewportSizeInvalid() ||
159358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host_impl_->EvictedUIResourcesExist() ||
1594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      input_throttled_until_commit_)
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    priority = NEW_CONTENT_TAKES_PRIORITY;
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_impl_->SetTreePriority(priority);
15981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scheduler_on_impl_thread_->SetSmoothnessTakesPriority(
15991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      priority == SMOOTHNESS_TAKES_PRIORITY);
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify the the client of this compositor via the output surface.
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(epenner): Route this to compositor-thread instead of output-surface
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after GTFO refactor of compositor-thread (http://crbug/170828).
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layer_tree_host_impl_->output_surface()) {
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_impl_->output_surface()->
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UpdateSmoothnessTakesPriority(priority == SMOOTHNESS_TAKES_PRIORITY);
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::TimeDelta delay = smoothness_takes_priority_expiration_time_ - now;
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Need to make sure a delayed task is posted when we have smoothness
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // takes priority expiration time in the future.
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delay <= base::TimeDelta())
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (renew_tree_priority_on_impl_thread_pending_)
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::RenewTreePriorityOnImplThread,
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_on_impl_thread_.GetWeakPtr()),
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = true;
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RenewTreePriorityOnImplThread() {
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(renew_tree_priority_on_impl_thread_pending_);
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  renew_tree_priority_on_impl_thread_pending_ = false;
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenewTreePriority();
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
1635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
1636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 impl_thread_weak_ptr_),
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delay);
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadProxy::StartScrollbarAnimationOnImplThread() {
16437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  layer_tree_host_impl_->StartScrollbarAnimation();
1644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1646a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ThreadProxy::DidActivatePendingTree() {
1647a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(IsImplThread());
1648a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
1649a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1650a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (completion_event_for_commit_held_on_tree_activation_ &&
1651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !layer_tree_host_impl_->pending_tree()) {
1652a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1653a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         TRACE_EVENT_SCOPE_THREAD);
1654a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1655a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_->Signal();
1656a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    completion_event_for_commit_held_on_tree_activation_ = NULL;
1657a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
16587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1659424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UpdateBackgroundAnimateTicking();
1660424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
16617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  commit_to_activate_duration_history_.InsertSample(
16627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::TimeTicks::HighResNow() - commit_complete_time_);
1663a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1664a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ThreadProxy::DidManageTiles() {
1666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsImplThread());
1667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler_on_impl_thread_->DidManageTiles();
1668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1671